From 5fdc9efa6267079ceb3d84c34a2d89a9534796d1 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 16 Apr 2019 18:43:30 -0500 Subject: [PATCH 0001/1172] MC-15901: Recursion in filter widget --- .../Magento/Catalog/Ui/Component/ColumnFactory.php | 1 + .../Ui/view/base/web/js/grid/filters/filters.js | 1 + lib/web/mage/utils/template.js | 12 +++++++++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index f7554219c6c3..1495d6a41d91 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -73,6 +73,7 @@ public function create($attribute, $context, array $config = []) 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, + '__disableTmpl' => true, ], $config); if ($attribute->usesSource()) { diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index 98c3eb1c6f88..e6ac0b2b80f4 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,6 +272,7 @@ define([ } filter = utils.extend({}, filters.base, filter); + filter.__disableTmpl = {label : true}; return utils.template(filter, { filters: this, diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 7aa695023cb5..861c352ee202 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -37,7 +37,7 @@ define([ * * @param {String} tmpl * @param {Object} target - * @returns {Boolean} + * @returns {Boolean|Object} */ function isTmplIgnored(tmpl, target) { var parsedTmpl; @@ -53,7 +53,7 @@ define([ if (typeof target !== 'undefined') { if (typeof target === 'object' && target.hasOwnProperty('__disableTmpl')) { - return true; + return target.__disableTmpl; } } @@ -201,6 +201,8 @@ define([ * Template iterator function. */ _.each(tmpl, function iterate(value, key, list) { + var disabled; + if (key === '$data') { return; } @@ -213,7 +215,11 @@ define([ } if (isTemplate(value)) { - list[key] = render(value, tmpl, castString, list); + disabled = isTmplIgnored(value, list); + + if (!((typeof disabled) == 'object' && disabled.hasOwnProperty(key) && disabled[key])) { + list[key] = render(value, tmpl, castString, list); + } } else if ($.isPlainObject(value) || Array.isArray(value)) { _.each(value, iterate); } From 29a98deda1da6b2b2a596668028049b8a32bd857 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 18 Apr 2019 10:52:54 -0500 Subject: [PATCH 0002/1172] MC-15901: Recursion in filter widget --- .../Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php | 1 + app/code/Magento/Catalog/Ui/Component/ColumnFactory.php | 2 +- app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js | 4 +++- lib/web/mage/utils/template.js | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php index 774edcfeb6b6..45d911f7e94e 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/ColumnFactoryTest.php @@ -111,6 +111,7 @@ public function testCreateWithNotFilterableInGridAttribute(array $filterModifier 'visible' => null, 'filter' => $filter, 'component' => 'Magento_Ui/js/grid/columns/column', + '__disableTmpl' => ['label' => true] ], ], 'context' => $this->context, diff --git a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php index 1495d6a41d91..491d945e4644 100644 --- a/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php +++ b/app/code/Magento/Catalog/Ui/Component/ColumnFactory.php @@ -73,7 +73,7 @@ public function create($attribute, $context, array $config = []) 'filter' => ($attribute->getIsFilterableInGrid() || array_key_exists($columnName, $filterModifiers)) ? $this->getFilterType($attribute->getFrontendInput()) : null, - '__disableTmpl' => true, + '__disableTmpl' => ['label' => true], ], $config); if ($attribute->usesSource()) { diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index e6ac0b2b80f4..26d21eac0c28 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,7 +272,9 @@ define([ } filter = utils.extend({}, filters.base, filter); - filter.__disableTmpl = {label : true}; + filter.__disableTmpl = { + label: true + }; return utils.template(filter, { filters: this, diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 861c352ee202..a459d73ff360 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -217,7 +217,7 @@ define([ if (isTemplate(value)) { disabled = isTmplIgnored(value, list); - if (!((typeof disabled) == 'object' && disabled.hasOwnProperty(key) && disabled[key])) { + if (typeof disabled !== 'object' || !disabled.hasOwnProperty(key) || !disabled[key]) { list[key] = render(value, tmpl, castString, list); } } else if ($.isPlainObject(value) || Array.isArray(value)) { From e51a4e2fa7b3930c964982f897981c72d7cc387e Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 18 Apr 2019 19:03:02 -0500 Subject: [PATCH 0003/1172] MC-15901: Recursion in filter widget --- .../view/base/web/js/grid/filters/filters.js | 11 ++++- lib/web/mage/utils/template.js | 43 +++++++++++++------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index 26d21eac0c28..c608400a6f17 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -272,14 +272,21 @@ define([ } filter = utils.extend({}, filters.base, filter); + //Accepting labels as is. filter.__disableTmpl = { - label: true + label: 1 }; - return utils.template(filter, { + filter = utils.template(filter, { filters: this, column: column }, true, true); + + filter.__disableTmpl = { + label: true + }; + + return filter; }, /** diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index a459d73ff360..cd3e66ef58cf 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -33,7 +33,11 @@ define([ })(); /** - * Validates template + * Objects can specify how to use templating for their properties - getting that configuration. + * + * To disable rendering for all properties of your object add __disableTmpl: true. + * To disable for specific property add __disableTmpl: {propertyName: true}. + * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}. * * @param {String} tmpl * @param {Object} target @@ -69,14 +73,10 @@ define([ * * @param {String} tmpl - Template string. * @param {Object} $ - Data object used in a template. - * @param {Object} target * @returns {String} Compiled template. */ - template = function (tmpl, $, target) { - - if (!isTmplIgnored(tmpl, target)) { - return eval('`' + tmpl + '`'); - } + template = function (tmpl, $) { + return eval('`' + tmpl + '`'); return tmpl; }; @@ -130,19 +130,22 @@ define([ * @param {Boolean} [castString=false] - Flag that indicates whether template * should be casted after evaluation to a value of another type or * that it should be leaved as a string. + * @param {Number|undefined} maxCycles Maximum number of rendering cycles, can be 0. * @returns {*} Compiled template. */ - function render(tmpl, data, castString, target) { - var last = tmpl; + function render(tmpl, data, castString, maxCycles) { + var last = tmpl, + cycles = 0; - while (~tmpl.indexOf(opener)) { - tmpl = template(tmpl, data, target); + while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { + tmpl = template(tmpl, data); if (tmpl === last) { break; } last = tmpl; + cycles++; } return castString ? @@ -201,7 +204,8 @@ define([ * Template iterator function. */ _.each(tmpl, function iterate(value, key, list) { - var disabled; + var disabled, + maxCycles; if (key === '$data') { return; @@ -215,11 +219,22 @@ define([ } if (isTemplate(value)) { + //Getting template disabling settings, can be true for all disabled and separate settings + //for each property. disabled = isTmplIgnored(value, list); - if (typeof disabled !== 'object' || !disabled.hasOwnProperty(key) || !disabled[key]) { - list[key] = render(value, tmpl, castString, list); + if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { + //Checking if specific settings for a property provided. + maxCycles = disabled[key]; + if (maxCycles === true) { + maxCycles = 0; + } + } else if (disabled === true) { + //Rendering for all properties is disabled. + maxCycles = 0; } + + list[key] = render(value, tmpl, castString, maxCycles); } else if ($.isPlainObject(value) || Array.isArray(value)) { _.each(value, iterate); } From 76c9f8353ff0f9437d970a4d73a1852149396202 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 19 Apr 2019 17:34:04 -0500 Subject: [PATCH 0004/1172] MC-15901: Recursion in filter widget --- lib/web/mage/utils/template.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index cd3e66ef58cf..192e6bddcf7a 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -77,8 +77,6 @@ define([ */ template = function (tmpl, $) { return eval('`' + tmpl + '`'); - - return tmpl; }; /*eslint-enable no-unused-vars, no-eval*/ @@ -130,7 +128,7 @@ define([ * @param {Boolean} [castString=false] - Flag that indicates whether template * should be casted after evaluation to a value of another type or * that it should be leaved as a string. - * @param {Number|undefined} maxCycles Maximum number of rendering cycles, can be 0. + * @param {Number|undefined} maxCycles - Maximum number of rendering cycles, can be 0. * @returns {*} Compiled template. */ function render(tmpl, data, castString, maxCycles) { @@ -226,10 +224,7 @@ define([ if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { //Checking if specific settings for a property provided. maxCycles = disabled[key]; - if (maxCycles === true) { - maxCycles = 0; - } - } else if (disabled === true) { + } else if (disabled === true || maxCycles === true) { //Rendering for all properties is disabled. maxCycles = 0; } From ac7fe775ef062af5ebe5bbfbb5cc85df1d212d86 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 19 Apr 2019 17:40:26 -0500 Subject: [PATCH 0005/1172] MC-15901: Recursion in filter widget --- lib/web/mage/utils/template.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 192e6bddcf7a..4032c9387904 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -224,7 +224,9 @@ define([ if (typeof disabled === 'object' && disabled.hasOwnProperty(key) && disabled[key] !== false) { //Checking if specific settings for a property provided. maxCycles = disabled[key]; - } else if (disabled === true || maxCycles === true) { + } + + if (disabled === true || maxCycles === true) { //Rendering for all properties is disabled. maxCycles = 0; } From 9051331d7782641ae855421340c0dbb27c8daaf1 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Mon, 22 Apr 2019 15:19:27 -0500 Subject: [PATCH 0006/1172] MC-15576: CMS block cache --- app/code/Magento/Cms/Block/Block.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php index d0d75ea69119..99c18c491394 100644 --- a/app/code/Magento/Cms/Block/Block.php +++ b/app/code/Magento/Cms/Block/Block.php @@ -18,6 +18,11 @@ class Block extends AbstractBlock implements \Magento\Framework\DataObject\Ident */ protected $_filterProvider; + /** + * Prefix for cache key of CMS block + */ + const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; + /** * Store manager * From 406024bc7abcc1d588211f00f01bd7606ae57c47 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Tue, 23 Apr 2019 15:03:55 -0500 Subject: [PATCH 0007/1172] MC-15132: Update XML Design --- .../Argument/Interpreter/ConfigurableObject.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index c40d26ab2f50..35a5fffd4526 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -13,6 +13,13 @@ */ class ConfigurableObject implements InterpreterInterface { + /** + * @var array + */ + private $classBlacklist = [ + \Zend\Code\Reflection\FileReflection::class + ]; + /** * @var ObjectManagerInterface */ @@ -53,6 +60,14 @@ public function evaluate(array $data) if (!isset($arguments['class'])) { throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } + + if (in_array(ltrim($arguments['class'], '\\'), $this->classBlacklist)) { + throw new \InvalidArgumentException(sprintf( + 'Class argument is invalid: %s', + $arguments['class'] + )); + } + $className = $arguments['class']; unset($arguments['class']); } From 966764b097664efdc34e6651703edb7ea27d01ab Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Wed, 24 Apr 2019 09:58:27 -0500 Subject: [PATCH 0008/1172] MC-15576: CMS block cache --- app/code/Magento/Cms/Block/Block.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Cms/Block/Block.php b/app/code/Magento/Cms/Block/Block.php index 99c18c491394..2ff740c9303b 100644 --- a/app/code/Magento/Cms/Block/Block.php +++ b/app/code/Magento/Cms/Block/Block.php @@ -14,14 +14,14 @@ class Block extends AbstractBlock implements \Magento\Framework\DataObject\IdentityInterface { /** - * @var \Magento\Cms\Model\Template\FilterProvider + * Prefix for cache key of CMS block */ - protected $_filterProvider; + const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; /** - * Prefix for cache key of CMS block + * @var \Magento\Cms\Model\Template\FilterProvider */ - const CACHE_KEY_PREFIX = 'CMS_BLOCK_'; + protected $_filterProvider; /** * Store manager From fe7fbce272c0c0fdd06b7eaadede0bd18cfe8212 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Wed, 24 Apr 2019 23:01:24 -0500 Subject: [PATCH 0009/1172] MC-15811: Incorrect Url Added Store Switcher Added Controller Added Unit test. --- .../Magento/Backend/etc/adminhtml/system.xml | 5 - .../Store/Controller/Store/SwitchRequest.php | 131 +++++++++++ .../Model/StoreSwitcher/HashGenerator.php | 88 ++++++++ .../Store/Setup/Patch/Data/DisableSid.php | 80 +++++++ .../Controller/Store/SwitchRequestTest.php | 128 +++++++++++ app/code/Magento/Store/etc/config.xml | 2 +- app/code/Magento/Store/etc/di.xml | 1 + .../Magento/Store/etc/frontend/sections.xml | 1 + .../Framework/Session/SidResolverTest.php | 210 ------------------ .../Magento/Framework/Session/SidResolver.php | 1 + 10 files changed, 431 insertions(+), 216 deletions(-) create mode 100644 app/code/Magento/Store/Controller/Store/SwitchRequest.php create mode 100644 app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php create mode 100644 app/code/Magento/Store/Setup/Patch/Data/DisableSid.php create mode 100644 app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 98b8e702b1c5..e58335d95dc6 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -583,11 +583,6 @@ Magento\Config\Model\Config\Source\Yesno - - - Allows customers to stay logged in when switching between different stores. - Magento\Config\Model\Config\Source\Yesno - diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php new file mode 100644 index 000000000000..af2d20b5fba8 --- /dev/null +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -0,0 +1,131 @@ +storeRepository = $storeRepository; + $this->customerSession = $session; + $this->deploymentConfig = $deploymentConfig; + $this->customerRepository=$customerRepository; + } + + /** + * Execute action + * + * @return void + */ + public function execute() + { + $fromStoreCode = (string)$this->_request->getParam('___from_store'); + $customerId = (int)$this->_request->getParam('customer_id'); + $timeStamp = (string)$this->_request->getParam('time_stamp'); + $targetStoreCode = $this->_request->getParam('___to_store'); + $signature = (string)$this->_request->getParam('signature'); + $error = null; + + try { + /** @var \Magento\Store\Model\Store $fromStore */ + $fromStore = $this->storeRepository->get($fromStoreCode); + } catch (NoSuchEntityException $e) { + $error = __('Requested store is not found.'); + } + + if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { + try { + $customer = $this->customerRepository->getById($customerId); + if (!$this->customerSession->isLoggedIn()) { + $this->customerSession->setCustomerDataAsLoggedIn($customer); + } + } catch (NoSuchEntityException $e) { + $error = __('The requested customer does not exist.'); + } catch (LocalizedException $e) { + $error = __('There was an error retrieving the customer record.'); + } + } else { + $error = __('Invalid request. Store switching action cannot be performed at this time.'); + } + + if ($error !== null) { + $this->messageManager->addErrorMessage($error); + $this->getResponse()->setRedirect('/'); + } else { + $this->getResponse()->setRedirect("/$targetStoreCode"); + } + } + + /** + * Validates one time token + * + * @param int $customerId + * @param string $timeStamp + * @param string $signature + * @param string $fromStoreCode + * @return bool + */ + private function validateHash(int $customerId, string $timeStamp, string $signature, string $fromStoreCode): bool + { + + if ($customerId && $timeStamp && $signature) { + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $data, $key))) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php new file mode 100644 index 000000000000..4a8549f299ed --- /dev/null +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -0,0 +1,88 @@ +customerSession = $customerSession; + $this->deploymentConfig = $deploymentConfig; + $this->urlHelper=$urlHelper; + } + + /** + * Builds redirect url with token + * + * @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; + $customerId = $this->customerSession->getId(); + + if ($customerId) { + $urlParts = parse_url($targetUrl); + $host = $urlParts['host']; + $scheme = $urlParts['scheme']; + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $timeStamp = time(); + $fromStoreCode = $fromStore->getCode(); + $targetStoreCode=$targetStore->getCode(); + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $key); + $targetUrl = $scheme . "://" . $host.'/stores/store/switchrequest'; + $targetUrl = $this->urlHelper->addRequestParam( + $targetUrl, + ['customer_id' => $this->customerSession->getId()] + ); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); + } + return $targetUrl; + } +} diff --git a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php new file mode 100644 index 000000000000..129f5538f5cd --- /dev/null +++ b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php @@ -0,0 +1,80 @@ +mutableScopeConfig=$mutableScopeConfig; + $this->_scopeType=$scopeType; + } + + /** + * {@inheritdoc} + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function apply() + { + $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, $this->_scopeType); + } + + /** + * {@inheritdoc} + */ + public static function getDependencies() + { + return []; + } + + /** + * {@inheritdoc} + */ + public static function getVersion() + { + return '2.0.0'; + } + + /** + * {@inheritdoc} + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php new file mode 100644 index 000000000000..a8d4472145de --- /dev/null +++ b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php @@ -0,0 +1,128 @@ +customerSessionMock = $this->getMockBuilder(CustomerSession::class) + ->disableOriginalConstructor()->getMock(); + $this->customerRepositoryMock = + $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); + $this->storeRepositoryMock = + $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) + ->disableOriginalConstructor()->setMethods(['get'])->getMockForAbstractClass(); + + $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); + $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) + ->disableOriginalConstructor() + ->setMethods(['setRedirect']) + ->getMockForAbstractClass(); + $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) + ->disableOriginalConstructor()->getMock(); + $this->storeMock = $this->getMockBuilder(StoreInterface::class) + ->disableOriginalConstructor() + ->setMethods(['getBaseUrl']) + ->getMockForAbstractClass(); + + $this->model = (new ObjectManager($this))->getObject( + \Magento\Store\Controller\Store\SwitchRequest::class, + [ + 'customerSession' => $this->customerRepositoryMock, + 'deploymentConfig' => $this->deploymentConfigMock, + 'storeRepository' => $this->storeRepositoryMock, + 'customerRepository' => $this->customerRepositoryMock, + '_request' => $this->requestMock, + '_response' => $this->responseMock, + ] + ); + } + + /** + * @return void + */ + public function testExecute() + { + $fromStoreCode = 'sv2'; + $targetStoreCode = 'default'; + $expectedRedirectUrl='/'; + $customerId=5; + $timestamp='1556131830'; + + $this->requestMock->method('getParam') + ->willReturnMap([ + ['___from_store', null, $fromStoreCode], + ['customer_id', null, $customerId], + ['time_stamp', null, $timestamp], + ['___to_store', null, $targetStoreCode], + ['signature', null, 'cbc099b3cc4a9a8f3a78a97e7a579ceff19a2b26a6c88b08f0f58442ea5bd968'] + ]); + + $this->storeRepositoryMock + ->expects($this->once()) + ->method('get') + ->with($fromStoreCode) + ->willReturn($this->storeMock); + + $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); + $this->model->execute(); + } +} \ No newline at end of file diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index b9e7ac1c6aca..23182c8d7647 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -83,7 +83,7 @@ 0 0 0 - 1 + 0 1 diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index defe0694d018..62f6f4142402 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -436,6 +436,7 @@ Magento\Store\Model\StoreSwitcher\CleanTargetUrl Magento\Store\Model\StoreSwitcher\ManageStoreCookie Magento\Store\Model\StoreSwitcher\ManagePrivateContent + Magento\Store\Model\StoreSwitcher\HashGenerator diff --git a/app/code/Magento/Store/etc/frontend/sections.xml b/app/code/Magento/Store/etc/frontend/sections.xml index b1a9fc3cb1d7..b7dbfe405263 100644 --- a/app/code/Magento/Store/etc/frontend/sections.xml +++ b/app/code/Magento/Store/etc/frontend/sections.xml @@ -8,4 +8,5 @@ + diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php deleted file mode 100644 index 5e70eb491b50..000000000000 --- a/dev/tests/integration/testsuite/Magento/Framework/Session/SidResolverTest.php +++ /dev/null @@ -1,210 +0,0 @@ -session = $objectManager->get(\Magento\Framework\Session\Generic::class); - - $this->scopeConfig = $this->getMockBuilder( - \Magento\Framework\App\Config\ScopeConfigInterface::class - )->setMethods( - ['getValue'] - )->disableOriginalConstructor()->getMockForAbstractClass(); - - $this->urlBuilder = $this->getMockBuilder( - \Magento\Framework\Url::class - )->setMethods( - ['isOwnOriginUrl'] - )->disableOriginalConstructor()->getMockForAbstractClass(); - - $this->request = $objectManager->get(\Magento\Framework\App\RequestInterface::class); - - $this->appState = $this->getMockBuilder(State::class) - ->setMethods(['getAreaCode']) - ->disableOriginalConstructor() - ->getMock(); - - $this->model = $objectManager->create( - \Magento\Framework\Session\SidResolver::class, - [ - 'scopeConfig' => $this->scopeConfig, - 'urlBuilder' => $this->urlBuilder, - 'sidNameMap' => [$this->customSessionName => $this->customSessionQueryParam], - 'request' => $this->request, - 'appState' => $this->appState, - ] - ); - } - - public function tearDown() - { - $this->request->setQuery(new Parameters()); - } - - /** - * @param mixed $sid - * @param bool $useFrontedSid - * @param bool $isOwnOriginUrl - * @param mixed $testSid - * @dataProvider dataProviderTestGetSid - */ - public function testGetSid($sid, $useFrontedSid, $isOwnOriginUrl, $testSid) - { - $this->appState->expects($this->atLeastOnce()) - ->method('getAreaCode') - ->willReturn(\Magento\Framework\App\Area::AREA_FRONTEND); - - $this->scopeConfig->expects( - $this->any() - )->method( - 'isSetFlag' - )->with( - \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - )->will( - $this->returnValue($useFrontedSid) - ); - - $this->urlBuilder->expects($this->any())->method('isOwnOriginUrl')->will($this->returnValue($isOwnOriginUrl)); - - if ($testSid) { - $this->request->getQuery()->set($this->model->getSessionIdQueryParam($this->session), $testSid); - } - $this->assertEquals($sid, $this->model->getSid($this->session)); - $this->assertEquals($useFrontedSid, $this->model->getUseSessionInUrl()); - } - - /** - * @return array - */ - public function dataProviderTestGetSid() - { - return [ - [null, false, false, 'test-sid'], - [null, false, true, 'test-sid'], - [null, false, false, 'test-sid'], - [null, true, false, 'test-sid'], - [null, false, true, 'test-sid'], - ['test-sid', true, true, 'test-sid'], - [null, true, true, null] - ]; - } - - public function testGetSessionIdQueryParam() - { - $this->assertEquals(SidResolver::SESSION_ID_QUERY_PARAM, $this->model->getSessionIdQueryParam($this->session)); - } - - public function testGetSessionIdQueryParamCustom() - { - $this->session->destroy(); - $oldSessionName = $this->session->getName(); - $this->session->setName($this->customSessionName); - $this->assertEquals($this->customSessionQueryParam, $this->model->getSessionIdQueryParam($this->session)); - $this->session->setName($oldSessionName); - $this->session->start(); - } - - public function testSetGetUseSessionVar() - { - $this->assertFalse($this->model->getUseSessionVar()); - $this->model->setUseSessionVar(true); - $this->assertTrue($this->model->getUseSessionVar()); - } - - /** - * Variations of Use SID on frontend value. - * - * @return array - */ - public function dataProviderSessionInUrl() - { - return [ - [true], - [false], - ]; - } - - /** - * Testing "Use SID in URLs" flag. - * Checking that the method returns config value if not explicitly - * overridden. - * - * @param bool $configValue Use SID on frontend config value. - * @dataProvider dataProviderSessionInUrl - */ - public function testSetGetUseSessionInUrl($configValue) - { - $this->scopeConfig->expects( - $this->any() - )->method( - 'isSetFlag' - )->with( - \Magento\Framework\Session\SidResolver::XML_PATH_USE_FRONTEND_SID, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - )->will( - $this->returnValue($configValue) - ); - - $this->assertEquals($configValue, $this->model->getUseSessionInUrl()); - $this->model->setUseSessionInUrl(!$configValue); - $this->assertEquals(!$configValue, $this->model->getUseSessionInUrl()); - } -} diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 1208aeb31eae..117c46f3443a 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -11,6 +11,7 @@ /** * Class SidResolver + * @deprecated 2.3.2 */ class SidResolver implements SidResolverInterface { From 25e7ae6d50d6fe4acbb7637361cda7842c9af820 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 12:43:29 -0500 Subject: [PATCH 0010/1172] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 1 + .../Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php | 2 ++ .../Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php | 1 + .../Product/Form/Modifier/Data/AssociatedProducts.php | 5 +++++ 4 files changed, 9 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index 97bc00bc7dd6..f279cc5150d7 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -50,6 +50,7 @@ public function getAllOptions() $this->_options[] = [ 'label' => __($attribute['frontend_label']), 'value' => $attribute['attribute_code'], + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 209fd235bcd6..bc15c269df1c 100755 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -671,6 +671,7 @@ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupC 'scopeLabel' => $this->getScopeLabel($attribute), 'globalScope' => $this->isScopeGlobal($attribute), 'sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER, + '__disableTmpl' => ['label' => true, 'code' => true] ]); // TODO: Refactor to $attribute->getOptions() when MAGETWO-48289 is done @@ -816,6 +817,7 @@ public function setupAttributeContainerMeta(ProductAttributeInterface $attribute 'breakLine' => false, 'label' => $attribute->getDefaultFrontendLabel(), 'required' => $attribute->getIsRequired(), + '__disableTmpl' => ['label' => true] ] ); diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php index 4874dc8ea03a..a7bdaaab64cb 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php @@ -411,6 +411,7 @@ private function prepareAttributes( 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], + '__disableTmpl' => true ]; foreach ($attribute->getOptions() as $option) { if (!empty($option->getValue())) { diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index c474acbec509..45a48a37e5ce 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -213,6 +213,7 @@ public function getConfigurableAttributesData() 'code' => $attribute['code'], 'label' => $attribute['label'], 'position' => $attribute['position'], + '__disableTmpl' => true ]; foreach ($attribute['chosen'] as $chosenOption) { @@ -261,6 +262,7 @@ protected function prepareVariations() 'id' => $attribute->getAttributeId(), 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], + '__disableTmpl' => true ]; foreach ($attribute->getOptions() as $option) { if (!empty($option->getValue())) { @@ -270,6 +272,7 @@ protected function prepareVariations() 'id' => $option->getValue(), 'label' => $option->getLabel(), 'value' => $option->getValue(), + '__disableTmpl' => true ]; } } @@ -281,6 +284,7 @@ protected function prepareVariations() 'id' => $optionId, 'label' => $variation[$attribute->getId()]['label'], 'value' => $optionId, + '__disableTmpl' => true ]; $variationOptions[] = $variationOption; $attributes[$attribute->getAttributeId()]['chosen'][$optionId] = $variationOption; @@ -306,6 +310,7 @@ protected function prepareVariations() 'newProduct' => 0, 'attributes' => $this->getTextAttributes($variationOptions), 'thumbnail_image' => $this->imageHelper->init($product, 'product_thumbnail_image')->getUrl(), + '__disableTmpl' => true ]; $productIds[] = $product->getId(); } From 2d3bb5074882cff729697338c0d6030f495f06f2 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 13:30:29 -0500 Subject: [PATCH 0011/1172] MC-15811: Incorrect Url Fix static errors. Modify unit test. Fix store patch. --- .../Store/Controller/Store/SwitchRequest.php | 12 ++++++--- .../Model/StoreSwitcher/HashGenerator.php | 26 ++++++++++++++----- .../Store/Setup/Patch/Data/DisableSid.php | 26 ++++++++----------- .../Controller/Store/SwitchRequestTest.php | 23 +++++++++++----- app/code/Magento/Store/composer.json | 3 ++- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index af2d20b5fba8..d962e6be64de 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -8,7 +8,7 @@ namespace Magento\Store\Controller\Store; use Magento\Framework\App\Action\Context; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; @@ -16,11 +16,12 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; +use Magento\Store\Model\StoreIsInactiveException; /** * Builds correct url to target store and performs redirect. */ -class SwitchRequest extends \Magento\Framework\App\Action\Action +class SwitchRequest extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface { /** * @var StoreRepositoryInterface @@ -78,10 +79,12 @@ public function execute() $error = null; try { - /** @var \Magento\Store\Model\Store $fromStore */ $fromStore = $this->storeRepository->get($fromStoreCode); + $this->storeRepository->getActiveStoreByCode($targetStoreCode); } catch (NoSuchEntityException $e) { $error = __('Requested store is not found.'); + } catch (StoreIsInactiveException $e) { + $error = __('Requested store is inactive.'); } if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { @@ -101,7 +104,8 @@ public function execute() if ($error !== null) { $this->messageManager->addErrorMessage($error); - $this->getResponse()->setRedirect('/'); + //redirect to previous store + $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); } else { $this->getResponse()->setRedirect("/$targetStoreCode"); } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 4a8549f299ed..56a865f8e2fd 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -13,6 +13,7 @@ use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Authorization\Model\UserContextInterface; /** * Generate one time token and build redirect url @@ -35,19 +36,27 @@ class HashGenerator implements StoreSwitcherInterface */ private $urlHelper; + /** + * @var UserContextInterface + */ + private $currentUser; + /** * @param CustomerSession $customerSession * @param DeploymentConfig $deploymentConfig * @param UrlHelper $urlHelper + * @param UserContextInterface $currentUser */ public function __construct( CustomerSession $customerSession, DeploymentConfig $deploymentConfig, - UrlHelper $urlHelper + UrlHelper $urlHelper, + UserContextInterface $currentUser ) { $this->customerSession = $customerSession; $this->deploymentConfig = $deploymentConfig; - $this->urlHelper=$urlHelper; + $this->urlHelper = $urlHelper; + $this->currentUser = $currentUser; } /** @@ -61,22 +70,27 @@ public function __construct( public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string { $targetUrl = $redirectUrl; - $customerId = $this->customerSession->getId(); + $customerId = null; + + if ($this->currentUser->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER) { + $customerId = $this->currentUser->getUserId(); + } if ($customerId) { + // phpcs:ignore $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); - $targetStoreCode=$targetStore->getCode(); + $targetStoreCode = $targetStore->getCode(); $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); $signature = hash_hmac('sha256', $data, $key); - $targetUrl = $scheme . "://" . $host.'/stores/store/switchrequest'; + $targetUrl = $scheme . "://" . $host . '/stores/store/switchrequest'; $targetUrl = $this->urlHelper->addRequestParam( $targetUrl, - ['customer_id' => $this->customerSession->getId()] + ['customer_id' => $customerId] ); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); diff --git a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php index 129f5538f5cd..95df83043f15 100644 --- a/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php +++ b/app/code/Magento/Store/Setup/Patch/Data/DisableSid.php @@ -11,8 +11,7 @@ use \Magento\Framework\App\Config\MutableScopeConfigInterface; /** - * Class CreateDefaultPages - * @package Magento\Cms\Setup\Patch + * Disable default frontend SID */ class DisableSid implements DataPatchInterface, PatchVersionInterface { @@ -28,34 +27,31 @@ class DisableSid implements DataPatchInterface, PatchVersionInterface private $mutableScopeConfig; /** - * @var string + * scope type */ - protected $_scopeType; + const SCOPE_STORE = 'store'; /** * Disable Sid constructor. + * * @param MutableScopeConfigInterface $mutableScopeConfig - * @param string $scopeType */ public function __construct( - MutableScopeConfigInterface $mutableScopeConfig, - $scopeType + MutableScopeConfigInterface $mutableScopeConfig ) { - $this->mutableScopeConfig=$mutableScopeConfig; - $this->_scopeType=$scopeType; + $this->mutableScopeConfig = $mutableScopeConfig; } /** - * {@inheritdoc} - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @inheritdoc */ public function apply() { - $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, $this->_scopeType); + $this->mutableScopeConfig->setValue(self::XML_PATH_USE_FRONTEND_SID, 0, self::SCOPE_STORE); } /** - * {@inheritdoc} + * @inheritdoc */ public static function getDependencies() { @@ -63,7 +59,7 @@ public static function getDependencies() } /** - * {@inheritdoc} + * @inheritdoc */ public static function getVersion() { @@ -71,7 +67,7 @@ public static function getVersion() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAliases() { diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php index a8d4472145de..ebd85d89c23a 100644 --- a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php +++ b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php @@ -13,7 +13,7 @@ use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; /** - * Test class for \Magento\Store\Controller\Store\SwitchAction + * Test class for \Magento\Store\Controller\Store\SwitchRequest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SwitchRequestTest extends \PHPUnit\Framework\TestCase @@ -51,7 +51,7 @@ class SwitchRequestTest extends \PHPUnit\Framework\TestCase /** * @var DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject */ - private $storeMock; + private $fromStoreMock; /** * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject @@ -69,7 +69,7 @@ protected function setUp() $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); $this->storeRepositoryMock = $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) - ->disableOriginalConstructor()->setMethods(['get'])->getMockForAbstractClass(); + ->disableOriginalConstructor()->setMethods(['get', 'getActiveStoreByCode'])->getMockForAbstractClass(); $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) @@ -78,7 +78,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) ->disableOriginalConstructor()->getMock(); - $this->storeMock = $this->getMockBuilder(StoreInterface::class) + $this->fromStoreMock = $this->getMockBuilder(StoreInterface::class) ->disableOriginalConstructor() ->setMethods(['getBaseUrl']) ->getMockForAbstractClass(); @@ -120,9 +120,20 @@ public function testExecute() ->expects($this->once()) ->method('get') ->with($fromStoreCode) - ->willReturn($this->storeMock); + ->willReturn($this->fromStoreMock); + + $this->storeRepositoryMock + ->expects($this->once()) + ->method('getActiveStoreByCode') + ->with($targetStoreCode); + + $this->fromStoreMock + ->expects($this->once()) + ->method('getBaseUrl') + ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) + ->willReturn($expectedRedirectUrl); $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); $this->model->execute(); } -} \ No newline at end of file +} diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index da408f105ccb..390c6214d59a 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -12,7 +12,8 @@ "magento/module-config": "*", "magento/module-directory": "*", "magento/module-media-storage": "*", - "magento/module-ui": "*" + "magento/module-ui": "*", + "magento/module-customer":"*" }, "suggest": { "magento/module-deploy": "*" From 25a8d8c0312a6347a47b292cea65c36e0903e849 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 15:39:42 -0500 Subject: [PATCH 0012/1172] MC-15811: Incorrect Url Add composer dependency. Fix Unit test. Fix static failure in controller. --- .../Magento/Store/Controller/Store/SwitchRequest.php | 2 +- .../Store/Model/StoreSwitcher/HashGenerator.php | 10 ---------- app/code/Magento/Store/composer.json | 3 ++- .../testsuite/Magento/Framework/UrlTest.php | 7 ------- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index d962e6be64de..e243cc912134 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -132,4 +132,4 @@ private function validateHash(int $customerId, string $timeStamp, string $signat } return false; } -} \ No newline at end of file +} diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 56a865f8e2fd..be110f965f74 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -9,7 +9,6 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreSwitcherInterface; -use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; @@ -20,12 +19,6 @@ */ class HashGenerator implements StoreSwitcherInterface { - - /** - * @var \Magento\Customer\Model\Session - */ - private $customerSession; - /** * @var \Magento\Framework\App\DeploymentConfig */ @@ -42,18 +35,15 @@ class HashGenerator implements StoreSwitcherInterface private $currentUser; /** - * @param CustomerSession $customerSession * @param DeploymentConfig $deploymentConfig * @param UrlHelper $urlHelper * @param UserContextInterface $currentUser */ public function __construct( - CustomerSession $customerSession, DeploymentConfig $deploymentConfig, UrlHelper $urlHelper, UserContextInterface $currentUser ) { - $this->customerSession = $customerSession; $this->deploymentConfig = $deploymentConfig; $this->urlHelper = $urlHelper; $this->currentUser = $currentUser; diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json index 390c6214d59a..8af8db8d935a 100644 --- a/app/code/Magento/Store/composer.json +++ b/app/code/Magento/Store/composer.json @@ -13,7 +13,8 @@ "magento/module-directory": "*", "magento/module-media-storage": "*", "magento/module-ui": "*", - "magento/module-customer":"*" + "magento/module-customer": "*", + "magento/module-authorization": "*" }, "suggest": { "magento/module-deploy": "*" diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 9d1d8761a16a..47e814c96d50 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -20,13 +20,6 @@ protected function setUp() $this->model = Bootstrap::getObjectManager()->create(\Magento\Framework\Url::class); } - public function testSetGetUseSession() - { - $this->assertTrue((bool)$this->model->getUseSession()); - $this->model->setUseSession(false); - $this->assertFalse($this->model->getUseSession()); - } - public function testSetRouteFrontName() { $value = 'route'; From be6ade8dcd4a9a156cd8e18d7377baba7e538801 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 16:01:35 -0500 Subject: [PATCH 0013/1172] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 3 +-- app/code/Magento/Catalog/Model/Category/DataProvider.php | 3 +++ .../Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php | 6 ++++++ .../Product/Form/Modifier/Data/AssociatedProducts.php | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index f279cc5150d7..2e152a569619 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -49,8 +49,7 @@ public function getAllOptions() foreach ($this->_getCatalogConfig()->getAttributesUsedForSortBy() as $attribute) { $this->_options[] = [ 'label' => __($attribute['frontend_label']), - 'value' => $attribute['attribute_code'], - '__disableTmpl' => true + 'value' => $attribute['attribute_code'] ]; } } diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index a4127c9a97ff..d3c4bfb8494b 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -340,6 +340,9 @@ public function getAttributesMeta(Type $entityType) } if ($attribute->usesSource()) { $meta[$code]['options'] = $attribute->getSource()->getAllOptions(); + foreach ($meta[$code]['options'] as &$option) { + $option['__disableTmpl'] = true; + } } } diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index 91a09c907de6..ddaa520d7f75 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -563,6 +563,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_not_new_locked_and_required' => [ @@ -582,6 +583,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], 'locked' => true, ], @@ -602,6 +604,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_new_and_not_required' => [ @@ -621,6 +624,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ], 'default_null_prod_new_locked_and_not_required' => [ @@ -640,6 +644,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], 'locked' => true, ], @@ -660,6 +665,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, + '__disableTmpl' => true ], ] ]; diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index 45a48a37e5ce..e98da6b6e425 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -21,6 +21,8 @@ use Magento\Framework\Escaper; /** + * Loads data for product configurations. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AssociatedProducts @@ -232,6 +234,7 @@ public function getConfigurableAttributesData() * * @return void * @throws \Zend_Currency_Exception + * phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ protected function prepareVariations() { @@ -321,6 +324,7 @@ protected function prepareVariations() $this->productIds = $productIds; $this->productAttributes = array_values($attributes); } + //phpcs: enable /** * Get JSON string that contains attribute code and value From 2d924eff1fff9fdc3e16511a99d8806595fd1340 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 25 Apr 2019 17:53:08 -0500 Subject: [PATCH 0014/1172] MC-15901: Recursion in filter widget --- .../Catalog/Model/Category/Attribute/Source/Sortby.php | 2 +- app/code/Magento/Catalog/Model/Category/DataProvider.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php index 2e152a569619..4dda2fe5786e 100644 --- a/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php +++ b/app/code/Magento/Catalog/Model/Category/Attribute/Source/Sortby.php @@ -40,7 +40,7 @@ protected function _getCatalogConfig() } /** - * {@inheritdoc} + * @inheritdoc */ public function getAllOptions() { diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index d3c4bfb8494b..8db6ab8c228c 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -210,6 +210,8 @@ public function getMeta() } /** + * Add 'use default checkbox' to attributes that can have it. + * * @param Category $category * @param array $meta * @return array @@ -501,6 +503,7 @@ private function convertValues($category, $categoryData) $stat = $fileInfo->getStat($fileName); $mime = $fileInfo->getMimeType($fileName); + // phpcs:ignore Magento2.Functions.DiscouragedFunction $categoryData[$attributeCode][0]['name'] = basename($fileName); if ($fileInfo->isBeginsWithMediaDirectoryPath($fileName)) { @@ -536,6 +539,8 @@ public function getDefaultMetaData($result) } /** + * List form field sets and fields. + * * @return array * @since 101.0.0 */ From 045f5520373222ea49e21a0bc7ef9d52124a18d1 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 25 Apr 2019 18:43:49 -0500 Subject: [PATCH 0015/1172] MC-15811: Incorrect Url Add class annotation. --- dev/tests/integration/testsuite/Magento/Framework/UrlTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 47e814c96d50..21f0ebd5b77f 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -8,6 +8,9 @@ use Zend\Stdlib\Parameters; use Magento\TestFramework\Helper\Bootstrap; +/** + * Test class for \Magento\Framework\Url + */ class UrlTest extends \PHPUnit\Framework\TestCase { /** From 38f2f3ad7451fb73b2ffc5e6be179840d8e9445f Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 26 Apr 2019 11:48:28 -0500 Subject: [PATCH 0016/1172] MC-15901: Recursion in filter widget --- .../DataProvider/Product/Form/Modifier/EavTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php index ddaa520d7f75..599d10c24027 100755 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/EavTest.php @@ -563,7 +563,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_not_new_locked_and_required' => [ @@ -583,7 +583,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -604,7 +604,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_and_not_required' => [ @@ -624,7 +624,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ], 'default_null_prod_new_locked_and_not_required' => [ @@ -644,7 +644,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], 'locked' => true, ], @@ -665,7 +665,7 @@ public function setupAttributeMetaDataProvider() 'scopeLabel' => '', 'globalScope' => false, 'sortOrder' => 0, - '__disableTmpl' => true + '__disableTmpl' => ['label' => true, 'code' => true] ], ] ]; From 2e9c607c12f2c065a74c4390cdaf23e9c5ff2485 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 29 Apr 2019 12:20:23 -0500 Subject: [PATCH 0017/1172] MC-15901: Recursion in filter widget --- .../app/Magento/Catalog/Test/Handler/Category/Curl.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php index 5c54b366b7ab..fb9d6e9772c7 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Category/Curl.php @@ -251,8 +251,13 @@ protected function getBlockId($landingName) $curl->write($url, [], CurlInterface::GET); $response = $curl->read(); $curl->close(); - preg_match('~\{"value":"(\d+)","label":"' . preg_quote($landingName) . '"\}~', $response, $matches); - $id = isset($matches[1]) ? (int)$matches[1] : null; + $id = null; + //Finding block option in 'Add block' options UI data. + preg_match('~\{[^\{\}]*?"label":"' . preg_quote($landingName) . '"[^\{\}]*?\}~', $response, $matches); + if (!empty($matches)) { + $blockOption = json_decode($matches[0], true); + $id = (int)$blockOption['value']; + } return $id; } From b5cb8f12faf14a013477bb4c164a336324a962c5 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Mon, 29 Apr 2019 15:47:46 -0500 Subject: [PATCH 0018/1172] MC-16045: Update symfony/http-foundation --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 06ab71ee7597..96c36a8b7cf3 100644 --- a/composer.lock +++ b/composer.lock @@ -8983,16 +8983,16 @@ }, { "name": "symfony/http-foundation", - "version": "v4.2.4", + "version": "v4.2.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "850a667d6254ccf6c61d853407b16f21c4579c77" + "reference": "6ebbe61f48069033225c9d3fa7eb5ed116d766d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/850a667d6254ccf6c61d853407b16f21c4579c77", - "reference": "850a667d6254ccf6c61d853407b16f21c4579c77", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6ebbe61f48069033225c9d3fa7eb5ed116d766d6", + "reference": "6ebbe61f48069033225c9d3fa7eb5ed116d766d6", "shasum": "" }, "require": { @@ -9033,7 +9033,7 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-02-26T08:03:39+00:00" + "time": "2019-04-17T14:56:00+00:00" }, { "name": "symfony/options-resolver", From 7c86433a2202eb1002dd29f423962ee5e6b95b94 Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu Date: Tue, 30 Apr 2019 00:27:17 +0300 Subject: [PATCH 0019/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Implemented validation URL key during category creation --- .../CategoryUrlPathAutogeneratorObserver.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index 713dd6ac0c73..95ddceed6ec8 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -3,13 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\CatalogUrlRewrite\Observer; use Magento\Catalog\Model\Category; use Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator; use Magento\CatalogUrlRewrite\Service\V1\StoreViewService; use Magento\Catalog\Api\CategoryRepositoryInterface; -use Magento\Framework\Event\Observer; use Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider; use Magento\Framework\Event\ObserverInterface; use Magento\Store\Model\Store; @@ -19,6 +20,14 @@ */ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface { + + /** + * Reserved endpoint names. + * + * @var array + */ + private $invalidValues = ['admin', 'soap', 'rest', 'graphql']; + /** * @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator */ @@ -72,7 +81,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($category->getUrlKey() !== false && !$useDefaultAttribute) { $resultUrlKey = $this->categoryUrlPathGenerator->getUrlKey($category); $this->updateUrlKey($category, $resultUrlKey); - } else if ($useDefaultAttribute) { + } elseif ($useDefaultAttribute) { $resultUrlKey = $category->formatUrlKey($category->getOrigData('name')); $this->updateUrlKey($category, $resultUrlKey); $category->setUrlKey(null)->setUrlPath(null); @@ -92,6 +101,17 @@ private function updateUrlKey($category, $urlKey) if (empty($urlKey)) { throw new \Magento\Framework\Exception\LocalizedException(__('Invalid URL key')); } + + if (in_array($urlKey, $this->invalidValues)) { + throw new \Magento\Framework\Exception\LocalizedException( + __( + 'URL key "%1" conflicts with reserved endpoint names: %2. Try another url key.', + $urlKey, + implode(', ', $this->invalidValues) + ) + ); + } + $category->setUrlKey($urlKey) ->setUrlPath($this->categoryUrlPathGenerator->getUrlPath($category)); if (!$category->isObjectNew()) { From 9672ace6359e41fd39825d732d747e3d9c149db0 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Wed, 1 May 2019 09:55:22 -0500 Subject: [PATCH 0020/1172] MC-15811: Incorrect Url Add integration test for token validator. Refactor validation logic from controller. --- .../Store/Controller/Store/SwitchRequest.php | 43 ++---- .../Model/StoreSwitcher/HashGenerator.php | 25 +++- .../Magento/Store/Model/HashGeneratorTest.php | 137 ++++++++++++++++++ 3 files changed, 176 insertions(+), 29 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index e243cc912134..6d97487df67b 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -13,7 +13,7 @@ use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; -use Magento\Framework\Config\ConfigOptionsListConstants; +use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; use Magento\Store\Model\StoreIsInactiveException; @@ -43,25 +43,33 @@ class SwitchRequest extends \Magento\Framework\App\Action\Action implements Http */ private $customerRepository; + /** + * @var HashGenerator + */ + private $hashGenerator; + /** * @param Context $context * @param StoreRepositoryInterface $storeRepository * @param CustomerSession $session * @param DeploymentConfig $deploymentConfig * @param CustomerRepositoryInterface $customerRepository + * @param HashGenerator $hashGenerator */ public function __construct( Context $context, StoreRepositoryInterface $storeRepository, CustomerSession $session, DeploymentConfig $deploymentConfig, - CustomerRepositoryInterface $customerRepository + CustomerRepositoryInterface $customerRepository, + HashGenerator $hashGenerator ) { parent::__construct($context); $this->storeRepository = $storeRepository; $this->customerSession = $session; $this->deploymentConfig = $deploymentConfig; - $this->customerRepository=$customerRepository; + $this->customerRepository = $customerRepository; + $this->hashGenerator = $hashGenerator; } /** @@ -80,14 +88,15 @@ public function execute() try { $fromStore = $this->storeRepository->get($fromStoreCode); - $this->storeRepository->getActiveStoreByCode($targetStoreCode); + $targetStore=$this->storeRepository->getActiveStoreByCode($targetStoreCode); + $targetUrl=$targetStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); } catch (NoSuchEntityException $e) { $error = __('Requested store is not found.'); } catch (StoreIsInactiveException $e) { $error = __('Requested store is inactive.'); } - if ($this->validateHash($customerId, $timeStamp, $signature, $fromStoreCode)) { + if ($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])) { try { $customer = $this->customerRepository->getById($customerId); if (!$this->customerSession->isLoggedIn()) { @@ -107,29 +116,7 @@ public function execute() //redirect to previous store $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); } else { - $this->getResponse()->setRedirect("/$targetStoreCode"); - } - } - - /** - * Validates one time token - * - * @param int $customerId - * @param string $timeStamp - * @param string $signature - * @param string $fromStoreCode - * @return bool - */ - private function validateHash(int $customerId, string $timeStamp, string $signature, string $fromStoreCode): bool - { - - if ($customerId && $timeStamp && $signature) { - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); - if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $data, $key))) { - return true; - } + $this->getResponse()->setRedirect($targetUrl); } - return false; } } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index be110f965f74..0e0e77b04f94 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -71,6 +71,7 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; + $path=$urlParts['path']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); @@ -82,11 +83,33 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $targetUrl, ['customer_id' => $customerId] ); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => time()]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => $timeStamp]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); + $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['path' => $path]); } return $targetUrl; } + + /** + * Validates one time token + * + * @param string $signature + * @param array $data + * @return bool + */ + public function validateHash(string $signature, array $data): bool + { + if (!empty($signature) && !empty($data)) { + $timeStamp = $data[1] ?? 0; + $value = implode(",", $data); + $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + + if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $value, $key))) { + return true; + } + } + return false; + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php new file mode 100644 index 000000000000..7b5bb357b934 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -0,0 +1,137 @@ +objectManager = Bootstrap::getObjectManager(); + $session = $this->objectManager->create( + Session::class + ); + $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); + $customer = $this->accountManagement->authenticate('customer@example.com', 'password'); + $session->setCustomerDataAsLoggedIn($customer); + $this->customerSessionUserContext = $this->objectManager->create( + \Magento\Customer\Model\Authorization\CustomerSessionUserContext::class, + ['customerSession' => $session] + ); + $this->hashGenerator = $this->objectManager->create( + StoreSwitcher\HashGenerator::class, + ['currentUser' => $this->customerSessionUserContext] + ); + $this->customerId = $customer->getId(); + $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); + $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + } + + /** + * @magentoDataFixture Magento/Store/_files/store.php + * @magentoDataFixture Magento/Store/_files/second_store.php + * @magentoDataFixture Magento/Customer/_files/customer.php + * @return void + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testSwitch(): void + { + $redirectUrl = "http://domain.com/"; + $fromStoreCode = 'test'; + $toStoreCode = 'fixture_second_store'; + /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ + $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); + $fromStore = $storeRepository->get($fromStoreCode); + $toStore = $storeRepository->get($toStoreCode); + $timeStamp = time(); + $data = implode(',', [$this->customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $customerId = $this->customerId; + + $expectedUrl = "http://domain.com/stores/store/switchrequest?customer_id=$customerId"; + $expectedUrl .= "&time_stamp=$timeStamp&signature=$signature"; + $expectedUrl .= "&___from_store=$fromStoreCode&___to_store=$toStoreCode"; + $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); + } + + /** + * @return void + */ + public function testValidateHashWithCorrectData(): void + { + $timeStamp = time(); + $customerId = $this->customerId; + $fromStoreCode = 'test'; + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $this->assertTrue($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + } + + /** + * @return void + */ + public function testValidateHashWithInCorrectData(): void + { + $timeStamp = 0; + $customerId = 8; + $fromStoreCode = 'test'; + $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); + $signature = hash_hmac('sha256', $data, $this->key); + $this->assertFalse($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + } +} From b4562e0a0d738c65818f4a8bb5a194fa275ee3a0 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Wed, 1 May 2019 15:51:31 -0500 Subject: [PATCH 0021/1172] MC-15975: Fixed incorrect behavior of template variables --- lib/internal/Magento/Framework/Filter/Template.php | 3 ++- .../Magento/Framework/Filter/Test/Unit/TemplateTest.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 6a04e8e8c695..38198bb9a717 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -81,7 +81,8 @@ class Template implements \Zend_Filter_Interface 'settemplateprocessor', 'gettemplateprocessor', 'vardirective', - 'delete' + 'delete', + 'getdatausingmethod' ]; /** diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php index 0ee3a06ce542..b7f76cb35953 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/TemplateTest.php @@ -445,7 +445,8 @@ public function disallowedMethods() ['setTemplateProcessor'], ['getTemplateProcessor'], ['varDirective'], - ['delete'] + ['delete'], + ['getDataUsingMethod'] ]; } } From 02babd14eaf25752c8bef5949773c09a0f3ebcc0 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 11:19:47 +0300 Subject: [PATCH 0022/1172] MC-13886: Downloadable Product controller|API save changes --- .../Helper/Plugin/Downloadable.php | 81 +++++++++++++++- .../Downloadable/Model/Link/Builder.php | 13 ++- .../Model/Link/ContentValidator.php | 80 +++++++++++----- .../Downloadable/Model/LinkRepository.php | 96 ++++++++++++++----- .../Model/Sample/ContentValidator.php | 55 ++++++++--- .../Downloadable/Model/SampleRepository.php | 38 ++++---- .../Helper/Plugin/DownloadableTest.php | 19 +++- .../Unit/Model/Link/ContentValidatorTest.php | 25 ++++- .../Model/Sample/ContentValidatorTest.php | 25 ++++- .../Product/Form/Modifier/Data/Links.php | 20 +++- .../Product/Form/Modifier/Data/Samples.php | 18 +++- .../Downloadable/Api/LinkRepositoryTest.php | 69 +++++++++++++ .../Api/ProductRepositoryTest.php | 5 +- .../Downloadable/Api/SampleRepositoryTest.php | 31 ++++++ 14 files changed, 484 insertions(+), 91 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php index a283891afc40..f310b376633d 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Downloadable.php @@ -5,11 +5,14 @@ */ namespace Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin; -use Magento\Framework\App\RequestInterface; +use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +use Magento\Downloadable\Api\Data\SampleInterfaceFactory; +use Magento\Downloadable\Helper\Download; use Magento\Downloadable\Model\Link\Builder as LinkBuilder; +use Magento\Downloadable\Model\Product\Type; +use Magento\Downloadable\Model\ResourceModel\Sample\Collection; use Magento\Downloadable\Model\Sample\Builder as SampleBuilder; -use Magento\Downloadable\Api\Data\SampleInterfaceFactory; -use Magento\Downloadable\Api\Data\LinkInterfaceFactory; +use Magento\Framework\App\RequestInterface; /** * Class for initialization downloadable info from request. @@ -42,8 +45,6 @@ class Downloadable private $linkBuilder; /** - * Constructor - * * @param RequestInterface $request * @param LinkBuilder $linkBuilder * @param SampleBuilder $sampleBuilder @@ -79,14 +80,18 @@ public function afterInitialize( \Magento\Catalog\Model\Product $product ) { if ($downloadable = $this->request->getPost('downloadable')) { + $product->setTypeId(Type::TYPE_DOWNLOADABLE); $product->setDownloadableData($downloadable); $extension = $product->getExtensionAttributes(); + $productLinks = $product->getTypeInstance()->getLinks($product); + $productSamples = $product->getTypeInstance()->getSamples($product); if (isset($downloadable['link']) && is_array($downloadable['link'])) { $links = []; foreach ($downloadable['link'] as $linkData) { if (!$linkData || (isset($linkData['is_delete']) && $linkData['is_delete'])) { continue; } else { + $linkData = $this->processLink($linkData, $productLinks); $links[] = $this->linkBuilder->setData( $linkData )->build( @@ -104,6 +109,7 @@ public function afterInitialize( if (!$sampleData || (isset($sampleData['is_delete']) && (bool)$sampleData['is_delete'])) { continue; } else { + $sampleData = $this->processSample($sampleData, $productSamples); $samples[] = $this->sampleBuilder->setData( $sampleData )->build( @@ -124,4 +130,69 @@ public function afterInitialize( } return $product; } + + /** + * Check Links type and status. + * + * @param array $linkData + * @param array $productLinks + * @return array + */ + private function processLink(array $linkData, array $productLinks): array + { + $linkId = $linkData['link_id'] ?? null; + if ($linkId && isset($productLinks[$linkId])) { + $linkData = $this->processFileStatus($linkData, $productLinks[$linkId]->getLinkFile()); + $linkData['sample'] = $this->processFileStatus( + $linkData['sample'] ?? [], + $productLinks[$linkId]->getSampleFile() + ); + } else { + $linkData = $this->processFileStatus($linkData, null); + $linkData['sample'] = $this->processFileStatus($linkData['sample'] ?? [], null); + } + + return $linkData; + } + + /** + * Check Sample type and status. + * + * @param array $sampleData + * @param Collection $productSamples + * @return array + */ + private function processSample(array $sampleData, Collection $productSamples): array + { + $sampleId = $sampleData['sample_id'] ?? null; + /** @var \Magento\Downloadable\Model\Sample $productSample */ + $productSample = $sampleId ? $productSamples->getItemById($sampleId) : null; + if ($sampleId && $productSample) { + $sampleData = $this->processFileStatus($sampleData, $productSample->getSampleFile()); + } else { + $sampleData = $this->processFileStatus($sampleData, null); + } + + return $sampleData; + } + + /** + * Compare file path from request with DB and set status. + * + * @param array $data + * @param string|null $file + * @return array + */ + private function processFileStatus(array $data, ?string $file): array + { + if (isset($data['type']) && $data['type'] === Download::LINK_TYPE_FILE && isset($data['file']['0']['file'])) { + if ($data['file'][0]['file'] !== $file) { + $data['file'][0]['status'] = 'new'; + } else { + $data['file'][0]['status'] = 'old'; + } + } + + return $data; + } } diff --git a/app/code/Magento/Downloadable/Model/Link/Builder.php b/app/code/Magento/Downloadable/Model/Link/Builder.php index 83d01f76fe9c..ff76f7eeda44 100644 --- a/app/code/Magento/Downloadable/Model/Link/Builder.php +++ b/app/code/Magento/Downloadable/Model/Link/Builder.php @@ -69,6 +69,8 @@ public function __construct( } /** + * Set Data. + * * @param array $data * @return $this * @since 100.1.0 @@ -80,6 +82,8 @@ public function setData(array $data) } /** + * Build correct data structure. + * * @param \Magento\Downloadable\Api\Data\LinkInterface $link * @return \Magento\Downloadable\Api\Data\LinkInterface * @throws \Magento\Framework\Exception\LocalizedException @@ -134,6 +138,8 @@ public function build(\Magento\Downloadable\Api\Data\LinkInterface $link) } /** + * Reset data. + * * @return void */ private function resetData() @@ -142,6 +148,8 @@ private function resetData() } /** + * Get existing component or create new. + * * @return Link */ private function getComponent() @@ -153,6 +161,8 @@ private function getComponent() } /** + * Build correct sample structure. + * * @param \Magento\Downloadable\Api\Data\LinkInterface $link * @param array $sample * @return \Magento\Downloadable\Api\Data\LinkInterface @@ -174,7 +184,8 @@ private function buildSample(\Magento\Downloadable\Api\Data\LinkInterface $link, ), \Magento\Downloadable\Api\Data\LinkInterface::class ); - if ($link->getSampleType() === \Magento\Downloadable\Helper\Download::LINK_TYPE_FILE) { + if ($link->getSampleType() === \Magento\Downloadable\Helper\Download::LINK_TYPE_FILE + && isset($sample['file'])) { $linkSampleFileName = $this->downloadableFile->moveFileFromTmp( $this->getComponent()->getBaseSampleTmpPath(), $this->getComponent()->getBaseSamplePath(), diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 088356caefad..8497bf7de659 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -6,10 +6,16 @@ namespace Magento\Downloadable\Model\Link; use Magento\Downloadable\Api\Data\LinkInterface; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator; use Magento\Framework\Exception\InputException; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +/** + * Class to validate Link Content. + */ class ContentValidator { /** @@ -22,20 +28,28 @@ class ContentValidator */ protected $urlValidator; + /** + * @var File + */ + private $fileHelper; + /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param File|null $fileHelper */ public function __construct( FileContentValidator $fileContentValidator, - UrlValidator $urlValidator + UrlValidator $urlValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); } /** - * Check if link content is valid + * Check if link content is valid. * * @param LinkInterface $link * @param bool $validateLinkContent @@ -63,50 +77,66 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid if ($validateSampleContent) { $this->validateSampleResource($link); } + return true; } /** - * Validate link resource (file or URL) + * Validate link resource (file or URL). * * @param LinkInterface $link - * @throws InputException * @return void + * @throws InputException */ protected function validateLinkResource(LinkInterface $link) { - if ($link->getLinkType() == 'url' - && !$this->urlValidator->isValid($link->getLinkUrl()) - ) { - throw new InputException(__('Link URL must have valid format.')); - } - if ($link->getLinkType() == 'file' - && (!$link->getLinkFileContent() - || !$this->fileContentValidator->isValid($link->getLinkFileContent())) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + if ($link->getLinkType() === 'url') { + if (!$this->urlValidator->isValid($link->getLinkUrl())) { + throw new InputException(__('Link URL must have valid format.')); + } + } elseif ($link->getLinkFileContent()) { + if (!$this->fileContentValidator->isValid($link->getLinkFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($link->getBasePath() . $link->getLinkFile())) { + throw new InputException(__('Link file not found. Please try again.')); } } /** - * Validate sample resource (file or URL) + * Validate sample resource (file or URL). * * @param LinkInterface $link - * @throws InputException * @return void + * @throws InputException */ protected function validateSampleResource(LinkInterface $link) { - if ($link->getSampleType() == 'url' - && !$this->urlValidator->isValid($link->getSampleUrl()) - ) { - throw new InputException(__('Sample URL must have valid format.')); + if ($link->getSampleType() === 'url') { + if (!$this->urlValidator->isValid($link->getSampleUrl())) { + throw new InputException(__('Sample URL must have valid format.')); + } + } elseif ($link->getSampleFileContent()) { + if (!$this->fileContentValidator->isValid($link->getSampleFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($link->getBaseSamplePath() . $link->getSampleFile())) { + throw new InputException(__('Link sample file not found. Please try again.')); } - if ($link->getSampleType() == 'file' - && (!$link->getSampleFileContent() - || !$this->fileContentValidator->isValid($link->getSampleFileContent())) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + + /** + * Check that Links File or Sample is valid. + * + * @param string $file + * @return bool + */ + private function isFileValid(string $file): bool + { + try { + return $this->fileHelper->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; } } } diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php index 0898f1924e53..57e0fee5c118 100644 --- a/app/code/Magento/Downloadable/Model/LinkRepository.php +++ b/app/code/Magento/Downloadable/Model/LinkRepository.php @@ -97,7 +97,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getList($sku) { @@ -107,6 +107,8 @@ public function getList($sku) } /** + * @inheritdoc + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @return array */ @@ -166,9 +168,11 @@ protected function setBasicFields($resourceData, $dataObject) } /** - * {@inheritdoc} + * @inheritdoc + * * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * @throws InputException */ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) { @@ -181,24 +185,23 @@ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) __('The product needs to be the downloadable type. Verify the product and try again.') ); } - $validateLinkContent = !($link->getLinkType() === 'file' && $link->getLinkFile()); - $validateSampleContent = !($link->getSampleType() === 'file' && $link->getSampleFile()); - if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) { + $this->validateLinkType($link); + $validateSampleContent = $this->isValidateSample($link); + if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } - - if (!in_array($link->getLinkType(), ['url', 'file'], true)) { - throw new InputException(__('The link type is invalid. Verify and try again.')); - } $title = $link->getTitle(); if (empty($title)) { throw new InputException(__('The link title is empty. Enter the link title and try again.')); } + return $this->saveLink($product, $link, $isGlobalScopeContent); } } /** + * Construct Data structure and Save it. + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param LinkInterface $link * @param bool $isGlobalScopeContent @@ -220,7 +223,7 @@ protected function saveLink( 'is_shareable' => $link->getIsShareable(), ]; - if ($link->getLinkType() == 'file' && $link->getLinkFile() === null) { + if ($link->getLinkType() == 'file' && $link->getLinkFileContent() !== null) { $linkData['file'] = $this->jsonEncoder->encode( [ $this->fileContentUploader->upload($link->getLinkFileContent(), 'link_file'), @@ -242,7 +245,7 @@ protected function saveLink( if ($link->getSampleType() == 'file') { $linkData['sample']['type'] = 'file'; - if ($link->getSampleFile() === null) { + if ($link->getSampleFileContent() !== null) { $fileData = [ $this->fileContentUploader->upload($link->getSampleFileContent(), 'link_sample_file'), ]; @@ -269,6 +272,8 @@ protected function saveLink( } /** + * Update existing Link. + * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param LinkInterface $link * @param bool $isGlobalScopeContent @@ -298,9 +303,9 @@ protected function updateLink( __("The downloadable link isn't related to the product. Verify the link and try again.") ); } - $validateLinkContent = !($link->getLinkFileContent() === null); - $validateSampleContent = !($link->getSampleFileContent() === null); - if (!$this->contentValidator->isValid($link, $validateLinkContent, $validateSampleContent)) { + $this->validateLinkType($link); + $validateSampleContent = $this->isValidateSample($link); + if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } if ($isGlobalScopeContent) { @@ -312,20 +317,16 @@ protected function updateLink( throw new InputException(__('The link title is empty. Enter the link title and try again.')); } } - - if ($link->getLinkType() == 'file' && $link->getLinkFileContent() === null && !$link->getLinkFile()) { - $link->setLinkFile($existingLink->getLinkFile()); - } - if ($link->getSampleType() == 'file' && $link->getSampleFileContent() === null && !$link->getSampleFile()) { - $link->setSampleFile($existingLink->getSampleFile()); + if (!$validateSampleContent) { + $this->resetLinkSampleContent($link, $existingLink); } - $this->saveLink($product, $link, $isGlobalScopeContent); + return $existingLink->getId(); } /** - * {@inheritdoc} + * @inheritdoc */ public function delete($id) { @@ -344,6 +345,57 @@ public function delete($id) return true; } + /** + * Check that Link type exist. + * + * @param LinkInterface $link + * @throws \Magento\Framework\Exception\InputException + */ + private function validateLinkType(LinkInterface $link): void + { + if (!in_array($link->getLinkType(), ['url', 'file'], true)) { + throw new InputException(__('The link type is invalid. Verify and try again.')); + } + } + + /** + * Check that Link sample type exist. + * + * @param \Magento\Downloadable\Api\Data\LinkInterface $link + * @return bool + * @throws \Magento\Framework\Exception\InputException + */ + private function isValidateSample(LinkInterface $link): bool + { + if ($link->hasSampleType()) { + if (in_array($link->getSampleType(), ['url', 'file'], true)) { + return true; + } else { + throw new InputException(__('The link sample type is invalid. Verify and try again.')); + } + } + + return false; + } + + /** + * Reset Sample type and file. + * + * @param LinkInterface $link + * @param LinkInterface $existingLink + * @return void + */ + private function resetLinkSampleContent(LinkInterface $link, LinkInterface $existingLink): void + { + $existingType = $existingLink->getSampleType(); + $link->setSampleType($existingType); + if ($existingType === 'file') { + $link->setSampleFile($existingLink->getSampleFile()); + } else { + $link->setSampleUrl($existingLink->getSampleUrl()); + } + } + /** * Get MetadataPool instance * diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 6a273bfe5d34..7348b04793a8 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -6,10 +6,16 @@ namespace Magento\Downloadable\Model\Sample; use Magento\Downloadable\Api\Data\SampleInterface; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\File\ContentValidator as FileContentValidator; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +/** + * Class to validate Sample Content. + */ class ContentValidator { /** @@ -22,20 +28,28 @@ class ContentValidator */ protected $fileContentValidator; + /** + * @var File + */ + private $fileHelper; + /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param File|null $fileHelper */ public function __construct( FileContentValidator $fileContentValidator, - UrlValidator $urlValidator + UrlValidator $urlValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); } /** - * Check if sample content is valid + * Check if sample content is valid. * * @param SampleInterface $sample * @param bool $validateSampleContent @@ -51,29 +65,44 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) if ($validateSampleContent) { $this->validateSampleResource($sample); } + return true; } /** - * Validate sample resource (file or URL) + * Validate sample resource (file or URL). * * @param SampleInterface $sample - * @throws InputException * @return void + * @throws InputException */ protected function validateSampleResource(SampleInterface $sample) { - $sampleFile = $sample->getSampleFileContent(); - if ($sample->getSampleType() == 'file' - && (!$sampleFile || !$this->fileContentValidator->isValid($sampleFile)) - ) { - throw new InputException(__('Provided file content must be valid base64 encoded data.')); + if ($sample->getSampleType() === 'url') { + if (!$this->urlValidator->isValid($sample->getSampleUrl())) { + throw new InputException(__('Sample URL must have valid format.')); + } + } elseif ($sample->getSampleFileContent()) { + if (!$this->fileContentValidator->isValid($sample->getSampleFileContent())) { + throw new InputException(__('Provided file content must be valid base64 encoded data.')); + } + } elseif (!$this->isFileValid($sample->getBasePath() . $sample->getSampleFile())) { + throw new InputException(__('Sample file not found. Please try again.')); } + } - if ($sample->getSampleType() == 'url' - && !$this->urlValidator->isValid($sample->getSampleUrl()) - ) { - throw new InputException(__('Sample URL must have valid format.')); + /** + * Check that Samples file is valid. + * + * @param string $file + * @return bool + */ + private function isFileValid(string $file): bool + { + try { + return $this->fileHelper->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; } } } diff --git a/app/code/Magento/Downloadable/Model/SampleRepository.php b/app/code/Magento/Downloadable/Model/SampleRepository.php index 07c7631fade1..37f376e66624 100644 --- a/app/code/Magento/Downloadable/Model/SampleRepository.php +++ b/app/code/Magento/Downloadable/Model/SampleRepository.php @@ -189,17 +189,12 @@ public function save( __('The product needs to be the downloadable type. Verify the product and try again.') ); } - $validateSampleContent = !($sample->getSampleType() === 'file' && $sample->getSampleFile()); - if (!$this->contentValidator->isValid($sample, $validateSampleContent)) { + $this->validateSampleType($sample); + if (!$this->contentValidator->isValid($sample, true)) { throw new InputException( __('The sample information is invalid. Verify the information and try again.') ); } - - if (!in_array($sample->getSampleType(), ['url', 'file'], true)) { - throw new InputException(__('The sample type is invalid. Verify the sample type and try again.')); - } - $title = $sample->getTitle(); if (empty($title)) { throw new InputException(__('The sample title is empty. Enter the title and try again.')); @@ -230,7 +225,7 @@ protected function saveSample( 'title' => $sample->getTitle(), ]; - if ($sample->getSampleType() === 'file' && $sample->getSampleFile() === null) { + if ($sample->getSampleType() === 'file' && $sample->getSampleFileContent() !== null) { $sampleData['file'] = $this->jsonEncoder->encode( [ $this->fileContentUploader->upload($sample->getSampleFileContent(), 'sample'), @@ -293,9 +288,8 @@ protected function updateSample( __("The downloadable sample isn't related to the product. Verify the link and try again.") ); } - - $validateFileContent = $sample->getSampleFileContent() === null ? false : true; - if (!$this->contentValidator->isValid($sample, $validateFileContent)) { + $this->validateSampleType($sample); + if (!$this->contentValidator->isValid($sample, true)) { throw new InputException(__('The sample information is invalid. Verify the information and try again.')); } if ($isGlobalScopeContent) { @@ -312,14 +306,8 @@ protected function updateSample( } else { $existingSample->setTitle($sample->getTitle()); } - - if ($sample->getSampleType() === 'file' - && $sample->getSampleFileContent() === null - && $sample->getSampleFile() !== null - ) { - $existingSample->setSampleFile($sample->getSampleFile()); - } $this->saveSample($product, $sample, $isGlobalScopeContent); + return $existingSample->getId(); } @@ -343,6 +331,20 @@ public function delete($id) return true; } + /** + * Check that Sample type exist. + * + * @param SampleInterface $sample + * @throws InputException + * @return void + */ + private function validateSampleType(SampleInterface $sample): void + { + if (!in_array($sample->getSampleType(), ['url', 'file'], true)) { + throw new InputException(__('The sample type is invalid. Verify the sample type and try again.')); + } + } + /** * Get MetadataPool instance * diff --git a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php index 25a5d86b0385..508ef930f5d0 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php @@ -7,6 +7,9 @@ use Magento\Catalog\Api\Data\ProductExtensionInterface; +/** + * Unit tests for \Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin\Downloadable. + */ class DownloadableTest extends \PHPUnit\Framework\TestCase { /** @@ -34,12 +37,17 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ private $extensionAttributesMock; + /** + * @var \Magento\Downloadable\Model\Product\Type|\Magento\Catalog\Api\Data\ProductExtensionInterface + */ + private $downloadableProductTypeMock; + protected function setUp() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); $this->productMock = $this->createPartialMock( \Magento\Catalog\Model\Product::class, - ['setDownloadableData', 'getExtensionAttributes', '__wakeup'] + ['setDownloadableData', 'getExtensionAttributes', '__wakeup', 'getTypeInstance'] ); $this->subjectMock = $this->createMock( \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::class @@ -62,6 +70,10 @@ protected function setUp() $sampleBuilderMock = $this->getMockBuilder(\Magento\Downloadable\Model\Sample\Builder::class) ->disableOriginalConstructor() ->getMock(); + $this->downloadableProductTypeMock = $this->createPartialMock( + \Magento\Downloadable\Model\Product\Type::class, + ['getLinks', 'getSamples'] + ); $this->downloadablePlugin = new \Magento\Downloadable\Controller\Adminhtml\Product\Initialization\Helper\Plugin\Downloadable( $this->requestMock, @@ -86,6 +98,11 @@ public function testAfterInitializeWithNoDataToSave($downloadable) $this->productMock->expects($this->once()) ->method('getExtensionAttributes') ->willReturn($this->extensionAttributesMock); + $this->productMock->expects($this->exactly(2)) + ->method('getTypeInstance') + ->willReturn($this->downloadableProductTypeMock); + $this->downloadableProductTypeMock->expects($this->once())->method('getLinks')->willReturn([]); + $this->downloadableProductTypeMock->expects($this->once())->method('getSamples')->willReturn([]); $this->extensionAttributesMock->expects($this->once()) ->method('setDownloadableProductLinks') ->with([]); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 2639c22ff2ca..5484e39bd57f 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -5,8 +5,12 @@ */ namespace Magento\Downloadable\Test\Unit\Model\Link; +use Magento\Downloadable\Helper\File; use Magento\Downloadable\Model\Link\ContentValidator; +/** + * Unit tests for Magento\Downloadable\Model\Link\ContentValidator. + */ class ContentValidatorTest extends \PHPUnit\Framework\TestCase { /** @@ -34,13 +38,32 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $sampleFileMock; + /** + * @var File|\PHPUnit_Framework_MockObject_MockObject + */ + private $fileMock; + + /** + * @inheritdoc + */ protected function setUp() { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); $this->linkFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); - $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + $this->fileMock = $this->createMock(File::class); + + $this->validator = $objectManager->getObject( + ContentValidator::class, + [ + 'fileContentValidator' => $this->fileValidatorMock, + 'urlValidator' => $this->urlValidatorMock, + 'fileHelper' => $this->fileMock, + ] + ); } public function testIsValid() diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php index c863fb7ad62f..90bcfa2e39be 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php @@ -6,7 +6,11 @@ namespace Magento\Downloadable\Test\Unit\Model\Sample; use Magento\Downloadable\Model\Sample\ContentValidator; +use Magento\Downloadable\Helper\File; +/** + * Unit tests for Magento\Downloadable\Model\Sample\ContentValidator. + */ class ContentValidatorTest extends \PHPUnit\Framework\TestCase { /** @@ -34,12 +38,31 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $sampleFileMock; + /** + * @var File|\PHPUnit_Framework_MockObject_MockObject + */ + private $fileMock; + + /** + * @inheritdoc + */ protected function setUp() { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); - $this->validator = new ContentValidator($this->fileValidatorMock, $this->urlValidatorMock); + $this->fileMock = $this->createMock(File::class); + + $this->validator = $objectManager->getObject( + ContentValidator::class, + [ + 'fileContentValidator' => $this->fileValidatorMock, + 'urlValidator' => $this->urlValidatorMock, + 'fileHelper' => $this->fileMock, + ] + ); } public function testIsValid() diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php index f29708cc9a2c..7a8d201d09c4 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php @@ -13,6 +13,7 @@ use Magento\Framework\UrlInterface; use Magento\Downloadable\Model\Link as LinkModel; use Magento\Downloadable\Api\Data\LinkInterface; +use Magento\Framework\Exception\ValidatorException; /** * Class Links @@ -155,7 +156,7 @@ protected function addSampleFile(array $linkData, LinkInterface $link) $sampleFile = $link->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBaseSamplePath(), $sampleFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkLinksFile($file)) { $linkData['sample']['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -184,7 +185,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) $linkFile = $link->getLinkFile(); if ($linkFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBasePath(), $linkFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkLinksFile($file)) { $linkData['file'][0] = [ 'file' => $linkFile, 'name' => $this->downloadableFile->getFileFromPathFile($linkFile), @@ -201,6 +202,21 @@ protected function addLinkFile(array $linkData, LinkInterface $link) return $linkData; } + /** + * Check that Links File or Sample is valid. + * + * @param string $file + * @return bool + */ + private function checkLinksFile(string $file): bool + { + try { + return $this->downloadableFile->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; + } + } + /** * Return formatted price with two digits after decimal point * diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php index b000de487b77..ac8f3eb96295 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php @@ -11,6 +11,7 @@ use Magento\Catalog\Model\Locator\LocatorInterface; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Downloadable\Helper\File as DownloadableFile; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\UrlInterface; use Magento\Downloadable\Api\Data\SampleInterface; @@ -136,7 +137,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) $sampleFile = $sample->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->sampleModel->getBasePath(), $sampleFile); - if ($this->downloadableFile->ensureFileInFilesystem($file)) { + if ($this->checkSamplesFile($file)) { $sampleData['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -152,4 +153,19 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) return $sampleData; } + + /** + * Check that Sample file is valid. + * + * @param string $file + * @return bool + */ + private function checkSamplesFile(string $file): bool + { + try { + return $this->downloadableFile->ensureFileInFilesystem($file); + } catch (ValidatorException $e) { + return false; + } + } } diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index c881969a3b67..3fa60f93fc68 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -12,6 +12,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; +/** + * API tests for Magento\Downloadable\Model\LinkRepository. + */ class LinkRepositoryTest extends WebapiAbstract { /** @@ -135,10 +138,12 @@ public function testCreateUploadsProvidedFileContent() 'number_of_downloads' => 100, 'link_type' => 'file', 'link_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], @@ -292,6 +297,64 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * Check that error appears when link file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'file', + 'link_file' => '/n/o/nexistfile.png', + 'sample_type' => 'url', + 'sample_file' => 'http://google.com', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + + /** + * Check that error appears when link sample file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link sample file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfLinkSampleFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://www.example.com/', + 'sample_type' => 'file', + 'sample_file' => '/n/o/nexistfile.png', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception @@ -339,6 +402,7 @@ public function testCreateThrowsExceptionIfLinkFileNameContainsForbiddenCharacte 'number_of_downloads' => 100, 'link_type' => 'file', 'link_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -370,6 +434,7 @@ public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharac 'link_url' => 'http://www.example.com/', 'sample_type' => 'file', 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -610,7 +675,9 @@ public function testUpdate() 'is_shareable' => 0, 'number_of_downloads' => 50, 'link_type' => 'url', + 'link_url' => 'http://google.com', 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; $this->assertEquals($linkId, $this->_webApiCall($this->updateServiceInfo, $requestData)); @@ -643,7 +710,9 @@ public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInSt 'is_shareable' => 0, 'number_of_downloads' => 50, 'link_type' => 'url', + 'link_url' => 'http://google.com', 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 769abadf2058..782c15a99b4d 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -227,7 +227,9 @@ public function testUpdateDownloadableProductLinks() 'price' => 5.0, 'number_of_downloads' => 999, 'link_type' => 'file', - 'sample_type' => 'file' + 'link_file' => $linkFile, + 'sample_type' => 'file', + 'sample_file' => $sampleFile, ]; $linkData = $this->getLinkData(); @@ -273,6 +275,7 @@ public function testUpdateDownloadableProductLinks() 'number_of_downloads' => 999, 'link_type' => 'file', 'sample_type' => 'file', + 'sample_file' => '/s/a/sample2.jpg', ]; $expectedLinkData = array_merge($expectedLinkData, $this->getExpectedLinkData()); $this->assertEquals($expectedLinkData, $resultLinks); diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php index b537947d5e4d..b339e97d8d69 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php @@ -11,6 +11,9 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\WebapiAbstract; +/** + * API tests for Magento\Downloadable\Model\SampleRepository. + */ class SampleRepositoryTest extends WebapiAbstract { /** @@ -131,6 +134,7 @@ public function testCreateUploadsProvidedFileContent() 'title' => 'Title', 'sort_order' => 1, 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'image.jpg', ], @@ -223,6 +227,30 @@ public function testCreateThrowsExceptionIfSampleTypeIsInvalid() $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * Check that error appears when sample file not existing in filesystem. + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Sample file not found. Please try again. + * @return void + */ + public function testCreateThrowsExceptionIfSampleFileNotFoundInSystem(): void + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'sample' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'sample_type' => 'file', + 'sample_file' => '/n/o/nexistfile.png', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception @@ -262,6 +290,7 @@ public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharac 'sort_order' => 15, 'sample_type' => 'file', 'sample_file_content' => [ + //phpcs:ignore Magento2.Functions.DiscouragedFunction 'file_data' => base64_encode(file_get_contents($this->testImagePath)), 'name' => 'name/with|forbidden{characters', ], @@ -380,6 +409,7 @@ public function testUpdate() 'title' => 'Updated Title', 'sort_order' => 2, 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; @@ -408,6 +438,7 @@ public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInSt 'title' => 'Updated Title', 'sort_order' => 2, 'sample_type' => 'url', + 'sample_url' => 'http://google.com', ], ]; From 01a7ea0f8f3977b700a05ccf650108476582c390 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 11:59:44 +0300 Subject: [PATCH 0023/1172] MC-13886: Downloadable Product controller|API save changes --- .../Downloadable/Test/Unit/Model/LinkRepositoryTest.php | 5 ++++- .../Downloadable/Test/Unit/Model/SampleRepositoryTest.php | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php index 821f251929f8..4494877b70f6 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php @@ -162,7 +162,8 @@ protected function getLinkMock(array $linkData) 'getNumberOfDownloads', 'getIsShareable', 'getLinkUrl', - 'getLinkFile' + 'getLinkFile', + 'hasSampleType', ] ) ->getMockForAbstractClass(); @@ -436,6 +437,8 @@ public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() 'price' => 10.1, 'number_of_downloads' => 100, 'is_shareable' => true, + 'link_type' => 'url', + 'link_url' => 'https://google.com', ]; $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) ->will($this->returnValue($this->productMock)); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php index 8e13bd83b039..f1ca30bd7dd3 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php @@ -353,6 +353,8 @@ public function testUpdateThrowsExceptionIfTitleIsEmptyAndScopeIsGlobal() 'id' => $sampleId, 'title' => '', 'sort_order' => 1, + 'sample_type' => 'url', + 'sample_url' => 'https://google.com', ]; $this->repositoryMock->expects($this->any())->method('get')->with($productSku, true) ->will($this->returnValue($this->productMock)); From 56edf648db291846e72cd50137b085c52797da03 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 12:37:01 +0300 Subject: [PATCH 0024/1172] MC-13886: Downloadable Product controller|API save changes --- .../testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 782c15a99b4d..cf99b3420712 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -275,7 +275,6 @@ public function testUpdateDownloadableProductLinks() 'number_of_downloads' => 999, 'link_type' => 'file', 'sample_type' => 'file', - 'sample_file' => '/s/a/sample2.jpg', ]; $expectedLinkData = array_merge($expectedLinkData, $this->getExpectedLinkData()); $this->assertEquals($expectedLinkData, $resultLinks); From a7b52c225775fab2591732986c2ca582ff6f3710 Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 2 May 2019 10:28:12 -0500 Subject: [PATCH 0025/1172] MC-16044: Update symfony/dependency-injection --- composer.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.lock b/composer.lock index 5d9f7fbdf695..cbeaac07eaa0 100644 --- a/composer.lock +++ b/composer.lock @@ -8853,16 +8853,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v4.2.4", + "version": "v4.2.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "cdadb3765df7c89ac93628743913b92bb91f1704" + "reference": "2748643dd378626c4d348a31ad12394e2d6f7ea8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/cdadb3765df7c89ac93628743913b92bb91f1704", - "reference": "cdadb3765df7c89ac93628743913b92bb91f1704", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2748643dd378626c4d348a31ad12394e2d6f7ea8", + "reference": "2748643dd378626c4d348a31ad12394e2d6f7ea8", "shasum": "" }, "require": { @@ -8922,7 +8922,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-02-23T15:17:42+00:00" + "time": "2019-04-16T11:19:53+00:00" }, { "name": "symfony/dom-crawler", From eb3249e41e3a9b052b492407bcccbc24f56ae935 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Thu, 2 May 2019 17:50:35 +0300 Subject: [PATCH 0026/1172] MC-13886: Downloadable Product controller|API save changes --- .../Downloadable/Model/LinkRepository.php | 30 ++++++++----------- .../Helper/Plugin/DownloadableTest.php | 3 ++ .../Product/Form/Modifier/Data/Links.php | 6 ++-- .../Product/Form/Modifier/Data/Samples.php | 4 +-- .../Downloadable/Api/LinkRepositoryTest.php | 4 +-- .../Downloadable/Api/SampleRepositoryTest.php | 2 +- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/LinkRepository.php b/app/code/Magento/Downloadable/Model/LinkRepository.php index 57e0fee5c118..68fbba2a7d38 100644 --- a/app/code/Magento/Downloadable/Model/LinkRepository.php +++ b/app/code/Magento/Downloadable/Model/LinkRepository.php @@ -180,14 +180,14 @@ public function save($sku, LinkInterface $link, $isGlobalScopeContent = true) if ($link->getId() !== null) { return $this->updateLink($product, $link, $isGlobalScopeContent); } else { - if ($product->getTypeId() !== \Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) { + if ($product->getTypeId() !== Type::TYPE_DOWNLOADABLE) { throw new InputException( __('The product needs to be the downloadable type. Verify the product and try again.') ); } $this->validateLinkType($link); - $validateSampleContent = $this->isValidateSample($link); - if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { + $this->validateSampleType($link); + if (!$this->contentValidator->isValid($link, true, $link->hasSampleType())) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } $title = $link->getTitle(); @@ -304,7 +304,8 @@ protected function updateLink( ); } $this->validateLinkType($link); - $validateSampleContent = $this->isValidateSample($link); + $this->validateSampleType($link); + $validateSampleContent = $link->hasSampleType(); if (!$this->contentValidator->isValid($link, true, $validateSampleContent)) { throw new InputException(__('The link information is invalid. Verify the link and try again.')); } @@ -349,7 +350,8 @@ public function delete($id) * Check that Link type exist. * * @param LinkInterface $link - * @throws \Magento\Framework\Exception\InputException + * @return void + * @throws InputException */ private function validateLinkType(LinkInterface $link): void { @@ -361,21 +363,15 @@ private function validateLinkType(LinkInterface $link): void /** * Check that Link sample type exist. * - * @param \Magento\Downloadable\Api\Data\LinkInterface $link - * @return bool - * @throws \Magento\Framework\Exception\InputException + * @param LinkInterface $link + * @return void + * @throws InputException */ - private function isValidateSample(LinkInterface $link): bool + private function validateSampleType(LinkInterface $link): void { - if ($link->hasSampleType()) { - if (in_array($link->getSampleType(), ['url', 'file'], true)) { - return true; - } else { - throw new InputException(__('The link sample type is invalid. Verify and try again.')); - } + if ($link->hasSampleType() && !in_array($link->getSampleType(), ['url', 'file'], true)) { + throw new InputException(__('The link sample type is invalid. Verify and try again.')); } - - return false; } /** diff --git a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php index 508ef930f5d0..55353c16b472 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/DownloadableTest.php @@ -42,6 +42,9 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ private $downloadableProductTypeMock; + /** + * @inheritdoc + */ protected function setUp() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php index 7a8d201d09c4..0a3ea2fc6ba1 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Links.php @@ -156,7 +156,7 @@ protected function addSampleFile(array $linkData, LinkInterface $link) $sampleFile = $link->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBaseSamplePath(), $sampleFile); - if ($this->checkLinksFile($file)) { + if ($this->isLinkFileValid($file)) { $linkData['sample']['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -185,7 +185,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) $linkFile = $link->getLinkFile(); if ($linkFile) { $file = $this->downloadableFile->getFilePath($this->linkModel->getBasePath(), $linkFile); - if ($this->checkLinksFile($file)) { + if ($this->isLinkFileValid($file)) { $linkData['file'][0] = [ 'file' => $linkFile, 'name' => $this->downloadableFile->getFileFromPathFile($linkFile), @@ -208,7 +208,7 @@ protected function addLinkFile(array $linkData, LinkInterface $link) * @param string $file * @return bool */ - private function checkLinksFile(string $file): bool + private function isLinkFileValid(string $file): bool { try { return $this->downloadableFile->ensureFileInFilesystem($file); diff --git a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php index ac8f3eb96295..988f429de1d8 100644 --- a/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php +++ b/app/code/Magento/Downloadable/Ui/DataProvider/Product/Form/Modifier/Data/Samples.php @@ -137,7 +137,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) $sampleFile = $sample->getSampleFile(); if ($sampleFile) { $file = $this->downloadableFile->getFilePath($this->sampleModel->getBasePath(), $sampleFile); - if ($this->checkSamplesFile($file)) { + if ($this->isSampleFileValid($file)) { $sampleData['file'][0] = [ 'file' => $sampleFile, 'name' => $this->downloadableFile->getFileFromPathFile($sampleFile), @@ -160,7 +160,7 @@ protected function addSampleFile(array $sampleData, SampleInterface $sample) * @param string $file * @return bool */ - private function checkSamplesFile(string $file): bool + private function isSampleFileValid(string $file): bool { try { return $this->downloadableFile->ensureFileInFilesystem($file); diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 3fa60f93fc68..1c239fba244a 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -305,7 +305,7 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod * @expectedExceptionMessage Link file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void + public function testCreateLinkWithMissingFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, @@ -334,7 +334,7 @@ public function testCreateThrowsExceptionIfLinkFileNotFoundInSystem(): void * @expectedExceptionMessage Link sample file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfLinkSampleFileNotFoundInSystem(): void + public function testCreateLinkWithMissingSampleThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php index b339e97d8d69..a97e4c5d9e11 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/SampleRepositoryTest.php @@ -235,7 +235,7 @@ public function testCreateThrowsExceptionIfSampleTypeIsInvalid() * @expectedExceptionMessage Sample file not found. Please try again. * @return void */ - public function testCreateThrowsExceptionIfSampleFileNotFoundInSystem(): void + public function testCreateSampleWithMissingFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, From 32be5b967d5c8f2e680e8cc39b64ddc1851567be Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 2 May 2019 14:48:00 -0500 Subject: [PATCH 0027/1172] MC-15811: Incorrect Url Refactor controller validation logic. Fix integration test. --- .../Store/Controller/Store/SwitchRequest.php | 53 ++++++------------- .../Model/StoreSwitcher/HashGenerator.php | 10 ++-- .../Magento/Store/Model/HashGeneratorTest.php | 28 ++++++++-- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index 6d97487df67b..e220941017c3 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -10,34 +10,24 @@ use Magento\Framework\App\Action\Context; use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Store\Api\StoreRepositoryInterface; use Magento\Customer\Model\Session as CustomerSession; -use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\CustomerRepositoryInterface; use \Magento\Framework\Exception\LocalizedException; -use Magento\Store\Model\StoreIsInactiveException; +use Magento\Framework\Url\DecoderInterface; +use \Magento\Framework\App\ActionInterface; /** * Builds correct url to target store and performs redirect. */ class SwitchRequest extends \Magento\Framework\App\Action\Action implements HttpGetActionInterface { - /** - * @var StoreRepositoryInterface - */ - private $storeRepository; /** * @var customerSession */ private $customerSession; - /** - * @var \Magento\Framework\App\DeploymentConfig - */ - private $deploymentConfig; - /** * @var CustomerRepositoryInterface */ @@ -48,28 +38,30 @@ class SwitchRequest extends \Magento\Framework\App\Action\Action implements Http */ private $hashGenerator; + /** + * @var DecoderInterface + */ + private $urlDecoder; + /** * @param Context $context - * @param StoreRepositoryInterface $storeRepository * @param CustomerSession $session - * @param DeploymentConfig $deploymentConfig * @param CustomerRepositoryInterface $customerRepository * @param HashGenerator $hashGenerator + * @param DecoderInterface $urlDecoder */ public function __construct( Context $context, - StoreRepositoryInterface $storeRepository, CustomerSession $session, - DeploymentConfig $deploymentConfig, CustomerRepositoryInterface $customerRepository, - HashGenerator $hashGenerator + HashGenerator $hashGenerator, + DecoderInterface $urlDecoder ) { parent::__construct($context); - $this->storeRepository = $storeRepository; $this->customerSession = $session; - $this->deploymentConfig = $deploymentConfig; $this->customerRepository = $customerRepository; $this->hashGenerator = $hashGenerator; + $this->urlDecoder = $urlDecoder; } /** @@ -82,41 +74,30 @@ public function execute() $fromStoreCode = (string)$this->_request->getParam('___from_store'); $customerId = (int)$this->_request->getParam('customer_id'); $timeStamp = (string)$this->_request->getParam('time_stamp'); - $targetStoreCode = $this->_request->getParam('___to_store'); $signature = (string)$this->_request->getParam('signature'); $error = null; + $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); + $targetUrl = $this->urlDecoder->decode($encodedUrl); + $data=[$customerId, $timeStamp, $fromStoreCode]; - try { - $fromStore = $this->storeRepository->get($fromStoreCode); - $targetStore=$this->storeRepository->getActiveStoreByCode($targetStoreCode); - $targetUrl=$targetStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK); - } catch (NoSuchEntityException $e) { - $error = __('Requested store is not found.'); - } catch (StoreIsInactiveException $e) { - $error = __('Requested store is inactive.'); - } - - if ($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])) { + if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { $customer = $this->customerRepository->getById($customerId); if (!$this->customerSession->isLoggedIn()) { $this->customerSession->setCustomerDataAsLoggedIn($customer); } + $this->getResponse()->setRedirect($targetUrl); } catch (NoSuchEntityException $e) { $error = __('The requested customer does not exist.'); } catch (LocalizedException $e) { $error = __('There was an error retrieving the customer record.'); } } else { - $error = __('Invalid request. Store switching action cannot be performed at this time.'); + $error = __('The requested store cannot be found. Please check the request and try again.'); } if ($error !== null) { $this->messageManager->addErrorMessage($error); - //redirect to previous store - $this->getResponse()->setRedirect($fromStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK)); - } else { - $this->getResponse()->setRedirect($targetUrl); } } } diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 0e0e77b04f94..945b5f36a0a8 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -13,6 +13,7 @@ use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; +use \Magento\Framework\App\ActionInterface; /** * Generate one time token and build redirect url @@ -61,6 +62,7 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s { $targetUrl = $redirectUrl; $customerId = null; + $encodedUrl = $this->urlHelper->getEncodedUrl($redirectUrl); if ($this->currentUser->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER) { $customerId = $this->currentUser->getUserId(); @@ -71,11 +73,9 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $urlParts = parse_url($targetUrl); $host = $urlParts['host']; $scheme = $urlParts['scheme']; - $path=$urlParts['path']; $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $timeStamp = time(); $fromStoreCode = $fromStore->getCode(); - $targetStoreCode = $targetStore->getCode(); $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); $signature = hash_hmac('sha256', $data, $key); $targetUrl = $scheme . "://" . $host . '/stores/store/switchrequest'; @@ -86,8 +86,10 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['time_stamp' => $timeStamp]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['signature' => $signature]); $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___from_store' => $fromStoreCode]); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['___to_store' => $targetStoreCode]); - $targetUrl = $this->urlHelper->addRequestParam($targetUrl, ['path' => $path]); + $targetUrl = $this->urlHelper->addRequestParam( + $targetUrl, + [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] + ); } return $targetUrl; } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 7b5bb357b934..8b0cec3dfa20 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -14,6 +14,8 @@ use Magento\Customer\Model\Session; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Config\ConfigOptionsListConstants; +use \Magento\Framework\App\ActionInterface; +use Magento\Framework\Url\Helper\Data as UrlHelper; /** * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator @@ -33,7 +35,7 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase private $objectManager; /** - * + * @var int */ private $customerId; @@ -51,10 +53,15 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase private $deploymentConfig; /** - * + * @var string */ private $key; + /** + * @var UrlHelper + */ + private $urlHelper; + /** * Class dependencies initialization * @return void @@ -80,6 +87,7 @@ protected function setUp() $this->customerId = $customer->getId(); $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); + $this->urlHelper=$this->objectManager->create(UrlHelper::class); } /** @@ -94,6 +102,7 @@ public function testSwitch(): void $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; $toStoreCode = 'fixture_second_store'; + $encodedUrl=$this->urlHelper->getEncodedUrl($redirectUrl); /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); $fromStore = $storeRepository->get($fromStoreCode); @@ -103,9 +112,18 @@ public function testSwitch(): void $signature = hash_hmac('sha256', $data, $this->key); $customerId = $this->customerId; - $expectedUrl = "http://domain.com/stores/store/switchrequest?customer_id=$customerId"; - $expectedUrl .= "&time_stamp=$timeStamp&signature=$signature"; - $expectedUrl .= "&___from_store=$fromStoreCode&___to_store=$toStoreCode"; + $expectedUrl = "http://domain.com/stores/store/switchrequest"; + $expectedUrl = $this->urlHelper->addRequestParam( + $expectedUrl, + ['customer_id' => $customerId] + ); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['time_stamp' => $timeStamp]); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['signature' => $signature]); + $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['___from_store' => $fromStoreCode]); + $expectedUrl = $this->urlHelper->addRequestParam( + $expectedUrl, + [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] + ); $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); } From 5bffe14b6ec4eab02a1e87b01c0bd62bfa2f7775 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Thu, 2 May 2019 15:04:46 -0500 Subject: [PATCH 0028/1172] MC-15811: Incorrect Url Remove redundant unit test. --- .../Controller/Store/SwitchRequestTest.php | 139 ------------------ 1 file changed, 139 deletions(-) delete mode 100644 app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php diff --git a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php b/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php deleted file mode 100644 index ebd85d89c23a..000000000000 --- a/app/code/Magento/Store/Test/Unit/Controller/Store/SwitchRequestTest.php +++ /dev/null @@ -1,139 +0,0 @@ -customerSessionMock = $this->getMockBuilder(CustomerSession::class) - ->disableOriginalConstructor()->getMock(); - $this->customerRepositoryMock = - $this->getMockBuilder(CustomerRepositoryInterface::class)->getMock(); - $this->storeRepositoryMock = - $this->getMockBuilder(\Magento\Store\Api\StoreRepositoryInterface::class) - ->disableOriginalConstructor()->setMethods(['get', 'getActiveStoreByCode'])->getMockForAbstractClass(); - - $this->requestMock = $this->getMockBuilder(\Magento\Framework\App\RequestInterface::class)->getMock(); - $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) - ->disableOriginalConstructor() - ->setMethods(['setRedirect']) - ->getMockForAbstractClass(); - $this->deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class) - ->disableOriginalConstructor()->getMock(); - $this->fromStoreMock = $this->getMockBuilder(StoreInterface::class) - ->disableOriginalConstructor() - ->setMethods(['getBaseUrl']) - ->getMockForAbstractClass(); - - $this->model = (new ObjectManager($this))->getObject( - \Magento\Store\Controller\Store\SwitchRequest::class, - [ - 'customerSession' => $this->customerRepositoryMock, - 'deploymentConfig' => $this->deploymentConfigMock, - 'storeRepository' => $this->storeRepositoryMock, - 'customerRepository' => $this->customerRepositoryMock, - '_request' => $this->requestMock, - '_response' => $this->responseMock, - ] - ); - } - - /** - * @return void - */ - public function testExecute() - { - $fromStoreCode = 'sv2'; - $targetStoreCode = 'default'; - $expectedRedirectUrl='/'; - $customerId=5; - $timestamp='1556131830'; - - $this->requestMock->method('getParam') - ->willReturnMap([ - ['___from_store', null, $fromStoreCode], - ['customer_id', null, $customerId], - ['time_stamp', null, $timestamp], - ['___to_store', null, $targetStoreCode], - ['signature', null, 'cbc099b3cc4a9a8f3a78a97e7a579ceff19a2b26a6c88b08f0f58442ea5bd968'] - ]); - - $this->storeRepositoryMock - ->expects($this->once()) - ->method('get') - ->with($fromStoreCode) - ->willReturn($this->fromStoreMock); - - $this->storeRepositoryMock - ->expects($this->once()) - ->method('getActiveStoreByCode') - ->with($targetStoreCode); - - $this->fromStoreMock - ->expects($this->once()) - ->method('getBaseUrl') - ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK) - ->willReturn($expectedRedirectUrl); - - $this->responseMock->expects($this->once())->method('setRedirect')->with($expectedRedirectUrl); - $this->model->execute(); - } -} From 6195986fe755284ce68aa0bb24a3c51548108f07 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 15 Apr 2019 14:35:56 -0500 Subject: [PATCH 0029/1172] MC-13900: Email to a Friend updates - default config option --- app/code/Magento/SendFriend/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/etc/config.xml b/app/code/Magento/SendFriend/etc/config.xml index d65e5a4a073d..6239a4da591e 100644 --- a/app/code/Magento/SendFriend/etc/config.xml +++ b/app/code/Magento/SendFriend/etc/config.xml @@ -9,7 +9,7 @@ - 1 + 0 0 5 From 4c7c050f2e7cb15055b5429e4bbd15eb6f858552 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Thu, 18 Apr 2019 13:42:07 -0500 Subject: [PATCH 0030/1172] MC-13900: Email to a Friend updates - update integration tests with compatible config --- .../SendFriend/Controller/Product/CustomerSendmailTest.php | 4 +++- .../testsuite/Magento/SendFriend/Controller/SendmailTest.php | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php index 8794dfdff8fd..686af841c7ff 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php @@ -58,6 +58,7 @@ protected function setUp() } /** + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ @@ -95,6 +96,7 @@ public function testExecute() * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @magentoConfigFixture default_store customer/captcha/forms product_sendtofriend_form + * @magentoConfigFixture default_store sendfriend/email/enabled 1 */ public function testWithCaptchaFailed() { @@ -133,7 +135,7 @@ public function testWithCaptchaFailed() * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/product_simple.php * @magentoConfigFixture default_store customer/captcha/forms product_sendtofriend_form - * + * @magentoConfigFixture default_store sendfriend/email/enabled 1 */ public function testWithCaptchaSuccess() { diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php index a075398e9cdb..5c2ddf86d6f9 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php @@ -26,6 +26,7 @@ class SendmailTest extends AbstractController * * @magentoDbIsolation enabled * @magentoAppIsolation enabled + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/SendFriend/_files/disable_allow_guest_config.php * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/products.php From b19cd09cca57b6daae9e1ed4078cbdcef2e2d3c4 Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Tue, 23 Apr 2019 12:49:09 -0500 Subject: [PATCH 0031/1172] MC-13900: Email to a Friend updates - add doc comment --- .../SendFriend/Controller/Product/CustomerSendmailTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php index 686af841c7ff..a94a96c5cbef 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/Product/CustomerSendmailTest.php @@ -17,6 +17,9 @@ use Magento\Framework\Message\MessageInterface; use Magento\Captcha\Helper\Data as CaptchaHelper; +/** + * Class CustomerSendmailTest + */ class CustomerSendmailTest extends AbstractController { /** From 18907a694d6e99d2a00ce4ca905b9505f44839cb Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 29 Apr 2019 10:51:52 -0500 Subject: [PATCH 0032/1172] MC-13900: Email to a Friend updates - add translation --- app/code/Magento/SendFriend/etc/adminhtml/system.xml | 5 ++++- app/code/Magento/SendFriend/i18n/en_US.csv | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriend/etc/adminhtml/system.xml b/app/code/Magento/SendFriend/etc/adminhtml/system.xml index 785b7a8bb40c..564f7bd306f8 100644 --- a/app/code/Magento/SendFriend/etc/adminhtml/system.xml +++ b/app/code/Magento/SendFriend/etc/adminhtml/system.xml @@ -13,8 +13,11 @@ Magento_Config::sendfriend - + + + CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> + Magento\Config\Model\Config\Source\Yesno diff --git a/app/code/Magento/SendFriend/i18n/en_US.csv b/app/code/Magento/SendFriend/i18n/en_US.csv index eee540c89a7b..24fdea50be53 100644 --- a/app/code/Magento/SendFriend/i18n/en_US.csv +++ b/app/code/Magento/SendFriend/i18n/en_US.csv @@ -45,3 +45,5 @@ Enabled,Enabled "Max Recipients","Max Recipients" "Max Products Sent in 1 Hour","Max Products Sent in 1 Hour" "Limit Sending By","Limit Sending By" +"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." + From 07fa87ae48a09e2f0eff5ec38617eeaae01b2c8f Mon Sep 17 00:00:00 2001 From: Anthoula Wojczak Date: Mon, 29 Apr 2019 11:40:20 -0500 Subject: [PATCH 0033/1172] MC-13900: Email to a Friend updates - add translation --- app/code/Magento/SendFriend/etc/adminhtml/system.xml | 2 +- app/code/Magento/SendFriend/i18n/en_US.csv | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriend/etc/adminhtml/system.xml b/app/code/Magento/SendFriend/etc/adminhtml/system.xml index 564f7bd306f8..5cace4bcf92d 100644 --- a/app/code/Magento/SendFriend/etc/adminhtml/system.xml +++ b/app/code/Magento/SendFriend/etc/adminhtml/system.xml @@ -16,7 +16,7 @@ - CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> + CAPTCHA solution alongside enabling "Email to a Friend" to ensure abuse of this feature does not occur.]]> Magento\Config\Model\Config\Source\Yesno diff --git a/app/code/Magento/SendFriend/i18n/en_US.csv b/app/code/Magento/SendFriend/i18n/en_US.csv index 24fdea50be53..8d5b596fe1ca 100644 --- a/app/code/Magento/SendFriend/i18n/en_US.csv +++ b/app/code/Magento/SendFriend/i18n/en_US.csv @@ -45,5 +45,4 @@ Enabled,Enabled "Max Recipients","Max Recipients" "Max Products Sent in 1 Hour","Max Products Sent in 1 Hour" "Limit Sending By","Limit Sending By" -"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." - +"We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur.","We strongly recommend to enable a CAPTCHA solution alongside enabling ""Email to a Friend"" to ensure abuse of this feature does not occur." From 54c07ca9a7559a433f0ea932715b6f2b4d0f2ada Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov Date: Fri, 3 May 2019 11:45:29 +0300 Subject: [PATCH 0034/1172] MC-13886: Downloadable Product controller|API save changes --- .../testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 1c239fba244a..0eb3da755c5f 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -305,7 +305,7 @@ public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64Encod * @expectedExceptionMessage Link file not found. Please try again. * @return void */ - public function testCreateLinkWithMissingFileThrowsException(): void + public function testCreateLinkWithMissingLinkFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, @@ -334,7 +334,7 @@ public function testCreateLinkWithMissingFileThrowsException(): void * @expectedExceptionMessage Link sample file not found. Please try again. * @return void */ - public function testCreateLinkWithMissingSampleThrowsException(): void + public function testCreateLinkWithMissingSampleFileThrowsException(): void { $requestData = [ 'isGlobalScopeContent' => false, From 686e79a0b3d9356012e9f1396efe351f54146a45 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Fri, 3 May 2019 09:45:50 -0500 Subject: [PATCH 0035/1172] MC-15811: Incorrect Url Fix static errors. --- .../Magento/Store/Model/StoreSwitcher/HashGenerator.php | 1 + .../integration/testsuite/Magento/Framework/UrlTest.php | 7 ------- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 945b5f36a0a8..ac195c699a96 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -57,6 +57,7 @@ public function __construct( * @param StoreInterface $targetStore store where to go to * @param string $redirectUrl original url requested for redirect after switching * @return string redirect url + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, string $redirectUrl): string { diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 21f0ebd5b77f..9d07c07e824d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -485,13 +485,6 @@ public function testSessionUrlVar() $this->assertEquals('www.example.com', $sessionUrl); } - public function testUseSessionIdForUrl() - { - $_SERVER['HTTP_HOST'] = 'localhost'; - $this->assertFalse($this->model->useSessionIdForUrl(true)); - $this->assertFalse($this->model->useSessionIdForUrl(false)); - } - /** * Note: isolation flushes the URL memory cache * @magentoAppIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 8b0cec3dfa20..c56f2bf347a7 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -21,7 +21,6 @@ * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ - class HashGeneratorTest extends \PHPUnit\Framework\TestCase { /** From 315ee90a45065b5bd35e4e8a6a4a401e05c5768b Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Fri, 3 May 2019 12:17:00 -0500 Subject: [PATCH 0036/1172] MC-15977: Email template preview --- .../Block/Adminhtml/Template/Preview.php | 16 +- .../Block/Adminhtml/Template/PreviewTest.php | 163 +++++++++++++----- 2 files changed, 131 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index acc367de742d..5b2705a1989e 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -55,19 +55,27 @@ public function __construct( * Prepare html output * * @return string + * @throws \Exception */ protected function _toHtml() { + /** @var $request \Magento\Framework\App\Request\Http */ + $request = $this->getRequest(); + + if(!$request->isSafeMethod()) { + throw new \Exception('Wrong request.'); + } + $storeId = $this->getAnyStoreView()->getId(); /** @var $template \Magento\Email\Model\Template */ $template = $this->_emailFactory->create(); - if ($id = (int)$this->getRequest()->getParam('id')) { + if ($id = (int)$request->getParam('id')) { $template->load($id); } else { - $template->setTemplateType($this->getRequest()->getParam('type')); - $template->setTemplateText($this->getRequest()->getParam('text')); - $template->setTemplateStyles($this->getRequest()->getParam('styles')); + $template->setTemplateType($request->getParam('type')); + $template->setTemplateText($request->getParam('text')); + $template->setTemplateStyles($request->getParam('styles')); } \Magento\Framework\Profiler::start($this->profilerName); diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index b91d94edb589..4363bf223157 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -18,26 +18,42 @@ class PreviewTest extends \PHPUnit\Framework\TestCase const MALICIOUS_TEXT = 'test malicious'; + /** + * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject + */ + protected $request; + + /** + * @var \Magento\Email\Block\Adminhtml\Template\Preview + */ + protected $preview; + + /** + * @var \Magento\Framework\Filter\Input\MaliciousCode|\PHPUnit_Framework_MockObject_MockObject + */ + protected $maliciousCode; + + /** + * @var \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject + */ + protected $template; + + /** + * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $storeManager; + /** * Init data */ protected function setUp() { $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - } - /** - * Check of processing email templates - * - * @param array $requestParamMap - * - * @dataProvider toHtmlDataProvider - * @param $requestParamMap - */ - public function testToHtml($requestParamMap) - { $storeId = 1; - $template = $this->getMockBuilder(\Magento\Email\Model\Template::class) + $designConfigData = []; + + $this->template = $this->getMockBuilder(\Magento\Email\Model\Template::class) ->setMethods([ 'setDesignConfig', 'getDesignConfig', @@ -48,36 +64,46 @@ public function testToHtml($requestParamMap) ]) ->disableOriginalConstructor() ->getMock(); - $template->expects($this->once()) + + $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); + + $this->maliciousCode = $this->createPartialMock( + \Magento\Framework\Filter\Input\MaliciousCode::class, ['filter'] + ); + + $this->template->expects($this->once()) ->method('getProcessedTemplate') ->with($this->equalTo([])) ->willReturn(self::MALICIOUS_TEXT); - $designConfigData = []; - $template->expects($this->atLeastOnce()) - ->method('getDesignConfig') + + $this->template->method('getDesignConfig') ->willReturn(new \Magento\Framework\DataObject( $designConfigData )); + $emailFactory = $this->createPartialMock(\Magento\Email\Model\TemplateFactory::class, ['create']); $emailFactory->expects($this->any()) ->method('create') - ->willReturn($template); + ->willReturn($this->template); - $request = $this->createMock(\Magento\Framework\App\RequestInterface::class); - $request->expects($this->any())->method('getParam')->willReturnMap($requestParamMap); $eventManage = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); $scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); $design = $this->createMock(\Magento\Framework\View\DesignInterface::class); $store = $this->createPartialMock(\Magento\Store\Model\Store::class, ['getId', '__wakeup']); - $store->expects($this->any())->method('getId')->willReturn($storeId); - $storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $storeManager->expects($this->atLeastOnce()) - ->method('getDefaultStoreView') + + $store->expects($this->any()) + ->method('getId') + ->willReturn($storeId); + + $this->storeManager->method('getDefaultStoreView') ->willReturn($store); - $storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); - $storeManager->expects($this->any())->method('getStores')->willReturn([$store]); + + $this->storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); + $this->storeManager->expects($this->any())->method('getStores')->willReturn([$store]); $appState = $this->getMockBuilder(\Magento\Framework\App\State::class) ->setConstructorArgs([ $scopeConfig @@ -87,36 +113,85 @@ public function testToHtml($requestParamMap) ->getMock(); $appState->expects($this->any()) ->method('emulateAreaCode') - ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$template, 'getProcessedTemplate']) - ->willReturn($template->getProcessedTemplate()); + ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$this->template, 'getProcessedTemplate']) + ->willReturn($this->template->getProcessedTemplate()); $context = $this->createPartialMock( \Magento\Backend\Block\Template\Context::class, ['getRequest', 'getEventManager', 'getScopeConfig', 'getDesignPackage', 'getStoreManager', 'getAppState'] ); - $context->expects($this->any())->method('getRequest')->willReturn($request); - $context->expects($this->any())->method('getEventManager')->willReturn($eventManage); - $context->expects($this->any())->method('getScopeConfig')->willReturn($scopeConfig); - $context->expects($this->any())->method('getDesignPackage')->willReturn($design); - $context->expects($this->any())->method('getStoreManager')->willReturn($storeManager); - $context->expects($this->once())->method('getAppState')->willReturn($appState); - - $maliciousCode = $this->createPartialMock(\Magento\Framework\Filter\Input\MaliciousCode::class, ['filter']); - $maliciousCode->expects($this->once()) - ->method('filter') - ->with($this->equalTo($requestParamMap[1][2])) - ->willReturn(self::MALICIOUS_TEXT); + $context->expects($this->any()) + ->method('getRequest') + ->willReturn($this->request); + $context->expects($this->any()) + ->method('getEventManager') + ->willReturn($eventManage); + $context->expects($this->any()) + ->method('getScopeConfig') + ->willReturn($scopeConfig); + $context->expects($this->any()) + ->method('getDesignPackage') + ->willReturn($design); + $context->expects($this->any()) + ->method('getStoreManager') + ->willReturn($this->storeManager); + $context->expects($this->once()) + ->method('getAppState') + ->willReturn($appState); /** @var \Magento\Email\Block\Adminhtml\Template\Preview $preview */ - $preview = $this->objectManagerHelper->getObject( + $this->preview = $this->objectManagerHelper->getObject( \Magento\Email\Block\Adminhtml\Template\Preview::class, [ 'context' => $context, - 'maliciousCode' => $maliciousCode, + 'maliciousCode' => $this->maliciousCode, 'emailFactory' => $emailFactory ] ); - $this->assertEquals(self::MALICIOUS_TEXT, $preview->toHtml()); + } + + /** + * Check of processing email templates + * + * @param array $requestParamMap + * + * @dataProvider toHtmlDataProvider + * @param $requestParamMap + */ + public function testToHtml($requestParamMap) + { + $this->request->expects($this->atLeastOnce()) + ->method('isSafeMethod') + ->willReturn(true); + $this->request->expects($this->any()) + ->method('getParam') + ->willReturnMap($requestParamMap); + $this->template + ->expects($this->atLeastOnce()) + ->method('getDesignConfig'); + $this->storeManager->expects($this->atLeastOnce()) + ->method('getDefaultStoreView'); + $this->maliciousCode->expects($this->once()) + ->method('filter') + ->with($this->equalTo($requestParamMap[1][2])) + ->willReturn(self::MALICIOUS_TEXT); + + $this->assertEquals(self::MALICIOUS_TEXT, $this->preview->toHtml()); + } + + /** + * @expectedException \Exception + */ + public function testToHtmlWithException() + { + $this->request->expects($this->atLeastOnce()) + ->method('isSafeMethod') + ->willReturn(false); + $this->template + ->expects($this->never()) + ->method('getDesignConfig'); + $this->expectException(\Exception::class); + $this->preview->toHtml(); } /** From 1e1b69be141d00ad3cbacdccb42b08593c5fe1fd Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Tue, 7 May 2019 13:21:24 -0500 Subject: [PATCH 0037/1172] MC-15977: Email template preview --- .../Block/Adminhtml/Template/Preview.php | 6 +-- .../Block/Adminhtml/Template/PreviewTest.php | 39 ++++++++----------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5b2705a1989e..d9cd5ef7f0c8 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -55,15 +55,15 @@ public function __construct( * Prepare html output * * @return string - * @throws \Exception + * @throws \Magento\Framework\Exception\LocalizedException */ protected function _toHtml() { /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); - if(!$request->isSafeMethod()) { - throw new \Exception('Wrong request.'); + if (!$request->isSafeMethod()) { + throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); } $storeId = $this->getAnyStoreView()->getId(); diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 4363bf223157..55757476ea82 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -72,7 +72,8 @@ protected function setUp() $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); $this->maliciousCode = $this->createPartialMock( - \Magento\Framework\Filter\Input\MaliciousCode::class, ['filter'] + \Magento\Framework\Filter\Input\MaliciousCode::class, + ['filter'] ); $this->template->expects($this->once()) @@ -113,31 +114,22 @@ protected function setUp() ->getMock(); $appState->expects($this->any()) ->method('emulateAreaCode') - ->with(\Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, [$this->template, 'getProcessedTemplate']) + ->with( + \Magento\Email\Model\AbstractTemplate::DEFAULT_DESIGN_AREA, + [$this->template, 'getProcessedTemplate'] + ) ->willReturn($this->template->getProcessedTemplate()); $context = $this->createPartialMock( \Magento\Backend\Block\Template\Context::class, ['getRequest', 'getEventManager', 'getScopeConfig', 'getDesignPackage', 'getStoreManager', 'getAppState'] ); - $context->expects($this->any()) - ->method('getRequest') - ->willReturn($this->request); - $context->expects($this->any()) - ->method('getEventManager') - ->willReturn($eventManage); - $context->expects($this->any()) - ->method('getScopeConfig') - ->willReturn($scopeConfig); - $context->expects($this->any()) - ->method('getDesignPackage') - ->willReturn($design); - $context->expects($this->any()) - ->method('getStoreManager') - ->willReturn($this->storeManager); - $context->expects($this->once()) - ->method('getAppState') - ->willReturn($appState); + $context->expects($this->any())->method('getRequest')->willReturn($this->request); + $context->expects($this->any())->method('getEventManager')->willReturn($eventManage); + $context->expects($this->any())->method('getScopeConfig')->willReturn($scopeConfig); + $context->expects($this->any())->method('getDesignPackage')->willReturn($design); + $context->expects($this->any())->method('getStoreManager')->willReturn($this->storeManager); + $context->expects($this->once())->method('getAppState')->willReturn($appState); /** @var \Magento\Email\Block\Adminhtml\Template\Preview $preview */ $this->preview = $this->objectManagerHelper->getObject( @@ -180,7 +172,7 @@ public function testToHtml($requestParamMap) } /** - * @expectedException \Exception + * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testToHtmlWithException() { @@ -190,7 +182,10 @@ public function testToHtmlWithException() $this->template ->expects($this->never()) ->method('getDesignConfig'); - $this->expectException(\Exception::class); + $this->expectException(\Magento\Framework\Exception\LocalizedException::class); + $this->expectExceptionMessage( + (string)__('Wrong request.') + ); $this->preview->toHtml(); } From 42c73b6d279f99b13d3166bc63da95cf8d289c64 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 7 May 2019 15:05:04 -0500 Subject: [PATCH 0038/1172] MC-6293: Fixed incorrect import behavior --- .../Model/Import/Uploader.php | 29 +++++++++--- .../Block/Adminhtml/Import/Edit/Form.php | 7 ++- .../Controller/Adminhtml/Import/Start.php | 44 +++++++++++++++++-- .../Magento/ImportExport/Model/Import.php | 29 +++++++++++- app/code/Magento/ImportExport/etc/config.xml | 1 + .../Model/Import/UploaderTest.php | 21 +++++++++ .../Magento/ImportExport/Model/ImportTest.php | 33 ++++++++++++-- 7 files changed, 147 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index 4ce1c0e39d6d..b5d7364dedc4 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -7,6 +7,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\ValidatorException; +use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\DriverPool; /** @@ -111,13 +113,18 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader */ private $random; + /** + * @var Filesystem + */ + private $fileSystem; + /** * @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDb * @param \Magento\MediaStorage\Helper\File\Storage $coreFileStorage * @param \Magento\Framework\Image\AdapterFactory $imageFactory * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator - * @param \Magento\Framework\Filesystem $filesystem - * @param \Magento\Framework\Filesystem\File\ReadFactory $readFactory + * @param Filesystem $filesystem + * @param Filesystem\File\ReadFactory $readFactory * @param string|null $filePath * @param \Magento\Framework\Math\Random|null $random * @throws \Magento\Framework\Exception\FileSystemException @@ -128,8 +135,8 @@ public function __construct( \Magento\MediaStorage\Helper\File\Storage $coreFileStorage, \Magento\Framework\Image\AdapterFactory $imageFactory, \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $validator, - \Magento\Framework\Filesystem $filesystem, - \Magento\Framework\Filesystem\File\ReadFactory $readFactory, + Filesystem $filesystem, + Filesystem\File\ReadFactory $readFactory, $filePath = null, \Magento\Framework\Math\Random $random = null ) { @@ -137,6 +144,7 @@ public function __construct( $this->_coreFileStorageDb = $coreFileStorageDb; $this->_coreFileStorage = $coreFileStorage; $this->_validator = $validator; + $this->fileSystem = $filesystem; $this->_directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $this->_readFactory = $readFactory; if ($filePath !== null) { @@ -236,7 +244,18 @@ private function downloadFileFromUrl($url, $driver) */ protected function _setUploadFile($filePath) { - if (!$this->_directory->isReadable($filePath)) { + try { + $fullPath = $this->_directory->getAbsolutePath($filePath); + if ($this->getTmpDir()) { + $tmpDir = $this->fileSystem->getDirectoryReadByPath($this->_directory->getAbsolutePath($this->getTmpDir())); + } else { + $tmpDir = $this->_directory; + } + $readable = $tmpDir->isReadable($fullPath); + } catch (ValidatorException $exception) { + $readable = false; + } + if (!$readable) { throw new \Magento\Framework\Exception\LocalizedException( __('File \'%1\' was not found or has read restriction.', $filePath) ); diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index d6b96a28afcc..c53ef36c8a2c 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -231,8 +231,11 @@ protected function _prepareForm() 'required' => false, 'class' => 'input-text', 'note' => __( - 'For Type "Local Server" use relative path to Magento installation, - e.g. var/export, var/import, var/export/some/dir' + $this->escapeHtml( + 'For Type "Local Server" use relative path to /' + .$this->_scopeConfig->getValue('general/file/import_images_base_dir') + .', e.g. product_images, import_images/batch1' + ) ), ] ); diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index e850f6af86cf..721ccabad992 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -6,9 +6,14 @@ namespace Magento\ImportExport\Controller\Adminhtml\Import; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\ObjectManager; use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; +use Magento\ImportExport\Model\ImportFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Filesystem; +use Magento\Framework\App\Filesystem\DirectoryList; /** * Controller responsible for initiating the import process @@ -25,25 +30,50 @@ class Start extends ImportResultController implements HttpPostActionInterface */ private $exceptionMessageFactory; + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @var ImportFactory + */ + private $importFactory; + + /** + * @var Filesystem + */ + private $fileSystem; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor * @param \Magento\ImportExport\Model\History $historyModel * @param \Magento\ImportExport\Helper\Report $reportHelper - * @param \Magento\ImportExport\Model\Import $importModel + * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory + * @param ScopeConfigInterface|null $config + * @param ImportFactory|null $importFactory + * @param Filesystem|null $fileSystem + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\ImportExport\Model\Report\ReportProcessorInterface $reportProcessor, \Magento\ImportExport\Model\History $historyModel, \Magento\ImportExport\Helper\Report $reportHelper, - \Magento\ImportExport\Model\Import $importModel, - \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory + Import $importModel, + \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory, + ?ScopeConfigInterface $config = null, + ?ImportFactory $importFactory = null, + ?Filesystem $fileSystem = null ) { parent::__construct($context, $reportProcessor, $historyModel, $reportHelper); - $this->importModel = $importModel; + $this->exceptionMessageFactory = $exceptionMessageFactory; + $this->config = $config ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class); + $this->importFactory = $importFactory ?? ObjectManager::getInstance()->get(ImportFactory::class); + $this->fileSystem = $fileSystem ?? ObjectManager::getInstance()->get(Filesystem::class); } /** @@ -53,6 +83,12 @@ public function __construct( */ public function execute() { + $imagesDirectoryPath = $this->config->getValue('general/file/import_images_base_dir'); + $imagesDirectory = $this->fileSystem->getDirectoryReadByPath( + $this->fileSystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($imagesDirectoryPath) + ); + $this->importModel = $this->importFactory->create(['imagesTempDirectoryBase' => $imagesDirectory]); + $data = $this->getRequest()->getPostValue(); if ($data) { /** @var \Magento\Framework\View\Result\Layout $resultLayout */ diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 04f4111d3a0a..1113165d4159 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -13,6 +13,7 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Filesystem; use Magento\Framework\HTTP\Adapter\FileTransferFactory; use Magento\Framework\Indexer\IndexerRegistry; @@ -198,6 +199,11 @@ class Import extends AbstractModel */ private $random; + /** + * @var Filesystem\Directory\Read|null + */ + private $imagesTempDirectoryBase; + /** * @param LoggerInterface $logger * @param Filesystem $filesystem @@ -216,6 +222,7 @@ class Import extends AbstractModel * @param array $data * @param ManagerInterface|null $messageManager * @param Random|null $random + * @param Filesystem\Directory\Read|null $imagesTempDirectoryBase * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -235,7 +242,8 @@ public function __construct( DateTime $localeDate, array $data = [], ManagerInterface $messageManager = null, - Random $random = null + Random $random = null, + ?Filesystem\Directory\Read $imagesTempDirectoryBase = null ) { $this->_importExportData = $importExportData; $this->_coreConfig = $coreConfig; @@ -254,6 +262,7 @@ public function __construct( ->get(ManagerInterface::class); $this->random = $random ?: ObjectManager::getInstance() ->get(Random::class); + $this->imagesTempDirectoryBase = $imagesTempDirectoryBase; parent::__construct($logger, $filesystem, $data); } @@ -464,8 +473,24 @@ public function importSource() { $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); - $this->importHistoryModel->updateReport($this); + //Validating images temporary directory path if the constraint has been provided + if ($this->imagesTempDirectoryBase) { + if (!$this->imagesTempDirectoryBase->isReadable()) { + $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); + $rootWrite->create($this->imagesTempDirectoryBase->getAbsolutePath()); + } + try { + $this->setData( + self::FIELD_NAME_IMG_FILE_DIR, + $this->imagesTempDirectoryBase->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) + ); + $this->_getEntityAdapter()->setParameters($this->getData()); + } catch (ValidatorException $exception) { + throw new LocalizedException(__('Images file directory is outside required directory'), $exception); + } + } + $this->importHistoryModel->updateReport($this); $this->addLogComment(__('Begin import of "%1" with "%2" behavior', $this->getEntity(), $this->getBehavior())); $result = $this->processImport(); diff --git a/app/code/Magento/ImportExport/etc/config.xml b/app/code/Magento/ImportExport/etc/config.xml index 7aee9bdd2fd6..b8ce1c70ee16 100644 --- a/app/code/Magento/ImportExport/etc/config.xml +++ b/app/code/Magento/ImportExport/etc/config.xml @@ -18,6 +18,7 @@ 100 + var/import/images diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php index f61aa7578d4a..a8672abd52c8 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php @@ -73,6 +73,27 @@ public function testMoveWithValidFile(): void $this->assertTrue($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); } + /** + * Check validation against temporary directory. + * + * @magentoAppIsolation enabled + * @return void + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testMoveWithFileOutsideTemp(): void + { + $tmpDir = $this->uploader->getTmpDir(); + if (!$this->directory->create($newTmpDir = $tmpDir .'/test1')) { + throw new \RuntimeException('Failed to create temp dir'); + } + $this->uploader->setTmpDir($newTmpDir); + $fileName = 'magento_additional_image_one.jpg'; + $filePath = $this->directory->getAbsolutePath($tmpDir . '/' . $fileName); + copy(__DIR__ . '/_files/' . $fileName, $filePath); + $this->uploader->move('../' .$fileName); + $this->assertTrue($this->directory->isExist($tmpDir . '/' . $fileName)); + } + /** * @magentoAppIsolation enabled * @return void diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index 0c1f2d2fcc8d..0fa37f6a753b 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -5,8 +5,11 @@ */ namespace Magento\ImportExport\Model; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; use Magento\Framework\Phrase; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; +use Magento\TestFramework\Helper\Bootstrap; /** * @magentoDataFixture Magento/ImportExport/_files/import_data.php @@ -65,13 +68,35 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->_importConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $this->_importConfig = Bootstrap::getObjectManager()->create( \Magento\ImportExport\Model\Import\Config::class ); - $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + /** @var Filesystem $fileSystem */ + $fileSystem = Bootstrap::getObjectManager()->get(Filesystem::class); + $this->_model = Bootstrap::getObjectManager()->create( Import::class, - ['importConfig' => $this->_importConfig] + [ + 'importConfig' => $this->_importConfig, + 'imagesTempDirectoryBase' => $fileSystem->getDirectoryRead(DirectoryList::VAR_DIR) + ] + ); + } + + /** + * Test validation of images directory against provided base directory. + * + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Images file directory is outside required directory + * @return void + */ + public function testImagesDirBase(): void + { + $this->_model->setData( + Import::FIELD_NAME_VALIDATION_STRATEGY, + ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS ); + $this->_model->setData(Import::FIELD_NAME_IMG_FILE_DIR, '../_files'); + $this->_model->importSource(); } /** @@ -80,7 +105,7 @@ protected function setUp() public function testImportSource() { /** @var $customersCollection \Magento\Customer\Model\ResourceModel\Customer\Collection */ - $customersCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $customersCollection = Bootstrap::getObjectManager()->create( \Magento\Customer\Model\ResourceModel\Customer\Collection::class ); From 567e512064353792db50597028382fef256ef507 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Tue, 7 May 2019 18:33:26 -0500 Subject: [PATCH 0039/1172] MC-6293: Fixed incorrect import behavior --- .../Magento/CatalogImportExport/Model/Import/Uploader.php | 4 +++- .../ImportExport/Controller/Adminhtml/Import/Start.php | 2 ++ .../Magento/CatalogImportExport/Model/Import/UploaderTest.php | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index b5d7364dedc4..09c3cc4daf1d 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -247,7 +247,9 @@ protected function _setUploadFile($filePath) try { $fullPath = $this->_directory->getAbsolutePath($filePath); if ($this->getTmpDir()) { - $tmpDir = $this->fileSystem->getDirectoryReadByPath($this->_directory->getAbsolutePath($this->getTmpDir())); + $tmpDir = $this->fileSystem->getDirectoryReadByPath( + $this->_directory->getAbsolutePath($this->getTmpDir()) + ); } else { $tmpDir = $this->_directory; } diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 721ccabad992..b18490505fee 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -17,6 +17,8 @@ /** * Controller responsible for initiating the import process + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php index a8672abd52c8..3961a7792731 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/UploaderTest.php @@ -68,6 +68,7 @@ public function testMoveWithValidFile(): void { $fileName = 'magento_additional_image_one.jpg'; $filePath = $this->directory->getAbsolutePath($this->uploader->getTmpDir() . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move($fileName); $this->assertTrue($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); @@ -89,6 +90,7 @@ public function testMoveWithFileOutsideTemp(): void $this->uploader->setTmpDir($newTmpDir); $fileName = 'magento_additional_image_one.jpg'; $filePath = $this->directory->getAbsolutePath($tmpDir . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move('../' .$fileName); $this->assertTrue($this->directory->isExist($tmpDir . '/' . $fileName)); @@ -104,6 +106,7 @@ public function testMoveWithInvalidFile(): void { $fileName = 'media_import_image.php'; $filePath = $this->directory->getAbsolutePath($this->uploader->getTmpDir() . '/' . $fileName); + //phpcs:ignore copy(__DIR__ . '/_files/' . $fileName, $filePath); $this->uploader->move($fileName); $this->assertFalse($this->directory->isExist($this->uploader->getTmpDir() . '/' . $fileName)); From 293667e01dd4c76f59a66e34f320f0056f513998 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Thu, 9 May 2019 10:27:39 -0500 Subject: [PATCH 0040/1172] MC-15977: Email template preview --- app/code/Magento/Email/Block/Adminhtml/Template/Preview.php | 2 +- .../Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index d9cd5ef7f0c8..5b7979c3d860 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -62,7 +62,7 @@ protected function _toHtml() /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); - if (!$request->isSafeMethod()) { + if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); } diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 55757476ea82..8143995f3b2a 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -146,9 +146,7 @@ protected function setUp() * Check of processing email templates * * @param array $requestParamMap - * * @dataProvider toHtmlDataProvider - * @param $requestParamMap */ public function testToHtml($requestParamMap) { From 703f00d90ad97aaefb26a41dfd971a7885deeb60 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov Date: Thu, 9 May 2019 11:02:46 -0500 Subject: [PATCH 0041/1172] MC-15977: Email template preview --- app/code/Magento/Email/Block/Adminhtml/Template/Preview.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5b7979c3d860..4f0479a9573f 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -59,7 +59,6 @@ public function __construct( */ protected function _toHtml() { - /** @var $request \Magento\Framework\App\Request\Http */ $request = $this->getRequest(); if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { From 24ee35853e53ba77b1954eb43829cbbdc982c2ed Mon Sep 17 00:00:00 2001 From: Dan Mooney Date: Thu, 9 May 2019 15:42:12 -0500 Subject: [PATCH 0042/1172] MC-15132: Update XML Design --- .../UiComponent/Argument/Interpreter/ConfigurableObject.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 35a5fffd4526..5135ad4d7f86 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -61,7 +61,10 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - if (in_array(ltrim($arguments['class'], '\\'), $this->classBlacklist)) { + if (in_array( + ltrim(strtolower($arguments['class']), '\\'), + array_map('strtolower', $this->classBlacklist) + )) { throw new \InvalidArgumentException(sprintf( 'Class argument is invalid: %s', $arguments['class'] From 6528d9abf3613433bebe8ec0b8e11327469483da Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 10 May 2019 11:45:24 -0500 Subject: [PATCH 0043/1172] MC-6293: Fixed incorrect import behavior --- .../Block/Adminhtml/Import/Edit/Form.php | 14 +++- .../Controller/Adminhtml/Import/Start.php | 41 +++--------- .../Magento/ImportExport/Model/Import.php | 27 ++++---- .../Import/ImageDirectoryBaseProvider.php | 64 +++++++++++++++++++ .../Magento/ImportExport/Model/ImportTest.php | 15 ++--- 5 files changed, 106 insertions(+), 55 deletions(-) create mode 100644 app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php index c53ef36c8a2c..af5377a6227c 100644 --- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php +++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php @@ -5,6 +5,7 @@ */ namespace Magento\ImportExport\Block\Adminhtml\Import\Edit; +use Magento\Framework\App\ObjectManager; use Magento\ImportExport\Model\Import; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; @@ -32,6 +33,11 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic */ protected $_behaviorFactory; + /** + * @var Import\ImageDirectoryBaseProvider + */ + private $imagesDirectoryProvider; + /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Framework\Registry $registry @@ -40,6 +46,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic * @param \Magento\ImportExport\Model\Source\Import\EntityFactory $entityFactory * @param \Magento\ImportExport\Model\Source\Import\Behavior\Factory $behaviorFactory * @param array $data + * @param Import\ImageDirectoryBaseProvider|null $imageDirProvider */ public function __construct( \Magento\Backend\Block\Template\Context $context, @@ -48,12 +55,15 @@ public function __construct( \Magento\ImportExport\Model\Import $importModel, \Magento\ImportExport\Model\Source\Import\EntityFactory $entityFactory, \Magento\ImportExport\Model\Source\Import\Behavior\Factory $behaviorFactory, - array $data = [] + array $data = [], + ?Import\ImageDirectoryBaseProvider $imageDirProvider = null ) { $this->_entityFactory = $entityFactory; $this->_behaviorFactory = $behaviorFactory; parent::__construct($context, $registry, $formFactory, $data); $this->_importModel = $importModel; + $this->imagesDirectoryProvider = $imageDirProvider + ?? ObjectManager::getInstance()->get(Import\ImageDirectoryBaseProvider::class); } /** @@ -233,7 +243,7 @@ protected function _prepareForm() 'note' => __( $this->escapeHtml( 'For Type "Local Server" use relative path to /' - .$this->_scopeConfig->getValue('general/file/import_images_base_dir') + .$this->imagesDirectoryProvider->getDirectoryRelativePath() .', e.g. product_images, import_images/batch1' ) ), diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index b18490505fee..0cc1fd40bf7e 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -10,15 +10,10 @@ use Magento\ImportExport\Controller\Adminhtml\ImportResult as ImportResultController; use Magento\Framework\Controller\ResultFactory; use Magento\ImportExport\Model\Import; -use Magento\ImportExport\Model\ImportFactory; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Filesystem; -use Magento\Framework\App\Filesystem\DirectoryList; /** * Controller responsible for initiating the import process * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { @@ -33,19 +28,9 @@ class Start extends ImportResultController implements HttpPostActionInterface private $exceptionMessageFactory; /** - * @var ScopeConfigInterface + * @var Import\ImageDirectoryBaseProvider */ - private $config; - - /** - * @var ImportFactory - */ - private $importFactory; - - /** - * @var Filesystem - */ - private $fileSystem; + private $imagesDirProvider; /** * @param \Magento\Backend\App\Action\Context $context @@ -54,9 +39,7 @@ class Start extends ImportResultController implements HttpPostActionInterface * @param \Magento\ImportExport\Helper\Report $reportHelper * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory - * @param ScopeConfigInterface|null $config - * @param ImportFactory|null $importFactory - * @param Filesystem|null $fileSystem + * @param Import\ImageDirectoryBaseProvider|null $imageDirectoryBaseProvider * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -66,16 +49,14 @@ public function __construct( \Magento\ImportExport\Helper\Report $reportHelper, Import $importModel, \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory, - ?ScopeConfigInterface $config = null, - ?ImportFactory $importFactory = null, - ?Filesystem $fileSystem = null + ?Import\ImageDirectoryBaseProvider $imageDirectoryBaseProvider = null ) { parent::__construct($context, $reportProcessor, $historyModel, $reportHelper); + $this->importModel = $importModel; $this->exceptionMessageFactory = $exceptionMessageFactory; - $this->config = $config ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class); - $this->importFactory = $importFactory ?? ObjectManager::getInstance()->get(ImportFactory::class); - $this->fileSystem = $fileSystem ?? ObjectManager::getInstance()->get(Filesystem::class); + $this->imagesDirProvider = $imageDirectoryBaseProvider + ?? ObjectManager::getInstance()->get(Import\ImageDirectoryBaseProvider::class); } /** @@ -85,12 +66,6 @@ public function __construct( */ public function execute() { - $imagesDirectoryPath = $this->config->getValue('general/file/import_images_base_dir'); - $imagesDirectory = $this->fileSystem->getDirectoryReadByPath( - $this->fileSystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($imagesDirectoryPath) - ); - $this->importModel = $this->importFactory->create(['imagesTempDirectoryBase' => $imagesDirectory]); - $data = $this->getRequest()->getPostValue(); if ($data) { /** @var \Magento\Framework\View\Result\Layout $resultLayout */ @@ -104,6 +79,8 @@ public function execute() ->addAction('hide', ['edit_form', 'upload_button', 'messages']); $this->importModel->setData($data); + //Images can be read only from given directory. + $this->importModel->setData(Import::IMAGES_BASE_DIR, $this->imagesDirProvider->getDirectory()); $errorAggregator = $this->importModel->getErrorAggregator(); $errorAggregator->initValidationStrategy( $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 1113165d4159..8d3bef38e3cb 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -72,6 +72,11 @@ class Import extends AbstractModel */ const FIELD_NAME_IMG_FILE_DIR = 'import_images_file_dir'; + /** + * ReadInterface of the directory constraint for images. + */ + const IMAGES_BASE_DIR = 'images_base_directory'; + /** * Allowed errors count field name */ @@ -199,11 +204,6 @@ class Import extends AbstractModel */ private $random; - /** - * @var Filesystem\Directory\Read|null - */ - private $imagesTempDirectoryBase; - /** * @param LoggerInterface $logger * @param Filesystem $filesystem @@ -222,7 +222,6 @@ class Import extends AbstractModel * @param array $data * @param ManagerInterface|null $messageManager * @param Random|null $random - * @param Filesystem\Directory\Read|null $imagesTempDirectoryBase * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -242,8 +241,7 @@ public function __construct( DateTime $localeDate, array $data = [], ManagerInterface $messageManager = null, - Random $random = null, - ?Filesystem\Directory\Read $imagesTempDirectoryBase = null + Random $random = null ) { $this->_importExportData = $importExportData; $this->_coreConfig = $coreConfig; @@ -262,7 +260,6 @@ public function __construct( ->get(ManagerInterface::class); $this->random = $random ?: ObjectManager::getInstance() ->get(Random::class); - $this->imagesTempDirectoryBase = $imagesTempDirectoryBase; parent::__construct($logger, $filesystem, $data); } @@ -474,15 +471,19 @@ public function importSource() $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); //Validating images temporary directory path if the constraint has been provided - if ($this->imagesTempDirectoryBase) { - if (!$this->imagesTempDirectoryBase->isReadable()) { + if ($this->hasData(self::IMAGES_BASE_DIR) + && $this->getData(self::IMAGES_BASE_DIR) instanceof Filesystem\Directory\ReadInterface + ) { + /** @var Filesystem\Directory\ReadInterface $imagesDirectory */ + $imagesDirectory = $this->getData(self::IMAGES_BASE_DIR); + if (!$imagesDirectory->isReadable()) { $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); - $rootWrite->create($this->imagesTempDirectoryBase->getAbsolutePath()); + $rootWrite->create($imagesDirectory->getAbsolutePath()); } try { $this->setData( self::FIELD_NAME_IMG_FILE_DIR, - $this->imagesTempDirectoryBase->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) + $imagesDirectory->getAbsolutePath($this->getData(self::FIELD_NAME_IMG_FILE_DIR)) ); $this->_getEntityAdapter()->setParameters($this->getData()); } catch (ValidatorException $exception) { diff --git a/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php b/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php new file mode 100644 index 000000000000..9c90b57c30ea --- /dev/null +++ b/app/code/Magento/ImportExport/Model/Import/ImageDirectoryBaseProvider.php @@ -0,0 +1,64 @@ +config = $config; + $this->filesystem = $filesystem; + } + + /** + * Directory that users are allowed to place images for importing. + * + * @return ReadInterface + */ + public function getDirectory(): ReadInterface + { + $path = $this->getDirectoryRelativePath(); + + return $this->filesystem->getDirectoryReadByPath( + $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath($path) + ); + } + + /** + * The directory's path relative to Magento root. + * + * @return string + */ + public function getDirectoryRelativePath(): string + { + return $this->config->getValue('general/file/import_images_base_dir'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index 0fa37f6a753b..c6abf51c0858 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -5,10 +5,9 @@ */ namespace Magento\ImportExport\Model; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Filesystem; use Magento\Framework\Phrase; use Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface; +use Magento\ImportExport\Model\Import\ImageDirectoryBaseProvider; use Magento\TestFramework\Helper\Bootstrap; /** @@ -24,7 +23,7 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected $_model; /** - * @var \Magento\ImportExport\Model\Import\Config + * @var Import\Config */ protected $_importConfig; @@ -69,17 +68,17 @@ class ImportTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->_importConfig = Bootstrap::getObjectManager()->create( - \Magento\ImportExport\Model\Import\Config::class + Import\Config::class ); - /** @var Filesystem $fileSystem */ - $fileSystem = Bootstrap::getObjectManager()->get(Filesystem::class); + /** @var ImageDirectoryBaseProvider $provider */ + $provider = Bootstrap::getObjectManager()->get(ImageDirectoryBaseProvider::class); $this->_model = Bootstrap::getObjectManager()->create( Import::class, [ - 'importConfig' => $this->_importConfig, - 'imagesTempDirectoryBase' => $fileSystem->getDirectoryRead(DirectoryList::VAR_DIR) + 'importConfig' => $this->_importConfig ] ); + $this->_model->setData(Import::IMAGES_BASE_DIR, $provider->getDirectory()); } /** From d188d7f2dee04ef3a7b2e76c159e6e9ea25dc69f Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Fri, 10 May 2019 14:17:38 -0500 Subject: [PATCH 0044/1172] MC-6293: Fixed incorrect import behavior --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 0cc1fd40bf7e..70e6f66329b7 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -12,8 +12,9 @@ use Magento\ImportExport\Model\Import; /** - * Controller responsible for initiating the import process + * Controller responsible for initiating the import process. * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Start extends ImportResultController implements HttpPostActionInterface { @@ -40,7 +41,6 @@ class Start extends ImportResultController implements HttpPostActionInterface * @param Import $importModel * @param \Magento\Framework\Message\ExceptionMessageFactoryInterface $exceptionMessageFactory * @param Import\ImageDirectoryBaseProvider|null $imageDirectoryBaseProvider - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( \Magento\Backend\App\Action\Context $context, From 5456745f8726eec4df2303d1e054a1ceed3cb74e Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 09:57:08 -0500 Subject: [PATCH 0045/1172] MC-15811: Incorrect Url Use data object for token generation. Modify unit and integration tests. Fix static error. --- .../Store/Controller/Store/SwitchRequest.php | 8 +- .../Model/StoreSwitcher/HashGenerator.php | 13 ++- .../StoreSwitcher/HashGenerator/HashData.php | 44 +++++++++ .../testsuite/Magento/Framework/UrlTest.php | 14 +++ .../Magento/Store/Model/HashGeneratorTest.php | 97 ++++++++++++------- 5 files changed, 135 insertions(+), 41 deletions(-) create mode 100644 app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index e220941017c3..24e07137497b 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -16,6 +16,7 @@ use \Magento\Framework\Exception\LocalizedException; use Magento\Framework\Url\DecoderInterface; use \Magento\Framework\App\ActionInterface; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; /** * Builds correct url to target store and performs redirect. @@ -78,7 +79,12 @@ public function execute() $error = null; $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); $targetUrl = $this->urlDecoder->decode($encodedUrl); - $data=[$customerId, $timeStamp, $fromStoreCode]; + + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index ac195c699a96..0fe47412537c 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -14,6 +14,7 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; use \Magento\Framework\App\ActionInterface; +use Magento\Framework\DataObject; /** * Generate one time token and build redirect url @@ -99,14 +100,16 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s * Validates one time token * * @param string $signature - * @param array $data + * @param DataObject $hashData * @return bool */ - public function validateHash(string $signature, array $data): bool + public function validateHash(string $signature, DataObject $hashData): bool { - if (!empty($signature) && !empty($data)) { - $timeStamp = $data[1] ?? 0; - $value = implode(",", $data); + if (!empty($signature) && !empty($hashData)) { + $timeStamp = $hashData->getTimestamp(); + $fromStoreCode = $hashData->getFromStoreCode(); + $customerId = $hashData->getCustomerId(); + $value = implode(",", [$customerId, $timeStamp, $fromStoreCode]); $key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); if (time() - $timeStamp <= 5 && hash_equals($signature, hash_hmac('sha256', $value, $key))) { diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php new file mode 100644 index 000000000000..19ca8fe7ddad --- /dev/null +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -0,0 +1,44 @@ +getData('customer_id'); + } + + /** + * Get Timestamp + * + * @return int + */ + public function getTimestamp() + { + return $this->getData('time_stamp'); + } + + /** + * Get Fromstore + * + * @return string + */ + public function getFromStoreCode() + { + return $this->getData('___from_store'); + } +} \ No newline at end of file diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index 9d07c07e824d..ae91d5042d41 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -23,6 +23,13 @@ protected function setUp() $this->model = Bootstrap::getObjectManager()->create(\Magento\Framework\Url::class); } + public function testSetGetUseSession() + { + $this->assertFalse((bool)$this->model->getUseSession()); + $this->model->setUseSession(false); + $this->assertFalse($this->model->getUseSession()); + } + public function testSetRouteFrontName() { $value = 'route'; @@ -485,6 +492,13 @@ public function testSessionUrlVar() $this->assertEquals('www.example.com', $sessionUrl); } + public function testUseSessionIdForUrl() + { + $_SERVER['HTTP_HOST'] = 'localhost'; + $this->assertFalse($this->model->useSessionIdForUrl(true)); + $this->assertFalse($this->model->useSessionIdForUrl(false)); + } + /** * Note: isolation flushes the URL memory cache * @magentoAppIsolation enabled diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index c56f2bf347a7..0eda33645b6b 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -11,11 +11,11 @@ use Magento\TestFramework\Helper\Bootstrap; use Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Customer\Api\AccountManagementInterface; -use Magento\Customer\Model\Session; +use Magento\Customer\Model\Session as CustomerSession; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Config\ConfigOptionsListConstants; -use \Magento\Framework\App\ActionInterface; use Magento\Framework\Url\Helper\Data as UrlHelper; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; /** * Test class for \Magento\Store\Model\StoreSwitcher\HashGenerator @@ -61,6 +61,16 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase */ private $urlHelper; + /** + * @var HashData + */ + private $hashData; + + /** + * @var CustomerSession + */ + private $customerSession; + /** * Class dependencies initialization * @return void @@ -69,15 +79,15 @@ class HashGeneratorTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $session = $this->objectManager->create( - Session::class + $this->customerSession = $this->objectManager->create( + CustomerSession::class ); $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); $customer = $this->accountManagement->authenticate('customer@example.com', 'password'); - $session->setCustomerDataAsLoggedIn($customer); + $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSessionUserContext = $this->objectManager->create( \Magento\Customer\Model\Authorization\CustomerSessionUserContext::class, - ['customerSession' => $session] + ['customerSession' => $this->customerSession] ); $this->hashGenerator = $this->objectManager->create( StoreSwitcher\HashGenerator::class, @@ -87,46 +97,53 @@ protected function setUp() $this->deploymentConfig = $this->objectManager->get(DeploymentConfig::class); $this->key = (string)$this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY); $this->urlHelper=$this->objectManager->create(UrlHelper::class); + $this->hashData=$this->objectManager->create(HashData::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + parent:tearDown(); } /** + * @magentoAppIsolation enabled * @magentoDataFixture Magento/Store/_files/store.php * @magentoDataFixture Magento/Store/_files/second_store.php * @magentoDataFixture Magento/Customer/_files/customer.php * @return void - * @throws \Magento\Framework\Exception\NoSuchEntityException */ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $toStoreCode = 'fixture_second_store'; - $encodedUrl=$this->urlHelper->getEncodedUrl($redirectUrl); - /** @var \Magento\Store\Api\StoreRepositoryInterface $storeRepository */ - $storeRepository = $this->objectManager->create(\Magento\Store\Api\StoreRepositoryInterface::class); - $fromStore = $storeRepository->get($fromStoreCode); - $toStore = $storeRepository->get($toStoreCode); + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); - $data = implode(',', [$this->customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $customerId = $this->customerId; + $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); + // phpcs:ignore + $urlParts=parse_url($targetUrl, PHP_URL_QUERY); + $signature=''; + // phpcs:ignore + parse_str($urlParts, $params); - $expectedUrl = "http://domain.com/stores/store/switchrequest"; - $expectedUrl = $this->urlHelper->addRequestParam( - $expectedUrl, - ['customer_id' => $customerId] - ); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['time_stamp' => $timeStamp]); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['signature' => $signature]); - $expectedUrl = $this->urlHelper->addRequestParam($expectedUrl, ['___from_store' => $fromStoreCode]); - $expectedUrl = $this->urlHelper->addRequestParam( - $expectedUrl, - [ActionInterface::PARAM_NAME_URL_ENCODED => $encodedUrl] - ); - $this->assertEquals($expectedUrl, $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl)); + if (isset($params['signature'])) { + $signature=$params['signature']; + } + $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ + "customer_id" => $this->customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]))); } /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ public function testValidateHashWithCorrectData(): void @@ -134,12 +151,18 @@ public function testValidateHashWithCorrectData(): void $timeStamp = time(); $customerId = $this->customerId; $fromStoreCode = 'test'; - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $this->assertTrue($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); + $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); } /** + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ public function testValidateHashWithInCorrectData(): void @@ -147,8 +170,12 @@ public function testValidateHashWithInCorrectData(): void $timeStamp = 0; $customerId = 8; $fromStoreCode = 'test'; - $data = implode(',', [$customerId, $timeStamp, $fromStoreCode]); - $signature = hash_hmac('sha256', $data, $this->key); - $this->assertFalse($this->hashGenerator->validateHash($signature, [$customerId, $timeStamp, $fromStoreCode])); + $data = new HashData([ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ]); + $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $this->assertFalse($this->hashGenerator->validateHash($signature, $data)); } } From 27af1c05e295f842b9efdb57174b257cb27b6afb Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 13 May 2019 11:29:07 -0500 Subject: [PATCH 0046/1172] MC-6293: Fixed incorrect import behavior --- .../ImportExport/Controller/Adminhtml/Import/Start.php | 2 +- app/code/Magento/ImportExport/Model/Import.php | 6 +++--- .../testsuite/Magento/ImportExport/Model/ImportTest.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php index 70e6f66329b7..5f036e51f66c 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php @@ -80,7 +80,7 @@ public function execute() $this->importModel->setData($data); //Images can be read only from given directory. - $this->importModel->setData(Import::IMAGES_BASE_DIR, $this->imagesDirProvider->getDirectory()); + $this->importModel->setData('images_base_directory', $this->imagesDirProvider->getDirectory()); $errorAggregator = $this->importModel->getErrorAggregator(); $errorAggregator->initValidationStrategy( $this->importModel->getData(Import::FIELD_NAME_VALIDATION_STRATEGY), diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index 8d3bef38e3cb..cbc5cf8ceeb8 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -471,11 +471,11 @@ public function importSource() $this->setData('entity', $this->getDataSourceModel()->getEntityTypeCode()); $this->setData('behavior', $this->getDataSourceModel()->getBehavior()); //Validating images temporary directory path if the constraint has been provided - if ($this->hasData(self::IMAGES_BASE_DIR) - && $this->getData(self::IMAGES_BASE_DIR) instanceof Filesystem\Directory\ReadInterface + if ($this->hasData('images_base_directory') + && $this->getData('images_base_directory') instanceof Filesystem\Directory\ReadInterface ) { /** @var Filesystem\Directory\ReadInterface $imagesDirectory */ - $imagesDirectory = $this->getData(self::IMAGES_BASE_DIR); + $imagesDirectory = $this->getData('images_base_directory'); if (!$imagesDirectory->isReadable()) { $rootWrite = $this->_filesystem->getDirectoryWrite(DirectoryList::ROOT); $rootWrite->create($imagesDirectory->getAbsolutePath()); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php index c6abf51c0858..0f92da2230f7 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/ImportTest.php @@ -78,7 +78,7 @@ protected function setUp() 'importConfig' => $this->_importConfig ] ); - $this->_model->setData(Import::IMAGES_BASE_DIR, $provider->getDirectory()); + $this->_model->setData('images_base_directory', $provider->getDirectory()); } /** From 7faf67bb2f1f77782edb45e64bcbda5c3d6d449a Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 11:35:40 -0500 Subject: [PATCH 0047/1172] MC-15811: Incorrect Url Fix typo in function call. --- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 0eda33645b6b..3f8a1768a1fa 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -106,7 +106,7 @@ protected function setUp() protected function tearDown() { $this->customerSession->logout(); - parent:tearDown(); + parent::tearDown(); } /** From 98239dd88a95456412403a8f588975caabfc6367 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 14:28:45 -0500 Subject: [PATCH 0048/1172] MC-15811: Incorrect Url Fix phpcs static errors. Fix integration test. --- .../Store/Model/StoreSwitcher/HashGenerator/HashData.php | 2 +- dev/tests/integration/testsuite/Magento/Framework/UrlTest.php | 1 + .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php index 19ca8fe7ddad..988b889b2d9b 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -41,4 +41,4 @@ public function getFromStoreCode() { return $this->getData('___from_store'); } -} \ No newline at end of file +} diff --git a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php index ae91d5042d41..db830d228201 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/UrlTest.php @@ -494,6 +494,7 @@ public function testSessionUrlVar() public function testUseSessionIdForUrl() { + // phpcs:ignore $_SERVER['HTTP_HOST'] = 'localhost'; $this->assertFalse($this->model->useSessionIdForUrl(true)); $this->assertFalse($this->model->useSessionIdForUrl(false)); diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 3f8a1768a1fa..aa3d8d36de29 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -120,8 +120,8 @@ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $fromStore = $this->createPartialMock(Store::class, ['getCode']); - $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore = $this->createMock(Store::class); + $toStore = $this->createMock(Store::class); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); From 337b7625740633ac10245a4b13894e4faa92c80c Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Mon, 13 May 2019 15:12:28 -0500 Subject: [PATCH 0049/1172] MC-6293: Fixed incorrect import behavior --- app/code/Magento/ImportExport/Model/Import.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index cbc5cf8ceeb8..c8a5921b41b1 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -72,11 +72,6 @@ class Import extends AbstractModel */ const FIELD_NAME_IMG_FILE_DIR = 'import_images_file_dir'; - /** - * ReadInterface of the directory constraint for images. - */ - const IMAGES_BASE_DIR = 'images_base_directory'; - /** * Allowed errors count field name */ From cdd3fe01612f6a32fb4d5dd7a617f02a233fc987 Mon Sep 17 00:00:00 2001 From: Sachin Admane Date: Mon, 13 May 2019 16:05:14 -0500 Subject: [PATCH 0050/1172] MC-15811: Incorrect Url Remove unused fixture. --- .../testsuite/Magento/Store/Model/HashGeneratorTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index aa3d8d36de29..0ff9f40e4c9c 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -111,8 +111,6 @@ protected function tearDown() /** * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Store/_files/store.php - * @magentoDataFixture Magento/Store/_files/second_store.php * @magentoDataFixture Magento/Customer/_files/customer.php * @return void */ @@ -120,8 +118,8 @@ public function testSwitch(): void { $redirectUrl = "http://domain.com/"; $fromStoreCode = 'test'; - $fromStore = $this->createMock(Store::class); - $toStore = $this->createMock(Store::class); + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); From eda0fcd0bf6a030e502a981dde7f2848f8534b10 Mon Sep 17 00:00:00 2001 From: David Haecker Date: Tue, 14 May 2019 12:33:16 -0500 Subject: [PATCH 0051/1172] MC-16261: Failing MFTF Test in 2.3.3-develop: MAGETWO-96164: Checking Catalog grid page number after Save and Close action - Fixing product grid reset in AdminGridPageNumberAfterSaveAndCloseActionTest --- .../Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml index b24ed7f9c9a8..aff5e8916632 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml @@ -24,9 +24,7 @@ - - + From 24889de9b1cf149b64fa0bd29d0ae64946e9cefd Mon Sep 17 00:00:00 2001 From: Lusine Papyan Date: Wed, 15 May 2019 17:58:43 +0400 Subject: [PATCH 0052/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Added automated test script --- .../ActionGroup/AdminCategoryActionGroup.xml | 12 ++ .../AdminCategorySidebarTreeSection.xml | 1 + ...goryWithRestrictedUrlKeyNotCreatedTest.xml | 125 ++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml index 90d732c9654e..a944aa72e5cc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml @@ -139,6 +139,18 @@ + + + + + + + + + + + + diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml index fba28b3feaff..c6f669ce5c13 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategorySidebarTreeSection.xml @@ -17,5 +17,6 @@ + diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml new file mode 100644 index 000000000000..58997aa7a518 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -0,0 +1,125 @@ + + + + + + + + + <description value="Category with restricted Url Key cannot be created"/> + <severity value="MAJOR"/> + <testCaseId value="MAGETWO-71221"/> + <useCaseId value="MAGETWO-69825"/> + <group value="CatalogUrlRewrite"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <!--Delete created categories--> + <comment userInput="Delete created categories" stepKey="commentDeleteCreatedCategories"/> + <actionGroup ref="deleteCategoryByName" stepKey="deleteAdminCategory"> + <argument name="categoryName" value="admin"/> + </actionGroup> + <actionGroup ref="deleteCategoryByName" stepKey="deleteSoapCategory"> + <argument name="categoryName" value="soap"/> + </actionGroup> + <actionGroup ref="deleteCategoryByName" stepKey="deleteRestCategory"> + <argument name="categoryName" value="rest"/> + </actionGroup> + <actionGroup ref="deleteCategoryByName" stepKey="deleteGraphQlCategory"> + <argument name="categoryName" value="graphql"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Check category creation with restricted url key 'admin'--> + <comment userInput="Check category creation with restricted url key 'admin'" stepKey="commentCheckAdminCategoryCreation"/> + <actionGroup ref="goToCreateCategoryPage" stepKey="goToCreateAdminCategoryPage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminFirstCategoryForm"> + <argument name="categoryName" value="admin"/> + <argument name="categoryUrlKey" value=""/> + </actionGroup> + <see userInput='URL key "admin" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeAdminFirstErrorMessage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminSecondCategoryForm"> + <argument name="categoryName" value="{{SimpleSubCategory.name}}"/> + <argument name="categoryUrlKey" value="admin"/> + </actionGroup> + <see userInput='URL key "admin" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeAdminSecondErrorMessage"/> + <!--Create category with 'admin' name--> + <comment userInput="Create category with 'admin' name" stepKey="commentAdminCategoryCreation"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminThirdCategoryForm"> + <argument name="categoryName" value="admin"/> + <argument name="categoryUrlKey" value="{{SimpleSubCategory.name}}"/> + </actionGroup> + <see userInput="You saved the category." stepKey="seeAdminSuccessMessage"/> + <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('admin')}}" stepKey="seeAdminCategoryInTree"/> + <!--Check category creation with restricted url key 'soap'--> + <comment userInput="Check category creation with restricted url key 'soap'" stepKey="commentCheckSoapCategoryCreation"/> + <actionGroup ref="goToCreateCategoryPage" stepKey="goToCreateSoapCategoryPage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapFirstCategoryForm"> + <argument name="categoryName" value="soap"/> + <argument name="categoryUrlKey" value=""/> + </actionGroup> + <see userInput='URL key "soap" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeSoapFirstErrorMessage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapSecondCategoryForm"> + <argument name="categoryName" value="{{ApiCategory.name}}"/> + <argument name="categoryUrlKey" value="soap"/> + </actionGroup> + <see userInput='URL key "soap" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeSoapSecondErrorMessage"/> + <!--Create category with 'soap' name--> + <comment userInput="Create category with 'soap' name" stepKey="commentSoapCategoryCreation"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapThirdCategoryForm"> + <argument name="categoryName" value="soap"/> + <argument name="categoryUrlKey" value="{{ApiCategory.name}}"/> + </actionGroup> + <see userInput="You saved the category." stepKey="seeSoapSuccessMessage"/> + <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('soap')}}" stepKey="seeSoapCategoryInTree"/> + <!--Check category creation with restricted url key 'rest'--> + <comment userInput="Check category creation with restricted url key 'rest'" stepKey="commentCheckRestCategoryCreation"/> + <actionGroup ref="goToCreateCategoryPage" stepKey="goToCreateRestCategoryPage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestFirstCategoryForm"> + <argument name="categoryName" value="rest"/> + <argument name="categoryUrlKey" value=""/> + </actionGroup> + <see userInput='URL key "rest" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeRestFirstErrorMessage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestSecondCategoryForm"> + <argument name="categoryName" value="{{SubCategoryWithParent.name}}"/> + <argument name="categoryUrlKey" value="rest"/> + </actionGroup> + <see userInput='URL key "rest" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeRestSecondErrorMessage"/> + <!--Create category with 'rest' name--> + <comment userInput="Create category with 'rest' name" stepKey="commentRestCategoryCreation"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestThirdCategoryForm"> + <argument name="categoryName" value="rest"/> + <argument name="categoryUrlKey" value="{{SubCategoryWithParent.name}}"/> + </actionGroup> + <see userInput="You saved the category." stepKey="seeRestSuccessMesdgssage"/> + <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('rest')}}" stepKey="seeRestCategoryInTree"/> + <!--Check category creation with restricted url key 'graphql'--> + <comment userInput="Check category creation with restricted url key 'graphql'" stepKey="commentCheckGraphQlCategoryCreation"/> + <actionGroup ref="goToCreateCategoryPage" stepKey="goToCreateCategoryPage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlFirstCategoryForm"> + <argument name="categoryName" value="graphql"/> + <argument name="categoryUrlKey" value=""/> + </actionGroup> + <see userInput='URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlFirstErrorMessage"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlSecondCategoryForm"> + <argument name="categoryName" value="{{NewSubCategoryWithParent.name}}"/> + <argument name="categoryUrlKey" value="graphql"/> + </actionGroup> + <see userInput='URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlSecondErrorMessage"/> + <!--Create category with 'graphql' name--> + <comment userInput="Create category with 'graphql' name" stepKey="commentGraphQlCategoryCreation"/> + <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlThirdCategoryForm"> + <argument name="categoryName" value="graphql"/> + <argument name="categoryUrlKey" value="{{NewSubCategoryWithParent.name}}"/> + </actionGroup> + <see userInput="You saved the category." stepKey="seeGraphQlSuccessMessage"/> + <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('graphql')}}" stepKey="seeGraphQlCategoryInTree"/> + </test> +</tests> From fef28787f80873a508acdc404401c48f81bd2db4 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 15 May 2019 10:33:36 -0500 Subject: [PATCH 0053/1172] MC-15132: Update XML Design --- .../UiComponent/Argument/Interpreter/ConfigurableObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 5135ad4d7f86..2810db656942 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -43,7 +43,7 @@ public function __construct(ObjectManagerInterface $objectManager, InterpreterIn } /** - * {@inheritdoc} + * @inheritdoc */ public function evaluate(array $data) { From f5bf195926f907ac9f6fe1b4e56cbe730c1dfbaf Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Wed, 15 May 2019 12:46:47 -0500 Subject: [PATCH 0054/1172] MC-15811: Incorrect Url Fix method signature. Add type hint. Fix integration test. --- .../Model/StoreSwitcher/HashGenerator.php | 6 +-- .../StoreSwitcher/HashGenerator/HashData.php | 14 ++++--- .../Magento/Store/Model/HashGeneratorTest.php | 42 +++++++++---------- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php index 0fe47412537c..456941bd41c2 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator.php @@ -8,13 +8,13 @@ namespace Magento\Store\Model\StoreSwitcher; use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreSwitcher\HashGenerator\HashData; use Magento\Store\Model\StoreSwitcherInterface; use \Magento\Framework\App\DeploymentConfig as DeploymentConfig; use Magento\Framework\Url\Helper\Data as UrlHelper; use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Authorization\Model\UserContextInterface; use \Magento\Framework\App\ActionInterface; -use Magento\Framework\DataObject; /** * Generate one time token and build redirect url @@ -100,10 +100,10 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s * Validates one time token * * @param string $signature - * @param DataObject $hashData + * @param HashData $hashData * @return bool */ - public function validateHash(string $signature, DataObject $hashData): bool + public function validateHash(string $signature, HashData $hashData): bool { if (!empty($signature) && !empty($hashData)) { $timeStamp = $hashData->getTimestamp(); diff --git a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php index 988b889b2d9b..2d0068efbdd9 100644 --- a/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php +++ b/app/code/Magento/Store/Model/StoreSwitcher/HashGenerator/HashData.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Store\Model\StoreSwitcher\HashGenerator; use Magento\Framework\DataObject; @@ -17,9 +19,9 @@ class HashData extends DataObject * * @return int */ - public function getCustomerId() + public function getCustomerId(): int { - return $this->getData('customer_id'); + return (int)$this->getData('customer_id'); } /** @@ -27,9 +29,9 @@ public function getCustomerId() * * @return int */ - public function getTimestamp() + public function getTimestamp(): int { - return $this->getData('time_stamp'); + return (int)$this->getData('time_stamp'); } /** @@ -37,8 +39,8 @@ public function getTimestamp() * * @return string */ - public function getFromStoreCode() + public function getFromStoreCode(): string { - return $this->getData('___from_store'); + return (string)$this->getData('___from_store'); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 0ff9f40e4c9c..226cacd71195 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -121,7 +121,6 @@ public function testSwitch(): void $fromStore = $this->createPartialMock(Store::class, ['getCode']); $toStore = $this->createPartialMock(Store::class, ['getCode']); $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); - $timeStamp = time(); $targetUrl=$this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); // phpcs:ignore $urlParts=parse_url($targetUrl, PHP_URL_QUERY); @@ -132,32 +131,16 @@ public function testSwitch(): void if (isset($params['signature'])) { $signature=$params['signature']; } + $this->assertEquals($params['customer_id'], $this->customerId); + $this->assertEquals($params['___from_store'], $fromStoreCode); + $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ "customer_id" => $this->customerId, - "time_stamp" => $timeStamp, + "time_stamp" => $params['time_stamp'], "___from_store" => $fromStoreCode ]))); } - /** - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Customer/_files/customer.php - * @return void - */ - public function testValidateHashWithCorrectData(): void - { - $timeStamp = time(); - $customerId = $this->customerId; - $fromStoreCode = 'test'; - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); - $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); - $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); - } - /** * @magentoAppIsolation enabled * @magentoDataFixture Magento/Customer/_files/customer.php @@ -167,13 +150,26 @@ public function testValidateHashWithInCorrectData(): void { $timeStamp = 0; $customerId = 8; - $fromStoreCode = 'test'; + $fromStoreCode = 'store1'; $data = new HashData([ "customer_id" => $customerId, "time_stamp" => $timeStamp, "___from_store" => $fromStoreCode ]); - $signature = hash_hmac('sha256', implode(',', [$this->customerId, $timeStamp, $fromStoreCode]), $this->key); + $redirectUrl = "http://domain.com/"; + $fromStore = $this->createPartialMock(Store::class, ['getCode']); + $toStore = $this->createPartialMock(Store::class, ['getCode']); + $fromStore->expects($this->once())->method('getCode')->willReturn($fromStoreCode); + $targetUrl = $this->hashGenerator->switch($fromStore, $toStore, $redirectUrl); + // phpcs:ignore + $urlParts = parse_url($targetUrl,PHP_URL_QUERY); + $signature = ''; + // phpcs:ignore + parse_str($urlParts, $params); + + if (isset($params['signature'])) { + $signature = $params['signature']; + } $this->assertFalse($this->hashGenerator->validateHash($signature, $data)); } } From d4c0c0d755119e87e7208f2949d8ac9dca8ba81d Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Thu, 16 May 2019 15:27:23 -0500 Subject: [PATCH 0055/1172] MC-15811: Incorrect Url Fix annotation. --- lib/internal/Magento/Framework/Session/SidResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Session/SidResolver.php b/lib/internal/Magento/Framework/Session/SidResolver.php index 117c46f3443a..041995d20fcd 100644 --- a/lib/internal/Magento/Framework/Session/SidResolver.php +++ b/lib/internal/Magento/Framework/Session/SidResolver.php @@ -11,7 +11,7 @@ /** * Class SidResolver - * @deprecated 2.3.2 + * @deprecated 2.3.3 SIDs in URLs are no longer used */ class SidResolver implements SidResolverInterface { From 40e805e8535eefcfcb7a3364fb0ff6e16a66a313 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 23 May 2019 15:59:52 -0500 Subject: [PATCH 0056/1172] MC-16865: Outdated js libraries - Updated js library --- lib/web/knockoutjs/knockout.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/web/knockoutjs/knockout.js b/lib/web/knockoutjs/knockout.js index cd11f4d0c0d1..93ccdc541511 100644 --- a/lib/web/knockoutjs/knockout.js +++ b/lib/web/knockoutjs/knockout.js @@ -502,16 +502,6 @@ ko.utils = (function () { setElementName: function(element, name) { element.name = name; - - // Workaround IE 6/7 issue - // - https://github.com/SteveSanderson/knockout/issues/197 - // - http://www.matts411.com/post/setting_the_name_attribute_in_ie_dom/ - if (ieVersion <= 7) { - try { - element.mergeAttributes(document.createElement("<input name='" + element.name + "'/>"), false); - } - catch(e) {} // For IE9 with doc mode "IE9 Standards" and browser mode "IE9 Compatibility View" - } }, forceRefresh: function(node) { From ec7f7b8708e1014e5e742bc1715ca3bf77cf1637 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 17 May 2019 13:20:51 -0500 Subject: [PATCH 0057/1172] MC-15733: firefox method update - Updated method for firefox consumption - Updated test for the change --- lib/internal/Magento/Framework/Escaper.php | 2 +- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b12548f27bc8..b7daadb04dab 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -135,7 +135,7 @@ private function removeNotAllowedTags(\DOMDocument $domDocument, array $allowedT . '\']' ); foreach ($nodes as $node) { - if ($node->nodeName != '#text' && $node->nodeName != '#comment') { + if ($node->nodeName != '#text') { $node->parentNode->replaceChild($domDocument->createTextNode($node->textContent), $node); } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 7b45765fdefe..a1d03f023a20 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -224,7 +224,7 @@ public function escapeHtmlDataProvider() ], 'text with html comment' => [ 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', - 'expected' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', + 'expected' => 'Only <span><b>2</b></span> in stock HTML COMMENT ', 'allowedTags' => ['span', 'b'], ], 'text with non ascii characters' => [ From 4b0823380c32a29aa3f1fec12aa2dabd4a608b97 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 17 May 2019 14:32:22 -0500 Subject: [PATCH 0058/1172] MC-15733: firefox method update - Resolved static failures --- lib/internal/Magento/Framework/Escaper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index b7daadb04dab..29e285114fa0 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -6,6 +6,8 @@ namespace Magento\Framework; +use Magento\Framework\Exception\LocalizedException; + /** * Magento escape methods * @@ -74,7 +76,7 @@ public function escapeHtml($data, $allowedTags = null) $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( function ($errorNumber, $errorString) { - throw new \Exception($errorString, $errorNumber); + throw new LocalizedException($errorString, $errorNumber); } ); $data = $this->prepareUnescapedCharacters($data); From ebc9622a6d09f505275ee8992233c83ceaed1184 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 17 May 2019 15:31:09 -0500 Subject: [PATCH 0059/1172] MC-15733: firefox method update - Resolved static failures --- lib/internal/Magento/Framework/Escaper.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index 29e285114fa0..fac4d9445c05 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -6,8 +6,6 @@ namespace Magento\Framework; -use Magento\Framework\Exception\LocalizedException; - /** * Magento escape methods * @@ -76,7 +74,7 @@ public function escapeHtml($data, $allowedTags = null) $domDocument = new \DOMDocument('1.0', 'UTF-8'); set_error_handler( function ($errorNumber, $errorString) { - throw new LocalizedException($errorString, $errorNumber); + throw new \InvalidArgumentException($errorString, $errorNumber); } ); $data = $this->prepareUnescapedCharacters($data); From 73381b2f4bddf5949d798fef4b98017e7fe22c36 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 20 May 2019 11:29:33 -0500 Subject: [PATCH 0060/1172] MC-15733: firefox method update - Added method for firefox consumption - Updated test for the change --- lib/internal/Magento/Framework/Escaper.php | 16 ++++++++++++++++ .../Magento/Framework/Test/Unit/EscaperTest.php | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index fac4d9445c05..9eec5aec530a 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -89,6 +89,7 @@ function ($errorNumber, $errorString) { } restore_error_handler(); + $this->removeComments($domDocument); $this->removeNotAllowedTags($domDocument, $allowedTags); $this->removeNotAllowedAttributes($domDocument); $this->escapeText($domDocument); @@ -158,6 +159,21 @@ private function removeNotAllowedAttributes(\DOMDocument $domDocument) } } + /** + * Remove comments + * + * @param \DOMDocument $domDocument + * @return void + */ + private function removeComments(\DOMDocument $domDocument) + { + $xpath = new \DOMXPath($domDocument); + $nodes = $xpath->query('//comment()'); + foreach ($nodes as $node) { + $node->parentNode->removeChild($node); + } + } + /** * Escape text * diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index a1d03f023a20..77ad480a53bd 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -224,7 +224,12 @@ public function escapeHtmlDataProvider() ], 'text with html comment' => [ 'data' => 'Only <span><b>2</b></span> in stock <!-- HTML COMMENT -->', - 'expected' => 'Only <span><b>2</b></span> in stock HTML COMMENT ', + 'expected' => 'Only <span><b>2</b></span> in stock ', + 'allowedTags' => ['span', 'b'], + ], + 'text with multi-line html comment' => [ + 'data' => 'Only <span><b>2</b></span> in stock <!-- --!\n\n><img src=#>-->', + 'expected' => 'Only <span><b>2</b></span> in stock ', 'allowedTags' => ['span', 'b'], ], 'text with non ascii characters' => [ From 191b33243a8bd2005d29e37155d29951bb2f3b90 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Tue, 21 May 2019 10:35:08 -0500 Subject: [PATCH 0061/1172] MC-15733: firefox method update - Resolved incorrect test quotes --- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 77ad480a53bd..bc12b0bd1227 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -228,7 +228,7 @@ public function escapeHtmlDataProvider() 'allowedTags' => ['span', 'b'], ], 'text with multi-line html comment' => [ - 'data' => 'Only <span><b>2</b></span> in stock <!-- --!\n\n><img src=#>-->', + 'data' => "Only <span><b>2</b></span> in stock <!-- --!\n\n><img src=#>-->", 'expected' => 'Only <span><b>2</b></span> in stock ', 'allowedTags' => ['span', 'b'], ], From 7dc3ef8ecef02e9e036cff69f27987605e473e57 Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Fri, 24 May 2019 11:22:34 -0500 Subject: [PATCH 0062/1172] MC-15811: Incorrect Url Fix multi line function static error. Refactor data object in integration test. --- .../Store/Controller/Store/SwitchRequest.php | 12 +++++---- .../Magento/Store/Model/HashGeneratorTest.php | 25 +++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Controller/Store/SwitchRequest.php b/app/code/Magento/Store/Controller/Store/SwitchRequest.php index 24e07137497b..9ce151bdab09 100644 --- a/app/code/Magento/Store/Controller/Store/SwitchRequest.php +++ b/app/code/Magento/Store/Controller/Store/SwitchRequest.php @@ -80,11 +80,13 @@ public function execute() $encodedUrl = (string)$this->_request->getParam(ActionInterface::PARAM_NAME_URL_ENCODED); $targetUrl = $this->urlDecoder->decode($encodedUrl); - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); + $data = new HashData( + [ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ] + ); if ($targetUrl && $this->hashGenerator->validateHash($signature, $data)) { try { diff --git a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php index 226cacd71195..1bacd79b74f4 100644 --- a/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/Model/HashGeneratorTest.php @@ -134,11 +134,14 @@ public function testSwitch(): void $this->assertEquals($params['customer_id'], $this->customerId); $this->assertEquals($params['___from_store'], $fromStoreCode); - $this->assertTrue($this->hashGenerator->validateHash($signature, new HashData([ - "customer_id" => $this->customerId, - "time_stamp" => $params['time_stamp'], - "___from_store" => $fromStoreCode - ]))); + $data = new HashData( + [ + "customer_id" => $this->customerId, + "time_stamp" => $params['time_stamp'], + "___from_store" => $fromStoreCode + ] + ); + $this->assertTrue($this->hashGenerator->validateHash($signature, $data)); } /** @@ -151,11 +154,13 @@ public function testValidateHashWithInCorrectData(): void $timeStamp = 0; $customerId = 8; $fromStoreCode = 'store1'; - $data = new HashData([ - "customer_id" => $customerId, - "time_stamp" => $timeStamp, - "___from_store" => $fromStoreCode - ]); + $data = new HashData( + [ + "customer_id" => $customerId, + "time_stamp" => $timeStamp, + "___from_store" => $fromStoreCode + ] + ); $redirectUrl = "http://domain.com/"; $fromStore = $this->createPartialMock(Store::class, ['getCode']); $toStore = $this->createPartialMock(Store::class, ['getCode']); From a22b9234a9f05512c5a47a9e64b0070b996c453b Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 24 May 2019 16:05:16 -0500 Subject: [PATCH 0063/1172] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index f5c3171a3fe9..ae6a55bdd112 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Controller\Product\Compare; +use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; @@ -18,6 +19,7 @@ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPos * Add item to compare list. * * @return \Magento\Framework\Controller\ResultInterface + * @throws NoSuchEntityException */ public function execute() { @@ -36,7 +38,7 @@ public function execute() $product = null; } - if ($product && $product->isSalable()) { + if ($product && $product->getStatus() === Status::STATUS_ENABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From cd67eab797cac72813a688cd7115d620164145a1 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 24 May 2019 16:56:58 -0500 Subject: [PATCH 0064/1172] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index ae6a55bdd112..3793a3858406 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -38,7 +38,7 @@ public function execute() $product = null; } - if ($product && $product->getStatus() === Status::STATUS_ENABLED) { + if ($product && $product->getStatus() !== Status::STATUS_DISABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From 70d8f5dead89f801be7b1af2d5f6782b93308803 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 28 May 2019 07:51:22 -0500 Subject: [PATCH 0065/1172] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index 3793a3858406..ac162652cf89 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -19,7 +19,6 @@ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPos * Add item to compare list. * * @return \Magento\Framework\Controller\ResultInterface - * @throws NoSuchEntityException */ public function execute() { From 26513db3d98d65fa3471f7ee1706affcb4fc1878 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 28 May 2019 09:26:03 -0500 Subject: [PATCH 0066/1172] MC-16977: Broken MFTF Test: MC-14208: Clear all products from the 'Compare Products' list --- app/code/Magento/Catalog/Controller/Product/Compare/Add.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index ac162652cf89..2b989dde9809 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -37,7 +37,7 @@ public function execute() $product = null; } - if ($product && $product->getStatus() !== Status::STATUS_DISABLED) { + if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class From 7447cc947e0a551ac45ab1fdb62dcfbe7d8f12aa Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov <ikolesov@magento.com> Date: Tue, 28 May 2019 15:35:16 -0500 Subject: [PATCH 0067/1172] MC-15977: Email template preview --- .../Block/Adminhtml/Template/PreviewTest.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 8143995f3b2a..83eda7e39a81 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -54,14 +54,16 @@ protected function setUp() $designConfigData = []; $this->template = $this->getMockBuilder(\Magento\Email\Model\Template::class) - ->setMethods([ - 'setDesignConfig', - 'getDesignConfig', - '__wakeup', - 'getProcessedTemplate', - 'getAppState', - 'revertDesign' - ]) + ->setMethods( + [ + 'setDesignConfig', + 'getDesignConfig', + '__wakeup', + 'getProcessedTemplate', + 'getAppState', + 'revertDesign' + ] + ) ->disableOriginalConstructor() ->getMock(); @@ -82,9 +84,7 @@ protected function setUp() ->willReturn(self::MALICIOUS_TEXT); $this->template->method('getDesignConfig') - ->willReturn(new \Magento\Framework\DataObject( - $designConfigData - )); + ->willReturn(new \Magento\Framework\DataObject($designConfigData)); $emailFactory = $this->createPartialMock(\Magento\Email\Model\TemplateFactory::class, ['create']); $emailFactory->expects($this->any()) @@ -106,9 +106,11 @@ protected function setUp() $this->storeManager->expects($this->any())->method('getDefaultStoreView')->willReturn(null); $this->storeManager->expects($this->any())->method('getStores')->willReturn([$store]); $appState = $this->getMockBuilder(\Magento\Framework\App\State::class) - ->setConstructorArgs([ - $scopeConfig - ]) + ->setConstructorArgs( + [ + $scopeConfig + ] + ) ->setMethods(['emulateAreaCode']) ->disableOriginalConstructor() ->getMock(); From 9b50d1eae804b70e85fd4fa65be82613823aac01 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 29 May 2019 12:03:18 -0500 Subject: [PATCH 0068/1172] MC-15573: Prevent invalid UPS configurations --- .../Ups/Model/Config/Backend/UpsUrl.php | 32 ++++++++ .../Unit/Model/Config/Backend/UpsUrlTest.php | 78 +++++++++++++++++++ app/code/Magento/Ups/etc/adminhtml/system.xml | 3 + app/code/Magento/Ups/i18n/en_US.csv | 1 + 4 files changed, 114 insertions(+) create mode 100644 app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php create mode 100644 app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php diff --git a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php new file mode 100644 index 000000000000..155ab7c87be3 --- /dev/null +++ b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Ups\Model\Config\Backend; + +use Magento\Framework\App\Config\Value; +use Magento\Framework\Exception\ValidatorException; + +/** + * Represents a config URL that may point to a UPS endpoint + */ +class UpsUrl extends Value +{ + /** + * @inheritdoc + */ + public function beforeSave() + { + $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); + + if (!empty($host) && !preg_match('/(?:.+\.|^)ups\.com$/i', $host)) { + throw new ValidatorException(__('UPS API endpoint URL\'s must use ups.com')); + } + + return parent::beforeSave(); + } +} diff --git a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php new file mode 100644 index 000000000000..8a480983b1bd --- /dev/null +++ b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php @@ -0,0 +1,78 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Ups\Test\Unit\Model\Config\Backend; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Ups\Model\Config\Backend\UpsUrl; +use PHPUnit\Framework\TestCase; + +/** + * Verify behavior of UpsUrl backend type + */ +class UpsUrlTest extends TestCase +{ + + /** + * @var UpsUrl + */ + private $config; + + protected function setUp() + { + $objectManager = new ObjectManager($this); + /** @var UpsUrl $upsUrl */ + $this->config = $objectManager->getObject(UpsUrl::class); + } + + /** + * @dataProvider validDataProvider + * @param string $data The valid data + */ + public function testBeforeSave($data=null) + { + $this->config->setValue($data); + $this->config->beforeSave(); + } + + /** + * @dataProvider invalidDataProvider + * @param string $data The invalid data + * @expectedException \Magento\Framework\Exception\ValidatorException + * @expectedExceptionMessage UPS API endpoint URL's must use ups.com + */ + public function testBeforeSaveErrors($data) + { + $this->config->setValue($data); + $this->config->beforeSave(); + } + + public function validDataProvider() + { + return [ + [], + [null], + [''], + ['http://ups.com'], + ['https://foo.ups.com'], + ['http://foo.ups.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } + + public function invalidDataProvider() + { + return [ + ['http://upsfoo.com'], + ['https://fooups.com'], + ['https://ups.com.fake.com'], + ['https://ups.info'], + ['http://ups.com.foo.com/foo/bar?baz=bash&fizz=buzz'], + ['http://fooups.com/foo/bar?baz=bash&fizz=buzz'], + ]; + } +} diff --git a/app/code/Magento/Ups/etc/adminhtml/system.xml b/app/code/Magento/Ups/etc/adminhtml/system.xml index 8b9dc30a0188..91eed08f31db 100644 --- a/app/code/Magento/Ups/etc/adminhtml/system.xml +++ b/app/code/Magento/Ups/etc/adminhtml/system.xml @@ -56,9 +56,11 @@ </field> <field id="gateway_url" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Gateway URL</label> + <backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model> </field> <field id="gateway_xml_url" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Gateway XML URL</label> + <backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model> </field> <field id="handling_type" translate="label" type="select" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Calculate Handling Fee</label> @@ -103,6 +105,7 @@ </field> <field id="tracking_xml_url" translate="label" type="text" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>Tracking XML URL</label> + <backend_model>Magento\Ups\Model\Config\Backend\UpsUrl</backend_model> </field> <field id="type" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1"> <label>UPS Type</label> diff --git a/app/code/Magento/Ups/i18n/en_US.csv b/app/code/Magento/Ups/i18n/en_US.csv index baf8ecc85544..68dd34a313bd 100644 --- a/app/code/Magento/Ups/i18n/en_US.csv +++ b/app/code/Magento/Ups/i18n/en_US.csv @@ -114,3 +114,4 @@ Title,Title Mode,Mode "This enables or disables SSL verification of the Magento server by UPS.","This enables or disables SSL verification of the Magento server by UPS." Debug,Debug +"UPS API endpoint URL's must use ups.com","UPS API endpoint URL's must use ups.com" From 5215bbad2c99f1c0d96a62c4276b08107c2e9b2d Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 29 May 2019 13:11:06 -0500 Subject: [PATCH 0069/1172] MC-15573: Prevent invalid UPS configurations --- .../Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php index 8a480983b1bd..149f9378889f 100644 --- a/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php +++ b/app/code/Magento/Ups/Test/Unit/Model/Config/Backend/UpsUrlTest.php @@ -34,7 +34,7 @@ protected function setUp() * @dataProvider validDataProvider * @param string $data The valid data */ - public function testBeforeSave($data=null) + public function testBeforeSave($data = null) { $this->config->setValue($data); $this->config->beforeSave(); From 1b80e1b84d22b1fdf341c2f3654b8b833dde9a2b Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 29 May 2019 14:17:32 -0500 Subject: [PATCH 0070/1172] MC-16114: Update Email Template Filter --- .../Magento/Framework/Filter/Template.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 38198bb9a717..c32df1b175d8 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -85,6 +85,16 @@ class Template implements \Zend_Filter_Interface 'getdatausingmethod' ]; + /** + * @var array[] + */ + private $restrictedMethodsByInstanceType = [ + \Magento\Framework\DB\Adapter\AdapterInterface::class => [ + 'rawquery', + 'rawfetchrow' + ] + ]; + /** * @param \Magento\Framework\Stdlib\StringUtils $string * @param array $variables @@ -405,6 +415,12 @@ private function validateVariableMethodCall($object, string $method): void if (in_array(mb_strtolower($method), $this->restrictedMethods)) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } + } else { + foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { + if ($object instanceof $instanceType && in_array(mb_strtolower($method), $restrictedMethods)) { + throw new \InvalidArgumentException("Method $method cannot be called from template."); + } + } } } From 95601282c252cde1ce14a6e26871cc6393071e6c Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 29 May 2019 14:20:52 -0500 Subject: [PATCH 0071/1172] MC-15573: Prevent invalid UPS configuration --- app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php index 155ab7c87be3..9db35b6a42dc 100644 --- a/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php +++ b/app/code/Magento/Ups/Model/Config/Backend/UpsUrl.php @@ -21,6 +21,7 @@ class UpsUrl extends Value */ public function beforeSave() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $host = parse_url((string)$this->getValue(), \PHP_URL_HOST); if (!empty($host) && !preg_match('/(?:.+\.|^)ups\.com$/i', $host)) { From b320ba646413422b8f379b16908d065ebfb40b03 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 30 May 2019 10:57:28 +0300 Subject: [PATCH 0072/1172] MC-13886: Downloadable Product controller|API save changes --- .../Unit/Model/Link/ContentValidatorTest.php | 51 +++++++------------ .../Test/Unit/Model/LinkRepositoryTest.php | 38 +++++++++----- .../Model/Sample/ContentValidatorTest.php | 33 ++++++------ .../Test/Unit/Model/SampleRepositoryTest.php | 36 +++++++------ 4 files changed, 79 insertions(+), 79 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 5484e39bd57f..771fbc37e5e1 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -246,45 +246,29 @@ protected function getLinkMock(array $linkData) 'isShareable', 'getNumberOfDownloads', 'getLinkType', - 'getLinkFile' + 'getLinkFile', ] ) ->getMockForAbstractClass(); - $linkMock->expects($this->any())->method('getTitle')->will($this->returnValue( - $linkData['title'] - )); - $linkMock->expects($this->any())->method('getPrice')->will($this->returnValue( - $linkData['price'] - )); - $linkMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $linkData['sort_order'] - )); - $linkMock->expects($this->any())->method('isShareable')->will($this->returnValue( - $linkData['shareable'] - )); - $linkMock->expects($this->any())->method('getNumberOfDownloads')->will($this->returnValue( - $linkData['number_of_downloads'] - )); - $linkMock->expects($this->any())->method('getLinkType')->will($this->returnValue( - $linkData['link_type'] - )); - $linkMock->expects($this->any())->method('getLinkFile')->will($this->returnValue( - $this->linkFileMock - )); + $linkMock->expects($this->any())->method('getTitle')->will($this->returnValue($linkData['title'])); + $linkMock->expects($this->any())->method('getPrice')->will($this->returnValue($linkData['price'])); + $linkMock->expects($this->any())->method('getSortOrder')->will($this->returnValue($linkData['sort_order'])); + $linkMock->expects($this->any())->method('isShareable')->will($this->returnValue($linkData['shareable'])); + $linkMock->expects($this->any())->method('getNumberOfDownloads')->will( + $this->returnValue($linkData['number_of_downloads']) + ); + $linkMock->expects($this->any())->method('getLinkType')->will($this->returnValue($linkData['link_type'])); + $linkMock->expects($this->any())->method('getLinkFile')->will($this->returnValue($this->linkFileMock)); if (isset($linkData['link_url'])) { - $linkMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue( - $linkData['link_url'] - )); + $linkMock->expects($this->any())->method('getLinkUrl')->will($this->returnValue($linkData['link_url'])); } if (isset($linkData['sample_url'])) { - $linkMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $linkData['sample_url'] - )); + $linkMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue($linkData['sample_url'])); } if (isset($linkData['sample_type'])) { - $linkMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $linkData['sample_type'] - )); + $linkMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($linkData['sample_type']) + ); } if (isset($linkData['link_file_content'])) { $linkMock->expects($this->any())->method('getLinkFileContent')->willReturn($linkData['link_file_content']); @@ -293,9 +277,8 @@ protected function getLinkMock(array $linkData) $linkMock->expects($this->any())->method('getSampleFileContent') ->willReturn($linkData['sample_file_content']); } - $linkMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $this->sampleFileMock - )); + $linkMock->expects($this->any())->method('getSampleFile')->will($this->returnValue($this->sampleFileMock)); + return $linkMock; } } diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php index 4494877b70f6..25f720f27150 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/LinkRepositoryTest.php @@ -98,7 +98,9 @@ protected function setUp() \Magento\Framework\Json\EncoderInterface::class ); $this->linkFactoryMock = $this->createPartialMock(\Magento\Downloadable\Model\LinkFactory::class, ['create']); - $this->productMock = $this->createPartialMock(\Magento\Catalog\Model\Product::class, [ + $this->productMock = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + [ '__wakeup', 'getTypeId', 'setDownloadableData', @@ -107,8 +109,9 @@ protected function setUp() 'getStoreId', 'getStore', 'getWebsiteIds', - 'getData' - ]); + 'getData', + ] + ); $this->service = new \Magento\Downloadable\Model\LinkRepository( $this->repositoryMock, $this->productTypeMock, @@ -310,12 +313,15 @@ public function testUpdate() $storeMock = $this->createMock(\Magento\Store\Model\Store::class); $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId)); $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); - $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $existingLinkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ '__wakeup', 'getId', 'load', - 'getProductId' - ]); + 'getProductId', + ] + ); $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock)); $linkMock = $this->getLinkMock($linkData); $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock) @@ -372,12 +378,15 @@ public function testUpdateWithExistingFile() $storeMock = $this->createMock(\Magento\Store\Model\Store::class); $storeMock->expects($this->any())->method('getWebsiteId')->will($this->returnValue($websiteId)); $this->productMock->expects($this->any())->method('getStore')->will($this->returnValue($storeMock)); - $existingLinkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $existingLinkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ '__wakeup', 'getId', 'load', - 'getProductId' - ]); + 'getProductId', + ] + ); $this->linkFactoryMock->expects($this->once())->method('create')->will($this->returnValue($existingLinkMock)); $linkMock = $this->getLinkMock($linkData); $this->contentValidatorMock->expects($this->any())->method('isValid')->with($linkMock) @@ -504,10 +513,12 @@ public function testGetList() 'sample_file' => '/r/o/rock.melody.ogg', 'link_type' => 'url', 'link_url' => 'http://link.url', - 'link_file' => null + 'link_file' => null, ]; - $linkMock = $this->createPartialMock(\Magento\Downloadable\Model\Link::class, [ + $linkMock = $this->createPartialMock( + \Magento\Downloadable\Model\Link::class, + [ 'getId', 'getStoreTitle', 'getTitle', @@ -522,8 +533,9 @@ public function testGetList() 'getSampleUrl', 'getLinkType', 'getLinkFile', - 'getLinkUrl' - ]); + 'getLinkUrl', + ] + ); $linkInterfaceMock = $this->createMock(\Magento\Downloadable\Api\Data\LinkInterface::class); diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php index 90bcfa2e39be..4a32a45859ce 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Sample/ContentValidatorTest.php @@ -117,28 +117,29 @@ public function getInvalidSortOrder() protected function getSampleContentMock(array $sampleContentData) { $contentMock = $this->createMock(\Magento\Downloadable\Api\Data\SampleInterface::class); - $contentMock->expects($this->any())->method('getTitle')->will($this->returnValue( - $sampleContentData['title'] - )); - - $contentMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $sampleContentData['sort_order'] - )); - $contentMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $sampleContentData['sample_type'] - )); + $contentMock->expects($this->any())->method('getTitle')->will( + $this->returnValue($sampleContentData['title']) + ); + + $contentMock->expects($this->any())->method('getSortOrder')->will( + $this->returnValue($sampleContentData['sort_order']) + ); + $contentMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($sampleContentData['sample_type']) + ); if (isset($sampleContentData['sample_url'])) { - $contentMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $sampleContentData['sample_url'] - )); + $contentMock->expects($this->any())->method('getSampleUrl')->will( + $this->returnValue($sampleContentData['sample_url']) + ); } if (isset($sampleContentData['sample_file_content'])) { $contentMock->expects($this->any())->method('getSampleFileContent') ->willReturn($sampleContentData['sample_file_content']); } - $contentMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $this->sampleFileMock - )); + $contentMock->expects($this->any())->method('getSampleFile')->will( + $this->returnValue($this->sampleFileMock) + ); + return $contentMock; } } diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php index f1ca30bd7dd3..f1674c6838a2 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/SampleRepositoryTest.php @@ -149,25 +149,26 @@ protected function getSampleMock(array $sampleData) $sampleMock->expects($this->any())->method('getId')->willReturn($sampleData['id']); } $sampleMock->expects($this->any())->method('getTitle')->will($this->returnValue($sampleData['title'])); - $sampleMock->expects($this->any())->method('getSortOrder')->will($this->returnValue( - $sampleData['sort_order'] - )); + $sampleMock->expects($this->any())->method('getSortOrder')->will( + $this->returnValue($sampleData['sort_order']) + ); if (isset($sampleData['sample_type'])) { - $sampleMock->expects($this->any())->method('getSampleType')->will($this->returnValue( - $sampleData['sample_type'] - )); + $sampleMock->expects($this->any())->method('getSampleType')->will( + $this->returnValue($sampleData['sample_type']) + ); } if (isset($sampleData['sample_url'])) { - $sampleMock->expects($this->any())->method('getSampleUrl')->will($this->returnValue( - $sampleData['sample_url'] - )); + $sampleMock->expects($this->any())->method('getSampleUrl')->will( + $this->returnValue($sampleData['sample_url']) + ); } if (isset($sampleData['sample_file'])) { - $sampleMock->expects($this->any())->method('getSampleFile')->will($this->returnValue( - $sampleData['sample_file'] - )); + $sampleMock->expects($this->any())->method('getSampleFile')->will( + $this->returnValue($sampleData['sample_file']) + ); } + return $sampleMock; } @@ -416,10 +417,12 @@ public function testGetList() 'sort_order' => 21, 'sample_type' => 'file', 'sample_url' => null, - 'sample_file' => '/r/o/rock.melody.ogg' + 'sample_file' => '/r/o/rock.melody.ogg', ]; - $sampleMock = $this->createPartialMock(\Magento\Downloadable\Model\Sample::class, [ + $sampleMock = $this->createPartialMock( + \Magento\Downloadable\Model\Sample::class, + [ 'getId', 'getStoreTitle', 'getTitle', @@ -428,8 +431,9 @@ public function testGetList() 'getSampleUrl', 'getSortOrder', 'getData', - '__wakeup' - ]); + '__wakeup', + ] + ); $sampleInterfaceMock = $this->createMock(\Magento\Downloadable\Api\Data\SampleInterface::class); From f7f8ceb43f2348257ae38498197d2dc3d1641266 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 30 May 2019 11:14:49 -0500 Subject: [PATCH 0073/1172] MC-17067: Update config table schema - Updated config table schema --- app/code/Magento/Config/etc/db_schema.xml | 2 ++ app/code/Magento/Config/etc/db_schema_whitelist.json | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Config/etc/db_schema.xml b/app/code/Magento/Config/etc/db_schema.xml index 8aeac802fbd9..1b2f7a051941 100644 --- a/app/code/Magento/Config/etc/db_schema.xml +++ b/app/code/Magento/Config/etc/db_schema.xml @@ -15,6 +15,8 @@ default="0" comment="Config Scope Id"/> <column xsi:type="varchar" name="path" nullable="false" length="255" default="general" comment="Config Path"/> <column xsi:type="text" name="value" nullable="true" comment="Config Value"/> + <column xsi:type="timestamp" name="updated_at" on_update="true" nullable="false" default="CURRENT_TIMESTAMP" + comment="Updated At"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="config_id"/> </constraint> diff --git a/app/code/Magento/Config/etc/db_schema_whitelist.json b/app/code/Magento/Config/etc/db_schema_whitelist.json index 850e160bc732..51ca41d8e6af 100644 --- a/app/code/Magento/Config/etc/db_schema_whitelist.json +++ b/app/code/Magento/Config/etc/db_schema_whitelist.json @@ -5,11 +5,12 @@ "scope": true, "scope_id": true, "path": true, - "value": true + "value": true, + "updated_at": true }, "constraint": { "PRIMARY": true, "CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH": true } } -} \ No newline at end of file +} From c7676c54342926a3d40878ceb6042899f0ec49fe Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Thu, 30 May 2019 15:36:53 -0500 Subject: [PATCH 0074/1172] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 70 +++++++++++++++---- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 2810db656942..654359ec30be 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -3,10 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; +use Magento\Framework\Code\Reader\ClassReader; +use Magento\Framework\Data\OptionSourceInterface; +use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -16,8 +22,9 @@ class ConfigurableObject implements InterpreterInterface /** * @var array */ - private $classBlacklist = [ - \Zend\Code\Reflection\FileReflection::class + private $classWhitelist = [ + DataProviderInterface::class, + OptionSourceInterface::class ]; /** @@ -29,17 +36,33 @@ class ConfigurableObject implements InterpreterInterface * @var InterpreterInterface */ protected $argumentInterpreter; + /** + * @var ClassReader|null + */ + private $classReader; + /** + * @var ConfigInterface + */ + private $objectManagerConfig; /** * Constructor * * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter + * @param ClassReader|null $classReader + * @param ConfigInterface $objectManagerConfig */ - public function __construct(ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter) - { + public function __construct( + ObjectManagerInterface $objectManager, + InterpreterInterface $argumentInterpreter, + ClassReader $classReader = null, + ConfigInterface $objectManagerConfig = null + ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; + $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); + $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } /** @@ -61,14 +84,18 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - if (in_array( - ltrim(strtolower($arguments['class']), '\\'), - array_map('strtolower', $this->classBlacklist) - )) { - throw new \InvalidArgumentException(sprintf( - 'Class argument is invalid: %s', - $arguments['class'] - )); + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($arguments['class']) + ); + + $classParents = $this->getParents($type); + + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $arguments['class']) + ); } $className = $arguments['class']; @@ -77,4 +104,23 @@ public function evaluate(array $data) return $this->objectManager->create($className, $arguments); } + + /** + * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself + * + * @param string $type + * @return string[] + */ + private function getParents(string $type) + { + $classParents = $this->classReader->getParents($type); + foreach ($classParents as $parent) { + if (empty($parent)) { + continue; + } + $classParents = array_merge($classParents, $this->getParents($parent)); + } + + return $classParents; + } } From 84bf99b4d098b4dde120546c7b727e153bdc94ae Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 31 May 2019 12:13:06 -0500 Subject: [PATCH 0075/1172] MC-16074: Sitemap generator update - Updated magento store config file --- app/code/Magento/Store/etc/config.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml index 23182c8d7647..07e4c8b0b652 100644 --- a/app/code/Magento/Store/etc/config.xml +++ b/app/code/Magento/Store/etc/config.xml @@ -135,14 +135,14 @@ </protected_extensions> <public_files_valid_paths> <protected> - <app>/app/*/*</app> - <bin>/bin/*/*</bin> - <dev>/dev/*/*</dev> - <generated>/generated/*/*</generated> - <lib>/lib/*/*</lib> - <setup>/setup/*/*</setup> - <update>/update/*/*</update> - <vendor>/vendor/*/*</vendor> + <app>*/app/*/*</app> + <bin>*/bin/*/*</bin> + <dev>*/dev/*/*</dev> + <generated>*/generated/*/*</generated> + <lib>*/lib/*/*</lib> + <setup>*/setup/*/*</setup> + <update>*/update/*/*</update> + <vendor>*/vendor/*/*</vendor> </protected> </public_files_valid_paths> </file> From e6e7665d54074c55fcd821d6682554c77f1b9f7b Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 31 May 2019 12:21:26 -0500 Subject: [PATCH 0076/1172] MC-16940: Prevent errors from incorrect configurations --- app/etc/di.xml | 8 ++++ .../Interpreter/ConfigurableObject.php | 47 +++++++------------ 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/app/etc/di.xml b/app/etc/di.xml index 200a56201239..cccae25b467e 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -662,6 +662,14 @@ <argument name="argumentInterpreter" xsi:type="object">layoutArgumentGeneratorInterpreter</argument> </arguments> </type> + <type name="Magento\Framework\View\Element\UiComponent\Argument\Interpreter\ConfigurableObject"> + <arguments> + <argument name="classWhitelist" xsi:type="array"> + <item name="0" xsi:type="string">Magento\Framework\Data\OptionSourceInterface</item> + <item name="1" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface</item> + </argument> + </arguments> + </type> <type name="Magento\Framework\Mview\View"> <arguments> <argument name="state" xsi:type="object" shared="false">Magento\Indexer\Model\Mview\View\State</argument> diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 654359ec30be..4e7caaf4c565 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -8,11 +8,9 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; use Magento\Framework\Code\Reader\ClassReader; -use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; -use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -22,10 +20,7 @@ class ConfigurableObject implements InterpreterInterface /** * @var array */ - private $classWhitelist = [ - DataProviderInterface::class, - OptionSourceInterface::class - ]; + private $classWhitelist = []; /** * @var ObjectManagerInterface @@ -36,10 +31,12 @@ class ConfigurableObject implements InterpreterInterface * @var InterpreterInterface */ protected $argumentInterpreter; + /** - * @var ClassReader|null + * @var ClassReader */ private $classReader; + /** * @var ConfigInterface */ @@ -50,17 +47,20 @@ class ConfigurableObject implements InterpreterInterface * * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter + * @param array $classWhitelist * @param ClassReader|null $classReader - * @param ConfigInterface $objectManagerConfig + * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, + array $classWhitelist = [], ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; + $this->classWhitelist = $classWhitelist; $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } @@ -88,11 +88,15 @@ public function evaluate(array $data) $this->objectManagerConfig->getPreference($arguments['class']) ); - $classParents = $this->getParents($type); - - $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + $classIsAllowed = false; + foreach ($this->classWhitelist as $allowedClass) { + if (is_subclass_of($type, $allowedClass, true)) { + $classIsAllowed = true; + break; + } + } - if (empty($whitelistIntersection)) { + if (!$classIsAllowed) { throw new \InvalidArgumentException( sprintf('Class argument is invalid: %s', $arguments['class']) ); @@ -104,23 +108,4 @@ public function evaluate(array $data) return $this->objectManager->create($className, $arguments); } - - /** - * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself - * - * @param string $type - * @return string[] - */ - private function getParents(string $type) - { - $classParents = $this->classReader->getParents($type); - foreach ($classParents as $parent) { - if (empty($parent)) { - continue; - } - $classParents = array_merge($classParents, $this->getParents($parent)); - } - - return $classParents; - } } From e06b4e596da2147f487413325528623da32eaac6 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 31 May 2019 12:26:13 -0500 Subject: [PATCH 0077/1172] MC-16940: Prevent errors from incorrect configurations --- .../Argument/Interpreter/ConfigurableObject.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 4e7caaf4c565..3098504ebfc5 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -7,7 +7,6 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; -use Magento\Framework\Code\Reader\ClassReader; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; @@ -32,11 +31,6 @@ class ConfigurableObject implements InterpreterInterface */ protected $argumentInterpreter; - /** - * @var ClassReader - */ - private $classReader; - /** * @var ConfigInterface */ @@ -48,20 +42,17 @@ class ConfigurableObject implements InterpreterInterface * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter * @param array $classWhitelist - * @param ClassReader|null $classReader * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, array $classWhitelist = [], - ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; $this->classWhitelist = $classWhitelist; - $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } From edb45bd6b45a5de87a35498f0340238fcb80ad6a Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 31 May 2019 16:02:24 -0500 Subject: [PATCH 0078/1172] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 60 ++-- .../Interpreter/ConfigurableObjectTest.php | 286 ++++++++++++++++++ 2 files changed, 329 insertions(+), 17 deletions(-) create mode 100644 lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 3098504ebfc5..2ea2856cc0f1 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -7,9 +7,12 @@ namespace Magento\Framework\View\Element\UiComponent\Argument\Interpreter; +use Magento\Framework\Code\Reader\ClassReader; +use Magento\Framework\Data\OptionSourceInterface; use Magento\Framework\ObjectManager\ConfigInterface; use Magento\Framework\ObjectManagerInterface; use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; /** * Class ConfigurableObject @@ -31,6 +34,11 @@ class ConfigurableObject implements InterpreterInterface */ protected $argumentInterpreter; + /** + * @var ClassReader|null + */ + private $classReader; + /** * @var ConfigInterface */ @@ -42,17 +50,20 @@ class ConfigurableObject implements InterpreterInterface * @param ObjectManagerInterface $objectManager * @param InterpreterInterface $argumentInterpreter * @param array $classWhitelist + * @param ClassReader|null $classReader * @param ConfigInterface|null $objectManagerConfig */ public function __construct( ObjectManagerInterface $objectManager, InterpreterInterface $argumentInterpreter, array $classWhitelist = [], + ClassReader $classReader = null, ConfigInterface $objectManagerConfig = null ) { $this->objectManager = $objectManager; $this->argumentInterpreter = $argumentInterpreter; $this->classWhitelist = $classWhitelist; + $this->classReader = $classReader ?? $objectManager->get(ClassReader::class); $this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class); } @@ -75,28 +86,43 @@ public function evaluate(array $data) throw new \InvalidArgumentException('Node "argument" with name "class" is required for this type.'); } - $type = $this->objectManagerConfig->getInstanceType( - $this->objectManagerConfig->getPreference($arguments['class']) - ); + $className = $arguments['class']; + unset($arguments['class']); + } - $classIsAllowed = false; - foreach ($this->classWhitelist as $allowedClass) { - if (is_subclass_of($type, $allowedClass, true)) { - $classIsAllowed = true; - break; - } - } + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($className) + ); - if (!$classIsAllowed) { - throw new \InvalidArgumentException( - sprintf('Class argument is invalid: %s', $arguments['class']) - ); - } + $classParents = $this->getParents($type); - $className = $arguments['class']; - unset($arguments['class']); + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $className) + ); } return $this->objectManager->create($className, $arguments); } + + /** + * Retrieves all the parent classes and interfaces for a class including the ones implemented by the class itself + * + * @param string $type + * @return string[] + */ + private function getParents(string $type) + { + $classParents = $this->classReader->getParents($type); + foreach ($classParents as $parent) { + if (empty($parent)) { + continue; + } + $classParents = array_merge($classParents, $this->getParents($parent)); + } + + return $classParents; + } } diff --git a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php new file mode 100644 index 000000000000..8b4f2a35c080 --- /dev/null +++ b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php @@ -0,0 +1,286 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\View\Test\Unit\UiComponent\Argument\Interpreter; + +use Magento\Framework\Code\Reader\ClassReader; +use Magento\Framework\Data\Argument\InterpreterInterface; +use Magento\Framework\ObjectManager\ConfigInterface; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\View\Element\UiComponent\Argument\Interpreter\ConfigurableObject; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; + +/** + * Unit tests for ConfigurableObject + */ +class ConfigurableObjectTest extends TestCase +{ + /** + * @var ConfigurableObject + */ + private $configurableObject; + + /** + * @var ObjectManagerInterface|MockObject + */ + private $objectManager; + + /** + * @var InterpreterInterface|MockObject + */ + private $interpreter; + + /** + * @var ClassReader|MockObject + */ + private $classReader; + + /** + * @var ConfigInterface|MockObject + */ + private $objectManagerConfig; + + protected function setUp() + { + $objectManager = new ObjectManager($this); + $this->objectManager = $this->createMock(ObjectManagerInterface::class); + $this->interpreter = $this->createMock(InterpreterInterface::class); + $this->classReader = $this->createMock(ClassReader::class); + $this->objectManagerConfig = $this->createMock(ConfigInterface::class); + $this->configurableObject = $objectManager->getObject( + ConfigurableObject::class, + [ + 'objectManager' => $this->objectManager, + 'argumentInterpreter' => $this->interpreter, + 'classWhitelist' => [ + \Foo\Bar\ClassA::class, + \Foo\Bar\InterfaceA::class, + ], + 'classReader' => $this->classReader, + 'objectManagerConfig' => $this->objectManagerConfig, + ] + ); + } + + /** + * @dataProvider validDataProvider + */ + public function testValidCombinations( + $data, + $expectedClass, + $classParentsValueMap, + $expectedArguments + ) { + $this->objectManagerConfig + ->method('getPreference') + ->with($expectedClass) + ->WillReturn('bar'); + $this->objectManagerConfig + ->method('getInstanceType') + ->with('bar') + ->willReturn($expectedClass); + + $this->classReader + ->method('getParents') + ->willReturnMap($classParentsValueMap); + + $this->objectManager + ->expects($this->once()) + ->method('create') + ->with($expectedClass, $expectedArguments) + ->willReturn('an object yay!'); + + $this->interpreter + ->method('evaluate') + ->will( + $this->returnCallback( + function (array $arg) { + return $arg['value']; + } + ) + ); + + $actualResult = $this->configurableObject->evaluate($data); + self::assertSame('an object yay!', $actualResult); + } + + /** + * @dataProvider invalidDataProvider + */ + public function testInvalidCombinations( + $data, + $expectedClass, + $classParentsValueMap, + $expectedException, + $expectedExceptionMessage + ) { + + $this->expectException($expectedException); + $this->expectExceptionMessage($expectedExceptionMessage); + + $this->objectManagerConfig + ->method('getPreference') + ->with($expectedClass) + ->WillReturn('bar'); + $this->objectManagerConfig + ->method('getInstanceType') + ->with('bar') + ->willReturn($expectedClass); + + $this->classReader + ->method('getParents') + ->willReturnMap($classParentsValueMap); + + $this->objectManager + ->expects($this->never()) + ->method('create'); + + $this->interpreter + ->method('evaluate') + ->will( + $this->returnCallback( + function (array $arg) { + return $arg['value']; + } + ) + ); + + $actualResult = $this->configurableObject->evaluate($data); + self::assertSame('an object yay!', $actualResult); + } + + public function validDataProvider() + { + return [ + // Test most basic syntax + [ + [ + 'value' => 'MyFooClass', + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + [] + ], + // Test alternative data syntax + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'] + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + [] + ], + // Test arguments + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + [\Foo\Bar\ClassA::class, []] + ], + ['myarg' => 'bar'] + ], + // Test multiple matching whitelisted classes + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', [\Foo\Bar\InterfaceA::class]], + [\Foo\Bar\ClassA::class, []], + [\Foo\Bar\InterfaceA::class, []] + ], + ['myarg' => 'bar'] + ], + ]; + } + + public function invalidDataProvider() + { + return [ + [ + [ + 'notvalid' => 'sup' + ], + '', + [], + \InvalidArgumentException::class, + 'Node "argument" required for this type.' + ], + [ + [ + 'argument' => [ + 'notclass' => ['value' => 'doesntmatter'] + ] + ], + '', + [], + \InvalidArgumentException::class, + 'Node "argument" with name "class" is required for this type.' + ], + [ + [ + 'argument' => [ + 'class' => ['value' => 'MyFooClass'], + 'myarg' => ['value' => 'bar'], + ] + ], + 'MyFooClass', + [ + ['MyFooClass', ['Something', 'skipme']], + ['Something', ['dontcare', 'SomethingElse']], + ['SomethingElse', ['unrelated']], + ['skipme', []], + ['dontcare', []], + ['unrelated', []], + ], + \InvalidArgumentException::class, + 'Class argument is invalid: MyFooClass' + ], + ]; + } +} From 839095db2229adb41e0b226b6b8737fb67f00096 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 3 Jun 2019 08:21:59 -0500 Subject: [PATCH 0079/1172] MC-16940: Prevent errors from incorrect configurations --- .../Interpreter/ConfigurableObject.php | 20 +++++++++---------- .../Interpreter/ConfigurableObjectTest.php | 16 ++++----------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php index 2ea2856cc0f1..2691bc21357b 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php @@ -88,20 +88,20 @@ public function evaluate(array $data) $className = $arguments['class']; unset($arguments['class']); - } - $type = $this->objectManagerConfig->getInstanceType( - $this->objectManagerConfig->getPreference($className) - ); + $type = $this->objectManagerConfig->getInstanceType( + $this->objectManagerConfig->getPreference($className) + ); - $classParents = $this->getParents($type); + $classParents = $this->getParents($type); - $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); + $whitelistIntersection = array_intersect($classParents, $this->classWhitelist); - if (empty($whitelistIntersection)) { - throw new \InvalidArgumentException( - sprintf('Class argument is invalid: %s', $className) - ); + if (empty($whitelistIntersection)) { + throw new \InvalidArgumentException( + sprintf('Class argument is invalid: %s', $className) + ); + } } return $this->objectManager->create($className, $arguments); diff --git a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php index 8b4f2a35c080..0d4be68a4c1b 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php @@ -159,21 +159,13 @@ function (array $arg) { public function validDataProvider() { return [ - // Test most basic syntax + // Test most basic syntax with no arguments [ [ - 'value' => 'MyFooClass', - ], - 'MyFooClass', - [ - ['MyFooClass', ['Something', 'skipme']], - ['Something', ['dontcare', 'SomethingElse']], - ['SomethingElse', [\Foo\Bar\ClassA::class, 'unrelated']], - ['skipme', []], - ['dontcare', []], - ['unrelated', []], - [\Foo\Bar\ClassA::class, []] + 'value' => 'MyObject', ], + 'MyObject', + [], [] ], // Test alternative data syntax From 1c0879c90dda4050fecb02e743d676e9b7036072 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 3 Jun 2019 12:11:42 -0500 Subject: [PATCH 0080/1172] MC-15134: Currency rate config update - Updated currency matrix template --- .../view/adminhtml/templates/system/currency/rate/matrix.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml index 8a16eb71e085..9701fc928e86 100644 --- a/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml +++ b/app/code/Magento/CurrencySymbol/view/adminhtml/templates/system/currency/rate/matrix.phtml @@ -28,7 +28,7 @@ $_rates = ($_newRates) ? $_newRates : $_oldRates; <tr> <th> </th> <?php $_i = 0; foreach ($block->getAllowedCurrencies() as $_currencyCode): ?> - <th><span><?= /* @escapeNotVerified */ $_currencyCode ?></span></th> + <th><span><?= $block->escapeHtml($_currencyCode) ?></span></th> <?php endforeach; ?> </tr> </thead> From ceb5524a85fa6cbfe5d63ff4d7912cf26cf6b926 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 4 Jun 2019 13:31:10 -0500 Subject: [PATCH 0081/1172] MC-16114: Update Email Template Filter --- lib/internal/Magento/Framework/Filter/Template.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index c32df1b175d8..1bb063fb279a 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -90,8 +90,7 @@ class Template implements \Zend_Filter_Interface */ private $restrictedMethodsByInstanceType = [ \Magento\Framework\DB\Adapter\AdapterInterface::class => [ - 'rawquery', - 'rawfetchrow' + '*' ] ]; @@ -417,7 +416,9 @@ private function validateVariableMethodCall($object, string $method): void } } else { foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { - if ($object instanceof $instanceType && in_array(mb_strtolower($method), $restrictedMethods)) { + if ($object instanceof $instanceType && + ($restrictedMethods === '*' || in_array(mb_strtolower($method), $restrictedMethods)) + ) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } } From 9a9b6e4733ec3dab4c0bf133bf9d4211e9789749 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Tue, 4 Jun 2019 14:58:11 -0500 Subject: [PATCH 0082/1172] MC-16056: Template engine optimizations --- .../Magento/Framework/Filter/Template.php | 108 ++++++++---------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 6a04e8e8c695..6654135b7f6c 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -9,9 +9,6 @@ */ namespace Magento\Framework\Filter; -use Magento\Framework\Model\AbstractExtensibleModel; -use Magento\Framework\Model\AbstractModel; - /** * Template filter * @@ -400,7 +397,7 @@ protected function getParameters($value) */ private function validateVariableMethodCall($object, string $method): void { - if ($object === $this) { + if ($object instanceof self || $object instanceof \Magento\Framework\DataObject) { if (in_array(mb_strtolower($method), $this->restrictedMethods)) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } @@ -408,28 +405,7 @@ private function validateVariableMethodCall($object, string $method): void } /** - * Check allowed methods for data objects. - * - * Deny calls for methods that may disrupt template processing. - * - * @param object $object - * @param string $method - * @return bool - * @throws \InvalidArgumentException - */ - private function isAllowedDataObjectMethod($object, string $method): bool - { - if ($object instanceof AbstractExtensibleModel || $object instanceof AbstractModel) { - if (in_array(mb_strtolower($method), $this->restrictedMethods)) { - throw new \InvalidArgumentException("Method $method cannot be called from template."); - } - } - - return true; - } - - /** - * Return variable value for var construction + * Return variable value for var construction. * * @param string $value raw parameters * @param string $default default value @@ -448,45 +424,18 @@ protected function getVariable($value, $default = '{no_value_defined}') if ($i == 0 && isset($this->templateVars[$stackVars[$i]['name']])) { // Getting of template value $stackVars[$i]['variable'] = & $this->templateVars[$stackVars[$i]['name']]; - } elseif (isset($stackVars[$i - 1]['variable']) - && $stackVars[$i - 1]['variable'] instanceof \Magento\Framework\DataObject - ) { - // If data object calling methods or getting properties + } elseif (isset($stackVars[$i - 1]['variable']) && is_object($stackVars[$i - 1]['variable'])) { if ($stackVars[$i]['type'] == 'property') { - $caller = 'get' . $this->string->upperCaseWords($stackVars[$i]['name'], '_', ''); - $stackVars[$i]['variable'] = method_exists( + $stackVars[$i]['variable'] = $this->evaluateObjectPropertyAccess( $stackVars[$i - 1]['variable'], - $caller - ) ? $stackVars[$i - 1]['variable']->{$caller}() : $stackVars[$i - 1]['variable']->getData( $stackVars[$i]['name'] ); } elseif ($stackVars[$i]['type'] == 'method') { - // Calling of data object method - if (method_exists($stackVars[$i - 1]['variable'], $stackVars[$i]['name']) - || substr($stackVars[$i]['name'], 0, 3) == 'get' - ) { - $stackVars[$i]['args'] = $this->getStackArgs($stackVars[$i]['args']); - - if ($this->isAllowedDataObjectMethod($stackVars[$i - 1]['variable'], $stackVars[$i]['name'])) { - $stackVars[$i]['variable'] = call_user_func_array( - [$stackVars[$i - 1]['variable'], $stackVars[$i]['name']], - $stackVars[$i]['args'] - ); - } - } - } - $last = $i; - } elseif (isset($stackVars[$i - 1]['variable']) - && is_object($stackVars[$i - 1]['variable']) - && $stackVars[$i]['type'] == 'method' - ) { - // Calling object methods - $object = $stackVars[$i - 1]['variable']; - $method = $stackVars[$i]['name']; - if (method_exists($object, $method)) { - $args = $this->getStackArgs($stackVars[$i]['args']); - $this->validateVariableMethodCall($object, $method); - $stackVars[$i]['variable'] = call_user_func_array([$object, $method], $args); + $stackVars[$i]['variable'] = $this->evaluateObjectMethodCall( + $stackVars[$i - 1]['variable'], + $stackVars[$i]['name'], + $stackVars[$i]['args'] + ); } $last = $i; } @@ -500,6 +449,45 @@ protected function getVariable($value, $default = '{no_value_defined}') return $result; } + /** + * Evaluate object property access. + * + * @param object $object + * @param string $property + * @return null + */ + private function evaluateObjectPropertyAccess($object, $property) + { + $method = 'get' . $this->string->upperCaseWords($property, '_', ''); + $this->validateVariableMethodCall($object, $method); + return method_exists($object, $method) + ? $object->{$method}() + : (($object instanceof \Magento\Framework\DataObject) ? $object->getData($property) : null); + } + + /** + * Evaluate object method call. + * + * @param object $object + * @param string $method + * @param array $arguments + * @return mixed|null + */ + private function evaluateObjectMethodCall($object, $method, $arguments) + { + if (method_exists($object, $method) + || ($object instanceof \Magento\Framework\DataObject && substr($method, 0, 3) == 'get') + ) { + $arguments = $this->getStackArgs($arguments); + $this->validateVariableMethodCall($object, $method); + return call_user_func_array( + [$object, $method], + $arguments + ); + } + return null; + } + /** * Loops over a set of stack args to process variables into array argument values * From 142e5fd71839d3f28a99fedf6a3ce11ad9cfdff1 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 5 Jun 2019 12:57:50 -0500 Subject: [PATCH 0083/1172] MC-15919: Customer attribute label update - Updated meta data resolver object --- app/code/Magento/Customer/Model/AttributeMetadataResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index 979730eb1c9c..84162bb8dae0 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -144,7 +144,7 @@ public function getAttributesMeta( $attribute, $meta['arguments']['data']['config'] ); - + $meta['arguments']['data']['config']['__disableTmpl'] = true; return $meta; } From 52dbfdf1905825b947265bc1fc44b159973e3790 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 5 Jun 2019 08:47:44 -0500 Subject: [PATCH 0084/1172] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Model/Design/BackendModelFactory.php | 22 ++++++++++++++----- .../Model/Design/Config/ValueChecker.php | 6 ++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php index 155afa89c417..2896e9f10129 100644 --- a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php +++ b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php @@ -11,6 +11,9 @@ use Magento\Theme\Model\Design\Config\MetadataProvider; use Magento\Theme\Model\ResourceModel\Design\Config\CollectionFactory; +/** + * Class BackendModelFactory + */ class BackendModelFactory extends ValueFactory { /** @@ -58,13 +61,15 @@ public function __construct( */ public function create(array $data = []) { + $storedData = $this->getStoredData($data['scope'], $data['scopeId'], $data['config']['path']); + $backendModelData = array_replace_recursive( - $this->getStoredData($data['scope'], $data['scopeId'], $data['config']['path']), + $storedData, [ 'path' => $data['config']['path'], 'scope' => $data['scope'], 'scope_id' => $data['scopeId'], - 'field_config' => $data['config'], + 'field_config' => $data['config'] ] ); @@ -76,6 +81,10 @@ public function create(array $data = []) $backendModel = $this->getNewBackendModel($backendType, $backendModelData); $backendModel->setValue($data['value']); + foreach ($storedData as $key => $value) { + $backendModel->setOrigData($key, $value); + } + return $backendModel; } @@ -166,9 +175,12 @@ protected function getMetadata() { if (!$this->metadata) { $this->metadata = $this->metadataProvider->get(); - array_walk($this->metadata, function (&$value) { - $value = $value['path']; - }); + array_walk( + $this->metadata, + function (&$value) { + $value = $value['path']; + } + ); } return $this->metadata; } diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php index 42801f57c882..00f30e9d7976 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Config as AppConfig; use Magento\Framework\App\ScopeFallbackResolverInterface; +/** + * Class ValueChecker + */ class ValueChecker { /** @@ -61,7 +64,7 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon $fieldConfig ), $this->valueProcessor->process( - $this->appConfig->getValue($fieldConfig['path'], $scope, $scopeId), + ($this->appConfig->getValue($fieldConfig['path'], $scope, $scopeId) ?? ""), $scope, $scopeId, $fieldConfig @@ -80,6 +83,7 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon */ protected function isEqual($value, $defaultValue) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction switch (gettype($value)) { case 'array': return $this->isEqualArrays($value, $defaultValue); From 5dad282326cc4c7aff794ad1db1df283be28540c Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 5 Jun 2019 14:38:26 +0300 Subject: [PATCH 0085/1172] MAGETWO-99862: wishlist_item_option table contains unrelated data --- .../Wishlist/Controller/Index/Plugin.php | 8 ++- .../Test/Unit/Controller/Index/PluginTest.php | 37 ++++++---- .../Wishlist/Controller/Index/PluginTest.php | 71 +++++++++++++++++++ 3 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php diff --git a/app/code/Magento/Wishlist/Controller/Index/Plugin.php b/app/code/Magento/Wishlist/Controller/Index/Plugin.php index 60d6859613d5..150e4de72b40 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Plugin.php +++ b/app/code/Magento/Wishlist/Controller/Index/Plugin.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -12,6 +11,9 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\App\Response\RedirectInterface; +/** + * Wishlist plugin before dispatch + */ class Plugin { /** @@ -75,7 +77,9 @@ public function beforeDispatch(\Magento\Framework\App\ActionInterface $subject, if (!$this->customerSession->getBeforeWishlistUrl()) { $this->customerSession->setBeforeWishlistUrl($this->redirector->getRefererUrl()); } - $this->customerSession->setBeforeWishlistRequest($request->getParams()); + $data = $request->getParams(); + unset($data['login']); + $this->customerSession->setBeforeWishlistRequest($data); $this->customerSession->setBeforeRequestParams($this->customerSession->getBeforeWishlistRequest()); $this->customerSession->setBeforeModuleName('wishlist'); $this->customerSession->setBeforeControllerName('index'); diff --git a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php index 399b48073b33..2b583f910151 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Controller/Index/PluginTest.php @@ -6,6 +6,9 @@ namespace Magento\Wishlist\Test\Unit\Controller\Index; +/** + * Test for wishlist plugin before dispatch + */ class PluginTest extends \PHPUnit\Framework\TestCase { /** @@ -38,22 +41,26 @@ class PluginTest extends \PHPUnit\Framework\TestCase */ protected $request; + /** + * @inheritdoc + */ protected function setUp() { $this->customerSession = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods([ - 'authenticate', - 'getBeforeWishlistUrl', - 'setBeforeWishlistUrl', - 'setBeforeWishlistRequest', - 'getBeforeWishlistRequest', - 'setBeforeRequestParams', - 'setBeforeModuleName', - 'setBeforeControllerName', - 'setBeforeAction', - ]) - ->getMock(); + ->setMethods( + [ + 'authenticate', + 'getBeforeWishlistUrl', + 'setBeforeWishlistUrl', + 'setBeforeWishlistRequest', + 'getBeforeWishlistRequest', + 'setBeforeRequestParams', + 'setBeforeModuleName', + 'setBeforeControllerName', + 'setBeforeAction', + ] + )->getMock(); $this->authenticationState = $this->createMock(\Magento\Wishlist\Model\AuthenticationState::class); $this->config = $this->createMock(\Magento\Framework\App\Config::class); @@ -62,6 +69,9 @@ protected function setUp() $this->request = $this->createMock(\Magento\Framework\App\Request\Http::class); } + /** + * @inheritdoc + */ protected function tearDown() { unset( @@ -96,6 +106,7 @@ public function testBeforeDispatch() $refererUrl = 'http://referer-url.com'; $params = [ 'product' => 1, + 'login' => [], ]; $actionFlag = $this->createMock(\Magento\Framework\App\ActionFlag::class); @@ -139,7 +150,7 @@ public function testBeforeDispatch() ->willReturnSelf(); $this->customerSession->expects($this->once()) ->method('setBeforeWishlistRequest') - ->with($params) + ->with(['product' => 1]) ->willReturnSelf(); $this->customerSession->expects($this->once()) ->method('getBeforeWishlistRequest') diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php new file mode 100644 index 000000000000..4c8937e1c6e9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Wishlist\Controller\Index; + +use Magento\TestFramework\TestCase\AbstractController; +use Magento\Customer\Model\Session as CustomerSession; +use Magento\Catalog\Api\ProductRepositoryInterface; + +/** + * Test for wishlist plugin before dispatch + */ +class PluginTest extends AbstractController +{ + /** + * @var CustomerSession + */ + private $customerSession; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + $this->customerSession = $this->_objectManager->get(CustomerSession::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + $this->customerSession->logout(); + $this->customerSession = null; + parent::tearDown(); + } + + /** + * Test for adding product to wishlist with invalidate credentials + * + * @return void + * @magentoDataFixture Magento/Catalog/_files/product_simple_xss.php + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoAppArea frontend + */ + public function testAddActionProductWithInvalidCredentials(): void + { + $this->getRequest()->setPostValue( + [ + 'login' => [ + 'username' => 'invalidCustomer@example.com', + 'password' => 'invalidPassword', + ], + ] + ); + + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->_objectManager->get(ProductRepositoryInterface::class); + + $product = $productRepository->get('product-with-xss'); + + $this->dispatch('wishlist/index/add/product/' . $product->getId() . '?nocookie=1'); + + $this->assertArrayNotHasKey('login', $this->customerSession->getBeforeWishlistRequest()); + } +} From cc3ce3d72904007b5d6b251f526f587cf0d4e83a Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 6 Jun 2019 10:40:36 -0500 Subject: [PATCH 0086/1172] MC-16114: Update Email Template Filter --- lib/internal/Magento/Framework/Filter/Template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 1bb063fb279a..0515b60cc316 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -417,7 +417,7 @@ private function validateVariableMethodCall($object, string $method): void } else { foreach ($this->restrictedMethodsByInstanceType as $instanceType => $restrictedMethods) { if ($object instanceof $instanceType && - ($restrictedMethods === '*' || in_array(mb_strtolower($method), $restrictedMethods)) + (in_array('*', $restrictedMethods) || in_array(mb_strtolower($method), $restrictedMethods)) ) { throw new \InvalidArgumentException("Method $method cannot be called from template."); } From 8b623dbea0ffeeca7ce698e5b5e7d76b95f0916f Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 6 Jun 2019 11:28:55 -0500 Subject: [PATCH 0087/1172] MC-15919: Customer attribute label update - Updated meta data resolver object --- .../Magento/Customer/Model/AttributeMetadataResolver.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index 84162bb8dae0..a41d52cdc45a 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -113,7 +113,12 @@ public function getAttributesMeta( // use getDataUsingMethod, since some getters are defined and apply additional processing of returning value foreach (self::$metaProperties as $metaName => $origName) { $value = $attribute->getDataUsingMethod($origName); - $meta['arguments']['data']['config'][$metaName] = ($metaName === 'label') ? __($value) : $value; + if ($metaName === 'label') { + $meta['arguments']['data']['config'][$metaName] = __($value); + $meta['arguments']['data']['config']['__disableTmpl'] = [$metaName => true]; + } else { + $meta['arguments']['data']['config'][$metaName] = $value; + } if ('frontend_input' === $origName) { $meta['arguments']['data']['config']['formElement'] = self::$formElement[$value] ?? $value; } @@ -144,7 +149,6 @@ public function getAttributesMeta( $attribute, $meta['arguments']['data']['config'] ); - $meta['arguments']['data']['config']['__disableTmpl'] = true; return $meta; } From 3d19d0f53aa7ed2903ae9170bac92046ec061348 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 6 Jun 2019 15:41:17 -0500 Subject: [PATCH 0088/1172] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Magento/Theme/Model/Design/BackendModelFactory.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php index 2896e9f10129..df4ad381ca0d 100644 --- a/app/code/Magento/Theme/Model/Design/BackendModelFactory.php +++ b/app/code/Magento/Theme/Model/Design/BackendModelFactory.php @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Theme\Model\Design; use Magento\Framework\App\Config\Value; @@ -81,8 +84,11 @@ public function create(array $data = []) $backendModel = $this->getNewBackendModel($backendType, $backendModelData); $backendModel->setValue($data['value']); - foreach ($storedData as $key => $value) { - $backendModel->setOrigData($key, $value); + if ($storedData) { + foreach ($storedData as $key => $value) { + $backendModel->setOrigData($key, $value); + } + $backendModel->setOrigData('field_config', $data['config']); } return $backendModel; From bd051c49790daa6756c1d9645d5d58f93811b714 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Fri, 7 Jun 2019 14:41:46 -0500 Subject: [PATCH 0089/1172] MC-15973: Incorrect ImportExport file handling --- app/code/Magento/ImportExport/Model/Import.php | 8 +++++++- .../Controller/Adminhtml/Import/ValidateTest.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php index c8a5921b41b1..d29bf29dd50a 100644 --- a/app/code/Magento/ImportExport/Model/Import.php +++ b/app/code/Magento/ImportExport/Model/Import.php @@ -568,9 +568,15 @@ public function uploadSource() $entity = $this->getEntity(); /** @var $uploader Uploader */ $uploader = $this->_uploaderFactory->create(['fileId' => self::FIELD_NAME_SOURCE_FILE]); + $uploader->setAllowedExtensions(['csv', 'zip']); $uploader->skipDbProcessing(true); $fileName = $this->random->getRandomString(32) . '.' . $uploader->getFileExtension(); - $result = $uploader->save($this->getWorkingDir(), $fileName); + try { + $result = $uploader->save($this->getWorkingDir(), $fileName); + } catch (\Exception $e) { + throw new LocalizedException(__('The file cannot be uploaded.')); + } + // phpcs:disable Magento2.Functions.DiscouragedFunction.Discouraged $extension = pathinfo($result['file'], PATHINFO_EXTENSION); diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php index a3cf42b48489..d9a758b54966 100644 --- a/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php +++ b/dev/tests/integration/testsuite/Magento/ImportExport/Controller/Adminhtml/Import/ValidateTest.php @@ -93,7 +93,7 @@ public function validationDataProvider(): array [ 'file_name' => 'test.txt', 'mime-type' => 'text/csv', - 'message' => '\'txt\' file extension is not supported', + 'message' => 'The file cannot be uploaded.', 'delimiter' => ',', ], [ From 57645ff1df01e3ddb467d30750d3c6957b26fc7f Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Mon, 10 Jun 2019 11:15:29 -0500 Subject: [PATCH 0090/1172] MC-17305: Product Form Update. --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index 8d298aec9f1c..e201877b47cc 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -22,7 +22,7 @@ <input type="hidden" name="product" value="<?= (int)$_product->getId() ?>" /> <input type="hidden" name="selected_configurable_option" value="" /> <input type="hidden" name="related_product" id="related-products-field" value="" /> - <input type="hidden" name="item" value="<?= $block->escapeHtmlAttr($block->getRequest()->getParam('id')) ?>" /> + <input type="hidden" name="item" value="<?= $block->escapeJs($block->escapeHtmlAttr($block->getRequest()->getParam('id'))) ?>" /> <?= $block->getBlockHtml('formkey') ?> <?= $block->getChildHtml('form_top') ?> <?php if (!$block->hasOptions()) :?> From 353f99504423191e1b09b6b1a4355949e60fe56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Bajsarowicz?= <lukasz.bajsarowicz@strix.net> Date: Tue, 11 Jun 2019 01:58:56 +0200 Subject: [PATCH 0091/1172] Refactor: Instead of using hardcoded `amOnPage` - use LogoutActionGroup instead --- .../Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml | 2 +- .../Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateSimpleProductTest.xml | 1 - .../Mftf/Test/AdminCreateSimpleProductWithUnicodeTest.xml | 2 +- .../Test/AdminMultipleWebsitesUseDefaultValuesTest.xml | 2 +- .../AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml | 2 +- .../Test/Mftf/Test/AdminSimpleProductImagesTest.xml | 4 ++-- .../Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml | 2 +- .../Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml | 2 +- .../SaveProductWithCustomOptionsSecondWebsiteTest.xml | 2 +- .../Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml | 4 ++-- .../Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml | 2 +- .../Test/Mftf/Test/StorefrontGuestCheckoutTest.xml | 4 ++-- .../Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml | 2 +- .../Test/Mftf/Test/AdminConfigurableProductCreateTest.xml | 2 +- .../Test/Mftf/Test/AdminConfigurableProductDeleteTest.xml | 4 ++-- .../Mftf/Test/AdminConfigurableProductLongSkuTest.xml | 2 +- .../Mftf/Test/AdminConfigurableProductOutOfStockTest.xml | 6 +++--- .../Test/Mftf/Test/AdminConfigurableProductSearchTest.xml | 4 ++-- .../Test/AdminConfigurableProductUpdateAttributeTest.xml | 4 ++-- .../Test/Mftf/Test/AdminConfigurableProductUpdateTest.xml | 6 +++--- .../ConfigurableProductPriceAdditionalStoreViewTest.xml | 2 +- ...efrontConfigurableProductCategoryViewChildOnlyTest.xml | 2 +- .../Test/StorefrontConfigurableProductChildSearchTest.xml | 2 +- .../Test/StorefrontConfigurableProductDetailsTest.xml | 8 ++++---- .../Mftf/Test/StorefrontConfigurableProductViewTest.xml | 6 +++--- ...refrontConfigurableProductWithFileCustomOptionTest.xml | 2 +- .../Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml | 2 +- .../Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml | 2 +- .../Test/Mftf/Test/StorefrontAddCustomerAddressTest.xml | 4 ++-- .../Test/Mftf/Test/StorefrontCreateCustomerTest.xml | 2 +- .../Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml | 2 +- .../Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml | 2 +- .../Test/AdminSubmitsOrderPaymentMethodValidationTest.xml | 2 +- .../Test/AdminSubmitsOrderWithAndWithoutEmailTest.xml | 2 +- ...dminSubmitsOrderWithAndWithoutFieldsValidationTest.xml | 2 +- .../Test/CreditMemoTotalAfterShippingDiscountTest.xml | 4 ++-- .../Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml | 2 +- .../AdminCreateCartPriceRuleForGeneratedCouponTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml | 2 +- .../Test/AdminCreateFixedAmountWholeCartDiscountTest.xml | 2 +- .../Mftf/Test/AdminCreatePercentOfProductPriceTest.xml | 2 +- .../Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml | 2 +- .../Swatches/Test/Mftf/Test/AdminCreateTextSwatchTest.xml | 2 +- .../Test/Mftf/Test/AdminCreateVisualSwatchTest.xml | 2 +- .../Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml | 2 +- .../Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml | 2 +- .../Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml | 2 +- .../StorefrontSwatchProductWithFileCustomOptionTest.xml | 2 +- .../Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml | 2 +- ...urableProductChildImageShouldBeShownOnWishListTest.xml | 2 +- .../StorefrontAddMultipleStoreProductsToWishlistTest.xml | 2 +- .../Mftf/Test/StorefrontDeletePersistedWishlistTest.xml | 2 +- 53 files changed, 69 insertions(+), 70 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml index 15171fe3713c..784b5d3fd182 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryTest.xml @@ -19,7 +19,7 @@ <group value="category"/> </annotations> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml index 6658ad36d715..291b6985bd3e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductDuplicateUrlkeyTest.xml @@ -23,7 +23,7 @@ </createData> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/> </after> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest.xml index 6096ee1fa399..a7587a5ed31f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductTest.xml @@ -22,7 +22,6 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> </after> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithUnicodeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithUnicodeTest.xml index 896a28d0298e..94d488f216b4 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithUnicodeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithUnicodeTest.xml @@ -22,7 +22,7 @@ <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> </after> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml index 264615ff6736..f7fd81f28199 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMultipleWebsitesUseDefaultValuesTest.xml @@ -22,7 +22,7 @@ <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> <argument name="websiteName" value="Second Website"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml index 240a5492355c..ebae27a1f718 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRequiredFieldsHaveRequiredFieldIndicatorTest.xml @@ -18,7 +18,7 @@ <group value="Catalog"/> </annotations> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index 1cd0e15780c1..41f27497a50e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -34,7 +34,7 @@ <deleteData createDataKey="category" stepKey="deletePreReqCategory"/> <deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/> <deleteData createDataKey="secondProduct" stepKey="deleteSecondProduct"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Go to the first product edit page --> @@ -186,7 +186,7 @@ <after> <deleteData createDataKey="category" stepKey="deletePreReqCategory"/> <deleteData createDataKey="product" stepKey="deleteProduct"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Go to the product edit page --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml index 2ff83afa15e5..0f63a7284445 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryStoreUrlKeyTest.xml @@ -22,7 +22,7 @@ <actionGroup ref="DeleteCategory" stepKey="deleteCategory"> <argument name="categoryEntity" value="_defaultCategory"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create category, change store view to default --> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml index 5cae81b36a32..674d46b9c18b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/DeleteCategoriesTest.xml @@ -36,7 +36,7 @@ <createData entity="NewRootCategory" stepKey="createNewRootCategoryA"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createProduct1" stepKey="deleteProduct1"/> <deleteData createDataKey="createProduct2" stepKey="deleteProduct2"/> <deleteData createDataKey="createProduct3" stepKey="deleteProduct3"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml index e9e9eb015878..8092b03c53cb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/SaveProductWithCustomOptionsSecondWebsiteTest.xml @@ -53,7 +53,7 @@ <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteTestWebsite"> <argument name="websiteName" value="Second Website"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="EnableWebUrlOptions" stepKey="addStoreCodeToUrls"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml index 9714b76a0561..163e71c50053 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/CheckCheckoutSuccessPageTest.xml @@ -30,7 +30,7 @@ <!--Logout from customer account--> <amOnPage url="customer/account/logout/" stepKey="logoutCustomerOne"/> <waitForPageLoad stepKey="waitLogoutCustomerOne"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createSimpleUsCustomer" stepKey="deleteCustomer"/> </after> @@ -147,7 +147,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> </after> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml index f77e3df11713..84e1017bf9cf 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTest.xml @@ -147,7 +147,7 @@ <argument name="name" value="{{SimpleTaxCA.state}}-{{SimpleTaxCA.rate}}"/> <argument name="searchInput" value="{{AdminSecondaryGridSection.taxIdentifierSearch}}"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="simpleproduct1" stepKey="deleteProduct1"/> <deleteData createDataKey="simplecategory" stepKey="deleteCategory"/> <deleteData createDataKey="multiple_address_customer" stepKey="deleteCustomer"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml index 15410921f1bb..6ff561564d9c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTest.xml @@ -25,7 +25,7 @@ </createData> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> </after> @@ -111,7 +111,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <magentoCLI stepKey="allowSpecificValue" command="config:set payment/checkmo/allowspecific 0" /> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml index fccc5b5980f2..b7c7e4a4212f 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminCreateCmsPageTest.xml @@ -23,7 +23,7 @@ <actionGroup ref="DisabledWYSIWYG" stepKey="disableWYSIWYG"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <amOnPage url="{{CmsPagesPage.url}}" stepKey="amOnPagePagesGrid"/> <waitForPageLoad stepKey="waitForPageLoad1"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml index 2af85e1bac04..9a648329dc04 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest.xml @@ -26,7 +26,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a configurable product via the UI --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductDeleteTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductDeleteTest.xml index 1a694b8adf17..33a6da9dabf3 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductDeleteTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductDeleteTest.xml @@ -66,7 +66,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> @@ -216,7 +216,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> <deleteData createDataKey="createConfigChildProduct3" stepKey="deleteConfigChildProduct3"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml index c599a6a23f19..c47e320b3a17 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml @@ -52,7 +52,7 @@ <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> <!--Clean up category--> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Create a configurable product with long name and sku--> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml index 5633c3675ca8..a7581cc694b1 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml @@ -77,7 +77,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> @@ -200,7 +200,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> @@ -301,7 +301,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductSearchTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductSearchTest.xml index 059a18200e90..410c85d31490 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductSearchTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductSearchTest.xml @@ -68,7 +68,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> @@ -147,7 +147,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateAttributeTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateAttributeTest.xml index 001d4d17ec21..736276933a3a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateAttributeTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateAttributeTest.xml @@ -96,7 +96,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <!-- Delete everything that was created in the before block --> <deleteData createDataKey="createCategory" stepKey="deleteCatagory" /> @@ -213,7 +213,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <!-- Delete everything that was created in the before block --> <deleteData createDataKey="createCategory" stepKey="deleteCatagory" /> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest.xml index 1791fc002ab9..18053da86fe1 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductUpdateTest.xml @@ -37,7 +37,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> </after> @@ -277,7 +277,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a configurable product via the UI --> @@ -326,7 +326,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a configurable product via the UI --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml index a71f51526c8a..83d9bbe8c270 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/ConfigurableProductPriceAdditionalStoreViewTest.xml @@ -77,7 +77,7 @@ <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> <argument name="websiteName" value="Second Website"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="EnableWebUrlOptions" stepKey="addStoreCodeToUrls"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductCategoryViewChildOnlyTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductCategoryViewChildOnlyTest.xml index ac468fc92e4d..805727e29a17 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductCategoryViewChildOnlyTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductCategoryViewChildOnlyTest.xml @@ -88,7 +88,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml index 1075f79aef18..c60b4d46f7fe 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml @@ -131,7 +131,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductDetailsTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductDetailsTest.xml index 836bc2cdca97..f75e30907a1f 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductDetailsTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductDetailsTest.xml @@ -31,7 +31,7 @@ </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify configurable product details in storefront product view --> @@ -72,7 +72,7 @@ </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify configurable product options in storefront product view --> @@ -113,7 +113,7 @@ </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify adding configurable product to cart after an option is selected in storefront product view --> @@ -151,7 +151,7 @@ </before> <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify not able to add configurable product to cart when no option is selected in storefront product view --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductViewTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductViewTest.xml index cc8291a83eb4..0ade410714a2 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductViewTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductViewTest.xml @@ -32,7 +32,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify the storefront category grid view --> @@ -68,7 +68,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Verify storefront category list view --> @@ -106,7 +106,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Should be taken to product details page when adding to cart because an option needs to be selected --> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml index d890d5985811..4c955f338564 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml @@ -25,7 +25,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml index 78bae7ad60dd..a11fb9d0eaa8 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml @@ -23,7 +23,7 @@ <magentoCLI command="indexer:reindex customer_grid" stepKey="reindexCustomerGrid"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml index 2b24233e8b07..bf8844b2cc7a 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/EndToEndB2CLoggedInUserTest.xml @@ -25,7 +25,7 @@ <resetCookie userInput="PHPSESSID" stepKey="resetCookieForCart"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Step 0: User signs up an account --> <comment userInput="Start of signing up user account" stepKey="startOfSigningUpUserAccount" /> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontAddCustomerAddressTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontAddCustomerAddressTest.xml index 413bbfd06a53..e2c55eb3962f 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontAddCustomerAddressTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontAddCustomerAddressTest.xml @@ -24,7 +24,7 @@ </before> <after> <deleteData createDataKey="createCustomer" stepKey="DeleteCustomer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="AmOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Log in to Storefront as Customer 1 --> @@ -101,7 +101,7 @@ </before> <after> <deleteData createDataKey="createCustomer" stepKey="DeleteCustomer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="AmOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Log in to Storefront as Customer 1 --> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCreateCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCreateCustomerTest.xml index 97c932f0cb28..7d51f97f2463 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCreateCustomerTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCreateCustomerTest.xml @@ -20,7 +20,7 @@ <group value="create"/> </annotations> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml index 22ca214c94ae..4d60b7676605 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifySubscribedNewsletterDisplayedTest.xml @@ -49,7 +49,7 @@ </actionGroup> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Go to store front (default) and click Create an Account.--> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml index ce66409ed9b3..3785651a3432 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateInvoiceTest.xml @@ -25,7 +25,7 @@ </createData> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteProduct1"/> <deleteData createDataKey="createProduct" stepKey="deleteCategory1"/> </after> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderPaymentMethodValidationTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderPaymentMethodValidationTest.xml index e487c62b9672..255a7a91f9b1 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderPaymentMethodValidationTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderPaymentMethodValidationTest.xml @@ -29,7 +29,7 @@ <magentoCLI stepKey="allowSpecificValue" command="config:set payment/cashondelivery/active 0" /> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Create order via Admin--> <comment userInput="Admin creates order" stepKey="adminCreateOrderComment"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutEmailTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutEmailTest.xml index ed536bd3351f..01021ad745f7 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutEmailTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutEmailTest.xml @@ -26,7 +26,7 @@ <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Create order via Admin--> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml index 1490fc1a1a38..9268e9e72865 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml @@ -25,7 +25,7 @@ <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!--Create order via Admin--> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml index dfbdc5367799..2a5123d57965 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml @@ -33,7 +33,7 @@ <argument name="ruleName" value="{{ApiSalesRule.name}}"/> </actionGroup> <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearOrderFilters"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <deleteData createDataKey="createCategory" stepKey="deleteProduct1"/> <deleteData createDataKey="createProduct" stepKey="deleteCategory1"/> </after> @@ -58,7 +58,7 @@ <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> <see selector="{{AdminCartPriceRulesSection.messages}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> <!-- Place an order from Storefront as a Guest --> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml index 92d221de9e15..02078ff15ecc 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateBuyXGetYFreeTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{_defaultCoupon.code}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a cart price rule of type Buy X get Y free --> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml index 03dffe9f448e..9d807de409a0 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{_defaultCoupon.code}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a cart price rule --> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml index 08a08275ee07..1681d910ccdb 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountDiscountTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{_defaultCoupon.code}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a cart price rule for $10 Fixed amount discount --> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml index a39530f7607e..69918bda8c42 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateFixedAmountWholeCartDiscountTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{SimpleSalesRule.name}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a cart price rule for Fixed amount discount for whole cart --> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml index 1f7d849ac02b..898e5a07304b 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreatePercentOfProductPriceTest.xml @@ -30,7 +30,7 @@ <argument name="ruleName" value="{{_defaultCoupon.code}}"/> </actionGroup> <deleteData createDataKey="createPreReqCategory" stepKey="deletePreReqCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a cart price rule for 50 percent of product price --> diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml index 25e93f8f6ff4..e93fd62a7499 100644 --- a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml +++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateStoreGroupTest.xml @@ -21,7 +21,7 @@ <createData stepKey="b2" entity="customStoreGroup"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateTextSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateTextSwatchTest.xml index 3ef347b7aca1..87d3f0bb5bcb 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateTextSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateTextSwatchTest.xml @@ -22,7 +22,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a new product attribute of type "Text Swatch" --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml index 90e94466351b..65f0e2b09b82 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml @@ -35,7 +35,7 @@ <waitForPageLoad stepKey="waitToClickSave"/> <click selector="{{AttributePropertiesSection.SaveAndEdit}}" stepKey="clickSaveAndEdit"/> <!-- Logout --> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Go to the edit page for the "color" attribute --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml index b1ae06428c0a..824817a32213 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml @@ -30,7 +30,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Begin creating a new product attribute --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml index 28df5ffd5343..f150c6697bb9 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml @@ -28,7 +28,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Begin creating a new product attribute --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml index d12cb0433fed..623fd7456830 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml @@ -30,7 +30,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Begin creating a new product attribute --> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml index 7ef030ef8dfa..5e712ebc3829 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontSwatchProductWithFileCustomOptionTest.xml @@ -26,7 +26,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> diff --git a/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml b/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml index 2c4e2e70fec7..9ed4e2ced99f 100644 --- a/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml +++ b/app/code/Magento/Widget/Test/Mftf/Test/NewProductsListWidgetTest.xml @@ -27,7 +27,7 @@ </before> <after> - <amOnPage url="admin/admin/auth/logout/" stepKey="logout"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Create a CMS page containing the New Products widget --> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/ConfigurableProductChildImageShouldBeShownOnWishListTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/ConfigurableProductChildImageShouldBeShownOnWishListTest.xml index 6b951c89208c..0489ec750b7e 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/ConfigurableProductChildImageShouldBeShownOnWishListTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/ConfigurableProductChildImageShouldBeShownOnWishListTest.xml @@ -32,7 +32,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="customer" stepKey="deleteCustomer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml index ede63322235f..2d2248705d80 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontAddMultipleStoreProductsToWishlistTest.xml @@ -43,7 +43,7 @@ <actionGroup ref="DeleteCustomStoreActionGroup" stepKey="deleteCustomStoreGroup"> <argument name="storeGroupName" value="$$storeGroup.group[name]$$"/> </actionGroup> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <!-- Change products visibility on store-view level --> <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForProduct1"> diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml index 0001bd9d6db7..1c6d66a8fc48 100644 --- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml +++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDeletePersistedWishlistTest.xml @@ -35,7 +35,7 @@ <deleteData stepKey="deleteCategory" createDataKey="category"/> <deleteData stepKey="deleteProduct" createDataKey="product"/> <deleteData stepKey="deleteCustomer" createDataKey="customer"/> - <amOnPage url="admin/admin/auth/logout/" stepKey="amOnLogoutPage"/> + <actionGroup ref="logout" stepKey="adminLogout"/> </after> <amOnPage stepKey="amOnSignInPage" url="{{StorefrontCustomerSignInPage.url}}"/> From 58836f072898c63edb8fa4afa9670570aca3beb8 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 11 Jun 2019 10:03:33 -0500 Subject: [PATCH 0092/1172] MC-15972: File uploads --- .../Model/Product/Gallery/Processor.php | 18 +++--- .../Model/ResourceModel/File/Storage/File.php | 39 +++++++++--- .../ResourceModel/File/Storage/FileTest.php | 34 +++++++++- .../Framework/File/Test/Unit/UploaderTest.php | 63 +++++++++++++++++++ .../Magento/Framework/File/Uploader.php | 56 ++++++++++------- 5 files changed, 169 insertions(+), 41 deletions(-) create mode 100644 lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php index e1b788bc3941..f1d27c38e945 100644 --- a/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php +++ b/app/code/Magento/Catalog/Model/Product/Gallery/Processor.php @@ -167,10 +167,10 @@ public function addImage( } $fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($pathinfo['basename']); - $dispretionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); - $fileName = $dispretionPath . '/' . $fileName; + $dispersionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); + $fileName = $dispersionPath . '/' . $fileName; - $fileName = $this->getNotDuplicatedFilename($fileName, $dispretionPath); + $fileName = $this->getNotDuplicatedFilename($fileName, $dispersionPath); $destinationFile = $this->mediaConfig->getTmpMediaPath($fileName); @@ -465,27 +465,27 @@ protected function getUniqueFileName($file, $forTmp = false) * Get filename which is not duplicated with other files in media temporary and media directories * * @param string $fileName - * @param string $dispretionPath + * @param string $dispersionPath * @return string * @since 101.0.0 */ - protected function getNotDuplicatedFilename($fileName, $dispretionPath) + protected function getNotDuplicatedFilename($fileName, $dispersionPath) { - $fileMediaName = $dispretionPath . '/' + $fileMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getMediaPath($fileName)); - $fileTmpMediaName = $dispretionPath . '/' + $fileTmpMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getTmpMediaPath($fileName)); if ($fileMediaName != $fileTmpMediaName) { if ($fileMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileMediaName, - $dispretionPath + $dispersionPath ); } elseif ($fileTmpMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileTmpMediaName, - $dispretionPath + $dispersionPath ); } } diff --git a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php index 8dfce40419b4..b847b4c13adf 100644 --- a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php +++ b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php @@ -6,12 +6,20 @@ namespace Magento\MediaStorage\Model\ResourceModel\File\Storage; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem\Io\File as FileIo; +use Magento\Framework\App\ObjectManager; /** * Class File */ class File { + /** + * @var FileIo + */ + private $fileIo; + /** * @var \Magento\Framework\Filesystem */ @@ -25,11 +33,16 @@ class File /** * @param \Magento\Framework\Filesystem $filesystem * @param \Psr\Log\LoggerInterface $log + * @param FileIo $fileIo */ - public function __construct(\Magento\Framework\Filesystem $filesystem, \Psr\Log\LoggerInterface $log) - { + public function __construct( + \Magento\Framework\Filesystem $filesystem, + \Psr\Log\LoggerInterface $log, + FileIo $fileIo = null + ) { $this->_logger = $log; $this->_filesystem = $filesystem; + $this->fileIo = $fileIo ?? ObjectManager::getInstance()->get(FileIo::class); } /** @@ -45,14 +58,15 @@ public function getStorageData($dir = '/') $directoryInstance = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA); if ($directoryInstance->isDirectory($dir)) { foreach ($directoryInstance->readRecursively($dir) as $path) { - $itemName = basename($path); + $pathInfo = $this->fileIo->getPathInfo($path); + $itemName = $pathInfo['basename']; if ($itemName == '.svn' || $itemName == '.htaccess') { continue; } if ($directoryInstance->isDirectory($path)) { $directories[] = [ 'name' => $itemName, - 'path' => dirname($path) == '.' ? '/' : dirname($path), + 'path' => $pathInfo['dirname'] === '.' ? '/' : $pathInfo['dirname'], ]; } else { $files[] = $path; @@ -64,7 +78,7 @@ public function getStorageData($dir = '/') } /** - * Clear files and directories in storage + * Clear all files in storage $dir * * @param string $dir * @return $this @@ -73,8 +87,17 @@ public function clear($dir = '') { $directoryInstance = $this->_filesystem->getDirectoryWrite(DirectoryList::MEDIA); if ($directoryInstance->isDirectory($dir)) { - foreach ($directoryInstance->read($dir) as $path) { - $directoryInstance->delete($path); + $paths = $directoryInstance->readRecursively($dir); + foreach ($paths as $path) { + if ($directoryInstance->isDirectory()) { + continue; + } + + $pathInfo = $this->fileIo->getPathInfo($path); + + if ($pathInfo['basename'] !== '.htaccess') { + $directoryInstance->delete($path); + } } } @@ -127,7 +150,7 @@ public function saveFile($filePath, $content, $overwrite = false) } } catch (\Magento\Framework\Exception\FileSystemException $e) { $this->_logger->info($e->getMessage()); - throw new \Magento\Framework\Exception\LocalizedException(__('Unable to save file: %1', $filePath)); + throw new LocalizedException(__('Unable to save file: %1', $filePath)); } return false; diff --git a/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php b/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php index 97dffbe0e39a..adc045cd0bed 100644 --- a/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php +++ b/app/code/Magento/MediaStorage/Test/Unit/Model/ResourceModel/File/Storage/FileTest.php @@ -6,12 +6,18 @@ namespace Magento\MediaStorage\Test\Unit\Model\ResourceModel\File\Storage; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; /** * Class FileTest */ class FileTest extends \PHPUnit\Framework\TestCase { + /** + * @var \Magento\Framework\Filesystem\Io\File + */ + private $fileIoMock; + /** * @var \Magento\MediaStorage\Model\ResourceModel\File\Storage\File */ @@ -44,9 +50,17 @@ protected function setUp() ['isDirectory', 'readRecursively'] ); - $this->storageFile = new \Magento\MediaStorage\Model\ResourceModel\File\Storage\File( - $this->filesystemMock, - $this->loggerMock + $this->fileIoMock = $this->createPartialMock(\Magento\Framework\Filesystem\Io\File::class, ['getPathInfo']); + + $objectManager = new ObjectManager($this); + + $this->storageFile = $objectManager->getObject( + \Magento\MediaStorage\Model\ResourceModel\File\Storage\File::class, + [ + 'filesystem' => $this->filesystemMock, + 'log' => $this->loggerMock, + 'fileIo' => $this->fileIoMock + ] ); } @@ -98,6 +112,20 @@ public function testGetStorageData() 'folder_one/folder_two/.htaccess', 'folder_one/folder_two/file_two.txt', ]; + + $pathInfos = array_map( + function ($path) { + return [$path, pathinfo($path)]; + }, + $paths + ); + + $this->fileIoMock->expects( + $this->any() + )->method( + 'getPathInfo' + )->will($this->returnValueMap($pathInfos)); + sort($paths); $this->directoryReadMock->expects( $this->once() diff --git a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php new file mode 100644 index 000000000000..ac19f4dc36ed --- /dev/null +++ b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php @@ -0,0 +1,63 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\File\Test\Unit; + +/** + * Unit Test class for \Magento\Framework\File\Uploader + */ +class UploaderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @param string $fileName + * @param string|bool $expectedCorrectedFileName + * + * @dataProvider getCorrectFileNameProvider + */ + public function testGetCorrectFileName($fileName, $expectedCorrectedFileName) + { + $isExceptionExpected = $expectedCorrectedFileName === true; + + if ($isExceptionExpected) { + $this->expectException(\InvalidArgumentException::class); + } + + $this->assertEquals( + $expectedCorrectedFileName, + \Magento\Framework\File\Uploader::getCorrectFileName($fileName) + ); + } + + /** + * @return array + */ + public function getCorrectFileNameProvider() + { + return [ + [ + '^&*&^&*^$$$$()', + 'file.' + ], + [ + '^&*&^&*^$$$$().png', + 'file.png' + ], + [ + '_', + 'file.' + ], + [ + '_.jpg', + 'file.jpg' + ], + [ + 'a.' . str_repeat('b', 100), + true + ] + ]; + } +} diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 328a748cfd5d..5396862195f8 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\File; +use Magento\Framework\Exception\FileSystemException; +use Magento\Framework\Validation\ValidationException; + /** * File upload class * @@ -75,7 +78,7 @@ class Uploader protected $_allowRenameFiles = false; /** - * If this variable is set to TRUE, files dispertion will be supported. + * If this variable is set to TRUE, files dispersion will be supported. * * @var bool * @access protected @@ -162,7 +165,7 @@ class Uploader * * @param string|array $fileId * @param \Magento\Framework\File\Mime|null $fileMime - * @throws \Exception + * @throws \DomainException */ public function __construct( $fileId, @@ -171,7 +174,7 @@ public function __construct( $this->_setUploadFileId($fileId); if (!file_exists($this->_file['tmp_name'])) { $code = empty($this->_file['tmp_name']) ? self::TMP_NAME_EMPTY : 0; - throw new \Exception('The file was not uploaded.', $code); + throw new \DomainException('The file was not uploaded.', $code); } else { $this->_fileExists = true; } @@ -256,7 +259,7 @@ public function save($destinationFolder, $newFileName = null) * * @param string $destinationFolder * @return void - * @throws \Exception + * @throws FileSystemException */ private function validateDestination($destinationFolder) { @@ -265,7 +268,7 @@ private function validateDestination($destinationFolder) } if (!is_writable($destinationFolder)) { - throw new \Exception('Destination folder is not writable or does not exists.'); + throw new FileSystemException(__('Destination folder is not writable or does not exists.')); } } @@ -302,7 +305,7 @@ protected function _moveFile($tmpPath, $destPath) * Validate file before save * * @return void - * @throws \Exception + * @throws ValidationException */ protected function _validateFile() { @@ -312,7 +315,7 @@ protected function _validateFile() //is file extension allowed if (!$this->checkAllowedExtension($this->getFileExtension())) { - throw new \Exception('Disallowed file type.'); + throw new ValidationException(__('Disallowed file type.')); } //run validate callbacks foreach ($this->_validateCallbacks as $params) { @@ -366,19 +369,27 @@ public function removeValidateCallback($callbackName) } /** - * Correct filename with special chars and spaces + * Correct filename with special chars and spaces; also trim excessively long filenames * * @param string $fileName * @return string + * @throws \InvalidArgumentException */ public static function getCorrectFileName($fileName) { $fileName = preg_replace('/[^a-z0-9_\\-\\.]+/i', '_', $fileName); $fileInfo = pathinfo($fileName); + $fileInfo['extension'] = $fileInfo['extension'] ?? ''; + + // account for excessively long filenames that cannot be stored completely in database + if (strlen($fileInfo['basename']) > 100) { + throw new \InvalidArgumentException('Filename is too long; must be 100 characters or less'); + } if (preg_match('/^_+$/', $fileInfo['filename'])) { $fileName = 'file.' . $fileInfo['extension']; } + return $fileName; } @@ -533,7 +544,8 @@ private function _getMimeType() * * @param string|array $fileId * @return void - * @throws \Exception + * @throws \DomainException + * @throws \InvalidArgumentException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function _setUploadFileId($fileId) @@ -543,7 +555,7 @@ private function _setUploadFileId($fileId) $this->_file = $fileId; } else { if (empty($_FILES)) { - throw new \Exception('$_FILES array is empty'); + throw new \DomainException('$_FILES array is empty'); } preg_match("/^(.*?)\[(.*?)\]$/", $fileId, $file); @@ -565,7 +577,9 @@ private function _setUploadFileId($fileId) $this->_uploadType = self::SINGLE_STYLE; $this->_file = $_FILES[$fileId]; } elseif ($fileId == '') { - throw new \Exception('Invalid parameter given. A valid $_FILES[] identifier is expected.'); + throw new \InvalidArgumentException( + 'Invalid parameter given. A valid $_FILES[] identifier is expected.' + ); } } } @@ -575,7 +589,7 @@ private function _setUploadFileId($fileId) * * @param string $destinationFolder * @return \Magento\Framework\File\Uploader - * @throws \Exception + * @throws FileSystemException */ private function _createDestinationFolder($destinationFolder) { @@ -590,7 +604,7 @@ private function _createDestinationFolder($destinationFolder) if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0777, true) )) { - throw new \Exception("Unable to create directory '{$destinationFolder}'."); + throw new FileSystemException(__('Unable to create directory %1.', $destinationFolder)); } return $this; } @@ -620,7 +634,7 @@ public static function getNewFileName($destinationFile) } /** - * Get dispertion path + * Get dispersion path * * @param string $fileName * @return string @@ -632,7 +646,7 @@ public static function getDispretionPath($fileName) } /** - * Get dispertion path + * Get dispersion path * * @param string $fileName * @return string @@ -640,17 +654,17 @@ public static function getDispretionPath($fileName) public static function getDispersionPath($fileName) { $char = 0; - $dispertionPath = ''; + $dispersionPath = ''; while ($char < 2 && $char < strlen($fileName)) { - if (empty($dispertionPath)) { - $dispertionPath = '/' . ('.' == $fileName[$char] ? '_' : $fileName[$char]); + if (empty($dispersionPath)) { + $dispersionPath = '/' . ('.' == $fileName[$char] ? '_' : $fileName[$char]); } else { - $dispertionPath = self::_addDirSeparator( - $dispertionPath + $dispersionPath = self::_addDirSeparator( + $dispersionPath ) . ('.' == $fileName[$char] ? '_' : $fileName[$char]); } $char++; } - return $dispertionPath; + return $dispersionPath; } } From 1322bd3c5c2be9f2ed06b7fbeebd167735cf6016 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Tue, 11 Jun 2019 11:16:54 -0500 Subject: [PATCH 0093/1172] MC-16963: Admin panel Design Configuration changes logs are missing --- .../Magento/Theme/Model/Design/Config/ValueChecker.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php index 00f30e9d7976..11d45616e387 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php @@ -83,13 +83,11 @@ public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldCon */ protected function isEqual($value, $defaultValue) { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - switch (gettype($value)) { - case 'array': - return $this->isEqualArrays($value, $defaultValue); - default: - return $value === $defaultValue; + if (is_array($value)) { + return $this->isEqualArrays($value, $defaultValue); } + + return $value === $defaultValue; } /** From dc8786a27f9f2a789f926ce0757c663f6633bf53 Mon Sep 17 00:00:00 2001 From: Sachin Admane <sadmane@magento.com> Date: Tue, 11 Jun 2019 11:22:48 -0500 Subject: [PATCH 0094/1172] MC-17305: Product Form Update. Add int typecast. --- .../Catalog/view/frontend/templates/product/view/form.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index e201877b47cc..7d59e9831e94 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -22,7 +22,7 @@ <input type="hidden" name="product" value="<?= (int)$_product->getId() ?>" /> <input type="hidden" name="selected_configurable_option" value="" /> <input type="hidden" name="related_product" id="related-products-field" value="" /> - <input type="hidden" name="item" value="<?= $block->escapeJs($block->escapeHtmlAttr($block->getRequest()->getParam('id'))) ?>" /> + <input type="hidden" name="item" value="<?= (int)$block->getRequest()->getParam('id') ?>" /> <?= $block->getBlockHtml('formkey') ?> <?= $block->getChildHtml('form_top') ?> <?php if (!$block->hasOptions()) :?> From 0a0f3943777aa64c48a76ac37a64aa1657c3e88b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Tue, 11 Jun 2019 13:20:07 -0500 Subject: [PATCH 0095/1172] MC-17065: Email error message - Resolved error message issue for inline editing customer --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 7220de035681..599415bc7bb7 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -70,8 +70,14 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn */ private $addressRegistry; + /** + * @var \Magento\Framework\Escaper + */ + private $escaper; + /** * @param Action\Context $context + * @param \Magento\Framework\Escaper $escaper * @param CustomerRepositoryInterface $customerRepository * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Customer\Model\Customer\Mapper $customerMapper @@ -86,6 +92,7 @@ public function __construct( \Magento\Customer\Model\Customer\Mapper $customerMapper, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, \Psr\Log\LoggerInterface $logger, + \Magento\Framework\Escaper $escaper, AddressRegistry $addressRegistry = null ) { $this->customerRepository = $customerRepository; @@ -93,6 +100,7 @@ public function __construct( $this->customerMapper = $customerMapper; $this->dataObjectHelper = $dataObjectHelper; $this->logger = $logger; + $this->escaper = $escaper; $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); parent::__construct($context); } @@ -315,7 +323,7 @@ protected function getCustomer() */ protected function getErrorWithCustomerId($errorText) { - return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . __($errorText); + return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . $this->escaper->escapeHtml(__($errorText)); } /** From 61c3ea0eda1e2b7cc4aa80a7f844c399b3a705cf Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Tue, 11 Jun 2019 15:40:42 -0500 Subject: [PATCH 0096/1172] MC-17065: Email error message - Resolved unit test failures --- .../Unit/Controller/Adminhtml/Index/InlineEditTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 45e64f6557d5..7d2db1cc16b0 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Model\EmailNotificationInterface; use Magento\Framework\DataObject; use Magento\Framework\Message\MessageInterface; +use Magento\Framework\Escaper; /** * Unit tests for Inline customer edit @@ -78,6 +79,9 @@ class InlineEditTest extends \PHPUnit\Framework\TestCase /** @var array */ private $items; + /** @var \Magento\Framework\Escaper */ + private $escaper; + /** * Sets up mocks * @@ -86,7 +90,7 @@ class InlineEditTest extends \PHPUnit\Framework\TestCase protected function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - + $this->escaper = new Escaper(); $this->request = $this->getMockForAbstractClass( \Magento\Framework\App\RequestInterface::class, [], @@ -172,7 +176,8 @@ protected function setUp() 'addressDataFactory' => $this->addressDataFactory, 'addressRepository' => $this->addressRepository, 'logger' => $this->logger, - 'addressRegistry' => $this->addressRegistry + 'escaper' => $this->escaper, + 'addressRegistry' => $this->addressRegistry, ] ); $reflection = new \ReflectionClass(get_class($this->controller)); @@ -365,6 +370,7 @@ public function testExecuteLocalizedException() ->method('save') ->with($this->customerData) ->willThrowException($exception); + $this->messageManager->expects($this->once()) ->method('addError') ->with('[Customer ID: 12] Exception message'); From 75180b57877fe3efdbce95722444c8c16a59f317 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Tue, 11 Jun 2019 15:42:38 -0500 Subject: [PATCH 0097/1172] MC-17065: Email error message - Updated implementation --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 599415bc7bb7..7405269f8451 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -242,10 +242,10 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Exception $e) { $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); @@ -323,7 +323,7 @@ protected function getCustomer() */ protected function getErrorWithCustomerId($errorText) { - return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . $this->escaper->escapeHtml(__($errorText)); + return '[Customer ID: ' . $this->getCustomer()->getId() . '] ' . __($errorText); } /** From e3c99770eab38dc7da5041760b4156871ef4f92b Mon Sep 17 00:00:00 2001 From: Mark Berube <berube@adobe.com> Date: Wed, 12 Jun 2019 00:29:44 -0500 Subject: [PATCH 0098/1172] MC-15974: Fixing payment title. --- .../view/frontend/web/js/action/select-payment-method.js | 4 ++++ .../Ui/Component/Listing/Column/Method/Options.php | 9 +++++++++ .../Magento/Ui/view/base/web/js/grid/filters/filters.js | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js index 702df4752671..6bda10fceb7b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js @@ -12,6 +12,10 @@ define([ 'use strict'; return function (paymentMethod) { + paymentMethod.__disableTmpl = { + title: true + }; + quote.paymentMethod(paymentMethod); }; }); diff --git a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php index fbf80de519f9..71e0384c72f7 100644 --- a/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php +++ b/app/code/Magento/Payment/Ui/Component/Listing/Column/Method/Options.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Payment\Ui\Component\Listing\Column\Method; /** @@ -41,6 +42,14 @@ public function toOptionArray() if ($this->options === null) { $this->options = $this->paymentHelper->getPaymentMethodList(true, true); } + + array_walk( + $this->options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); + return $this->options; } } diff --git a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js index c608400a6f17..78016ee489a1 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js @@ -274,7 +274,8 @@ define([ filter = utils.extend({}, filters.base, filter); //Accepting labels as is. filter.__disableTmpl = { - label: 1 + label: 1, + options: 1 }; filter = utils.template(filter, { From 3c9064feec8d18cc17503a0f1f3726afb8ac45b9 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 12 Jun 2019 10:16:33 -0500 Subject: [PATCH 0099/1172] MC-15972: File uploads --- .../MediaStorage/Model/ResourceModel/File/Storage/File.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php index b847b4c13adf..8c9fe7b848fa 100644 --- a/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php +++ b/app/code/Magento/MediaStorage/Model/ResourceModel/File/Storage/File.php @@ -89,7 +89,7 @@ public function clear($dir = '') if ($directoryInstance->isDirectory($dir)) { $paths = $directoryInstance->readRecursively($dir); foreach ($paths as $path) { - if ($directoryInstance->isDirectory()) { + if ($directoryInstance->isDirectory($path)) { continue; } From fcc01ed7486aba33bc6380d3a3664cc30504682d Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 12 Jun 2019 10:44:43 -0500 Subject: [PATCH 0100/1172] MC-17065: Email error message - Resolved static test failures --- .../Controller/Adminhtml/Index/InlineEdit.php | 33 ++++++++++++------- .../Adminhtml/Index/InlineEditTest.php | 24 +++++++++----- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 7405269f8451..77c9cbad07a1 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -77,12 +77,12 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn /** * @param Action\Context $context - * @param \Magento\Framework\Escaper $escaper * @param CustomerRepositoryInterface $customerRepository * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory * @param \Magento\Customer\Model\Customer\Mapper $customerMapper * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param \Psr\Log\LoggerInterface $logger + * @param \Magento\Framework\Escaper $escaper * @param AddressRegistry|null $addressRegistry */ public function __construct( @@ -136,10 +136,14 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]); + return $resultJson->setData( + [ + 'messages' => [ + __('Please correct the data sent.') + ], + 'error' => true, + ] + ); } foreach (array_keys($postItems) as $customerId) { @@ -155,10 +159,12 @@ public function execute() $this->getEmailNotification()->credentialsChanged($this->getCustomer(), $currentCustomer->getEmail()); } - return $resultJson->setData([ - 'messages' => $this->getErrorMessages(), - 'error' => $this->isErrorExists() - ]); + return $resultJson->setData( + [ + 'messages' => $this->getErrorMessages(), + 'error' => $this->isErrorExists() + ] + ); } /** @@ -242,13 +248,16 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId($this->escaper->escapeHtml($e->getMessage()))); $this->logger->critical($e); } catch (\Exception $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); + $this->getMessageManager() + ->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); $this->logger->critical($e); } } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 7d2db1cc16b0..7fca556fc2cd 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -296,10 +296,14 @@ protected function prepareMocksForErrorMessagesProcessing() ->willReturn('Error text'); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => ['Error text'], - 'error' => true, - ]) + ->with( + [ + 'messages' => [ + 'Error text', + ], + 'error' => true, + ] + ) ->willReturnSelf(); } @@ -345,10 +349,14 @@ public function testExecuteWithoutItems() $this->resultJson ->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]) + ->with( + [ + 'messages' => [ + __('Please correct the data sent.'), + ], + 'error' => true, + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); } From bfaab3775c93767d8b58dca6c27481d89c0822a8 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 12 Jun 2019 11:17:27 -0500 Subject: [PATCH 0101/1172] MC-17447: Update wishlist controller - Updated wishlist controller - Updated integration test for wishlist controller --- app/code/Magento/Wishlist/Controller/Index/Add.php | 5 ++++- .../Magento/Wishlist/Controller/Index/PluginTest.php | 1 + .../testsuite/Magento/Wishlist/Controller/IndexTest.php | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php index 5cb60905aea4..ad7ff670a9c5 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Add.php +++ b/app/code/Magento/Wishlist/Controller/Index/Add.php @@ -7,15 +7,18 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\Exception\NotFoundException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Controller\ResultFactory; /** + * Wish list Add controller + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Add extends \Magento\Wishlist\Controller\AbstractIndex +class Add extends \Magento\Wishlist\Controller\AbstractIndex implements HttpPostActionInterface { /** * @var \Magento\Wishlist\Controller\WishlistProviderInterface diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php index 4c8937e1c6e9..5303c9f352b8 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/Index/PluginTest.php @@ -50,6 +50,7 @@ protected function tearDown() */ public function testAddActionProductWithInvalidCredentials(): void { + $this->getRequest()->setMethod('POST'); $this->getRequest()->setPostValue( [ 'login' => [ diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php index e020d31838f0..f43133c92fc3 100644 --- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php @@ -98,9 +98,12 @@ public function testAddActionProductNameXss() { /** @var \Magento\Framework\Data\Form\FormKey $formKey */ $formKey = $this->_objectManager->get(\Magento\Framework\Data\Form\FormKey::class); - $this->getRequest()->setPostValue([ - 'form_key' => $formKey->getFormKey(), - ]); + $this->getRequest()->setMethod('POST'); + $this->getRequest()->setPostValue( + [ + 'form_key' => $formKey->getFormKey(), + ] + ); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() From f290df20014d522fcc395cc78e707743cb944d6a Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 12 Jun 2019 12:43:10 -0500 Subject: [PATCH 0102/1172] MC-17447: Update wishlist controller - Resolved static test failure --- app/code/Magento/Wishlist/Controller/Index/Add.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php index ad7ff670a9c5..3ed152cb8412 100644 --- a/app/code/Magento/Wishlist/Controller/Index/Add.php +++ b/app/code/Magento/Wishlist/Controller/Index/Add.php @@ -141,6 +141,7 @@ public function execute() 'referer' => $referer ] ); + // phpcs:disable Magento2.Exceptions.ThrowCatch } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addErrorMessage( __('We can\'t add the item to Wish List right now: %1.', $e->getMessage()) From b573a7a447287403cab785c6656345f95302a8f0 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 12 Jun 2019 14:21:34 -0500 Subject: [PATCH 0103/1172] MC-17065: Email error message - Resolved backward incompatibility issue --- .../Customer/Controller/Adminhtml/Index/InlineEdit.php | 8 ++++---- .../Unit/Controller/Adminhtml/Index/InlineEditTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 77c9cbad07a1..eff812a65a3b 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -82,8 +82,8 @@ class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionIn * @param \Magento\Customer\Model\Customer\Mapper $customerMapper * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Escaper $escaper * @param AddressRegistry|null $addressRegistry + * @param \Magento\Framework\Escaper $escaper */ public function __construct( Action\Context $context, @@ -92,16 +92,16 @@ public function __construct( \Magento\Customer\Model\Customer\Mapper $customerMapper, \Magento\Framework\Api\DataObjectHelper $dataObjectHelper, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Escaper $escaper, - AddressRegistry $addressRegistry = null + AddressRegistry $addressRegistry = null, + \Magento\Framework\Escaper $escaper = null ) { $this->customerRepository = $customerRepository; $this->resultJsonFactory = $resultJsonFactory; $this->customerMapper = $customerMapper; $this->dataObjectHelper = $dataObjectHelper; $this->logger = $logger; - $this->escaper = $escaper; $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); + $this->escaper = $escaper ?: ObjectManager::getInstance()->get(\Magento\Framework\Escaper::class); parent::__construct($context); } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 7fca556fc2cd..8267624f7b00 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -176,8 +176,8 @@ protected function setUp() 'addressDataFactory' => $this->addressDataFactory, 'addressRepository' => $this->addressRepository, 'logger' => $this->logger, - 'escaper' => $this->escaper, 'addressRegistry' => $this->addressRegistry, + 'escaper' => $this->escaper, ] ); $reflection = new \ReflectionClass(get_class($this->controller)); From 592d49b5de426c89a819818fedf0b7f6f5f1e13f Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 12 Jun 2019 16:26:16 -0500 Subject: [PATCH 0104/1172] MC-16284: Visible message alert --- .../view/base/web/js/form/element/file-uploader.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 f28569caa005..f4b267758cf1 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 @@ -427,7 +427,8 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: '%s' + error.message, // %s to be used as placeholder for html injection + // %s to be used as placeholders for html injection + message: '%s' + error.filename + '%s ' + $t('was not uploaded.') + '%s' + error.message, /** * Adds constructed error notification to aggregatedErrorMessages @@ -435,12 +436,11 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - var errorMsgBodyHtml = '<strong>%s</strong> %s.<br>' - .replace('%s', error.filename) - .replace('%s', $t('was not uploaded')); - // html is escaped in message body for notification widget; prepend unescaped html here - constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); + constructedMessage = constructedMessage + .replace('%s', '<strong>') + .replace('%s', '</strong>') + .replace('%s', '<br>'); aggregatedErrorMessages.push(constructedMessage); } From 61b0be7ba66cfff980022246039767782f033b19 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 13 Jun 2019 15:07:31 -0500 Subject: [PATCH 0105/1172] MC-15972: File uploads --- .../Magento/Framework/File/Test/Unit/UploaderTest.php | 6 +++++- lib/internal/Magento/Framework/File/Uploader.php | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php index ac19f4dc36ed..d0aa65818445 100644 --- a/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php +++ b/lib/internal/Magento/Framework/File/Test/Unit/UploaderTest.php @@ -55,7 +55,11 @@ public function getCorrectFileNameProvider() 'file.jpg' ], [ - 'a.' . str_repeat('b', 100), + 'a.' . str_repeat('b', 88), + 'a.' . str_repeat('b', 88) + ], + [ + 'a.' . str_repeat('b', 89), true ] ]; diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index 5396862195f8..af19c619ae68 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -382,8 +382,8 @@ public static function getCorrectFileName($fileName) $fileInfo['extension'] = $fileInfo['extension'] ?? ''; // account for excessively long filenames that cannot be stored completely in database - if (strlen($fileInfo['basename']) > 100) { - throw new \InvalidArgumentException('Filename is too long; must be 100 characters or less'); + if (strlen($fileInfo['basename']) > 90) { + throw new \InvalidArgumentException('Filename is too long; must be 90 characters or less'); } if (preg_match('/^_+$/', $fileInfo['filename'])) { From 6786439ab125a564c2a8ba50b0f8387c26f7c486 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 14 Jun 2019 09:45:11 +0300 Subject: [PATCH 0106/1172] MC-16042: Zip archive validation --- lib/internal/Magento/Framework/Archive/Zip.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index c41f8b28ce34..925adda48504 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,6 +54,7 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); + $filename = $this->filterExcludedFiles($filename); if ($filename) { $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); @@ -82,4 +83,19 @@ private function filterRelativePaths(string $path): string return $path; } + + /** + * Filter excluded files. + * + * @param string $file + * @return string + */ + private function filterExcludedFiles(string $file): string + { + if ($file && preg_match('/^\.htaccess$/', $file)) { + $file = ''; + } + + return $file; + } } From 102cc0fa543b0fcba9faa1fc4c610bd28ad53775 Mon Sep 17 00:00:00 2001 From: Vital_Pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Thu, 13 Jun 2019 14:47:01 +0300 Subject: [PATCH 0107/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Implemented validation URL key during category creation --- .../CategoryUrlPathAutogeneratorObserver.php | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index 95ddceed6ec8..346804db8a18 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -48,22 +48,31 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface */ private $categoryRepository; + /** + * @var \Magento\Backend\App\Area\FrontNameResolver + */ + private $frontNameResolver; + /** * @param CategoryUrlPathGenerator $categoryUrlPathGenerator * @param ChildrenCategoriesProvider $childrenCategoriesProvider * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService * @param CategoryRepositoryInterface $categoryRepository + * @param \Magento\Backend\App\Area\FrontNameResolver $frontNameResolver */ public function __construct( CategoryUrlPathGenerator $categoryUrlPathGenerator, ChildrenCategoriesProvider $childrenCategoriesProvider, StoreViewService $storeViewService, - CategoryRepositoryInterface $categoryRepository + CategoryRepositoryInterface $categoryRepository, + \Magento\Backend\App\Area\FrontNameResolver $frontNameResolver = null ) { $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; $this->childrenCategoriesProvider = $childrenCategoriesProvider; $this->storeViewService = $storeViewService; $this->categoryRepository = $categoryRepository; + $this->frontNameResolver = $frontNameResolver ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Backend\App\Area\FrontNameResolver::class); } /** @@ -102,12 +111,12 @@ private function updateUrlKey($category, $urlKey) throw new \Magento\Framework\Exception\LocalizedException(__('Invalid URL key')); } - if (in_array($urlKey, $this->invalidValues)) { + if (in_array($urlKey, $this->getInvalidValues())) { throw new \Magento\Framework\Exception\LocalizedException( __( 'URL key "%1" conflicts with reserved endpoint names: %2. Try another url key.', $urlKey, - implode(', ', $this->invalidValues) + implode(', ', $this->getInvalidValues()) ) ); } @@ -122,6 +131,16 @@ private function updateUrlKey($category, $urlKey) } } + /** + * Get reserved endpoint names. + * + * @return array + */ + private function getInvalidValues() + { + return array_unique(array_merge($this->invalidValues, [$this->frontNameResolver->getFrontName()])); + } + /** * Update url path for children category. * From 6c7c45103cc2aeb4f6c51cb5b266c85cb024d80c Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 14 Jun 2019 15:56:52 +0300 Subject: [PATCH 0108/1172] MC-17303: Customer login fix --- app/code/Magento/Customer/Controller/Account/LoginPost.php | 2 +- app/code/Magento/Customer/Controller/Ajax/Login.php | 2 +- app/code/Magento/Customer/Model/Plugin/CustomerNotification.php | 2 +- app/code/Magento/Customer/Model/Session.php | 2 +- app/code/Magento/Rss/Controller/Feed.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 04051fbbf366..9afaab412164 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -182,8 +182,8 @@ public function execute() if (!empty($login['username']) && !empty($login['password'])) { try { $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']); - $this->session->setCustomerDataAsLoggedIn($customer); $this->session->regenerateId(); + $this->session->setCustomerDataAsLoggedIn($customer); if ($this->getCookieManager()->getCookie('mage-cache-sessid')) { $metadata = $this->getCookieMetadataFactory()->createCookieMetadata(); $metadata->setPath('/'); diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index 5049c83e60f3..d5425bfc2733 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -190,8 +190,8 @@ public function execute() $credentials['username'], $credentials['password'] ); - $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); + $this->customerSession->setCustomerDataAsLoggedIn($customer); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); if ($this->cookieManager->getCookie('mage-cache-sessid')) { $metadata = $this->cookieMetadataFactory->createCookieMetadata(); diff --git a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php index 517aef5690ee..9b655fc84352 100644 --- a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php +++ b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php @@ -82,10 +82,10 @@ public function beforeDispatch(AbstractAction $subject, RequestInterface $reques ) ) { try { + $this->session->regenerateId(); $customer = $this->customerRepository->getById($customerId); $this->session->setCustomerData($customer); $this->session->setCustomerGroupId($customer->getGroupId()); - $this->session->regenerateId(); $this->notificationStorage->remove(NotificationStorage::UPDATE_CUSTOMER_SESSION, $customer->getId()); } catch (NoSuchEntityException $e) { $this->logger->error($e); diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index 5900fed218ed..c37a28d04fc5 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -412,10 +412,10 @@ public function checkCustomerId($customerId) */ public function setCustomerAsLoggedIn($customer) { + $this->regenerateId(); $this->setCustomer($customer); $this->_eventManager->dispatch('customer_login', ['customer' => $customer]); $this->_eventManager->dispatch('customer_data_object_login', ['customer' => $this->getCustomerDataObject()]); - $this->regenerateId(); return $this; } diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index 8fbe7addb560..634540dde5d9 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -84,8 +84,8 @@ protected function auth() list($login, $password) = $this->httpAuthentication->getCredentials(); try { $customer = $this->customerAccountManagement->authenticate($login, $password); - $this->customerSession->setCustomerDataAsLoggedIn($customer); $this->customerSession->regenerateId(); + $this->customerSession->setCustomerDataAsLoggedIn($customer); } catch (\Exception $e) { $this->logger->critical($e); } From 5e4f83b39c41d32416886a7a794a8c2315a5810c Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Fri, 7 Jun 2019 13:18:57 -0500 Subject: [PATCH 0109/1172] MC-16724: Prevent errors from incorrect import data --- .../Model/Import/Product.php | 3 + .../Import/Product/Validator/LayoutUpdate.php | 85 +++++++++++++++ .../Validator/LayoutUpdatePermissions.php | 81 ++++++++++++++ .../Validator/LayoutUpdatePermissionsTest.php | 101 ++++++++++++++++++ .../Product/Validator/LayoutUpdateTest.php | 97 +++++++++++++++++ .../Magento/CatalogImportExport/composer.json | 3 +- .../Magento/CatalogImportExport/etc/di.xml | 7 ++ .../LayoutUpdate/PermissionsValidatorTest.php | 101 ++++++++++++++++++ app/etc/di.xml | 10 ++ .../Model/Import/ProductTest.php | 21 ++++ .../Unit/ValidationState/ConfigurableTest.php | 30 ++++++ .../Config/ValidationState/Configurable.php | 38 +++++++ 12 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php create mode 100644 app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php create mode 100644 app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php create mode 100644 app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php create mode 100644 app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php create mode 100644 lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php create mode 100644 lib/internal/Magento/Framework/Config/ValidationState/Configurable.php diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 0b7fbaf86826..036bd5de0fb2 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -301,6 +301,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values', 'invalidNewToDateValue' => 'Make sure new_to_date is later than or the same as new_from_date', + 'invalidLayoutUpdate' => 'Invalid layout update', + 'insufficientPermissions' => 'You do not have permissions to update "%s"', ]; //@codingStandardsIgnoreEnd @@ -1508,6 +1510,7 @@ public function getImagesFromRow(array $rowData) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.UnusedLocalVariable) * @throws LocalizedException + * phpcs:disable Generic.Metrics.NestingLevel.TooHigh */ protected function _saveProducts() { diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php new file mode 100644 index 000000000000..99919628518c --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdate.php @@ -0,0 +1,85 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogImportExport\Model\Import\Product\Validator; + +use Magento\Framework\Config\ValidationStateInterface; +use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; + +/** + * Validates layout and custom layout update fields + */ +class LayoutUpdate extends AbstractImportValidator +{ + private const ERROR_INVALID_LAYOUT_UPDATE = 'invalidLayoutUpdate'; + + /** + * @var ValidatorFactory + */ + private $layoutValidatorFactory; + + /** + * @var ValidationStateInterface + */ + private $validationState; + + /** + * @param ValidatorFactory $layoutValidatorFactory + * @param ValidationStateInterface $validationState + */ + public function __construct( + ValidatorFactory $layoutValidatorFactory, + ValidationStateInterface $validationState + ) { + $this->layoutValidatorFactory = $layoutValidatorFactory; + $this->validationState = $validationState; + } + + /** + * @inheritdoc + */ + public function isValid($value): bool + { + if (!empty($value['custom_layout_update']) && !$this->validateXml($value['custom_layout_update'])) { + $this->_addMessages( + [ + $this->context->retrieveMessageTemplate(self::ERROR_INVALID_LAYOUT_UPDATE) + ] + ); + return false; + } + + return true; + } + + /** + * Validate XML layout update + * + * @param string $xml + * @return bool + */ + private function validateXml(string $xml): bool + { + /** @var $layoutXmlValidator \Magento\Framework\View\Model\Layout\Update\Validator */ + $layoutXmlValidator = $this->layoutValidatorFactory->create( + [ + 'validationState' => $this->validationState, + ] + ); + + try { + if (!$layoutXmlValidator->isValid($xml)) { + return false; + } + } catch (\Exception $e) { + return false; + } + + return true; + } +} diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php new file mode 100644 index 000000000000..d1df04b8e95c --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogImportExport\Model\Import\Product\Validator; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Framework\AuthorizationInterface; +use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator; + +/** + * Validator to assert that the current user is allowed to make design updates if a layout is provided in the import + */ +class LayoutUpdatePermissions extends AbstractImportValidator +{ + private const ERROR_INSUFFICIENT_PERMISSIONS = 'insufficientPermissions'; + + /** + * @var UserContextInterface + */ + private $userContext; + + /** + * @var AuthorizationInterface + */ + private $authorization; + + /** + * @var array + */ + private $allowedUserTypes = [ + UserContextInterface::USER_TYPE_ADMIN, + UserContextInterface::USER_TYPE_INTEGRATION + ]; + + /** + * @param UserContextInterface $userContext + * @param AuthorizationInterface $authorization + */ + public function __construct( + UserContextInterface $userContext, + AuthorizationInterface $authorization + ) { + $this->userContext = $userContext; + $this->authorization = $authorization; + } + + /** + * Validate that the current user is allowed to make design updates + * + * @param array $data + * @return boolean + */ + public function isValid($data): bool + { + if (empty($data['custom_layout_update'])) { + return true; + } + + $userType = $this->userContext->getUserType(); + $isValid = in_array($userType, $this->allowedUserTypes) + && $this->authorization->isAllowed('Magento_Catalog::edit_product_design'); + + if (!$isValid) { + $this->_addMessages( + [ + sprintf( + $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), + 'custom_layout_update' + ) + ] + ); + } + + return $isValid; + } +} diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php new file mode 100644 index 000000000000..2f883b5f4146 --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Validator; + +use Magento\CatalogImportExport\Model\Import\Product; +use Magento\Authorization\Model\UserContextInterface; +use Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdatePermissions; +use Magento\Framework\AuthorizationInterface; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Test validation for layout update permissions + */ +class LayoutUpdatePermissionsTest extends TestCase +{ + /** + * @var LayoutUpdatePermissions|MockObject + */ + private $validator; + + /** + * @var UserContextInterface|MockObject + */ + private $userContext; + + /** + * @var AuthorizationInterface|MockObject + */ + private $authorization; + + /** + * @var Product + */ + private $context; + + protected function setUp() + { + $this->userContext = $this->createMock(UserContextInterface::class); + $this->authorization = $this->createMock(AuthorizationInterface::class); + $this->context = $this->createMock(Product::class); + $this->context + ->method('retrieveMessageTemplate') + ->with('insufficientPermissions') + ->willReturn('oh no "%s"'); + $this->validator = new LayoutUpdatePermissions( + $this->userContext, + $this->authorization + ); + $this->validator->init($this->context); + } + + /** + * @param $value + * @param $userContext + * @param $isAllowed + * @param $isValid + * @dataProvider configurationsProvider + */ + public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) + { + $this->userContext + ->method('getUserType') + ->willReturn($userContext); + + $this->authorization + ->method('isAllowed') + ->with('Magento_Catalog::edit_product_design') + ->willReturn($isAllowed); + + $result = $this->validator->isValid(['custom_layout_update' => $value]); + $messages = $this->validator->getMessages(); + + self::assertSame($isValid, $result); + + if ($isValid) { + self::assertSame([], $messages); + } else { + self::assertSame(['oh no "custom_layout_update"'], $messages); + } + } + + public function configurationsProvider() + { + return [ + ['', null, null, true], + [null, null, null, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], + ['foo', 'something', null, false], + ]; + } +} diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php new file mode 100644 index 000000000000..d1e8b879f6a0 --- /dev/null +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdateTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Validator; + +use Magento\CatalogImportExport\Model\Import\Product; +use Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdate; +use Magento\Framework\Config\ValidationStateInterface; +use Magento\Framework\View\Model\Layout\Update\Validator; +use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Test validation for layout update + */ +class LayoutUpdateTest extends TestCase +{ + /** + * @var LayoutUpdate|MockObject + */ + private $validator; + + /** + * @var Validator|MockObject + */ + private $layoutValidator; + + protected function setUp() + { + $validatorFactory = $this->createMock(ValidatorFactory::class); + $validationState = $this->createMock(ValidationStateInterface::class); + $this->layoutValidator = $this->createMock(Validator::class); + $validatorFactory->method('create') + ->with(['validationState' => $validationState]) + ->willReturn($this->layoutValidator); + + $this->validator = new LayoutUpdate( + $validatorFactory, + $validationState + ); + } + + public function testValidationIsSkippedWithDataNotPresent() + { + $this->layoutValidator + ->expects($this->never()) + ->method('isValid'); + + $result = $this->validator->isValid([]); + self::assertTrue($result); + } + + public function testValidationFailsProperly() + { + $this->layoutValidator + ->method('isValid') + ->with('foo') + ->willReturn(false); + + $contextMock = $this->createMock(Product::class); + $contextMock + ->method('retrieveMessageTemplate') + ->with('invalidLayoutUpdate') + ->willReturn('oh no'); + $this->validator->init($contextMock); + + $result = $this->validator->isValid(['custom_layout_update' => 'foo']); + $messages = $this->validator->getMessages(); + self::assertFalse($result); + self::assertSame(['oh no'], $messages); + } + + public function testInvalidDataException() + { + $this->layoutValidator + ->method('isValid') + ->willThrowException(new \Exception('foo')); + + $contextMock = $this->createMock(Product::class); + $contextMock + ->method('retrieveMessageTemplate') + ->with('invalidLayoutUpdate') + ->willReturn('oh no'); + $this->validator->init($contextMock); + + $result = $this->validator->isValid(['custom_layout_update' => 'foo']); + $messages = $this->validator->getMessages(); + self::assertFalse($result); + self::assertSame(['oh no'], $messages); + } +} diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json index 56307a01e1cb..a15c1d5e7b22 100644 --- a/app/code/Magento/CatalogImportExport/composer.json +++ b/app/code/Magento/CatalogImportExport/composer.json @@ -16,7 +16,8 @@ "magento/module-import-export": "*", "magento/module-media-storage": "*", "magento/module-store": "*", - "magento/module-tax": "*" + "magento/module-tax": "*", + "magento/module-authorization": "*" }, "type": "magento2-module", "license": [ diff --git a/app/code/Magento/CatalogImportExport/etc/di.xml b/app/code/Magento/CatalogImportExport/etc/di.xml index 6906272b11d6..4e2fe390e0b1 100644 --- a/app/code/Magento/CatalogImportExport/etc/di.xml +++ b/app/code/Magento/CatalogImportExport/etc/di.xml @@ -25,7 +25,14 @@ <item name="website" xsi:type="object">Magento\CatalogImportExport\Model\Import\Product\Validator\Website</item> <item name="weight" xsi:type="object">Magento\CatalogImportExport\Model\Import\Product\Validator\Weight</item> <item name="quantity" xsi:type="object">Magento\CatalogImportExport\Model\Import\Product\Validator\Quantity</item> + <item name="layout_update" xsi:type="object">Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdate</item> + <item name="layout_update_permissions" xsi:type="object">Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdatePermissions</item> </argument> </arguments> </type> + <type name="Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdate"> + <arguments> + <argument name="validationState" xsi:type="object">Magento\Framework\Config\ValidationState\Required</argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php new file mode 100644 index 000000000000..1bb2037462f3 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php @@ -0,0 +1,101 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Test\Unit\Model\CatalogImport\LayoutUpdate; + +use Magento\CatalogImportExport\Model\Import\Product; +use Magento\Authorization\Model\UserContextInterface; +use Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdatePermissions; +use Magento\Framework\AuthorizationInterface; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject as MockObject; + +/** + * Test validation for layout update + */ +class PermissionsValidatorTest extends TestCase +{ + /** + * @var PermissionsValidator|MockObject + */ + private $validator; + + /** + * @var UserContextInterface|MockObject + */ + private $userContext; + + /** + * @var AuthorizationInterface|MockObject + */ + private $authorization; + + /** + * @var Product + */ + private $context; + + protected function setUp() + { + $this->userContext = $this->createMock(UserContextInterface::class); + $this->authorization = $this->createMock(AuthorizationInterface::class); + $this->context = $this->createMock(Product::class); + $this->context + ->method('retrieveMessageTemplate') + ->with('insufficientPermissions') + ->willReturn('oh no "%s"'); + $this->validator = new LayoutUpdatePermissions( + $this->userContext, + $this->authorization + ); + $this->validator->init($this->context); + } + + /** + * @param $value + * @param $userContext + * @param $isAllowed + * @param $isValid + * @dataProvider configurationsProvider + */ + public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) + { + $this->userContext + ->method('getUserType') + ->willReturn($userContext); + + $this->authorization + ->method('isAllowed') + ->with('Magento_Catalog::edit_product_design') + ->willReturn($isAllowed); + + $result = $this->validator->isValid(['custom_layout_update' => $value]); + $messages = $this->validator->getMessages(); + + self::assertSame($isValid, $result); + + if ($isValid) { + self::assertSame([], $messages); + } else { + self::assertSame(['oh no "custom_layout_update"'], $messages); + } + } + + public function configurationsProvider() + { + return [ + ['', null, null, true], + [null, null, null, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], + ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], + ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], + ['foo', 'something', null, false], + ]; + } +} diff --git a/app/etc/di.xml b/app/etc/di.xml index cccae25b467e..5c10216ba757 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -1500,6 +1500,16 @@ </argument> </arguments> </type> + <virtualType name="Magento\Framework\Config\ValidationState\Required" type="Magento\Framework\Config\ValidationState\Configurable"> + <arguments> + <argument name="required" xsi:type="boolean">true</argument> + </arguments> + </virtualType> + <virtualType name="Magento\Framework\Config\ValidationState\NotRequired" type="Magento\Framework\Config\ValidationState\Configurable"> + <arguments> + <argument name="required" xsi:type="boolean">false</argument> + </arguments> + </virtualType> <virtualType name="Magento\Framework\Setup\Declaration\Schema\Config\SchemaLocator" type="Magento\Framework\Config\SchemaLocator"> <arguments> <argument name="realPath" xsi:type="string">urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd</argument> diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 41cd85e6ec2f..4863aadfac0c 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -95,6 +95,7 @@ protected function tearDown() try { $product = $productRepository->get($productSku, false, null, true); $productRepository->delete($product); + // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (NoSuchEntityException $e) { // nothing to delete } @@ -2335,6 +2336,8 @@ public function testImportImageForNonDefaultStore() */ public function testProductsWithMultipleStoresWhenMediaIsDisabled(): void { + $this->loginAdminUserWithUsername(\Magento\TestFramework\Bootstrap::ADMIN_NAME); + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); $source = $this->objectManager->create( @@ -2417,4 +2420,22 @@ private function importFile(string $fileName): void $this->_model->importData(); } + + /** + * Set the current admin session user based on a username + * + * @param string $username + */ + private function loginAdminUserWithUsername(string $username) + { + $user = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\User\Model\User::class + )->loadByUsername($username); + + /** @var $session \Magento\Backend\Model\Auth\Session */ + $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Backend\Model\Auth\Session::class + ); + $session->setUser($user); + } } diff --git a/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php b/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php new file mode 100644 index 000000000000..cbd9e4363248 --- /dev/null +++ b/lib/internal/Magento/Framework/Config/Test/Unit/ValidationState/ConfigurableTest.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\Config\Test\Unit\ValidationState; + +use Magento\Framework\Config\ValidationState\Configurable; +use PHPUnit\Framework\TestCase; + +/** + * Tests for configurable validation state + */ +class ConfigurableTest extends TestCase +{ + public function testTrue() + { + $state = new Configurable(true); + self::assertTrue($state->isValidationRequired()); + } + + public function testFalse() + { + $state = new Configurable(false); + self::assertFalse($state->isValidationRequired()); + } +} diff --git a/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php b/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php new file mode 100644 index 000000000000..c996b2a3e135 --- /dev/null +++ b/lib/internal/Magento/Framework/Config/ValidationState/Configurable.php @@ -0,0 +1,38 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Framework\Config\ValidationState; + +use Magento\Framework\Config\ValidationStateInterface; + +/** + * A configurable validation state + */ +class Configurable implements ValidationStateInterface +{ + /** + * @var bool + */ + private $required; + + /** + * @param bool $required + */ + public function __construct(bool $required) + { + $this->required = $required; + } + + /** + * @inheritdoc + */ + public function isValidationRequired(): bool + { + return $this->required; + } +} From 13e06bd99ac2056a623a13621357e9a49afd993a Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 14 Jun 2019 14:30:58 -0500 Subject: [PATCH 0110/1172] MC-16118: Email template name config update - Updated email option array value --- .../Magento/Config/Model/Config/Source/Email/Template.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Config/Model/Config/Source/Email/Template.php b/app/code/Magento/Config/Model/Config/Source/Email/Template.php index 04222733418d..c6b28cd7c46a 100644 --- a/app/code/Magento/Config/Model/Config/Source/Email/Template.php +++ b/app/code/Magento/Config/Model/Config/Source/Email/Template.php @@ -62,6 +62,12 @@ public function toOptionArray() $templateLabel = $this->_emailConfig->getTemplateLabel($templateId); $templateLabel = __('%1 (Default)', $templateLabel); array_unshift($options, ['value' => $templateId, 'label' => $templateLabel]); + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); return $options; } } From 939eaf4e1e254376bfd2e398d2c4f6ce288bfa5b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 14 Jun 2019 14:38:27 -0500 Subject: [PATCH 0111/1172] MC-16118: Email template name config update - Updated email template unit test --- .../Model/Config/Source/Email/TemplateTest.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php index b29ad244e7a8..a5878a04e3e6 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php @@ -76,9 +76,21 @@ public function testToOptionArray() $this->returnValue('Template New') ); $expectedResult = [ - ['value' => 'template_new', 'label' => 'Template New (Default)'], - ['value' => 'template_one', 'label' => 'Template One'], - ['value' => 'template_two', 'label' => 'Template Two'], + [ + 'value' => 'template_new', + 'label' => 'Template New (Default)', + '__disableTmpl' => true + ], + [ + 'value' => 'template_one', + 'label' => 'Template One', + '__disableTmpl' => true + ], + [ + 'value' => 'template_two', + 'label' => 'Template Two', + '__disableTmpl' => true + ], ]; $this->_model->setPath('template/new'); $this->assertEquals($expectedResult, $this->_model->toOptionArray()); From 327cd700be97b505fe9bd61052a3da58cd0d46e5 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Fri, 14 Jun 2019 16:15:44 -0500 Subject: [PATCH 0112/1172] MC-16118: Email template name config update - Resolved static test failures --- app/code/Magento/Config/Model/Config/Source/Email/Template.php | 2 ++ .../Test/Unit/Model/Config/Source/Email/TemplateTest.php | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/code/Magento/Config/Model/Config/Source/Email/Template.php b/app/code/Magento/Config/Model/Config/Source/Email/Template.php index c6b28cd7c46a..e4f1ae65bcac 100644 --- a/app/code/Magento/Config/Model/Config/Source/Email/Template.php +++ b/app/code/Magento/Config/Model/Config/Source/Email/Template.php @@ -6,6 +6,8 @@ namespace Magento\Config\Model\Config\Source\Email; /** + * Source for template + * * @api * @since 100.0.2 */ diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php index a5878a04e3e6..9fabe6fef0c8 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Source/Email/TemplateTest.php @@ -6,6 +6,9 @@ namespace Magento\Config\Test\Unit\Model\Config\Source\Email; +/** + * Test class for Template. + */ class TemplateTest extends \PHPUnit\Framework\TestCase { /** From 03d1ccc5526d6a8639e75c9748aeda2b01896162 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 17 Jun 2019 08:27:32 -0500 Subject: [PATCH 0113/1172] MC-16284: Visible message alert --- .../base/web/js/form/element/file-uploader.js | 9 +------- .../Image/Adapter/AbstractAdapter.php | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 11 deletions(-) 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 f4b267758cf1..a53481ad1386 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 @@ -427,8 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - // %s to be used as placeholders for html injection - message: '%s' + error.filename + '%s ' + $t('was not uploaded.') + '%s' + error.message, + message: error.message, /** * Adds constructed error notification to aggregatedErrorMessages @@ -436,12 +435,6 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - // html is escaped in message body for notification widget; prepend unescaped html here - constructedMessage = constructedMessage - .replace('%s', '<strong>') - .replace('%s', '</strong>') - .replace('%s', '<br>'); - aggregatedErrorMessages.push(constructedMessage); } }); diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index 6042e4eee491..276a8a719d6a 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -3,11 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Framework\Image\Adapter; use Magento\Framework\App\Filesystem\DirectoryList; /** + * Class AbstractAdapter + * * @file Abstract.php * @author Magento Core Team <core@magentocommerce.com> * @SuppressWarnings(PHPMD.TooManyFields) @@ -169,7 +173,8 @@ abstract public function open($fileName); /** * Save image to specific path. - * If some folders of path does not exist they will be created + * + * If some folders of the path do not exist they will be created. * * @param null|string $destination * @param null|string $newName @@ -620,6 +625,7 @@ protected function _checkDimensions($frameWidth, $frameHeight) $frameHeight !== null && $frameHeight <= 0 || empty($frameWidth) && empty($frameHeight) ) { + //phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception('Invalid image dimensions.'); } } @@ -687,6 +693,7 @@ protected function _prepareDestination($destination = null, $newName = null) $this->directoryWrite->create($this->directoryWrite->getRelativePath($destination)); } catch (\Magento\Framework\Exception\FileSystemException $e) { $this->logger->critical($e); + //phpcs:ignore Magento2.Exceptions.DirectThrow throw new \Exception('Unable to write file into directory ' . $destination . '. Access forbidden.'); } } @@ -714,11 +721,19 @@ protected function _canProcess() public function validateUploadFile($filePath) { if (!file_exists($filePath)) { - throw new \InvalidArgumentException("File '{$filePath}' does not exists."); + throw new \InvalidArgumentException('Upload file does not exist.'); + } + + try { + $imageSize = getimagesize($filePath); + } catch (\Exception $e) { + $imageSize = false; } - if (!getimagesize($filePath)) { + + if (!$imageSize) { throw new \InvalidArgumentException('Disallowed file type.'); } + $this->checkDependencies(); $this->open($filePath); From 9dd3e4b1c6fee2bf2796f7e9778275f0ac398c85 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 17 Jun 2019 08:43:02 -0500 Subject: [PATCH 0114/1172] MC-16284: Visible message alert --- .../Ui/view/base/web/js/form/element/file-uploader.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 a53481ad1386..68c9e7308bc0 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 @@ -427,7 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: error.message, + message: '%s' + error.message, // %s to be used as placeholder for html injection, /** * Adds constructed error notification to aggregatedErrorMessages @@ -435,6 +435,11 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { + var errorMsgBodyHtml = '<strong>File was not uploaded.</strong><br>'; + + // html is escaped in message body for notification widget; prepend unescaped html here + constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); + aggregatedErrorMessages.push(constructedMessage); } }); From 4cea9401c486671e5428e6da835398427faec330 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 17 Jun 2019 08:44:36 -0500 Subject: [PATCH 0115/1172] MC-16284: Visible message alert --- .../Magento/Ui/view/base/web/js/form/element/file-uploader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 68c9e7308bc0..2db7aef0acf6 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 @@ -427,7 +427,7 @@ define([ _.each(this.aggregatedErrors, function (error) { notification().add({ error: true, - message: '%s' + error.message, // %s to be used as placeholder for html injection, + message: '%s' + error.message, // %s to be used as placeholder for html injection /** * Adds constructed error notification to aggregatedErrorMessages From 48dba482ef080aa937875427c2127f6b6ffbcbe7 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 17 Jun 2019 11:44:56 -0500 Subject: [PATCH 0116/1172] MC-16284: Visible message alert --- .../Ui/view/base/web/js/form/element/file-uploader.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 2db7aef0acf6..73bef6291064 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 @@ -435,7 +435,10 @@ define([ * @param {String} constructedMessage */ insertMethod: function (constructedMessage) { - var errorMsgBodyHtml = '<strong>File was not uploaded.</strong><br>'; + var escapedFileName = $('<div>').text(error.filename).html(), + errorMsgBodyHtml = '<strong>%s</strong> %s.<br>' + .replace('%s', escapedFileName) + .replace('%s', $t('was not uploaded')); // html is escaped in message body for notification widget; prepend unescaped html here constructedMessage = constructedMessage.replace('%s', errorMsgBodyHtml); From 5439b01c11464fab72122cb8b549b3fc844b1713 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 17 Jun 2019 12:41:02 -0500 Subject: [PATCH 0117/1172] MC-15979: New Customer Attribute Options Issue - Resolved incorrect attribute meta data resolver --- .../Magento/Customer/Model/AttributeMetadataResolver.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index a41d52cdc45a..acc54424c3ac 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -129,7 +129,14 @@ public function getAttributesMeta( $meta['arguments']['data']['config']['options'] = $this->countryWithWebsiteSource ->getAllOptions(); } else { - $meta['arguments']['data']['config']['options'] = $attribute->getSource()->getAllOptions(); + $options = $attribute->getSource()->getAllOptions(); + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = ['label' => true]; + } + ); + $meta['arguments']['data']['config']['options'] = $options; } } From ffc30aa55a16272a4c698c466a199ceb5e01db40 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 4 Jun 2019 21:21:40 -0500 Subject: [PATCH 0118/1172] MC-16041: Prevent errors from incorrect configuration --- .../Controller/Adminhtml/Page/InlineEdit.php | 27 ++-- .../Adminhtml/Page/PostDataProcessor.php | 1 + .../Cms/Controller/Adminhtml/Page/Save.php | 4 - .../PageRepository/ValidationComposite.php | 92 +++++++++++++ .../Validator/LayoutUpdateValidator.php | 128 ++++++++++++++++++ .../PageRepository/ValidatorInterface.php | 27 ++++ app/code/Magento/Cms/etc/di.xml | 11 +- 7 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php create mode 100644 app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php create mode 100644 app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php index 8774d7e69adf..77f648e5f12c 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php @@ -7,6 +7,7 @@ use Magento\Backend\App\Action\Context; use Magento\Cms\Api\PageRepositoryInterface as PageRepository; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\Result\JsonFactory; use Magento\Cms\Api\Data\PageInterface; @@ -15,7 +16,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class InlineEdit extends \Magento\Backend\App\Action +class InlineEdit extends \Magento\Backend\App\Action implements HttpPostActionInterface { /** * Authorization level of a basic admin session @@ -56,6 +57,8 @@ public function __construct( } /** + * Process the request + * * @return \Magento\Framework\Controller\ResultInterface * @throws \Magento\Framework\Exception\LocalizedException */ @@ -68,10 +71,12 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]); + return $resultJson->setData( + [ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ] + ); } foreach (array_keys($postItems) as $pageId) { @@ -79,7 +84,6 @@ public function execute() $page = $this->pageRepository->getById($pageId); try { $pageData = $this->filterPost($postItems[$pageId]); - $this->validatePost($pageData, $page, $error, $messages); $extendedPageData = $page->getData(); $this->setCmsPageData($page, $extendedPageData, $pageData); $this->pageRepository->save($page); @@ -98,10 +102,12 @@ public function execute() } } - return $resultJson->setData([ - 'messages' => $messages, - 'error' => $error - ]); + return $resultJson->setData( + [ + 'messages' => $messages, + 'error' => $error + ] + ); } /** @@ -128,6 +134,7 @@ protected function filterPost($postData = []) * @param bool $error * @param array $messages * @return void + * @deprecated */ protected function validatePost(array $pageData, \Magento\Cms\Model\Page $page, &$error, array &$messages) { diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php index 9b8933c8dba2..f934cac6da11 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php @@ -80,6 +80,7 @@ public function filter($data) * * @param array $data * @return bool Return FALSE if some item is invalid + * @deprecated */ public function validate($data) { diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php index 37cb45753174..569f6b256163 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php @@ -107,10 +107,6 @@ public function execute() ['page' => $model, 'request' => $this->getRequest()] ); - if (!$this->dataProcessor->validate($data)) { - return $resultRedirect->setPath('*/*/edit', ['page_id' => $model->getId(), '_current' => true]); - } - try { $this->pageRepository->save($model); $this->messageManager->addSuccessMessage(__('You saved the page.')); diff --git a/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php b/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php new file mode 100644 index 000000000000..9fd94d4c11e1 --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/ValidationComposite.php @@ -0,0 +1,92 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Model\PageRepository; + +use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Api\PageRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaInterface; + +/** + * Validates and saves a page + */ +class ValidationComposite implements PageRepositoryInterface +{ + /** + * @var PageRepositoryInterface + */ + private $repository; + + /** + * @var array + */ + private $validators; + + /** + * @param PageRepositoryInterface $repository + * @param ValidatorInterface[] $validators + */ + public function __construct( + PageRepositoryInterface $repository, + array $validators = [] + ) { + foreach ($validators as $validator) { + if (!$validator instanceof ValidatorInterface) { + throw new \InvalidArgumentException( + sprintf('Supplied validator does not implement %s', ValidatorInterface::class) + ); + } + } + $this->repository = $repository; + $this->validators = $validators; + } + + /** + * @inheritdoc + */ + public function save(PageInterface $page) + { + foreach ($this->validators as $validator) { + $validator->validate($page); + } + + return $this->repository->save($page); + } + + /** + * @inheritdoc + */ + public function getById($pageId) + { + return $this->repository->getById($pageId); + } + + /** + * @inheritdoc + */ + public function getList(SearchCriteriaInterface $searchCriteria) + { + return $this->repository->getList($searchCriteria); + } + + /** + * @inheritdoc + */ + public function delete(PageInterface $page) + { + return $this->repository->delete($page); + } + + /** + * @inheritdoc + */ + public function deleteById($pageId) + { + return $this->repository->deleteById($pageId); + } +} diff --git a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php new file mode 100644 index 000000000000..8cfb6f1433b6 --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php @@ -0,0 +1,128 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Model\PageRepository\Validator; + +use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Model\PageRepository\ValidatorInterface; +use Magento\Framework\Config\Dom\ValidationException; +use Magento\Framework\Config\Dom\ValidationSchemaException; +use Magento\Framework\Config\ValidationStateInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Model\Layout\Update\Validator; +use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; + +/** + * Validate a given page + */ +class LayoutUpdateValidator implements ValidatorInterface +{ + /** + * @var ValidatorFactory + */ + private $validatorFactory; + + /** + * @var ValidationStateInterface + */ + private $validationState; + + /** + * @param ValidatorFactory $validatorFactory + * @param ValidationStateInterface $validationState + */ + public function __construct( + ValidatorFactory $validatorFactory, + ValidationStateInterface $validationState + ) { + $this->validatorFactory = $validatorFactory; + $this->validationState = $validationState; + } + + /** + * Validate the data before saving + * + * @param PageInterface $page + * @throws LocalizedException + */ + public function validate(PageInterface $page): void + { + $this->validateRequiredFields($page); + $this->validateLayoutUpdate($page); + $this->validateCustomLayoutUpdate($page); + } + + /** + * Validate required fields + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateRequiredFields(PageInterface $page): void + { + if (empty($page->getTitle())) { + throw new LocalizedException(__(sprintf('Required field "%s" is empty.', 'title'))); + } + } + + /** + * Validate layout update + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateLayoutUpdate(PageInterface $page): void + { + $layoutXmlValidator = $this->getLayoutValidator(); + + try { + if (!empty($page->getLayoutUpdateXml()) + && !$layoutXmlValidator->isValid($page->getLayoutUpdateXml()) + ) { + throw new LocalizedException(__('Layout update is invalid')); + } + } catch (ValidationException|ValidationSchemaException $e) { + throw new LocalizedException(__('Layout update is invalid')); + } + } + + /** + * Validate custom layout update + * + * @param PageInterface $page + * @throws LocalizedException + */ + private function validateCustomLayoutUpdate(PageInterface $page): void + { + $layoutXmlValidator = $this->getLayoutValidator(); + + try { + if (!empty($page->getCustomLayoutUpdateXml()) + && !$layoutXmlValidator->isValid($page->getCustomLayoutUpdateXml()) + ) { + throw new LocalizedException(__('Custom layout update is invalid')); + } + } catch (ValidationException|ValidationSchemaException $e) { + throw new LocalizedException(__('Custom layout update is invalid')); + } + } + + /** + * Return a new validator + * + * @return Validator + */ + private function getLayoutValidator(): Validator + { + return $this->validatorFactory->create( + [ + 'validationState' => $this->validationState, + ] + ); + } +} diff --git a/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php b/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php new file mode 100644 index 000000000000..ff5c7648a9fa --- /dev/null +++ b/app/code/Magento/Cms/Model/PageRepository/ValidatorInterface.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Model\PageRepository; + +use Magento\Cms\Api\Data\PageInterface; +use Magento\Framework\Exception\LocalizedException; + +/** + * Validate a page repository + */ +interface ValidatorInterface +{ + /** + * Assert the given page valid + * + * @param PageInterface $page + * @return void + * @throws LocalizedException + */ + public function validate(PageInterface $page): void; +} diff --git a/app/code/Magento/Cms/etc/di.xml b/app/code/Magento/Cms/etc/di.xml index 66b0edf6e1ea..94b004a9d4b8 100644 --- a/app/code/Magento/Cms/etc/di.xml +++ b/app/code/Magento/Cms/etc/di.xml @@ -15,7 +15,7 @@ <preference for="Magento\Cms\Api\Data\PageInterface" type="Magento\Cms\Model\Page" /> <preference for="Magento\Cms\Api\Data\BlockInterface" type="Magento\Cms\Model\Block" /> <preference for="Magento\Cms\Api\BlockRepositoryInterface" type="Magento\Cms\Model\BlockRepository" /> - <preference for="Magento\Cms\Api\PageRepositoryInterface" type="Magento\Cms\Model\PageRepository" /> + <preference for="Magento\Cms\Api\PageRepositoryInterface" type="Magento\Cms\Model\PageRepository\ValidationComposite" /> <preference for="Magento\Ui\Component\Wysiwyg\ConfigInterface" type="Magento\Cms\Model\Wysiwyg\Config"/> <preference for="Magento\Cms\Api\GetUtilityPageIdentifiersInterface" type="Magento\Cms\Model\GetUtilityPageIdentifiers" /> <type name="Magento\Cms\Model\Wysiwyg\Config"> @@ -232,5 +232,14 @@ </argument> </arguments> </type> + + <type name="Magento\Cms\Model\PageRepository\ValidationComposite"> + <arguments> + <argument name="repository" xsi:type="object">Magento\Cms\Model\PageRepository</argument> + <argument name="validators" xsi:type="array"> + <item name="layout_update" xsi:type="object">Magento\Cms\Model\PageRepository\Validator\LayoutUpdateValidator</item> + </argument> + </arguments> + </type> </config> From ba19d6dfa713e3555a4cac91457362f8182ef0e5 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 17 Jun 2019 16:13:58 -0500 Subject: [PATCH 0119/1172] MC-16724: Prevent errors from incorrect import data --- .../LayoutUpdate/PermissionsValidatorTest.php | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php diff --git a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php deleted file mode 100644 index 1bb2037462f3..000000000000 --- a/app/code/Magento/Cms/Test/Unit/Model/CatalogImport/LayoutUpdate/PermissionsValidatorTest.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -declare(strict_types=1); - -namespace Magento\Cms\Test\Unit\Model\CatalogImport\LayoutUpdate; - -use Magento\CatalogImportExport\Model\Import\Product; -use Magento\Authorization\Model\UserContextInterface; -use Magento\CatalogImportExport\Model\Import\Product\Validator\LayoutUpdatePermissions; -use Magento\Framework\AuthorizationInterface; -use PHPUnit\Framework\TestCase; -use PHPUnit_Framework_MockObject_MockObject as MockObject; - -/** - * Test validation for layout update - */ -class PermissionsValidatorTest extends TestCase -{ - /** - * @var PermissionsValidator|MockObject - */ - private $validator; - - /** - * @var UserContextInterface|MockObject - */ - private $userContext; - - /** - * @var AuthorizationInterface|MockObject - */ - private $authorization; - - /** - * @var Product - */ - private $context; - - protected function setUp() - { - $this->userContext = $this->createMock(UserContextInterface::class); - $this->authorization = $this->createMock(AuthorizationInterface::class); - $this->context = $this->createMock(Product::class); - $this->context - ->method('retrieveMessageTemplate') - ->with('insufficientPermissions') - ->willReturn('oh no "%s"'); - $this->validator = new LayoutUpdatePermissions( - $this->userContext, - $this->authorization - ); - $this->validator->init($this->context); - } - - /** - * @param $value - * @param $userContext - * @param $isAllowed - * @param $isValid - * @dataProvider configurationsProvider - */ - public function testValidationConfiguration($value, $userContext, $isAllowed, $isValid) - { - $this->userContext - ->method('getUserType') - ->willReturn($userContext); - - $this->authorization - ->method('isAllowed') - ->with('Magento_Catalog::edit_product_design') - ->willReturn($isAllowed); - - $result = $this->validator->isValid(['custom_layout_update' => $value]); - $messages = $this->validator->getMessages(); - - self::assertSame($isValid, $result); - - if ($isValid) { - self::assertSame([], $messages); - } else { - self::assertSame(['oh no "custom_layout_update"'], $messages); - } - } - - public function configurationsProvider() - { - return [ - ['', null, null, true], - [null, null, null, true], - ['foo', UserContextInterface::USER_TYPE_ADMIN, true, true], - ['foo', UserContextInterface::USER_TYPE_INTEGRATION, true, true], - ['foo', UserContextInterface::USER_TYPE_ADMIN, false, false], - ['foo', UserContextInterface::USER_TYPE_INTEGRATION, false, false], - ['foo', 'something', null, false], - ]; - } -} From 425c34f75f3d43c145248fe0a04772c28b5e288a Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 17 Jun 2019 16:52:46 -0500 Subject: [PATCH 0120/1172] MC-16041: Prevent errors from incorrect configuration --- .../ValidationCompositeTest.php | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php new file mode 100644 index 000000000000..f73396230a66 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php @@ -0,0 +1,145 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Test\Unit\Model\PageRepository; + +use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Api\PageRepositoryInterface; +use Magento\Cms\Model\PageRepository\ValidationComposite; +use Magento\Cms\Model\PageRepository\ValidatorInterface; +use Magento\Framework\Api\SearchCriteriaInterface; +use Magento\Framework\Exception\LocalizedException; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Validate behavior of the validation composite + */ +class ValidationCompositeTest extends TestCase +{ + /** + * @var PageRepositoryInterface|MockObject + */ + private $subject; + + protected function setUp() + { + /** @var PageRepositoryInterface subject */ + $this->subject = $this->createMock(PageRepositoryInterface::class); + } + + /** + * @param $validators + * @expectedException \InvalidArgumentException + * @dataProvider constructorArgumentProvider + */ + public function testConstructorValidation($validators) + { + new ValidationComposite($this->subject, $validators); + } + + public function testSaveInvokesValidatorsWithSucess() + { + $validator1 = $this->createMock(ValidatorInterface::class); + $validator2 = $this->createMock(ValidatorInterface::class); + $page = $this->createMock(PageInterface::class); + + // Assert each are called + $validator1 + ->expects($this->once()) + ->method('validate') + ->with($page); + $validator2 + ->expects($this->once()) + ->method('validate') + ->with($page); + + // Assert that the success is called + $this->subject + ->expects($this->once()) + ->method('save') + ->with($page) + ->willReturn('foo'); + + $composite = new ValidationComposite($this->subject, [$validator1, $validator2]); + $result = $composite->save($page); + + self::assertSame('foo', $result); + } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Oh no. That isn't right. + */ + public function testSaveInvokesValidatorsWithErrors() + { + $validator1 = $this->createMock(ValidatorInterface::class); + $validator2 = $this->createMock(ValidatorInterface::class); + $page = $this->createMock(PageInterface::class); + + // Assert the first is called + $validator1 + ->expects($this->once()) + ->method('validate') + ->with($page) + ->willThrowException(new LocalizedException(__('Oh no. That isn\'t right.'))); + + // Assert the second is NOT called + $validator2 + ->expects($this->never()) + ->method('validate'); + + // Assert that the success is NOT called + $this->subject + ->expects($this->never()) + ->method('save'); + + $composite = new ValidationComposite($this->subject, [$validator1, $validator2]); + $composite->save($page); + } + + /** + * @param $method + * @param $arg + * @dataProvider passthroughMethodDataProvider + */ + public function testPassthroughMethods($method, $arg) + { + $this->subject + ->method($method) + ->with($arg) + ->willReturn('foo'); + + $composite = new ValidationComposite($this->subject, []); + $result = $composite->{$method}($arg); + + self::assertSame('foo', $result); + } + + public function constructorArgumentProvider() + { + return [ + [[null], false], + [[''], false], + [['foo'], false], + [[new \stdClass()], false], + [[$this->createMock(ValidatorInterface::class), 'foo'], false], + ]; + } + + public function passthroughMethodDataProvider() + { + return [ + ['save', $this->createMock(PageInterface::class)], + ['getById', 1], + ['getList', $this->createMock(SearchCriteriaInterface::class)], + ['delete', $this->createMock(PageInterface::class)], + ['deleteById', 1], + ]; + } +} From 9e322c82af00ee46451aa90d3adf6174edd02b1f Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 18 Jun 2019 11:32:50 +0300 Subject: [PATCH 0121/1172] MC-17303: Customer login fix --- .../Customer/Controller/Account/LoginPost.php | 2 ++ .../Customer/Model/Plugin/CustomerNotification.php | 7 +++++++ app/code/Magento/Customer/Model/Session.php | 12 ++++++++++-- app/code/Magento/Rss/Controller/Feed.php | 2 ++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 9afaab412164..48221b00bbb4 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -26,6 +26,8 @@ use Magento\Framework\Phrase; /** + * Post login customer action. + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class LoginPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface diff --git a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php index 9b655fc84352..577c97a19268 100644 --- a/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php +++ b/app/code/Magento/Customer/Model/Plugin/CustomerNotification.php @@ -15,6 +15,11 @@ use Magento\Framework\Exception\NoSuchEntityException; use Psr\Log\LoggerInterface; +/** + * Plugin before \Magento\Framework\App\Action\AbstractAction::dispatch. + * + * Plugin to remove notifications from cache. + */ class CustomerNotification { /** @@ -66,6 +71,8 @@ public function __construct( } /** + * Removes notifications from cache. + * * @param AbstractAction $subject * @param RequestInterface $request * @return void diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index c37a28d04fc5..e6612fe77a9b 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -17,6 +17,7 @@ * @api * @method string getNoReferer() * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) * @since 100.0.2 */ class Session extends \Magento\Framework\Session\SessionManager @@ -354,8 +355,9 @@ public function setCustomerGroupId($id) } /** - * Get customer group id - * If customer is not logged in system, 'not logged in' group id will be returned + * Get customer group id. + * + * If customer is not logged in system, 'not logged in' group id will be returned. * * @return int */ @@ -407,6 +409,8 @@ public function checkCustomerId($customerId) } /** + * Sets customer as logged in. + * * @param Customer $customer * @return $this */ @@ -420,6 +424,8 @@ public function setCustomerAsLoggedIn($customer) } /** + * Sets customer as logged in. + * * @param CustomerData $customer * @return $this */ @@ -567,6 +573,8 @@ public function regenerateId() } /** + * Creates \Magento\Framework\UrlInterface object. + * * @return \Magento\Framework\UrlInterface */ protected function _createUrl() diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index 634540dde5d9..c3ef4fb80833 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -76,6 +76,8 @@ public function __construct( } /** + * Authenticate not logged in customer. + * * @return bool */ protected function auth() From 878140b1a1df622107cb09be33598da59e933a6c Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Tue, 18 Jun 2019 08:51:04 -0500 Subject: [PATCH 0122/1172] MC-16284: Visible message alert * Updated Integration test --- .../Framework/Image/Adapter/InterfaceTest.php | 39 ++++++++++++++++++- .../Magento/Framework/Image/_files/empty.png | 0 .../Framework/Image/_files/notanimage.txt | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index bc8281d55ac4..59ad82334a95 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -703,12 +703,47 @@ public function testValidateUploadFile() } /** + * @dataProvider testValidateUploadFileExceptionDataProvider * @expectedException \InvalidArgumentException + * @param string $fileName + * @param string $expectedErrorMsg + * @param bool $useFixture */ - public function testValidateUploadFileException() + public function testValidateUploadFileException($fileName, $expectedErrorMsg, $useFixture) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $imageAdapter = $objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create(); - $imageAdapter->validateUploadFile(__FILE__); + $filePath = $useFixture ? $this->_getFixture($fileName) : $fileName; + + try { + $imageAdapter->validateUploadFile($filePath); + } catch (\InvalidArgumentException $e) { + $this->assertEquals($expectedErrorMsg, $e->getMessage()); + throw $e; + } + } + + /** + * @return array + */ + public function testValidateUploadFileExceptionDataProvider() + { + return [ + 'image_notfound' => [ + 'fileName' => 'notfound.png', + 'expectedErrorMsg' => 'Upload file does not exist.', + 'useFixture' => false + ], + 'image_empty' => [ + 'fileName' => 'empty.png', + 'expectedErrorMsg' => 'Disallowed file type.', + 'useFixture' => true + ], + 'notanimage' => [ + 'fileName' => 'notanimage.txt', + 'expectedErrorMsg' => 'Disallowed file type.', + 'useFixture' => true + ] + ]; } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/empty.png new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt new file mode 100644 index 000000000000..81bc3abd3712 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/_files/notanimage.txt @@ -0,0 +1 @@ +Not an image. From 5f4222b47413c88b906ea8fbaa341b35ec6d47d5 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 18 Jun 2019 09:49:15 -0500 Subject: [PATCH 0123/1172] MC-16041: Prevent errors from incorrect configuration --- .../Validator/LayoutUpdateValidator.php | 2 +- .../Validator/LayoutUpdateValidatorTest.php | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php diff --git a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php index 8cfb6f1433b6..721fd9efbdd9 100644 --- a/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php +++ b/app/code/Magento/Cms/Model/PageRepository/Validator/LayoutUpdateValidator.php @@ -66,7 +66,7 @@ public function validate(PageInterface $page): void private function validateRequiredFields(PageInterface $page): void { if (empty($page->getTitle())) { - throw new LocalizedException(__(sprintf('Required field "%s" is empty.', 'title'))); + throw new LocalizedException(__('Required field "%1" is empty.', 'title')); } } diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php new file mode 100644 index 000000000000..8fbea1525073 --- /dev/null +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Cms\Model\PageRepository\Validator; + +use Magento\Cms\Api\Data\PageInterface; +use Magento\Framework\Config\Dom\ValidationException; +use Magento\Framework\Config\Dom\ValidationSchemaException as SchemaException; +use Magento\Framework\Config\ValidationStateInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; +use Magento\Framework\View\Model\Layout\Update\Validator; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +/** + * Test cases for the layout update validator + */ +class LayoutUpdateValidatorTest extends TestCase +{ + /** + * @var Validator|MockObject + */ + private $layoutValidator; + + /** + * @var LayoutUpdateValidator + */ + private $validator; + + protected function setUp() + { + $layoutValidatorFactory = $this->createMock(ValidatorFactory::class); + $this->layoutValidator = $this->createMock(Validator::class); + $layoutValidatorState = $this->createMock(ValidationStateInterface::class); + + $layoutValidatorFactory + ->method('create') + ->with(['validationState' => $layoutValidatorState]) + ->willReturn($this->layoutValidator); + + $this->validator = new LayoutUpdateValidator($layoutValidatorFactory, $layoutValidatorState); + } + + /** + * @dataProvider validationSetDataProvider + */ + public function testValidate($data, $expectedExceptionMessage, $layoutValidatorException, $isLayoutValid = false) + { + if ($expectedExceptionMessage) { + $this->expectException(LocalizedException::class); + $this->expectExceptionMessage($expectedExceptionMessage); + } + + if ($layoutValidatorException) { + $this->layoutValidator + ->method('isValid') + ->with($data['getLayoutUpdateXml'] ?? $data['getCustomLayoutUpdateXml']) + ->willThrowException($layoutValidatorException); + } elseif (!empty($data['getLayoutUpdateXml'])) { + $this->layoutValidator + ->method('isValid') + ->with($data['getLayoutUpdateXml']) + ->willReturn($isLayoutValid); + } elseif (!empty($data['getCustomLayoutUpdateXml'])) { + $this->layoutValidator + ->method('isValid') + ->with($data['getCustomLayoutUpdateXml']) + ->willReturn($isLayoutValid); + } + + $page = $this->createMock(PageInterface::class); + foreach ($data as $method => $value) { + $page + ->method($method) + ->willReturn($value); + } + + self::assertNull($this->validator->validate($page)); + } + + public function validationSetDataProvider() + { + $layoutError = 'Layout update is invalid'; + $customLayoutError = 'Custom layout update is invalid'; + + return [ + [['getTitle' => ''], 'Required field "title" is empty.', null], + [['getTitle' => null], 'Required field "title" is empty.', null], + [['getTitle' => false], 'Required field "title" is empty.', null], + [['getTitle' => 0], 'Required field "title" is empty.', null], + [['getTitle' => '0'], 'Required field "title" is empty.', null], + [['getTitle' => []], 'Required field "title" is empty.', null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => ''], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => null], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => false], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 0], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => '0'], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => []], null, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, null], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new ValidationException], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], null, null, true], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => ''], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => null], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => false], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 0], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => '0'], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => []], null, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, null], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new ValidationException], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], null, null, true], + ]; + } +} From d7b059f3689ef29ac58cd46eb16140c84e7193e7 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 18 Jun 2019 10:47:08 -0500 Subject: [PATCH 0124/1172] MC-16041: Prevent errors from incorrect configuration --- .../Adminhtml/Page/PostDataProcessor.php | 3 +-- .../Validator/LayoutUpdateValidatorTest.php | 14 ++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php index f934cac6da11..46f68955531a 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php @@ -12,8 +12,7 @@ use Magento\Framework\Config\Dom\ValidationSchemaException; /** - * Class PostDataProcessor - * @package Magento\Cms\Controller\Adminhtml\Page + * Processes form data */ class PostDataProcessor { diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php index 8fbea1525073..83db12d77ab3 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -6,11 +6,11 @@ declare(strict_types=1); -namespace Magento\Cms\Model\PageRepository\Validator; +namespace Magento\Cms\Test\Unit\Model\PageRepository\Validator; use Magento\Cms\Api\Data\PageInterface; use Magento\Framework\Config\Dom\ValidationException; -use Magento\Framework\Config\Dom\ValidationSchemaException as SchemaException; +use Magento\Framework\Config\Dom\ValidationSchemaException; use Magento\Framework\Config\ValidationStateInterface; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\View\Model\Layout\Update\ValidatorFactory; @@ -88,6 +88,8 @@ public function validationSetDataProvider() { $layoutError = 'Layout update is invalid'; $customLayoutError = 'Custom layout update is invalid'; + $validationException = new ValidationException('Invalid format'); + $schemaException = new ValidationSchemaException(__('Invalid format')); return [ [['getTitle' => ''], 'Required field "title" is empty.', null], @@ -103,8 +105,8 @@ public function validationSetDataProvider() [['getTitle' => 'foo', 'getLayoutUpdateXml' => '0'], null, null], [['getTitle' => 'foo', 'getLayoutUpdateXml' => []], null, null], [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, null], - [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new ValidationException], - [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, $validationException], + [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], $layoutError, $schemaException], [['getTitle' => 'foo', 'getLayoutUpdateXml' => 'foo'], null, null, true], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => ''], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => null], null, null], @@ -113,8 +115,8 @@ public function validationSetDataProvider() [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => '0'], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => []], null, null], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, null], - [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new ValidationException], - [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, new SchemaException(__(''))], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, $validationException], + [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], $customLayoutError, $schemaException], [['getTitle' => 'foo', 'getCustomLayoutUpdateXml' => 'foo'], null, null, true], ]; } From a3180003aec1eff6dcacc05e5c39fc633496d5bb Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 18 Jun 2019 11:23:02 -0500 Subject: [PATCH 0125/1172] MC-16041: Prevent errors from incorrect configuration --- app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php | 4 ++-- .../Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php index 77f648e5f12c..2237f35ed0b8 100644 --- a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php +++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php @@ -84,6 +84,7 @@ public function execute() $page = $this->pageRepository->getById($pageId); try { $pageData = $this->filterPost($postItems[$pageId]); + $this->validatePost($pageData, $page, $error, $messages); $extendedPageData = $page->getData(); $this->setCmsPageData($page, $extendedPageData, $pageData); $this->pageRepository->save($page); @@ -134,11 +135,10 @@ protected function filterPost($postData = []) * @param bool $error * @param array $messages * @return void - * @deprecated */ protected function validatePost(array $pageData, \Magento\Cms\Model\Page $page, &$error, array &$messages) { - if (!($this->dataProcessor->validate($pageData) && $this->dataProcessor->validateRequireEntry($pageData))) { + if (!$this->dataProcessor->validateRequireEntry($pageData)) { $error = true; foreach ($this->messageManager->getMessages(true)->getItems() as $error) { $messages[] = $this->getErrorWithPageId($page, $error->getText()); diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index 9d51431b26d8..ea5e8d607f48 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -102,10 +102,6 @@ public function prepareMocksForTestExecute() ->method('filter') ->with($postData[1]) ->willReturnArgument(0); - $this->dataProcessor->expects($this->once()) - ->method('validate') - ->with($postData[1]) - ->willReturn(false); $this->messageManager->expects($this->once()) ->method('getMessages') ->with(true) From 073ce7843732f336c148249d9457f0850c105c77 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Tue, 18 Jun 2019 12:46:40 -0500 Subject: [PATCH 0126/1172] MC-16041: Prevent errors from incorrect configuration --- .../Adminhtml/Page/InlineEditTest.php | 88 +++++++++++-------- .../Validator/LayoutUpdateValidatorTest.php | 1 + 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index ea5e8d607f48..681e62d15986 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -118,19 +118,23 @@ public function prepareMocksForTestExecute() ->willReturn('1'); $this->cmsPage->expects($this->atLeastOnce()) ->method('getData') - ->willReturn([ - 'layout' => '1column', - 'identifier' => 'test-identifier' - ]); + ->willReturn( + [ + 'layout' => '1column', + 'identifier' => 'test-identifier' + ] + ); $this->cmsPage->expects($this->once()) ->method('setData') - ->with([ - 'layout' => '1column', - 'title' => '404 Not Found', - 'identifier' => 'no-route', - 'custom_theme' => '1', - 'custom_root_template' => '2' - ]); + ->with( + [ + 'layout' => '1column', + 'title' => '404 Not Found', + 'identifier' => 'no-route', + 'custom_theme' => '1', + 'custom_root_template' => '2' + ] + ); $this->jsonFactory->expects($this->once()) ->method('create') ->willReturn($this->resultJson); @@ -145,13 +149,15 @@ public function testExecuteWithLocalizedException() ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__('LocalizedException'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] LocalizedException' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] LocalizedException' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -166,13 +172,15 @@ public function testExecuteWithRuntimeException() ->willThrowException(new \RuntimeException(__('RuntimeException'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] RuntimeException' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] RuntimeException' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -187,13 +195,15 @@ public function testExecuteWithException() ->willThrowException(new \Exception(__('Exception'))); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - '[Page ID: 1] Error message', - '[Page ID: 1] Something went wrong while saving the page.' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + '[Page ID: 1] Error message', + '[Page ID: 1] Something went wrong while saving the page.' + ], + + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); @@ -214,12 +224,14 @@ public function testExecuteWithoutData() ); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [ - 'Please correct the data sent.' - ], - 'error' => true - ]) + ->with( + [ + 'messages' => [ + 'Please correct the data sent.' + ], + 'error' => true + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php index 83db12d77ab3..487a90bb9a18 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/Validator/LayoutUpdateValidatorTest.php @@ -9,6 +9,7 @@ namespace Magento\Cms\Test\Unit\Model\PageRepository\Validator; use Magento\Cms\Api\Data\PageInterface; +use Magento\Cms\Model\PageRepository\Validator\LayoutUpdateValidator; use Magento\Framework\Config\Dom\ValidationException; use Magento\Framework\Config\Dom\ValidationSchemaException; use Magento\Framework\Config\ValidationStateInterface; From f86eafd52c2a90608c62cfa5569d8abf1092fa2c Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 19 Jun 2019 08:41:24 -0500 Subject: [PATCH 0127/1172] MC-16284: Visible message alert --- .../Magento/Framework/Image/Adapter/AbstractAdapter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php index 276a8a719d6a..5a2102708b41 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php +++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php @@ -291,7 +291,7 @@ public function getMimeType() if ($this->_fileMimeType) { return $this->_fileMimeType; } else { - $this->_fileMimeType = image_type_to_mime_type($this->getImageType()); + $this->_fileMimeType = image_type_to_mime_type((int) $this->getImageType()); return $this->_fileMimeType; } } @@ -523,7 +523,7 @@ public function backgroundColor($value = null) */ protected function _getFileAttributes() { - $pathinfo = pathinfo($this->_fileName); + $pathinfo = pathinfo((string) $this->_fileName); $this->_fileSrcPath = $pathinfo['dirname']; $this->_fileSrcName = $pathinfo['basename']; @@ -675,7 +675,7 @@ protected function _prepareDestination($destination = null, $newName = null) $destination = $this->_fileSrcPath; } else { if (empty($newName)) { - $info = pathinfo($destination); + $info = pathinfo((string) $destination); $newName = $info['basename']; $destination = $info['dirname']; } From fe7c222607d72226dbc93c56a810d47cdfa16d0e Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 19 Jun 2019 11:49:47 -0500 Subject: [PATCH 0128/1172] MC-15978: Catalog Product Attribute Set Name --- .../Magento/Catalog/Model/Product/AttributeSet/Options.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index d0c710385149..26ca1f4d31c7 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -33,6 +33,10 @@ public function toOptionArray() $this->options = $this->collectionFactory->create() ->setEntityTypeFilter($this->product->getTypeId()) ->toOptionArray(); + + array_walk($this->options, function (&$option) { + $option['__disableTmpl'] = true; + }); } return $this->options; } From 5752b6568517fb707deff7ef3a4dad629d94b005 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 19 Jun 2019 12:03:22 -0500 Subject: [PATCH 0129/1172] MC-15978: Catalog Product Attribute Set Name --- .../Magento/Catalog/Model/Product/AttributeSet/Options.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index 26ca1f4d31c7..ab3f7b1a84fb 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model\Product\AttributeSet; +/** + * Attribute Set Options + */ class Options implements \Magento\Framework\Data\OptionSourceInterface { /** From b7dbf8991629cfc120f6de237e01056c3362a309 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 19 Jun 2019 14:21:08 -0500 Subject: [PATCH 0130/1172] MC-15978: Catalog Product Attribute Set Name --- .../Catalog/Model/Product/AttributeSet/Options.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php index ab3f7b1a84fb..57d08916bcd4 100644 --- a/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php +++ b/app/code/Magento/Catalog/Model/Product/AttributeSet/Options.php @@ -11,7 +11,7 @@ class Options implements \Magento\Framework\Data\OptionSourceInterface { /** - * @var null|array + * @var array */ protected $options; @@ -28,7 +28,7 @@ public function __construct( } /** - * @return array|null + * @inheritDoc */ public function toOptionArray() { @@ -37,10 +37,14 @@ public function toOptionArray() ->setEntityTypeFilter($this->product->getTypeId()) ->toOptionArray(); - array_walk($this->options, function (&$option) { - $option['__disableTmpl'] = true; - }); + array_walk( + $this->options, + function (&$option) { + $option['__disableTmpl'] = true; + } + ); } + return $this->options; } } From 4d0ae578c4adb31c2ae51db1102973d20cdc5e9f Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 19 Jun 2019 15:36:03 -0500 Subject: [PATCH 0131/1172] MC-17581: Import Export --- lib/internal/Magento/Framework/Archive/Zip.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index c41f8b28ce34..eee2a3bf4a55 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,7 +54,7 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - if ($filename) { + if (!preg_match('#[:"*?|<>%]#', $filename)) { $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); } else { From 0599bb53cfa42bcfc47f4db2cfd1a36fd5a7d8ee Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Wed, 19 Jun 2019 15:55:19 -0500 Subject: [PATCH 0132/1172] MC-16724: Prevent errors from incorrect import data --- .../Magento/CatalogImportExport/Model/Import/Product.php | 5 +++-- .../Import/Product/Validator/LayoutUpdatePermissions.php | 5 +---- .../Import/Product/Validator/LayoutUpdatePermissionsTest.php | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 036bd5de0fb2..9088868a595f 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -301,8 +301,9 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually', ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values', 'invalidNewToDateValue' => 'Make sure new_to_date is later than or the same as new_from_date', - 'invalidLayoutUpdate' => 'Invalid layout update', - 'insufficientPermissions' => 'You do not have permissions to update "%s"', + // Can't add new translated strings in patch release + 'invalidLayoutUpdate' => 'Invalid format.', + 'insufficientPermissions' => 'Invalid format.', ]; //@codingStandardsIgnoreEnd diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php index d1df04b8e95c..50d38cedfb75 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/LayoutUpdatePermissions.php @@ -68,10 +68,7 @@ public function isValid($data): bool if (!$isValid) { $this->_addMessages( [ - sprintf( - $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), - 'custom_layout_update' - ) + $this->context->retrieveMessageTemplate(self::ERROR_INSUFFICIENT_PERMISSIONS), ] ); } diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php index 2f883b5f4146..e018fc0cf5cc 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/LayoutUpdatePermissionsTest.php @@ -48,7 +48,7 @@ protected function setUp() $this->context ->method('retrieveMessageTemplate') ->with('insufficientPermissions') - ->willReturn('oh no "%s"'); + ->willReturn('oh no'); $this->validator = new LayoutUpdatePermissions( $this->userContext, $this->authorization @@ -82,7 +82,7 @@ public function testValidationConfiguration($value, $userContext, $isAllowed, $i if ($isValid) { self::assertSame([], $messages); } else { - self::assertSame(['oh no "custom_layout_update"'], $messages); + self::assertSame(['oh no'], $messages); } } From cb86e985f7067679fdfd10b9d526cf473e66629d Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 20 Jun 2019 10:09:15 +0300 Subject: [PATCH 0133/1172] MC-17303: Customer login fix --- app/code/Magento/Customer/Controller/Account/LoginPost.php | 1 - app/code/Magento/Customer/Controller/Ajax/Login.php | 1 - app/code/Magento/Customer/Model/Session.php | 1 + app/code/Magento/Rss/Controller/Feed.php | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 48221b00bbb4..4091a068e309 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -184,7 +184,6 @@ public function execute() if (!empty($login['username']) && !empty($login['password'])) { try { $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']); - $this->session->regenerateId(); $this->session->setCustomerDataAsLoggedIn($customer); if ($this->getCookieManager()->getCookie('mage-cache-sessid')) { $metadata = $this->getCookieMetadataFactory()->createCookieMetadata(); diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php index d5425bfc2733..1215c47ab990 100644 --- a/app/code/Magento/Customer/Controller/Ajax/Login.php +++ b/app/code/Magento/Customer/Controller/Ajax/Login.php @@ -190,7 +190,6 @@ public function execute() $credentials['username'], $credentials['password'] ); - $this->customerSession->regenerateId(); $this->customerSession->setCustomerDataAsLoggedIn($customer); $redirectRoute = $this->getAccountRedirect()->getRedirectCookie(); if ($this->cookieManager->getCookie('mage-cache-sessid')) { diff --git a/app/code/Magento/Customer/Model/Session.php b/app/code/Magento/Customer/Model/Session.php index e6612fe77a9b..ca15b8ab2034 100644 --- a/app/code/Magento/Customer/Model/Session.php +++ b/app/code/Magento/Customer/Model/Session.php @@ -431,6 +431,7 @@ public function setCustomerAsLoggedIn($customer) */ public function setCustomerDataAsLoggedIn($customer) { + $this->regenerateId(); $this->_httpContext->setValue(Context::CONTEXT_AUTH, true, false); $this->setCustomerData($customer); diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php index c3ef4fb80833..4c5acf97bde8 100644 --- a/app/code/Magento/Rss/Controller/Feed.php +++ b/app/code/Magento/Rss/Controller/Feed.php @@ -86,7 +86,6 @@ protected function auth() list($login, $password) = $this->httpAuthentication->getCredentials(); try { $customer = $this->customerAccountManagement->authenticate($login, $password); - $this->customerSession->regenerateId(); $this->customerSession->setCustomerDataAsLoggedIn($customer); } catch (\Exception $e) { $this->logger->critical($e); From ab4641cc603e76a63b2768679de2e08dc55081c3 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 20 Jun 2019 12:24:35 +0300 Subject: [PATCH 0134/1172] MC-17303: Customer login fix --- .../Test/Unit/Controller/Account/LoginPostTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 762c76b695de..78acc339284c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -292,9 +292,8 @@ public function testExecuteSuccessCustomRedirect() ->method('setCustomerDataAsLoggedIn') ->with($customerMock) ->willReturnSelf(); - $this->session->expects($this->once()) - ->method('regenerateId') - ->willReturnSelf(); + $this->session->expects($this->never()) + ->method('regenerateId'); $this->accountRedirect->expects($this->never()) ->method('getRedirect') @@ -357,9 +356,8 @@ public function testExecuteSuccess() ->method('setCustomerDataAsLoggedIn') ->with($customerMock) ->willReturnSelf(); - $this->session->expects($this->once()) - ->method('regenerateId') - ->willReturnSelf(); + $this->session->expects($this->never()) + ->method('regenerateId'); $this->accountRedirect->expects($this->once()) ->method('getRedirect') From 492a377cf660964b11d512b9cec26df8f5b88310 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Thu, 20 Jun 2019 13:10:49 +0300 Subject: [PATCH 0135/1172] MC-16042: Zip archive validation --- .../Magento/Framework/Archive/Zip.php | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index 925adda48504..20f408a605c1 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -53,11 +53,10 @@ public function unpack($source, $destination) { $zip = new \ZipArchive(); if ($zip->open($source) === true) { - $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - $filename = $this->filterExcludedFiles($filename); + $zip->renameIndex(0, basename($destination)); + $filename = $zip->getNameIndex(0) ?: ''; if ($filename) { $zip->extractTo(dirname($destination), $filename); - rename(dirname($destination).'/'.$filename, $destination); } else { $destination = ''; } @@ -68,34 +67,4 @@ public function unpack($source, $destination) return $destination; } - - /** - * Filter file names with relative paths. - * - * @param string $path - * @return string - */ - private function filterRelativePaths(string $path): string - { - if ($path && preg_match('#^\s*(../)|(/../)#i', $path)) { - $path = ''; - } - - return $path; - } - - /** - * Filter excluded files. - * - * @param string $file - * @return string - */ - private function filterExcludedFiles(string $file): string - { - if ($file && preg_match('/^\.htaccess$/', $file)) { - $file = ''; - } - - return $file; - } } From 5aa361068d0f5722d4d4587e66255ff0977b2db2 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 20 Jun 2019 12:11:48 -0500 Subject: [PATCH 0136/1172] MC-17581: Import Export --- app/code/Magento/ImportExport/Model/Import/Source/Zip.php | 8 +++++++- lib/internal/Magento/Framework/Archive/Zip.php | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php index 6fa87ab5d5c4..7e69d837d652 100644 --- a/app/code/Magento/ImportExport/Model/Import/Source/Zip.php +++ b/app/code/Magento/ImportExport/Model/Import/Source/Zip.php @@ -33,6 +33,12 @@ public function __construct( throw new ValidatorException(__('Sorry, but the data is invalid or the file is not uploaded.')); } $directory->delete($directory->getRelativePath($file)); - parent::__construct($csvFile, $directory, $options); + + try { + parent::__construct($csvFile, $directory, $options); + } catch (\LogicException $e) { + $directory->delete($directory->getRelativePath($csvFile)); + throw $e; + } } } diff --git a/lib/internal/Magento/Framework/Archive/Zip.php b/lib/internal/Magento/Framework/Archive/Zip.php index eee2a3bf4a55..2cb6e47d3942 100644 --- a/lib/internal/Magento/Framework/Archive/Zip.php +++ b/lib/internal/Magento/Framework/Archive/Zip.php @@ -54,7 +54,8 @@ public function unpack($source, $destination) $zip = new \ZipArchive(); if ($zip->open($source) === true) { $filename = $this->filterRelativePaths($zip->getNameIndex(0) ?: ''); - if (!preg_match('#[:"*?|<>%]#', $filename)) { + if ($filename && !preg_match('#[:"*?|<>%]#', $filename)) { + // extract first entry in zip file to destination directory $zip->extractTo(dirname($destination), $filename); rename(dirname($destination).'/'.$filename, $destination); } else { From dedd073a80bebb83233c6d937c0f3cee61d74612 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 21 Jun 2019 12:26:24 +0300 Subject: [PATCH 0137/1172] MC-17650: Change Confirmation key generation --- app/code/Magento/Customer/Model/Customer.php | 10 +++++-- .../Customer/Test/Unit/Model/CustomerTest.php | 29 ++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php index 1287dbe5df70..32b0a9c1ec48 100644 --- a/app/code/Magento/Customer/Model/Customer.php +++ b/app/code/Magento/Customer/Model/Customer.php @@ -20,6 +20,7 @@ use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Store\Model\ScopeInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Math\Random; /** * Customer model @@ -180,7 +181,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel protected $_encryptor; /** - * @var \Magento\Framework\Math\Random + * @var Random */ protected $mathRandom; @@ -248,6 +249,7 @@ class Customer extends \Magento\Framework\Model\AbstractModel * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection * @param array $data * @param AccountConfirmation|null $accountConfirmation + * @param Random|null $mathRandom * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -272,7 +274,8 @@ public function __construct( \Magento\Framework\Indexer\IndexerRegistry $indexerRegistry, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], - AccountConfirmation $accountConfirmation = null + AccountConfirmation $accountConfirmation = null, + Random $mathRandom = null ) { $this->metadataService = $metadataService; $this->_scopeConfig = $scopeConfig; @@ -291,6 +294,7 @@ public function __construct( $this->indexerRegistry = $indexerRegistry; $this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance() ->get(AccountConfirmation::class); + $this->mathRandom = $mathRandom ?: ObjectManager::getInstance()->get(Random::class); parent::__construct( $context, $registry, @@ -805,7 +809,7 @@ public function isConfirmationRequired() */ public function getRandomConfirmationKey() { - return md5(uniqid()); + return $this->mathRandom->getRandomString(32); } /** diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php index 65831069aa1f..8bb37adc875c 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php @@ -15,6 +15,7 @@ use Magento\Customer\Model\AccountConfirmation; use Magento\Customer\Model\ResourceModel\Address\CollectionFactory as AddressCollectionFactory; use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Framework\Math\Random; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -86,6 +87,14 @@ class CustomerTest extends \PHPUnit\Framework\TestCase */ private $dataObjectHelper; + /** + * @var Random|\PHPUnit_Framework_MockObject_MockObject + */ + private $mathRandom; + + /** + * @inheritdoc + */ protected function setUp() { $this->_website = $this->createMock(\Magento\Store\Model\Website::class); @@ -130,6 +139,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['populateWithArray']) ->getMock(); + $this->mathRandom = $this->createMock(Random::class); $this->_model = $helper->getObject( \Magento\Customer\Model\Customer::class, @@ -146,7 +156,8 @@ protected function setUp() 'accountConfirmation' => $this->accountConfirmation, '_addressesFactory' => $this->addressesFactory, 'customerDataFactory' => $this->customerDataFactory, - 'dataObjectHelper' => $this->dataObjectHelper + 'dataObjectHelper' => $this->dataObjectHelper, + 'mathRandom' => $this->mathRandom, ] ); } @@ -383,4 +394,20 @@ public function testGetDataModel() $this->_model->getDataModel(); $this->assertEquals($customerDataObject, $this->_model->getDataModel()); } + + /** + * Check getRandomConfirmationKey use cryptographically secure function + * + * @return void + */ + public function testGetRandomConfirmationKey() : void + { + $this->mathRandom + ->expects($this->once()) + ->method('getRandomString') + ->with(32) + ->willReturn('random_string'); + + $this->_model->getRandomConfirmationKey(); + } } From fe9deec39afeab1a30cb4a7c2507b754fa2c6930 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Fri, 21 Jun 2019 15:09:53 +0300 Subject: [PATCH 0138/1172] MC-17650: Change Confirmation key generation --- .../Customer/Test/Unit/Model/CustomerTest.php | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php index 8bb37adc875c..170cd001e5b9 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php @@ -230,15 +230,17 @@ public function testSendNewAccountEmailWithoutStoreId() ->method('getTransport') ->will($this->returnValue($transportMock)); - $this->_model->setData([ - 'website_id' => 1, - 'store_id' => 1, - 'email' => 'email@example.com', - 'firstname' => 'FirstName', - 'lastname' => 'LastName', - 'middlename' => 'MiddleName', - 'prefix' => 'Name Prefix', - ]); + $this->_model->setData( + [ + 'website_id' => 1, + 'store_id' => 1, + 'email' => 'email@example.com', + 'firstname' => 'FirstName', + 'lastname' => 'LastName', + 'middlename' => 'MiddleName', + 'prefix' => 'Name Prefix', + ] + ); $this->_model->sendNewAccountEmail('registered'); } From ce3e108be879190254b2d5ae38b0125ca73abae6 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Fri, 21 Jun 2019 11:41:15 -0500 Subject: [PATCH 0139/1172] MC-17648: Registration email confirmation --- app/code/Magento/Customer/Model/AccountManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index cfb788a2516a..e030f2107356 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -977,6 +977,7 @@ protected function sendEmailConfirmation(CustomerInterface $customer, $redirectU $templateType = self::NEW_ACCOUNT_EMAIL_REGISTERED_NO_PASSWORD; } $this->getEmailNotification()->newAccount($customer, $templateType, $redirectUrl, $customer->getStoreId()); + $customer->setConfirmation(null); } catch (MailException $e) { // If we are not able to send a new account email, this should be ignored $this->logger->critical($e); From 69cec9091e52bdfd15ed65c4903fe890dca393fe Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Mon, 24 Jun 2019 15:09:20 +0300 Subject: [PATCH 0140/1172] MC-17303: Customer login fix --- .../Unit/Controller/Account/LoginPostTest.php | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 78acc339284c..13cf195ab5f6 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -93,13 +93,14 @@ protected function setUp() $this->session = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods([ - 'isLoggedIn', - 'setCustomerDataAsLoggedIn', - 'regenerateId', - 'setUsername', - ]) - ->getMock(); + ->setMethods( + [ + 'isLoggedIn', + 'setCustomerDataAsLoggedIn', + 'regenerateId', + 'setUsername', + ] + )->getMock(); $this->accountManagement = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) ->getMockForAbstractClass(); @@ -253,10 +254,12 @@ public function testExecuteSuccessCustomRedirect() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -334,10 +337,12 @@ public function testExecuteSuccess() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -424,10 +429,12 @@ public function testExecuteWithException( $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $exception = new $exceptionData['exception'](__($exceptionData['message'])); @@ -486,11 +493,12 @@ protected function prepareContext() $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) ->disableOriginalConstructor() - ->setMethods([ - 'isPost', - 'getPost', - ]) - ->getMock(); + ->setMethods( + [ + 'isPost', + 'getPost', + ] + )->getMock(); $this->resultRedirect = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) ->disableOriginalConstructor() From 6f33211850d2c2666b99278b23200cd542ae20d2 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 24 Jun 2019 16:23:19 -0500 Subject: [PATCH 0141/1172] MC-16284: Visible message alert --- .../Adminhtml/Product/Gallery/Upload.php | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php index ff7311e93175..779617254f6a 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php @@ -8,6 +8,7 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\LocalizedException; class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterface { @@ -23,6 +24,16 @@ class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterf */ protected $resultRawFactory; + /** + * @var array + */ + private $allowedMimeTypes = [ + 'jpg' => 'image/jpg', + 'jpeg' => 'image/jpeg', + 'gif' => 'image/png', + 'png' => 'image/gif' + ]; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory @@ -45,7 +56,12 @@ public function execute() \Magento\MediaStorage\Model\File\Uploader::class, ['fileId' => 'image'] ); - $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']); + $uploader->setAllowedExtensions($this->getAllowedExtensions()); + + if (!$uploader->checkMimeType($this->getAllowedMimeTypes())) { + throw new LocalizedException(__('Disallowed File Type.')); + } + /** @var \Magento\Framework\Image\Adapter\AdapterInterface $imageAdapter */ $imageAdapter = $this->_objectManager->get(\Magento\Framework\Image\AdapterFactory::class)->create(); $uploader->addValidateCallback('catalog_product_image', $imageAdapter, 'validateUploadFile'); @@ -78,4 +94,24 @@ public function execute() $response->setContents(json_encode($result)); return $response; } + + /** + * Get the set of allowed file extensions. + * + * @return array + */ + private function getAllowedExtensions() + { + return array_keys($this->allowedMimeTypes); + } + + /** + * Get the set of allowed mime types. + * + * @return array + */ + private function getAllowedMimeTypes() + { + return array_values($this->allowedMimeTypes); + } } From 31caade6fa679b6c492120cd73ef3d0c50f9b00f Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Mon, 24 Jun 2019 16:39:30 -0500 Subject: [PATCH 0142/1172] MC-16284: Visible message alert --- .../Catalog/Controller/Adminhtml/Product/Gallery/Upload.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php index 779617254f6a..820f2e5e5b8c 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -10,6 +9,9 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; +/** + * Class Upload + */ class Upload extends \Magento\Backend\App\Action implements HttpPostActionInterface { /** @@ -47,6 +49,8 @@ public function __construct( } /** + * Upload image(s) to the product gallery. + * * @return \Magento\Framework\Controller\Result\Raw */ public function execute() From 7e3bc32a1fdbbebf7557e6e282bc8f291c305748 Mon Sep 17 00:00:00 2001 From: Mark Berube <berube@adobe.com> Date: Mon, 24 Jun 2019 17:45:41 -0500 Subject: [PATCH 0143/1172] MC-16110: Fixing column name for store --- .../Listing/Column/Store/Options.php | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php index 1fc13390e30b..907eb74e20fa 100644 --- a/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php +++ b/app/code/Magento/Store/Ui/Component/Listing/Column/Store/Options.php @@ -68,6 +68,26 @@ public function toOptionArray() return $this->options; } + /** + * Sanitize website/store option name + * + * @param string $name + * + * @return string + */ + protected function sanitizeName($name) + { + $matches = []; + preg_match('/\$[:]*{(.)*}/', $name, $matches); + if (count($matches) > 0) { + $name = $this->escaper->escapeHtml($this->escaper->escapeJs($name)); + } else { + $name = $this->escaper->escapeHtml($name); + } + + return $name; + } + /** * Generate current options * @@ -88,20 +108,20 @@ protected function generateCurrentOptions() /** @var \Magento\Store\Model\Store $store */ foreach ($storeCollection as $store) { if ($store->getGroupId() == $group->getId()) { - $name = $this->escaper->escapeHtml($store->getName()); + $name = $this->sanitizeName($store->getName()); $stores[$name]['label'] = str_repeat(' ', 8) . $name; $stores[$name]['value'] = $store->getId(); } } if (!empty($stores)) { - $name = $this->escaper->escapeHtml($group->getName()); + $name = $this->sanitizeName($group->getName()); $groups[$name]['label'] = str_repeat(' ', 4) . $name; $groups[$name]['value'] = array_values($stores); } } } if (!empty($groups)) { - $name = $this->escaper->escapeHtml($website->getName()); + $name = $this->sanitizeName($website->getName()); $this->currentOptions[$name]['label'] = $name; $this->currentOptions[$name]['value'] = array_values($groups); } From 6db05a87e98474826e406890ef9d0643e279d568 Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 24 Jun 2019 23:00:18 -0500 Subject: [PATCH 0144/1172] MC-16724: Prevent errors from incorrect import data --- .../Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php index 681e62d15986..7f2ff2086df9 100644 --- a/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php +++ b/app/code/Magento/Cms/Test/Unit/Controller/Adminhtml/Page/InlineEditTest.php @@ -201,7 +201,7 @@ public function testExecuteWithException() '[Page ID: 1] Error message', '[Page ID: 1] Something went wrong while saving the page.' ], - + 'error' => true ] ) ->willReturnSelf(); From 827ac377c916d0eb77a387733a757a2b78315253 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Wed, 26 Jun 2019 13:26:07 +0000 Subject: [PATCH 0145/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Set shipping address in checkout provider --- .../Magento/Checkout/view/frontend/web/js/view/shipping.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index c811d3a1e836..71cdf9bd8324 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -246,9 +246,14 @@ define([ * Set shipping information handler */ setShippingInformation: function () { + var checkoutProvider = registry.get('checkoutProvider'); if (this.validateShippingInformation()) { quote.billingAddress(null); checkoutDataResolver.resolveBillingAddress(); + checkoutProvider.set( + 'shippingAddress', + $.extend(true, {}, checkoutProvider.get('shippingAddress'), quote.shippingAddress()) + ); setShippingInformationAction().done( function () { stepNavigator.next(); From 6705536c470405e535374c8c226b8b878fb68bae Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 26 Jun 2019 14:43:38 -0500 Subject: [PATCH 0146/1172] MC-17806: Store name rendering in customer section - Resolved template issue for store name in customer admin section - Updated unit test for related issue --- app/code/Magento/Store/Model/System/Store.php | 6 ++++++ .../Store/Test/Unit/Model/System/StoreTest.php | 9 +++++---- .../Ui/view/base/web/js/grid/editing/record.js | 5 +++++ .../web/js/lib/knockout/bindings/optgroup.js | 17 ++++++++++++----- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index 86eec555f1d5..f0ec7a375add 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -152,6 +152,12 @@ public function getStoreValuesForForm($empty = false, $all = false) } } } + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); return $options; } 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 9cc4bb6ac8e5..a9208876eaa7 100644 --- a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php @@ -262,14 +262,15 @@ public function getStoreValuesForFormDataProvider() 'storeGroupId' => $groupId, 'groupWebsiteId' => $websiteId, 'expectedResult' => [ - ['label' => '', 'value' => ''], - ['label' => __('All Store Views'), 'value' => 0], - ['label' => $websiteName, 'value' => []], + ['label' => '', 'value' => '','__disableTmpl' => true], + ['label' => __('All Store Views'), 'value' => 0,'__disableTmpl' => true], + ['label' => $websiteName, 'value' => [],'__disableTmpl' => true], [ 'label' => str_repeat($nonEscapableNbspChar, 4) . $groupName, 'value' => [ ['label' => str_repeat($nonEscapableNbspChar, 4) . $storeName, 'value' => $storeId] - ] + ], + '__disableTmpl' => true ], ] ], diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js index 9b8998368c5f..14bed73a694c 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js @@ -134,6 +134,11 @@ define([ field = utils.extend({}, fields.base, field); + field.__disableTmpl = { + label: true, + options: true + }; + return utils.template(field, { record: this, column: column diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 2925c5859edd..148256f72d01 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -222,10 +222,14 @@ define([ ko.utils.setTextContent(option, allBindings.get('optionsCaption')); ko.selectExtensions.writeValue(option, undefined); } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup - option = utils.template(optgroupTmpl, { - label: arrayEntry[optionsText], - title: arrayEntry[optionsText + 'title'] - }); + if (arrayEntry['__disableTmpl']) { + option = '<optgroup label="' + arrayEntry[optionsText] + '"></optgroup>'; + } else { + option = utils.template(optgroupTmpl, { + label: arrayEntry[optionsText], + title: arrayEntry[optionsText + 'title'] + }); + } option = ko.utils.parseHtmlFragment(option)[0]; } else { @@ -302,11 +306,14 @@ define([ space = '\u2007\u2007\u2007'; obj[optionTitle] = applyToObject(option, optionsText + 'title', value); - if (disabled) { obj.disabled = disabled; } + if ("__disableTmpl" in option) { + obj.__disableTmpl = option.__disableTmpl; + } + label = label.replace(nbspRe, '').trim(); if (Array.isArray(value)) { From f4479aa992334e22c5fba0829c7b75c14821109e Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Wed, 26 Jun 2019 15:05:48 -0500 Subject: [PATCH 0147/1172] MC-16112: Signifyd Guarantee Option - fix options, actions, mass actions rendering --- .../Catalog/Ui/Component/Product/MassAction.php | 2 +- .../Magento/Translation/Model/Inline/Parser.php | 13 ++++++++++++- .../Component/Form/Element/AbstractOptionsField.php | 7 +++++++ app/code/Magento/Ui/Component/MassAction.php | 2 +- .../Framework/View/Element/UiComponent/Context.php | 8 ++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index 894e2b701b5a..e54605fbe3ee 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -49,7 +49,7 @@ public function prepare() : void foreach ($this->getChildComponents() as $actionComponent) { $actionType = $actionComponent->getConfiguration()['type']; if ($this->isActionAllowed($actionType)) { - $config['actions'][] = $actionComponent->getConfiguration(); + $config['actions'][] = array_merge($actionComponent->getConfiguration(), ['__disableTmpl' => true]); } } $origConfig = $this->getConfiguration(); diff --git a/app/code/Magento/Translation/Model/Inline/Parser.php b/app/code/Magento/Translation/Model/Inline/Parser.php index e0b2ce40405d..9dc123854e87 100644 --- a/app/code/Magento/Translation/Model/Inline/Parser.php +++ b/app/code/Magento/Translation/Model/Inline/Parser.php @@ -6,6 +6,9 @@ namespace Magento\Translation\Model\Inline; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Escaper; + /** * This class is responsible for parsing content and applying necessary html element * wrapping and client scripts for inline translation. @@ -196,6 +199,9 @@ public function processAjaxPost(array $translateParams) /** @var $validStoreId int */ $validStoreId = $this->_storeManager->getStore()->getId(); + /** @var $escaper Escaper */ + $escaper = ObjectManager::getInstance()->get(Escaper::class); + /** @var $resource \Magento\Translation\Model\ResourceModel\StringUtils */ $resource = $this->_resourceFactory->create(); foreach ($translateParams as $param) { @@ -209,7 +215,12 @@ public function processAjaxPost(array $translateParams) $storeId = $validStoreId; } } - $resource->saveTranslate($param['original'], $param['custom'], null, $storeId); + $resource->saveTranslate( + $param['original'], + $escaper->escapeHtml($param['custom']), + null, + $storeId + ); } return $this->getCacheManger()->updateAndGetTranslations(); diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 09583f65bf15..55b4ae15cdce 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -59,6 +59,13 @@ public function prepare() if (empty($config['rawOptions'])) { $options = $this->convertOptionsValueToString($options); } + array_walk( + $options, + function (&$item) { + $item['__disableTmpl'] = true; + } + ); + $config['options'] = array_values(array_merge_recursive($config['options'], $options)); } $this->setData('config', (array)$config); diff --git a/app/code/Magento/Ui/Component/MassAction.php b/app/code/Magento/Ui/Component/MassAction.php index 4cca8d4c012b..5af263dd861c 100644 --- a/app/code/Magento/Ui/Component/MassAction.php +++ b/app/code/Magento/Ui/Component/MassAction.php @@ -28,7 +28,7 @@ public function prepare() if ($disabledAction) { continue; } - $config['actions'][] = $componentConfig; + $config['actions'][] = array_merge($componentConfig, ['__disableTmpl' => true]); } $origConfig = $this->getConfiguration(); diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index fbb84712b2af..e95a9d44edbb 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -382,6 +382,14 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); + foreach ($data['data']['items'] as & $item) { + $name = $component->getData('name'); + if (array_key_exists($name, $item) && is_array($item[$name])) { + foreach ($item[$name] as $action => &$actionItem) { + !is_array($actionItem) ?: $actionItem['__disableTmpl'] = true; + } + } + } } /** From f829086961d62dad8d185cbf112f6d6d5547e113 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 26 Jun 2019 16:27:44 -0500 Subject: [PATCH 0148/1172] MC-17806: Store name rendering in customer section - Resolved static and integration test failures --- .../base/web/js/lib/knockout/bindings/optgroup.js | 2 +- .../UrlRewrite/Block/Catalog/Edit/FormTest.php | 15 +++++++++------ .../UrlRewrite/Block/Cms/Page/Edit/FormTest.php | 5 +++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 148256f72d01..81ce64f64ce5 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -222,7 +222,7 @@ define([ ko.utils.setTextContent(option, allBindings.get('optionsCaption')); ko.selectExtensions.writeValue(option, undefined); } else if (typeof arrayEntry[optionsValue] === 'undefined') { // empty value === optgroup - if (arrayEntry['__disableTmpl']) { + if (arrayEntry.__disableTmpl) { option = '<optgroup label="' + arrayEntry[optionsText] + '"></optgroup>'; } else { option = utils.template(optgroupTmpl, { diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php index 8dcc30951473..c1cfa3cf02d5 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php @@ -234,10 +234,11 @@ public static function getEntityStoresDataProvider() null, ['entity_id' => 3, 'store_ids' => [1]], [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ], ], @@ -245,10 +246,11 @@ public static function getEntityStoresDataProvider() ['entity_id' => 2, 'name' => 'product2', 'url_key' => 'product2', 'store_ids' => [1]], null, [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ] ], @@ -256,10 +258,11 @@ public static function getEntityStoresDataProvider() ['entity_id' => 2, 'name' => 'product2', 'url_key' => 'product2', 'store_ids' => [1]], ['entity_id' => 3, 'name' => 'product3', 'url_key' => 'product3', 'store_ids' => [1]], [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ] ] ] diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php index c3b93efece45..5bbd27640215 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php @@ -78,10 +78,11 @@ public function testGetEntityStores() $form = $this->_getFormInstance($args); $expectedStores = [ - ['label' => 'Main Website', 'value' => []], + ['label' => 'Main Website', 'value' => [], '__disableTmpl' => true], [ 'label' => '    Main Website Store', - 'value' => [['label' => '    Default Store View', 'value' => 1]] + 'value' => [['label' => '    Default Store View', 'value' => 1]], + '__disableTmpl' => true ], ]; $this->assertEquals($expectedStores, $form->getElement('store_id')->getValues()); From 8572d837c58a8717dd6d75835c1b793e13cc8198 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Wed, 26 Jun 2019 16:58:21 -0500 Subject: [PATCH 0149/1172] MC-17806: Store name rendering in customer section - Resolved static test failures --- .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 81ce64f64ce5..a1646e0cff06 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -310,7 +310,7 @@ define([ obj.disabled = disabled; } - if ("__disableTmpl" in option) { + if (option.hasOwnProperty("__disableTmpl")) { obj.__disableTmpl = option.__disableTmpl; } From c44db50097ca188f27cca2aced224ca57a61913b Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 27 Jun 2019 10:41:03 -0500 Subject: [PATCH 0150/1172] MC-17806: Store name rendering in customer section - Resolved static test failures --- app/code/Magento/Store/Model/System/Store.php | 2 ++ app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php | 3 +++ .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 2 +- .../Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php | 2 ++ .../Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Store/Model/System/Store.php b/app/code/Magento/Store/Model/System/Store.php index f0ec7a375add..53338a8fec5a 100644 --- a/app/code/Magento/Store/Model/System/Store.php +++ b/app/code/Magento/Store/Model/System/Store.php @@ -118,6 +118,7 @@ public function getStoreValuesForForm($empty = false, $all = false) $options[] = ['label' => __('All Store Views'), 'value' => 0]; } + //phpcs:ignore Magento2.Functions.DiscouragedFunction $nonEscapableNbspChar = html_entity_decode(' ', ENT_NOQUOTES, 'UTF-8'); foreach ($this->_websiteCollection as $website) { @@ -404,6 +405,7 @@ public function getStoreCollection() /** * Load/Reload collection(s) by type + * * Allowed types: website, group, store or null for all * * @param string $type 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 a9208876eaa7..6befb28e3538 100644 --- a/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/System/StoreTest.php @@ -6,6 +6,9 @@ namespace Magento\Store\Test\Unit\Model\System; +/** + * Class StoreTest covers Magento\Store\Model\System\Store. + */ class StoreTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index a1646e0cff06..1c4ab4eaebb4 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -310,7 +310,7 @@ define([ obj.disabled = disabled; } - if (option.hasOwnProperty("__disableTmpl")) { + if (option.hasOwnProperty('__disableTmpl')) { obj.__disableTmpl = option.__disableTmpl; } diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php index c1cfa3cf02d5..65cba5947ba0 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Catalog/Edit/FormTest.php @@ -190,6 +190,7 @@ public function testGetEntityStoresCategoryStoresException() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function formPostInitDataProvider() { @@ -226,6 +227,7 @@ public static function formPostInitDataProvider() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function getEntityStoresDataProvider() { diff --git a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php index 5bbd27640215..041a2c268a55 100644 --- a/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php +++ b/dev/tests/integration/testsuite/Magento/UrlRewrite/Block/Cms/Page/Edit/FormTest.php @@ -111,6 +111,7 @@ public function testGetEntityStoresProductStoresException() * * @static * @return array + * phpcs:disable Magento2.Functions.StaticFunction */ public static function formPostInitDataProvider() { From 64421d8acf0004ac3f1688a825948a2770fb1331 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Thu, 27 Jun 2019 12:10:47 -0500 Subject: [PATCH 0151/1172] MC-17806: Store name rendering in customer section - Resolved static test failures --- .../Ui/view/base/web/js/lib/knockout/bindings/optgroup.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js index 1c4ab4eaebb4..6ff7c1f67321 100644 --- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js +++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/optgroup.js @@ -306,6 +306,7 @@ define([ space = '\u2007\u2007\u2007'; obj[optionTitle] = applyToObject(option, optionsText + 'title', value); + if (disabled) { obj.disabled = disabled; } From 1a3dacd7e27b8befa81ce7d2aedd45b4853dd273 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Thu, 27 Jun 2019 13:27:11 -0500 Subject: [PATCH 0152/1172] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Ui/Component/Product/MassActionTest.php | 24 ++++++---- .../Translation/Model/Inline/Parser.php | 47 +++++++++++-------- .../Form/Element/AbstractOptionsField.php | 13 +++-- .../Ui/Test/Unit/Component/MassActionTest.php | 6 ++- .../View/Element/UiComponent/Context.php | 15 ++++-- 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php index dcd50d4739d7..1b2a58672a5c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -103,7 +103,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'first_action', 'label' => 'First Action', - 'url' => '/module/controller/firstAction' + 'url' => '/module/controller/firstAction', + '__disableTmpl' => true ], ], [ @@ -122,7 +123,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/secondSubAction2' ], - ] + ], + '__disableTmpl' => true ], ], [ @@ -141,7 +143,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/disable' ], - ] + ], + '__disableTmpl' => true ], ], [ @@ -160,7 +163,8 @@ public function getPrepareDataProvider() : array 'label' => 'Second Sub Action 2', 'url' => '/module/controller/disable' ], - ] + ], + '__disableTmpl' => true ], false, false @@ -170,7 +174,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/delete' + 'url' => '/module/controller/delete', + '__disableTmpl' => true ], ], [ @@ -178,7 +183,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/delete' + 'url' => '/module/controller/delete', + '__disableTmpl' => true ], false, false @@ -188,7 +194,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/attributes' + 'url' => '/module/controller/attributes', + '__disableTmpl' => true ], ], [ @@ -196,7 +203,8 @@ public function getPrepareDataProvider() : array [ 'type' => 'delete', 'label' => 'First Action', - 'url' => '/module/controller/attributes' + 'url' => '/module/controller/attributes', + '__disableTmpl' => true ], false, false diff --git a/app/code/Magento/Translation/Model/Inline/Parser.php b/app/code/Magento/Translation/Model/Inline/Parser.php index 9dc123854e87..c64622acbb6c 100644 --- a/app/code/Magento/Translation/Model/Inline/Parser.php +++ b/app/code/Magento/Translation/Model/Inline/Parser.php @@ -6,12 +6,8 @@ namespace Magento\Translation\Model\Inline; -use Magento\Framework\App\ObjectManager; -use Magento\Framework\Escaper; - /** - * This class is responsible for parsing content and applying necessary html element - * wrapping and client scripts for inline translation. + * Parses content and applies necessary html element wrapping and client scripts for inline translation. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -135,6 +131,8 @@ class Parser implements \Magento\Framework\Translate\Inline\ParserInterface private $relatedCacheTypes; /** + * Return cache manager + * * @return \Magento\Translation\Model\Inline\CacheManager * * @deprecated 100.1.0 @@ -152,8 +150,8 @@ private function getCacheManger() /** * Initialize base inline translation model * - * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Translation\Model\ResourceModel\StringUtilsFactory $resource + * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Zend_Filter_Interface $inputFilter * @param \Magento\Framework\App\State $appState * @param \Magento\Framework\App\Cache\TypeListInterface $appCache @@ -199,9 +197,6 @@ public function processAjaxPost(array $translateParams) /** @var $validStoreId int */ $validStoreId = $this->_storeManager->getStore()->getId(); - /** @var $escaper Escaper */ - $escaper = ObjectManager::getInstance()->get(Escaper::class); - /** @var $resource \Magento\Translation\Model\ResourceModel\StringUtils */ $resource = $this->_resourceFactory->create(); foreach ($translateParams as $param) { @@ -217,7 +212,7 @@ public function processAjaxPost(array $translateParams) } $resource->saveTranslate( $param['original'], - $escaper->escapeHtml($param['custom']), + $param['custom'], null, $storeId ); @@ -247,7 +242,7 @@ protected function _validateTranslationParams(array $translateParams) /** * Apply input filter to values of translation parameters * - * @param array &$translateParams + * @param array $translateParams * @param array $fieldNames Names of fields values of which are to be filtered * @return void */ @@ -371,7 +366,7 @@ protected function _applySpecialTagsFormat($tagHtml, $tagName, $trArr) * Format translation for simple tags. Added translate mode attribute for vde requests. * * @param string $tagHtml - * @param string $tagName + * @param string $tagName * @param array $trArr * @return string */ @@ -397,7 +392,7 @@ protected function _applySimpleTagsFormat($tagHtml, $tagName, $trArr) * Get translate data by regexp * * @param string $regexp - * @param string &$text + * @param string $text * @param string|array $locationCallback * @param array $options * @return array @@ -412,7 +407,7 @@ private function _getTranslateData($regexp, &$text, $locationCallback, $options 'shown' => htmlspecialchars_decode($matches[1][0]), 'translated' => htmlspecialchars_decode($matches[2][0]), 'original' => htmlspecialchars_decode($matches[3][0]), - 'location' => htmlspecialchars_decode(call_user_func($locationCallback, $matches, $options)), + 'location' => htmlspecialchars_decode($locationCallback($matches, $options)), ] ); $text = substr_replace($text, $matches[1][0], $matches[0][1], strlen($matches[0][0])); @@ -523,16 +518,28 @@ private function _getHtmlQuote() */ private function _specialTags() { - $this->_translateTags($this->_content, $this->_allowedTagsGlobal, '_applySpecialTagsFormat'); - $this->_translateTags($this->_content, $this->_allowedTagsSimple, '_applySimpleTagsFormat'); + $this->_translateTags( + $this->_content, + $this->_allowedTagsGlobal, + function ($tagHtml, $tagName, $trArr) { + return $this->_applySpecialTagsFormat($tagHtml, $tagName, $trArr); + } + ); + $this->_translateTags( + $this->_content, + $this->_allowedTagsSimple, + function ($tagHtml, $tagName, $trArr) { + return $this->_applySimpleTagsFormat($tagHtml, $tagName, $trArr); + } + ); } /** * Prepare simple tags * - * @param string &$content + * @param string $content * @param array $tagsList - * @param string|array $formatCallback + * @param callable $formatCallback * @return void */ private function _translateTags(&$content, $tagsList, $formatCallback) @@ -586,10 +593,10 @@ private function _translateTags(&$content, $tagsList, $formatCallback) if (array_key_exists($tagName, $this->_allowedTagsGlobal) && $tagBodyOpenStartPosition > $tagMatch[0][1] ) { - $tagHtmlHead = call_user_func([$this, $formatCallback], $tagHtml, $tagName, $trArr); + $tagHtmlHead = $formatCallback($tagHtml, $tagName, $trArr); $headTranslateTags .= substr($tagHtmlHead, strlen($tagHtml)); } else { - $tagHtml = call_user_func([$this, $formatCallback], $tagHtml, $tagName, $trArr); + $tagHtml = $formatCallback($tagHtml, $tagName, $trArr); } } diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 55b4ae15cdce..1229fbeec77c 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -9,6 +9,8 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; /** + * Class AbstractOptionsField + * * @api * @since 100.1.0 */ @@ -91,11 +93,14 @@ abstract public function getIsSelected($optionValue); */ protected function convertOptionsValueToString(array $options) { - array_walk($options, function (&$value) { - if (isset($value['value']) && is_scalar($value['value'])) { - $value['value'] = (string)$value['value']; + array_walk( + $options, + function (&$value) { + if (isset($value['value']) && is_scalar($value['value'])) { + $value['value'] = (string)$value['value']; + } } - }); + ); return $options; } } diff --git a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php index b2f494351597..c2e064bb3b06 100644 --- a/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php +++ b/app/code/Magento/Ui/Test/Unit/Component/MassActionTest.php @@ -104,7 +104,8 @@ public function getPrepareDataProvider() [ 'type' => 'first_action', 'label' => 'First Action', - 'url' => '/module/controller/firstAction' + 'url' => '/module/controller/firstAction', + '__disableTmpl' => true ], ], [ @@ -123,7 +124,8 @@ public function getPrepareDataProvider() 'label' => 'Second Sub Action 2', 'url' => '/module/controller/secondSubAction2' ], - ] + ], + '__disableTmpl' => true ], ], ]; diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index e95a9d44edbb..62ee657bbd6d 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -372,6 +372,7 @@ public function getUrl($route = '', $params = []) * @param array $data * @param UiComponentInterface $component * @return void + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ protected function prepareDataSource(array & $data, UiComponentInterface $component) { @@ -382,11 +383,15 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); - foreach ($data['data']['items'] as & $item) { - $name = $component->getData('name'); - if (array_key_exists($name, $item) && is_array($item[$name])) { - foreach ($item[$name] as $action => &$actionItem) { - !is_array($actionItem) ?: $actionItem['__disableTmpl'] = true; + if (isset($data['data']['items'])) { + foreach ($data['data']['items'] as & $item) { + $name = $component->getData('name'); + if (array_key_exists($name, $item) && is_array($item[$name])) { + foreach ($item[$name] as $action => &$actionItem) { + if (is_array($actionItem)) { + $actionItem['__disableTmpl'] = true; + } + } } } } From 269137ffcd98c696c59f9da6dd3bcf8a499b602f Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Thu, 27 Jun 2019 15:38:13 -0500 Subject: [PATCH 0153/1172] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Test/Unit/Ui/Component/Product/MassActionTest.php | 3 +++ .../Magento/Catalog/Ui/Component/Product/MassAction.php | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php index 1b2a58672a5c..c704d9f89581 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/Component/Product/MassActionTest.php @@ -12,6 +12,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Element\UiComponent\ContextInterface; +/** + * MassAction test + */ class MassActionTest extends \PHPUnit\Framework\TestCase { /** diff --git a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php index e54605fbe3ee..8db1bf8268b6 100644 --- a/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php +++ b/app/code/Magento/Catalog/Ui/Component/Product/MassAction.php @@ -12,6 +12,9 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Ui\Component\AbstractComponent; +/** + * Class MassAction + */ class MassAction extends AbstractComponent { const NAME = 'massaction'; @@ -40,7 +43,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function prepare() : void { @@ -64,7 +67,7 @@ public function prepare() : void } /** - * {@inheritdoc} + * @inheritdoc */ public function getComponentName() : string { From 03d5342b206b0b4fa9fefa7e6df0ec61229021e7 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 28 Jun 2019 11:09:41 -0500 Subject: [PATCH 0154/1172] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Ui/Component/Listing/Columns/ProductActions.php | 1 + .../Cms/Ui/Component/Listing/Column/BlockActions.php | 2 ++ .../Cms/Ui/Component/Listing/Column/PageActions.php | 7 +++++-- .../Customer/Ui/Component/Listing/Column/Actions.php | 1 + .../Ui/Component/Listing/Column/GroupActions.php | 4 +++- .../Ui/Component/Listing/Column/SynonymActions.php | 4 +++- .../Theme/Ui/Component/Listing/Column/EditAction.php | 3 ++- .../Theme/Ui/Component/Listing/Column/ViewAction.php | 3 ++- .../Framework/View/Element/UiComponent/Context.php | 12 ------------ 9 files changed, 19 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php index 0c4efa87c1a3..596b0f411859 100644 --- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php +++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/ProductActions.php @@ -60,6 +60,7 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php index 6e9eef47281c..65940c5d7b4f 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/BlockActions.php @@ -70,6 +70,7 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => $this->urlBuilder->getUrl( @@ -84,6 +85,7 @@ public function prepareDataSource(array $dataSource) 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, + '__disableTmpl' => true, ], ]; } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index cfac3bbf5495..ca86aec03355 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -77,7 +77,8 @@ public function prepareDataSource(array $dataSource) if (isset($item['page_id'])) { $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]), - 'label' => __('Edit') + 'label' => __('Edit'), + '__disableTmpl' => true, ]; $title = $this->getEscaper()->escapeHtml($item['title']); $item[$name]['delete'] = [ @@ -89,6 +90,7 @@ public function prepareDataSource(array $dataSource) '__disableTmpl' => true, ], 'post' => true, + '__disableTmpl' => true, ]; } if (isset($item['identifier'])) { @@ -98,7 +100,8 @@ public function prepareDataSource(array $dataSource) isset($item['_first_store_id']) ? $item['_first_store_id'] : null, isset($item['store_code']) ? $item['store_code'] : null ), - 'label' => __('View') + 'label' => __('View'), + '__disableTmpl' => true, ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php index d6a4067ef3db..9441beeb7dc6 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/Actions.php @@ -60,6 +60,7 @@ public function prepareDataSource(array $dataSource) ), 'label' => __('Edit'), 'hidden' => false, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php index 6870bd1136d1..12f6f2705125 100644 --- a/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php +++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/GroupActions.php @@ -79,6 +79,7 @@ public function prepareDataSource(array $dataSource) ] ), 'label' => __('Edit'), + '__disableTmpl' => true ], ]; @@ -102,7 +103,8 @@ public function prepareDataSource(array $dataSource) $this->escaper->escapeJs($title) ) ], - 'post' => true + 'post' => true, + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php index 8cc9b809ff88..f42ce50d2804 100644 --- a/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php +++ b/app/code/Magento/Search/Ui/Component/Listing/Column/SynonymActions.php @@ -63,11 +63,13 @@ public function prepareDataSource(array $dataSource) 'confirm' => [ 'title' => __('Delete'), 'message' => __('Are you sure you want to delete synonym group with id: %1?', $item['group_id']) - ] + ], + '__disableTmpl' => true ]; $item[$name]['edit'] = [ 'href' => $this->urlBuilder->getUrl(self::SYNONYM_URL_PATH_EDIT, ['group_id' => $item['group_id']]), 'label' => __('View/Edit'), + '__disableTmpl' => true ]; } } diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php index 801f30ce30b0..1eeeaccff88c 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/EditAction.php @@ -73,7 +73,8 @@ public function prepareDataSource(array $dataSource) 'scope_id' => $scopeId, ] ), - 'label' => __('Edit') + 'label' => __('Edit'), + '__disableTmpl' => true, ] ]; } diff --git a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php index 774d5bab660a..9e47e2c52bdd 100644 --- a/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php +++ b/app/code/Magento/Theme/Ui/Component/Listing/Column/ViewAction.php @@ -65,7 +65,8 @@ public function prepareDataSource(array $dataSource) : array $urlEntityParamName => $item[$indexField] ] ), - 'label' => __('View') + 'label' => __('View'), + '__disableTmpl' => true, ] ]; } diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index 62ee657bbd6d..c49832dac963 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -383,18 +383,6 @@ protected function prepareDataSource(array & $data, UiComponentInterface $compon } } $data = $component->prepareDataSource($data); - if (isset($data['data']['items'])) { - foreach ($data['data']['items'] as & $item) { - $name = $component->getData('name'); - if (array_key_exists($name, $item) && is_array($item[$name])) { - foreach ($item[$name] as $action => &$actionItem) { - if (is_array($actionItem)) { - $actionItem['__disableTmpl'] = true; - } - } - } - } - } } /** From 0ff326fc4574fbf1dc7140adad69bc46c22141b6 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 28 Jun 2019 11:13:03 -0500 Subject: [PATCH 0155/1172] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Magento/Framework/View/Element/UiComponent/Context.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php index c49832dac963..fbb84712b2af 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Context.php @@ -372,7 +372,6 @@ public function getUrl($route = '', $params = []) * @param array $data * @param UiComponentInterface $component * @return void - * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ protected function prepareDataSource(array & $data, UiComponentInterface $component) { From 05cd916091d467c7c7ead9ce537d30d4c0507636 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 28 Jun 2019 12:54:42 -0500 Subject: [PATCH 0156/1172] MC-16112: Signifyd Guarantee Option - clean up code, fix test failures --- .../Listing/Column/BlockActionsTest.php | 13 +++-- .../Listing/Column/PageActionsTest.php | 4 +- .../Component/Listing/Column/ActionsTest.php | 6 ++- .../Listing/Column/EditActionTest.php | 4 ++ .../Listing/Column/ViewActionTest.php | 50 +++++++++++++++---- 5 files changed, 61 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php index 6981a7983049..4ffe4a6ad877 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/BlockActionsTest.php @@ -56,10 +56,13 @@ protected function setUp() ->setMethods(['escapeHtmlAttr']) ->getMock(); - $this->blockActions = $objectManager->getObject(BlockActions::class, [ - 'context' => $context, - 'urlBuilder' => $this->urlBuilder - ]); + $this->blockActions = $objectManager->getObject( + BlockActions::class, + [ + 'context' => $context, + 'urlBuilder' => $this->urlBuilder + ] + ); $objectManager->setBackwardCompatibleProperty($this->blockActions, 'escaper', $this->escaper); } @@ -93,6 +96,7 @@ public function testPrepareDataSource() 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -102,6 +106,7 @@ public function testPrepareDataSource() 'message' => __('Are you sure you want to delete a %1 record?', $title), ], 'post' => true, + '__disableTmpl' => true, ], ], ], diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php index 32bbeed0788a..53d8ee522076 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/Column/PageActionsTest.php @@ -65,6 +65,7 @@ public function testPrepareItemsByPageId() 'edit' => [ 'href' => 'test/url/edit', 'label' => __('Edit'), + '__disableTmpl' => true, ], 'delete' => [ 'href' => 'test/url/delete', @@ -75,6 +76,7 @@ public function testPrepareItemsByPageId() '__disableTmpl' => true, ], 'post' => true, + '__disableTmpl' => true, ], ], ], @@ -84,7 +86,6 @@ public function testPrepareItemsByPageId() ->method('escapeHtml') ->with($title) ->willReturn($title); - // Configure mocks and object data $urlBuilderMock->expects($this->any()) ->method('getUrl') @@ -106,7 +107,6 @@ public function testPrepareItemsByPageId() ], ] ); - $model->setName($name); $items = $model->prepareDataSource($items); // Run test diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php index 056c7e71e182..4a16acd98d82 100644 --- a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php +++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ActionsTest.php @@ -7,6 +7,9 @@ use Magento\Customer\Ui\Component\Listing\Column\Actions; +/** + * Class ActionsTest + */ class ActionsTest extends \PHPUnit\Framework\TestCase { /** @var Actions */ @@ -64,7 +67,8 @@ public function testPrepareDataSource() 'edit' => [ 'href' => 'http://magento.com/customer/index/edit', 'label' => new \Magento\Framework\Phrase('Edit'), - 'hidden' => false + 'hidden' => false, + '__disableTmpl' => true, ] ] ], 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 2ac959d0a988..22cc1c9e89fb 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 @@ -9,6 +9,9 @@ use Magento\Store\Model\ScopeInterface; use Magento\Theme\Ui\Component\Listing\Column\EditAction; +/** + * Class EditActionTest + */ class EditActionTest extends \PHPUnit\Framework\TestCase { /** @var EditAction */ @@ -64,6 +67,7 @@ public function testPrepareDataSource($dataSourceItem, $scope, $scopeId) 'edit' => [ 'href' => 'http://magento.com/theme/design_config/edit', 'label' => new \Magento\Framework\Phrase('Edit'), + '__disableTmpl' => true, ] ], ]; diff --git a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php index 03d1fe70f2f0..5e2fe5104388 100644 --- a/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Ui/Component/Listing/Column/ViewActionTest.php @@ -99,20 +99,52 @@ public function getPrepareDataSourceDataProvider() { return [ [ - ['name' => 'itemName', 'config' => []], - [['itemName' => '', 'entity_id' => 1]], - [['itemName' => ['view' => ['href' => 'url', 'label' => __('View')]], 'entity_id' => 1]], + [ + 'name' => 'itemName', + 'config' => [] + ], + [ + ['itemName' => '', 'entity_id' => 1] + ], + [ + [ + 'itemName' => [ + 'view' => [ + 'href' => 'url', + 'label' => __('View'), + '__disableTmpl' => true, + ] + ], + 'entity_id' => 1 + ] + ], '#', ['id' => 1] ], [ - ['name' => 'itemName', 'config' => [ - 'viewUrlPath' => 'url_path', - 'urlEntityParamName' => 'theme_id', - 'indexField' => 'theme_id'] + [ + 'name' => 'itemName', + 'config' => [ + 'viewUrlPath' => 'url_path', + 'urlEntityParamName' => 'theme_id', + 'indexField' => 'theme_id' + ] + ], + [ + ['itemName' => '', 'theme_id' => 2] + ], + [ + [ + 'itemName' => [ + 'view' => [ + 'href' => 'url', + 'label' => __('View'), + '__disableTmpl' => true, + ] + ], + 'theme_id' => 2 + ] ], - [['itemName' => '', 'theme_id' => 2]], - [['itemName' => ['view' => ['href' => 'url', 'label' => __('View')]], 'theme_id' => 2]], 'url_path', ['theme_id' => 2] ] From cdf56a8105361fa4c4a339369b0bfd0128cee76a Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Mon, 8 Jul 2019 09:06:51 -0500 Subject: [PATCH 0157/1172] MC-17309: Sql builder readability --- .../Rule/Model/Condition/Sql/Builder.php | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 33e1bf97c347..961474b9d286 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -145,11 +145,8 @@ protected function _joinTablesToCollection( * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function _getMappedSqlCondition( - AbstractCondition $condition, - string $value = '', - bool $isDefaultStoreUsed = true - ): string { + protected function _getMappedSqlCondition(AbstractCondition $condition, string $value = ''): string + { $argument = $condition->getMappedSqlField(); // If rule hasn't valid argument - create negative expression to prevent incorrect rule behavior. @@ -241,6 +238,7 @@ protected function _getMappedSqlCombination( * @param AbstractCollection $collection * @param Combine $combine * @return void + * @throws \Magento\Framework\Exception\LocalizedException */ public function attachConditionToCollection( AbstractCollection $collection, @@ -250,29 +248,45 @@ public function attachConditionToCollection( $this->_joinTablesToCollection($collection, $combine); $whereExpression = (string)$this->_getMappedSqlCombination($combine); if (!empty($whereExpression)) { - if (!empty($combine->getConditions())) { - $conditions = ''; - $attributeField = ''; - foreach ($combine->getConditions() as $condition) { - if ($condition->getData('attribute') === \Magento\Catalog\Api\Data\ProductInterface::SKU) { - $conditions = $condition->getData('value'); - $attributeField = $condition->getMappedSqlField(); - } - } + $collection->getSelect()->where($whereExpression); + $this->buildConditions($collection, $combine); + } + } - $collection->getSelect()->where($whereExpression); + /** + * Build sql conditions from combination. + * + * @param AbstractCollection $collection + * @param Combine $combine + * @return void + */ + private function buildConditions(AbstractCollection $collection, Combine $combine) : void + { + if (!empty($combine->getConditions())) { + $conditions = ''; + $attributeField = ''; + foreach ($combine->getConditions() as $condition) { + if ($condition->getData('attribute') === \Magento\Catalog\Api\Data\ProductInterface::SKU) { + $conditions = $condition->getData('value'); + $attributeField = $condition->getMappedSqlField(); + } + } - if (!empty($conditions) && !empty($attributeField)) { - $conditions = explode(',', $conditions); - foreach ($conditions as &$condition) { - $condition = "'" . trim($condition) . "'"; - } - $conditions = implode(', ', $conditions); - $collection->getSelect()->order("FIELD($attributeField, $conditions)"); + if (!empty($conditions) && !empty($attributeField)) { + $conditions = explode(',', $conditions); + foreach ($conditions as &$condition) { + $condition = trim($condition); } - } else { - // Select ::where method adds braces even on empty expression - $collection->getSelect()->where($whereExpression); + $conditions = implode(', ', $conditions); + $collection->getSelect()->order( + $this->_connection->quoteInto( + "FIELD(?, ?)", + [ + $attributeField, + $conditions + ] + ) + ); } } } From 60c3c25db3b0ad5eae6f700dfbb6d60d8f64314f Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 8 Jul 2019 14:11:58 -0500 Subject: [PATCH 0158/1172] MC-16112: Signifyd Guarantee Option - fix test failure --- .../Magento/Ui/Component/Form/Element/AbstractOptionsField.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php index 1229fbeec77c..d8d1733ffdef 100644 --- a/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php +++ b/app/code/Magento/Ui/Component/Form/Element/AbstractOptionsField.php @@ -11,6 +11,7 @@ /** * Class AbstractOptionsField * + * phpcs:disable Magento2.Classes.AbstractApi * @api * @since 100.1.0 */ From 20ed50f4a77a961ad34869e3167dc3047a7cd7ad Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Tue, 9 Jul 2019 12:11:34 -0500 Subject: [PATCH 0159/1172] MC-17309: Sql builder readability --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 961474b9d286..6b1692c9723d 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -149,9 +149,11 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, string $ { $argument = $condition->getMappedSqlField(); - // If rule hasn't valid argument - create negative expression to prevent incorrect rule behavior. + // If rule hasn't valid argument - prevent incorrect rule behavior. if (empty($argument)) { return $this->_expressionFactory->create(['expression' => '1 = -1']); + } elseif (preg_match('/[^a-z0-9\-_\.\`]/i', $argument) > 0) { + throw new \Magento\Framework\Exception\LocalizedException(__('Invalid field')); } $conditionOperator = $condition->getOperatorForValidate(); @@ -192,7 +194,6 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, string $ ); } } - return $this->_expressionFactory->create( ['expression' => $expression] ); From 06a7fcd3295aa5429ccae25c6080d1625fd0aa83 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Tue, 9 Jul 2019 14:25:45 -0500 Subject: [PATCH 0160/1172] MC-17309: Sql builder readability --- app/code/Magento/Rule/Model/Condition/Sql/Builder.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php index 6b1692c9723d..f44b78835410 100644 --- a/app/code/Magento/Rule/Model/Condition/Sql/Builder.php +++ b/app/code/Magento/Rule/Model/Condition/Sql/Builder.php @@ -145,8 +145,11 @@ protected function _joinTablesToCollection( * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function _getMappedSqlCondition(AbstractCondition $condition, string $value = ''): string - { + protected function _getMappedSqlCondition( + AbstractCondition $condition, + string $value = '', + bool $isDefaultStoreUsed = true + ): string { $argument = $condition->getMappedSqlField(); // If rule hasn't valid argument - prevent incorrect rule behavior. From 861ef75fbb90f5bb0b04b7f27833ac4c25a9c6df Mon Sep 17 00:00:00 2001 From: Ani Tumanyan <ani_tumanyan@epam.com> Date: Wed, 10 Jul 2019 16:13:14 +0400 Subject: [PATCH 0161/1172] MC-15507: shipping address is dropped after zip code in new billing address form is filled - Added automated test --- ...eckoutFillNewBillingAddressActionGroup.xml | 4 + .../Checkout/Test/Mftf/Page/CheckoutPage.xml | 1 + .../Mftf/Section/CheckoutPaymentSection.xml | 2 +- .../Mftf/Section/CheckoutShippingSection.xml | 1 + .../SelectShippingAddressPopupSection.xml | 16 ++ ...AffectOnShippingAddressAfterUpdateTest.xml | 148 ++++++++++++++++++ .../Customer/Test/Mftf/Data/AddressData.xml | 15 ++ .../Customer/Test/Mftf/Data/CustomerData.xml | 14 ++ 8 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 59e997eccecc..6d92ca79000e 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -24,6 +24,10 @@ <fillField selector="{{CheckoutPaymentSection.guestPostcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> <fillField selector="{{CheckoutPaymentSection.guestTelephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> </actionGroup> + <actionGroup name="CheckoutFillNewBillingAddressActionGroup" extends="GuestCheckoutFillNewBillingAddressActionGroup"> + <remove keyForRemoval="enterEmail"/> + <remove keyForRemoval="waitForLoading3"/> + </actionGroup> <actionGroup name="LoggedInCheckoutFillNewBillingAddressActionGroup"> <arguments> diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutPage.xml index d3fa045e4654..d6173dfa1791 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutPage.xml @@ -14,5 +14,6 @@ <section name="CheckoutOrderSummarySection"/> <section name="CheckoutSuccessMainSection"/> <section name="CheckoutPaymentSection"/> + <section name="SelectShippingBillingPopupSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index e1c2a3b1550f..13bac9cefb68 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -46,7 +46,6 @@ <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> <element name="productItemPriceByName" type="text" selector="//div[@class='product-item-details'][contains(., '{{ProductName}}')]//span[@class='price']" parameterized="true"/> - <element name="tax" type="text" selector="[data-th='Tax'] span" timeout="30"/> <element name="taxPercentage" type="text" selector=".totals-tax-details .mark"/> <element name="orderSummaryTotalIncluding" type="text" selector="//tr[@class='grand totals incl']//span[@class='price']" /> @@ -59,5 +58,6 @@ <element name="billingAddressSelectShared" type="select" selector=".checkout-billing-address select[name='billing_address_id']"/> <element name="discount" type="block" selector="tr.totals.discount"/> <element name="discountPrice" type="text" selector=".discount .price"/> + <element name="changeAddressButton" type="button" selector="(//button[@class='action action-additional'][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index f90ec0aad462..bf1001ad6b28 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -41,5 +41,6 @@ <element name="shipHereButton" type="button" selector="//div[text()='{{street}}']/button[@class='action action-select-shipping-item']" parameterized="true" timeout="30"/> <element name="textFieldAttrRequireMessage" type="text" selector="//input[@name='custom_attributes[{{attribute}}]']/ancestor::div[contains(@class, 'control')]/div/span" parameterized="true" timeout="30"/> <element name="textFieldAttribute" type="input" selector="[name*='custom_attributes[{{attribute}}]']" parameterized="true" timeout="30"/> + <element name="changeAddressButton" type="button" selector="//button[@class='action action-additional'][contains(@data-bind,'openAddressSelection')]"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml new file mode 100644 index 000000000000..ff1431ab33ba --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="SelectBillingAddressPopupSection"> + <element name="shippingAddressSearch" type="input" selector="//input[@class='admin__control-text admin__action-multiselect-search']"/> + <element name="selectButton" type="button" selector="//button[@class='action-primary action-select-billing-item']"/> + <element name="shippingAddressSearchParametrised" type="input" selector="(//input[@class='admin__control-text admin__action-multiselect-search'])[{{index}}]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml new file mode 100644 index 000000000000..9b2958a190be --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml @@ -0,0 +1,148 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="BillingAddressFormAffectOnShippingAddressAfterUpdateTest"> + <annotations> + <features value="Checkout"/> + <title value="Billing address form does not affect shipping address after update"/> + <description value="Billing address form does not affect shipping address after update"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-16961"/> + <useCaseId value="MC-15507"/> + <group value="checkout"/> + </annotations> + <before> + <!-- Login as Admin --> + <comment userInput="Login as Admin" stepKey="commentLoginAsAdmin"/> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <!-- Create simple product and add to category --> + <comment userInput="Create simple product and add to category" stepKey="commentAddProductToCategory"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!-- Create customer --> + <comment userInput="Create customer" stepKey="commentCreateCustomer"/> + <createData entity="Simple_US_Customer_Without_Default_Address" stepKey="createCustomer"/> + </before> + <after> + <!-- Log out --> + <comment userInput="Log out" stepKey="commentLogOut"/> + <actionGroup ref="logout" stepKey="logout"/> + <!-- Delete data --> + <comment userInput="Delete data" stepKey="commentDeleteData"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <!-- Set default configurations --> + <comment userInput="Set default configurations" stepKey="commentSetDefaultConfigurations"/> + <magentoCLI command="config:set checkout/options/enable_address_search 0" stepKey="setDefaultEnableAddressSearch"/> + <magentoCLI command="config:set checkout/options/customer_address_limit 10" stepKey="setDefaultCount"/> + </after> + <!-- Login to the Storefront as created customer --> + <comment userInput="Login to the Storefront as created customer" stepKey="commentLoginAsCustomer"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <!-- Add 3 addresses to Address book--> + <comment userInput="Add 3 addresses to Address book" stepKey="commentAddAddresses"/> + <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressFirst"> + <argument name="Address" value="US_Address_NY"/> + </actionGroup> + <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressSecond"> + <argument name="Address" value="US_Address_CA"/> + </actionGroup> + <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressThird"> + <argument name="Address" value="US_Address_TX"/> + </actionGroup> + <!-- Add product to the Shopping Cart --> + <comment userInput="Add product to the Shopping Cart" stepKey="commentAddProductToTheCart"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnStorefrontProductFirstPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCart"> + <argument name="product" value="$$createProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckout"/> + <click selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="changeShippingAddressButton"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNext"/> + <!-- Click next button to open payment section --> + <comment userInput="Click next button to open payment section" stepKey="commentClickToNextButton"/> + <click selector="{{CheckoutShippingGuestInfoSection.next}}" stepKey="clickNext"/> + <waitForPageLoad stepKey="waitForShipmentPageLoad"/> + <uncheckOption selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="selectPaymentSolution"/> + <waitForElement selector="{{CheckoutPaymentSection.billingAddressSelectShared}}" time="30" stepKey="waitForAddressField"/> + <selectOption selector="{{CheckoutPaymentSection.billingAddressSelectShared}}" userInput="New Address" stepKey="chooseNewAddress"/> + <waitForPageLoad stepKey="waitForNewAddressPageLoad"/> + <actionGroup ref="CheckoutFillNewBillingAddressActionGroup" stepKey="guestCheckoutFillingBillingAddress"> + <argument name="customerVar" value="CustomerEntityOne"/> + <argument name="customerAddressVar" value="CustomerAddressSimple"/> + </actionGroup> + <click selector="{{CheckoutPaymentSection.update}}" stepKey="clickUpdateButton"/> + <waitForPageLoad stepKey="waitForProcessing"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickToPlaceOrder"/> + <see userInput="Thank you for your purchase!" stepKey="seeSuccessMessage"/> + <waitForPageLoad stepKey="waitForSuccess"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> + <!-- Go to my Orders page --> + <comment userInput="Go to my Orders page" stepKey="commentOpenMyOrders"/> + <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onMyAccount"/> + <waitForPageLoad stepKey="waitForAccountPage"/> + <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickOnMyOrders"/> + <waitForPageLoad stepKey="waitForOrdersLoad"/> + <!-- Click 'View Order' link on order --> + <comment userInput="Click 'View Order' link on order" stepKey="commentViewOrder"/> + <click selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabOrderNumber})}}" stepKey="clickOrderView"/> + <waitForPageLoad stepKey="waitForOrderPageLoad"/> + <see selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" userInput="New York" stepKey="seeNewYorkInShippingSection"/> + <!-- Set configurations --> + <comment userInput="Set configurations" stepKey="commentSetConfigurations"/> + <magentoCLI command="config:set checkout/options/enable_address_search 1" stepKey="setEnableAddressSearch"/> + <magentoCLI command="config:set checkout/options/customer_address_limit 2" stepKey="setCount"/> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnStorefrontProductFirstPageSecond"/> + <waitForPageLoad stepKey="waitForPageLoadSecond"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCartSecond"> + <argument name="product" value="$$createProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutSecond"/> + <click selector="{{CheckoutShippingSection.changeAddressButton}}" stepKey="clickToChangeShippingAddress"/> + <waitForPageLoad stepKey="waitForPopupLoad"/> + <fillField selector="{{SelectBillingAddressPopupSection.shippingAddressSearch}}" userInput="California" stepKey="fillAddressSearchField"/> + <waitForPageLoad stepKey="waitForAddressPopupLoad"/> + <waitForElementVisible selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="waitForShipHereButton"/> + <click selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="changeShippingAddress"/> + <waitForElementVisible selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> + <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickToNextButtonSecond"/> + <waitForPageLoad stepKey="waitForNextPageLoadSecond"/> + <click selector="{{CheckoutPaymentSection.changeAddressButton('2')}}" stepKey="clickToChangePaymentAddress"/> + <waitForPageLoad stepKey="waitForPaymentAddressPopupLoad"/> + <fillField selector="{{SelectBillingAddressPopupSection.shippingAddressSearchParametrised('2')}}" userInput="New York" stepKey="fillPaymentAddressSearchField"/> + <waitForPageLoad stepKey="waitForAddressPopup"/> + <waitForElementVisible selector="{{SelectBillingAddressPopupSection.selectButton}}" stepKey="waitForSelectButton"/> + <click selector="{{SelectBillingAddressPopupSection.selectButton}}" stepKey="clickToSelectButtonSecond"/> + <waitForPageLoad stepKey="waitForPaymentLoading"/> + <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickToPlaceOrderButton"/> + <waitForPageLoad stepKey="waitForSuccessMessage"/> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderId"/> + <!-- Go to my Orders page --> + <comment userInput="Go to my Orders page" stepKey="commentGoToMyOrders"/> + <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="openMyAccount"/> + <waitForPageLoad stepKey="waitForAccountPageLoad"/> + <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickToMyOrders"/> + <waitForPageLoad stepKey="waitForOrderLoad"/> + <!-- Click 'View Order' link on order from preconditions --> + <click selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabOrderId})}}" stepKey="clickToOrderViewButton"/> + <waitForPageLoad stepKey="waitForOrderPage"/> + <comment userInput="Click 'View Order' link on order" stepKey="commentClickToViewOrder"/> + <see selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" userInput="California" stepKey="seeCaliforniaInShippingSection"/> + <see selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" userInput="New York" stepKey="seeNewYorkInBillingSection"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 88f86e456e5b..1ea7b924ba10 100755 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -51,6 +51,21 @@ <data key="default_shipping">Yes</data> <requiredEntity type="region">RegionTX</requiredEntity> </entity> + <entity name="US_Address_TX_Without_Default" type="address"> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="company">Magento</data> + <array key="street"> + <item>7700 West Parmer Lane</item> + </array> + <data key="city">Austin</data> + <data key="state">Texas</data> + <data key="country_id">US</data> + <data key="country">United States</data> + <data key="postcode">78729</data> + <data key="telephone">512-345-6789</data> + <requiredEntity type="region">RegionTX</requiredEntity> + </entity> <entity name="US_Address_TX_Default_Billing" type="address"> <data key="firstname">John</data> <data key="lastname">Doe</data> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index 55bc9b56c791..d19d0bfa6518 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -47,6 +47,20 @@ <data key="group">General</data> <requiredEntity type="address">US_Address_TX</requiredEntity> </entity> + <entity name="Simple_US_Customer_Without_Default_Address" type="customer"> + <data key="group_id">1</data> + <data key="default_billing">true</data> + <data key="default_shipping">true</data> + <data key="email" unique="prefix">John.Doe@example.com</data> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="fullname">John Doe</data> + <data key="password">pwdTest123!</data> + <data key="store_id">0</data> + <data key="website_id">0</data> + <data key="group">General</data> + <requiredEntity type="address">US_Address_TX_Without_Default</requiredEntity> + </entity> <entity name="SimpleUsCustomerWithNewCustomerGroup" type="customer"> <data key="default_billing">true</data> <data key="default_shipping">true</data> From 04f44c3295679ce5efbf21b37bafca8717887579 Mon Sep 17 00:00:00 2001 From: Mark Berube <berube@adobe.com> Date: Mon, 15 Jul 2019 14:12:33 -0500 Subject: [PATCH 0162/1172] MC-18101: Validate file deletion path on data export --- .../ImportExport/Controller/Adminhtml/Export/File/Delete.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php index 6996ba90c3e1..4ba0d024ef68 100644 --- a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php +++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/File/Delete.php @@ -67,6 +67,11 @@ public function execute() } $directory = $this->filesystem->getDirectoryRead(DirectoryList::VAR_DIR); $path = $directory->getAbsolutePath() . 'export/' . $fileName; + + if (!$directory->isFile($path)) { + throw new LocalizedException(__('Sorry, but the data is invalid or the file is not uploaded.')); + } + $this->file->deleteFile($path); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); From c98cfd565d5f660bca73221214ac8241105777e7 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 16 Jul 2019 16:54:17 +0300 Subject: [PATCH 0163/1172] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/File/Upload.php | 30 +++++++++++------- .../Adminhtml/Downloadable/FileTest.php | 31 +++++++++++++++++-- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php index 83b2797050db..c8f7a4ff4a50 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php @@ -7,6 +7,8 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Exception\FileSystemException; +use Magento\Framework\Exception\LocalizedException; /** * Class Upload @@ -76,23 +78,27 @@ public function __construct( */ public function execute() { - $type = $this->getRequest()->getParam('type'); - $tmpPath = ''; - if ($type == 'samples') { - $tmpPath = $this->_sample->getBaseTmpPath(); - } elseif ($type == 'links') { - $tmpPath = $this->_link->getBaseTmpPath(); - } elseif ($type == 'link_samples') { - $tmpPath = $this->_link->getBaseSampleTmpPath(); - } - try { + $type = $this->getRequest()->getParam('type'); + $tmpPath = ''; + if ($type == 'samples') { + $tmpPath = $this->_sample->getBaseTmpPath(); + } elseif ($type == 'links') { + $tmpPath = $this->_link->getBaseTmpPath(); + } elseif ($type == 'link_samples') { + $tmpPath = $this->_link->getBaseSampleTmpPath(); + } else { + throw new LocalizedException(__('Upload type can not be determined.')); + } + $uploader = $this->uploaderFactory->create(['fileId' => $type]); $result = $this->_fileHelper->uploadFromTmp($tmpPath, $uploader); if (!$result) { - throw new \Exception('File can not be moved from temporary folder to the destination folder.'); + throw new FileSystemException( + __('File can not be moved from temporary folder to the destination folder.') + ); } unset($result['tmp_name'], $result['path']); @@ -101,7 +107,7 @@ public function execute() $relativePath = rtrim($tmpPath, '/') . '/' . ltrim($result['file'], '/'); $this->storageDatabase->saveFile($relativePath); } - } catch (\Exception $e) { + } catch (\Throwable $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index 60c2a41fae49..ac35fa9a23b1 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -1,4 +1,9 @@ <?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + namespace Magento\Downloadable\Controller\Adminhtml\Downloadable; use Magento\Framework\Serialize\Serializer\Json; @@ -7,9 +12,10 @@ /** * Magento\Downloadable\Controller\Adminhtml\Downloadable\File * - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. * @magentoAppArea adminhtml + * + * phpcs:disable Magento2.Functions.DiscouragedFunction + * phpcs:disable Magento2.Security.Superglobal */ class FileTest extends \Magento\TestFramework\TestCase\AbstractBackendController { @@ -90,4 +96,25 @@ public function extensionsDataProvider() ['sample.php7'], ]; } + + /** + * @return void + */ + public function testUploadWrongUploadType(): void + { + $postData = [ + 'type' => [ + 'tmp_name' => 'test.txt', + 'name' => 'result.txt', + ], + ]; + $this->getRequest()->setPostValue($postData); + + $this->getRequest()->setMethod('POST'); + $this->dispatch('backend/admin/downloadable_file/upload'); + $body = $this->getResponse()->getBody(); + $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $this->assertEquals('Upload type can not be determined.', $result['error']); + $this->assertEquals(0, $result['errorcode']); + } } From 54986eddee7fc6311a03978640a17e3b9085c02f Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 16 Jul 2019 13:44:56 -0500 Subject: [PATCH 0164/1172] MC-17700: Downloadable Product links --- .../Mftf/Test/SearchEntityResultsTest.xml | 2 + ...ownloadableProductFromShoppingCartTest.xml | 2 + ...OnePageCheckoutWithAllProductTypesTest.xml | 2 + ...dDownloadableProductToShoppingCartTest.xml | 2 + ...oadableProductFromMiniShoppingCartTest.xml | 2 + .../StorefrontClearAllCompareProductsTest.xml | 2 + .../Console/Command/DomainsAddCommand.php | 118 ++++++++++++++ .../Console/Command/DomainsRemoveCommand.php | 120 ++++++++++++++ .../Console/Command/DomainsShowCommand.php | 79 +++++++++ .../Model/Link/ContentValidator.php | 29 +++- .../Model/Sample/ContentValidator.php | 24 ++- .../Model/Url/DomainValidator.php | 124 ++++++++++++++ .../Patch/Data/AddDownloadableHostsConfig.php | 151 ++++++++++++++++++ ...AddDefaultImageDownloadableProductTest.xml | 2 + ...AddDefaultVideoDownloadableProductTest.xml | 7 +- ...bleProductAndAssignItToCustomStoreTest.xml | 2 + ...wnloadableProductWithCustomOptionsTest.xml | 2 + ...loadableProductWithDefaultSetLinksTest.xml | 2 + ...eDownloadableProductWithGroupPriceTest.xml | 2 + ...nCreateDownloadableProductWithLinkTest.xml | 2 + ...DownloadableProductWithManageStockTest.xml | 2 + ...oadableProductWithOutOfStockStatusTest.xml | 2 + ...ownloadableProductWithSpecialPriceTest.xml | 2 + ...teDownloadableProductWithTierPriceText.xml | 6 + ...ductWithoutFillingQuantityAndStockTest.xml | 2 + ...wnloadableProductWithoutTaxClassIdTest.xml | 2 + .../AdminDeleteDownloadableProductTest.xml | 2 + ...oveDefaultImageDownloadableProductTest.xml | 2 + ...oveDefaultVideoDownloadableProductTest.xml | 6 + ...ceCatalogSearchDownloadableProductTest.xml | 20 +++ ...loadableProductFromGuestToCustomerTest.xml | 2 + ...ductsListWidgetDownloadableProductTest.xml | 7 + .../Unit/Model/Link/ContentValidatorTest.php | 13 ++ app/code/Magento/Downloadable/etc/di.xml | 9 ++ app/code/Magento/Downloadable/i18n/en_US.csv | 1 + .../Api/ProductRepositoryInterfaceTest.php | 48 +++++- .../Api/ProductRepositoryTest.php | 18 +++ .../Mtf/Util/Command/Cli/EnvWhitelist.php | 40 +++++ .../ProductTypeSwitchingOnUpdateTest.php | 15 +- .../AddProductsToShoppingCartEntityTest.php | 16 +- ...ePageCheckoutOfflinePaymentMethodsTest.php | 29 ++++ ...eProductFromMiniShoppingCartEntityTest.php | 24 ++- .../TestCase/PrintOrderFrontendGuestTest.php | 18 ++- .../AddProductToWishlistEntityTest.php | 27 +++- ...ProductInCustomerWishlistOnBackendTest.php | 27 +++- ...ProductInCustomerWishlistOnBackendTest.php | 27 +++- ...ote_with_downloadable_product_rollback.php | 8 + .../Model/Url/DomainValidatorTest.php | 93 +++++++++++ ...able_product_with_files_and_sample_url.php | 12 +- ...uct_with_files_and_sample_url_rollback.php | 11 ++ .../_files/product_downloadable.php | 25 ++- .../_files/product_downloadable_rollback.php | 24 ++- .../product_downloadable_with_files.php | 21 ++- 53 files changed, 1191 insertions(+), 46 deletions(-) create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php create mode 100644 app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php create mode 100644 app/code/Magento/Downloadable/Model/Url/DomainValidator.php create mode 100644 app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php create mode 100644 dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php create mode 100644 dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index 19db201e91f4..f98e715963d2 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -368,6 +368,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <createData entity="_defaultCategory" stepKey="createCategory"/> <createData entity="DownloadableProductWithOneLink" stepKey="createProduct"> <requiredEntity createDataKey="createCategory"/> @@ -379,6 +380,7 @@ <after> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToFrontPage"/> <actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="searchStorefront"> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml index 1a51e1e02fe8..1eee2d510e7b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create downloadable product --> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink"> @@ -32,6 +33,7 @@ <after> <!-- Delete downloadable product --> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteDownloadableProduct"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add downloadable product to the cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index 3ec73aec580d..56d1b97974bb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="_defaultCategory" stepKey="createCategory"/> @@ -109,6 +110,7 @@ <!-- Logout customer --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogoutStorefront"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add Simple Product to cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml index 7a4655bb19ce..734cedd2c1a3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml @@ -18,6 +18,7 @@ </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"/> <createData entity="downloadableLink1" stepKey="addDownloadableLink1"> @@ -32,6 +33,7 @@ <after> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml index 461139b6d4b3..ed2e2c62f54b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml @@ -19,6 +19,7 @@ </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> <createData entity="FlatRateShippingMethodDefault" stepKey="setDefaultFlatRateShippingMethod"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"/> @@ -31,6 +32,7 @@ <after> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index 2b88657c6ca2..e27650ff251d 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -20,6 +20,7 @@ </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create Simple Customer --> <createData entity="Simple_US_Customer_CA" stepKey="createSimpleCustomer1"/> @@ -94,6 +95,7 @@ <deleteData createDataKey="createBundleProduct1" stepKey="deleteBundleProduct1"/> <deleteData createDataKey="createGroupedProduct1" stepKey="deleteGroupedProduct1"/> <deleteData createDataKey="createDownloadableProduct1" stepKey="deleteDownloadableProduct1"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer1"> diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php new file mode 100644 index 000000000000..8158296678de --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -0,0 +1,118 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Downloadable\Console\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; + +use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; +use Magento\Downloadable\Model\Url\DomainValidator; +use Magento\Framework\Config\File\ConfigFilePool; + +/** + * Class DomainsAddCommand + * + * Command for adding downloadable domain to the whitelist + */ +class DomainsAddCommand extends Command +{ + /** + * Name of domains input argument + */ + const INPUT_KEY_DOMAINS = 'domains'; + + /** + * @var ConfigWriter + */ + private $configWriter; + + /** + * @var DomainValidator + */ + private $domainValidator; + + /** + * DomainsAddCommand constructor. + * + * @param ConfigWriter $configWriter + * @param DomainValidator $domainValidator + */ + public function __construct( + ConfigWriter $configWriter, + DomainValidator $domainValidator + ) { + $this->configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Add domains to the downloadable domains whitelist'; + + $this->setName('downloadable:domains:add') + ->setDescription($description) + ->setDefinition( + [ + new InputArgument( + self::INPUT_KEY_DOMAINS, + InputArgument::IS_ARRAY, + 'Domains name' + ) + ] + ); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); + $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); + + $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; + foreach ($newDomains as $newDomain) { + if (in_array($newDomain, $whitelist)) { + $output->writeln( + "$newDomain is already in the whitelist" + ); + continue; + } else { + array_push($whitelist, $newDomain); + $output->writeln( + "$newDomain was added to the whitelist" + ); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ] + ); + } + + } catch (\Exception $e) { + $output->writeln('<error>' . $e->getMessage() . '</error>'); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php new file mode 100644 index 000000000000..1fa02ae6359b --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -0,0 +1,120 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Downloadable\Console\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputArgument; + +use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; +use Magento\Downloadable\Model\Url\DomainValidator; +use Magento\Framework\Config\File\ConfigFilePool; + +/** + * Class DomainsRemoveCommand + * + * Command for removing downloadable domain from the whitelist + */ +class DomainsRemoveCommand extends Command +{ + /** + * Name of domains input argument + */ + const INPUT_KEY_DOMAINS = 'domains'; + + /** + * @var ConfigWriter + */ + private $configWriter; + + /** + * @var DomainValidator + */ + private $domainValidator; + + /** + * DomainsRemoveCommand constructor. + * + * @param ConfigWriter $configWriter + * @param DomainValidator $domainValidator + */ + public function __construct( + ConfigWriter $configWriter, + DomainValidator $domainValidator + ) { + $this->configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Remove domains from the downloadable domains whitelist'; + + $this->setName('downloadable:domains:remove') + ->setDescription($description) + ->setDefinition( + [ + new InputArgument( + self::INPUT_KEY_DOMAINS, + InputArgument::IS_ARRAY, + 'Domain names' + ) + ] + ); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); + $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); + + $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; + foreach ($removeDomains as $removeDomain) { + if (in_array($removeDomain, $whitelist)) { + $index = array_search($removeDomain, $whitelist); + unset($whitelist[$index]); + $output->writeln( + "$removeDomain was removed from the whitelist" + ); + continue; + } else { + $output->writeln( + "$removeDomain is absent in the whitelist" + ); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } + + } catch (\Exception $e) { + $output->writeln('<error>' . $e->getMessage() . '</error>'); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php new file mode 100644 index 000000000000..70e031eb3e41 --- /dev/null +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -0,0 +1,79 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Downloadable\Console\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Input\InputInterface; + +use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; +use Magento\Downloadable\Model\Url\DomainValidator; + +/** + * Class DomainsAddCommand + * + * Command for listing allowed downloadable domains + */ +class DomainsShowCommand extends Command +{ + /** + * @var ConfigWriter + */ + private $configWriter; + + /** + * @var DomainValidator + */ + private $domainValidator; + + /** + * DomainsShowCommand constructor. + * + * @param ConfigWriter $configWriter + * @param DomainValidator $domainValidator + */ + public function __construct( + ConfigWriter $configWriter, + DomainValidator $domainValidator + ) { + $this->configWriter = $configWriter; + $this->domainValidator = $domainValidator; + parent::__construct(); + } + + /** + * @inheritdoc + */ + protected function configure() + { + $description = 'Display downloadable domains whitelist'; + + $this->setName('downloadable:domains:show') + ->setDescription($description); + parent::configure(); + } + + /** + * @inheritdoc + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + try { + $whitelist = implode("\n", $this->domainValidator->getEnvDomainWhitelist() ?: []); + $output->writeln( + "Downloadable domains whitelist:\n$whitelist" + ); + + } catch (\Exception $e) { + $output->writeln('<error>' . $e->getMessage() . '</error>'); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln($e->getTraceAsString()); + } + return; + } + } +} diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 8497bf7de659..08345c8079dd 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -12,12 +12,23 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +use Magento\Downloadable\Model\Url\DomainValidator; /** * Class to validate Link Content. */ class ContentValidator { + /** + * @var DomainValidator + */ + private $domainValidator; + + /** + * @var File + */ + private $fileHelper; + /** * @var FileContentValidator */ @@ -28,24 +39,22 @@ class ContentValidator */ protected $urlValidator; - /** - * @var File - */ - private $fileHelper; - /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator * @param File|null $fileHelper + * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null + File $fileHelper = null, + DomainValidator $domainValidator = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); + $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** @@ -91,7 +100,9 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid protected function validateLinkResource(LinkInterface $link) { if ($link->getLinkType() === 'url') { - if (!$this->urlValidator->isValid($link->getLinkUrl())) { + if (!$this->urlValidator->isValid($link->getLinkUrl()) + || !$this->domainValidator->isValid($link->getLinkUrl()) + ) { throw new InputException(__('Link URL must have valid format.')); } } elseif ($link->getLinkFileContent()) { @@ -113,7 +124,9 @@ protected function validateLinkResource(LinkInterface $link) protected function validateSampleResource(LinkInterface $link) { if ($link->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($link->getSampleUrl())) { + if (!$this->urlValidator->isValid($link->getSampleUrl()) + || !$this->domainValidator->isValid($link->getSampleUrl()) + ) { throw new InputException(__('Sample URL must have valid format.')); } } elseif ($link->getSampleFileContent()) { diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7348b04793a8..7b8c65580f16 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -12,12 +12,23 @@ use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\ValidatorException; use Magento\Framework\Url\Validator as UrlValidator; +use Magento\Downloadable\Model\Url\DomainValidator; /** * Class to validate Sample Content. */ class ContentValidator { + /** + * @var File + */ + private $fileHelper; + + /** + * @var DomainValidator + */ + private $domainValidator; + /** * @var UrlValidator */ @@ -28,24 +39,22 @@ class ContentValidator */ protected $fileContentValidator; - /** - * @var File - */ - private $fileHelper; - /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator * @param File|null $fileHelper + * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null + File $fileHelper = null, + DomainValidator $domainValidator = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); + $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** @@ -79,7 +88,8 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) protected function validateSampleResource(SampleInterface $sample) { if ($sample->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($sample->getSampleUrl())) { + if (!$this->urlValidator->isValid($sample->getSampleUrl()) + || !$this->domainValidator->isValid($sample->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } } elseif ($sample->getSampleFileContent()) { diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php new file mode 100644 index 000000000000..5cdd954edb15 --- /dev/null +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -0,0 +1,124 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Downloadable\Model\Url; + +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Validator\Ip as IpValidator; +use Zend\Uri\Uri as UriHandler; + +/** + * Class is responsible for checking if downloadable product link domain is allowed. + */ +class DomainValidator extends \Zend_Validate_Abstract +{ + /** + * Invalid host message key + */ + const INVALID_HOST = 'invalidHost'; + + /** + * Path to the allowed domains in the deployment config + */ + const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; + + /** + * @var IpValidator + */ + private $ipValidator; + + /** + * @var UriHandler + */ + private $uriHandler; + + /** + * @var DeploymentConfig + */ + private $deploymentConfig; + + /** + * @param DeploymentConfig $deploymentConfig + * @param IpValidator $ipValidator + * @param UriHandler $uriHandler + */ + public function __construct( + DeploymentConfig $deploymentConfig, + IpValidator $ipValidator, + UriHandler $uriHandler + ) { + $this->deploymentConfig = $deploymentConfig; + $this->ipValidator = $ipValidator; + $this->uriHandler = $uriHandler; + + $this->initMessageTemplates(); + } + + /** + * Validate url input. + * + * Assert parsed host of $value is contained within environment whitelist + * + * @param string $value + * @return bool + */ + public function isValid($value): bool + { + $host = $this->getHost($value); + + $isIpAddress = $this->ipValidator->isValid($host); + $isValid = !$isIpAddress && in_array($host, $this->getEnvDomainWhitelist()); + + if (!$isValid) { + $this->_error(self::INVALID_HOST, $host); + } + + return $isValid; + } + + /** + * Get environment whitelist + * + * @return array + */ + public function getEnvDomainWhitelist(): array + { + return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); + } + + /** + * Extract host from url + * + * @param string $url + * @return string + */ + private function getHost($url): string + { + $host = $this->uriHandler->parse($url)->getHost(); + + if ($host === null) { + return ''; + } + + // ipv6 hosts are brace-delimited in url; they are removed here for subsequent validation + return trim($host, '[] '); + } + + /** + * Initialize message templates with translating + * + * @return void + */ + private function initMessageTemplates() + { + if (!$this->_messageTemplates) { + $this->_messageTemplates = [ + self::INVALID_HOST => __('Host "%value%" is not allowed.'), + ]; + } + } +} diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php new file mode 100644 index 000000000000..d63d28256809 --- /dev/null +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -0,0 +1,151 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Downloadable\Setup\Patch\Data; + +use Magento\Framework\Setup\Patch\DataPatchInterface; +use Zend\Uri\Uri as UriHandler; +use Magento\Framework\Url\ScopeResolverInterface; +use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; +use Magento\Downloadable\Model\Url\DomainValidator; +use Magento\Framework\Config\File\ConfigFilePool; +use Magento\Framework\Setup\ModuleDataSetupInterface; + +/** + * Adding base url as allowed downloadable domain. + */ +class AddDownloadableHostsConfig implements DataPatchInterface +{ + /** + * @var UriHandler + */ + private $uriHandler; + + /** + * @var ScopeResolverInterface + */ + private $scopeResolver; + + /** + * @var ConfigWriter + */ + private $configWriter; + + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var array + */ + private $whitelist = []; + + /** + * AddDownloadableHostsConfig constructor. + * + * @param UriHandler $uriHandler + * @param ScopeResolverInterface $scopeResolver + * @param ConfigWriter $configWriter + * @param ModuleDataSetupInterface $moduleDataSetup + */ + public function __construct( + UriHandler $uriHandler, + ScopeResolverInterface $scopeResolver, + ConfigWriter $configWriter, + ModuleDataSetupInterface $moduleDataSetup + ) { + $this->uriHandler = $uriHandler; + $this->scopeResolver = $scopeResolver; + $this->configWriter = $configWriter; + $this->moduleDataSetup = $moduleDataSetup; + } + + /** + * @inheritdoc + */ + public function apply() + { + if ($this->moduleDataSetup->tableExists('downloadable_link')) { + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_link'), + ['link_url'] + )->where('link_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['link_url']); + } + + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_link'), + ['sample_url'] + )->where('sample_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['sample_url']); + } + } + + if ($this->moduleDataSetup->tableExists('downloadable_sample')) { + $select = $this->moduleDataSetup->getConnection() + ->select() + ->from( + $this->moduleDataSetup->getTable('downloadable_sample'), + ['sample_url'] + )->where('sample_type = ?', 'url'); + + foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { + $this->addHost($link['sample_url']); + } + } + + foreach ($this->scopeResolver->getScopes() as $scope) { + $this->addHost($scope->getBaseUrl()); + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + DomainValidator::PARAM_DOWNLOADABLE_DOMAINS => array_unique($this->whitelist) + ] + ] + ); + } + + /** + * Add host to whitelist + * + * @param string $url + */ + private function addHost($url) + { + $host = $this->uriHandler->parse($url)->getHost(); + if ($host && !in_array($host, $this->whitelist)) { + $this->whitelist[] = $host; + } + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return []; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml index 3d779740849c..15e64b9bbd35 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml @@ -19,9 +19,11 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml index a7acdfded29b..4bbd815e8db0 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml @@ -18,7 +18,12 @@ <testCaseId value="MC-114"/> <group value="Downloadable"/> </annotations> - + <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> <!-- Create a downloadable product --> <!-- Replacing steps in base AdminAddDefaultVideoSimpleProductTest --> <actionGroup ref="goToCreateProductPage" stepKey="goToCreateProductPage"> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml index 5d7e4518525f..fc638633fbf3 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml @@ -25,6 +25,7 @@ <!-- Login as admin --> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> </before> <after> <!-- Delete category --> @@ -40,6 +41,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create store view --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml index 0ae2c1254be0..f45e5f1a47e4 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index eadefabb8bbc..d9b4e8087cbc 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml index 8bd4305e6b35..afac869d69c3 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml index d8bd641e84e5..8b38f91f8719 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -27,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml index 3efd4b8ab276..081230760e1d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml index 07f7c40bb356..a815d838c29d 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml index 275e72b2ec8c..f0cc503f74c4 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml index ca4e560506ad..f6455766a090 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml @@ -19,6 +19,12 @@ <group value="Downloadable"/> <group value="mtf_migrated"/> </annotations> + <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> <remove keyForRemoval="addCustomerGroupPrice"/> <!-- Add tier price to product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml index f326a047c32b..6e29fe13d85e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml index 8e33a082d0ba..757ac7958f5c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml @@ -20,6 +20,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> @@ -37,6 +38,7 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml index d3c2d6e5d71a..83e0c587c078 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml @@ -18,6 +18,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <createData entity="_defaultCategory" stepKey="createCategory"/> <createData entity="DownloadableProductWithTwoLink" stepKey="createDownloadableProduct"> @@ -33,6 +34,7 @@ <after> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <actionGroup ref="logout" stepKey="logout"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteDownloadableProductFilteredBySkuAndName"> <argument name="product" value="$$createDownloadableProduct$$"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml index 3ee6cef47738..3597c12e82df 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml @@ -19,9 +19,11 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml index d8bbbb2b4d62..bc929cd3a68c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml @@ -18,6 +18,12 @@ <testCaseId value="MC-207"/> <group value="Downloadable"/> </annotations> + <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> <!-- Create a downloadable product --> <!-- Replacing steps in base AdminRemoveDefaultVideoSimpleProductTest --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 66177b6875dd..19477fb80484 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -19,6 +19,7 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -27,6 +28,9 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> </test> <test name="AdvanceCatalogSearchDownloadableBySkuTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> <annotations> @@ -39,6 +43,7 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -47,6 +52,9 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> </test> <test name="AdvanceCatalogSearchDownloadableByDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> <annotations> @@ -59,6 +67,7 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -67,6 +76,9 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> </test> <test name="AdvanceCatalogSearchDownloadableByShortDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> <annotations> @@ -79,6 +91,7 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -87,6 +100,9 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> </test> <test name="AdvanceCatalogSearchDownloadableByPriceTest" extends="AdvanceCatalogSearchSimpleProductByPriceTest"> <annotations> @@ -99,6 +115,7 @@ <group value="Downloadable"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -107,5 +124,8 @@ <requiredEntity createDataKey="product"/> </createData> </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> </test> </tests> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml index b960d15b2fdf..25dfe1adcb7c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-16011"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add example.com static.magento.com"/> <magentoCLI command="config:set {{EnableGuestCheckoutWithDownloadableItems.path}} {{EnableGuestCheckoutWithDownloadableItems.value}}" stepKey="enableGuestCheckoutWithDownloadableItems" /> <createData entity="_defaultCategory" stepKey="createCategory"/> <createData entity="DownloadableProductWithOneLink" stepKey="createProduct"> @@ -31,6 +32,7 @@ <magentoCLI command="config:set {{DisableGuestCheckoutWithDownloadableItems.path}} {{DisableGuestCheckoutWithDownloadableItems.value}}" stepKey="disableGuestCheckoutWithDownloadableItems" /> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!--Step 1: Go to Storefront as Guest--> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnStorefrontPage"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml index 4864d11c884b..9fed2d68c98c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml @@ -20,6 +20,13 @@ <group value="WYSIWYGDisabled"/> </annotations> + <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + </before> + <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + </after> + <!-- A Cms page containing the New Products Widget gets created here via extends --> <!-- Create a Downloadable product to appear in the widget --> diff --git a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php index 771fbc37e5e1..152e3699f969 100644 --- a/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php +++ b/app/code/Magento/Downloadable/Test/Unit/Model/Link/ContentValidatorTest.php @@ -28,6 +28,11 @@ class ContentValidatorTest extends \PHPUnit\Framework\TestCase */ protected $urlValidatorMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $domainValidatorMock; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -52,6 +57,7 @@ protected function setUp() $this->fileValidatorMock = $this->createMock(\Magento\Downloadable\Model\File\ContentValidator::class); $this->urlValidatorMock = $this->createMock(\Magento\Framework\Url\Validator::class); + $this->domainValidatorMock = $this->createMock(\Magento\Downloadable\Model\Url\DomainValidator::class); $this->linkFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->sampleFileMock = $this->createMock(\Magento\Downloadable\Api\Data\File\ContentInterface::class); $this->fileMock = $this->createMock(File::class); @@ -62,6 +68,7 @@ protected function setUp() 'fileContentValidator' => $this->fileValidatorMock, 'urlValidator' => $this->urlValidatorMock, 'fileHelper' => $this->fileMock, + 'domainValidator' => $this->domainValidatorMock, ] ); } @@ -83,6 +90,7 @@ public function testIsValid() ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock)); } @@ -103,6 +111,7 @@ public function testIsValidSkipLinkContent() ]; $this->fileValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock, false)); } @@ -123,6 +132,7 @@ public function testIsValidSkipSampleContent() ]; $this->fileValidatorMock->expects($this->never())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->once())->method('isValid')->will($this->returnValue(true)); $linkMock = $this->getLinkMock($linkData); $this->assertTrue($this->validator->isValid($linkMock, true, false)); } @@ -146,6 +156,7 @@ public function testIsValidThrowsExceptionIfSortOrderIsInvalid($sortOrder) ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); } @@ -181,6 +192,7 @@ public function testIsValidThrowsExceptionIfPriceIsInvalid($price) ]; $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); } @@ -214,6 +226,7 @@ public function testIsValidThrowsExceptionIfNumberOfDownloadsIsInvalid($numberOf 'sample_type' => 'file', ]; $this->urlValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); + $this->domainValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue(true)); $contentMock = $this->getLinkMock($linkContentData); $this->validator->isValid($contentMock); diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 4e9b0b55afb0..8ee05029333b 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -164,4 +164,13 @@ <argument name="connectionName" xsi:type="string">indexer</argument> </arguments> </type> + <type name="Magento\Framework\Console\CommandListInterface"> + <arguments> + <argument name="commands" xsi:type="array"> + <item name="addDomainsCommand" xsi:type="object">Magento\Downloadable\Console\Command\DomainsAddCommand</item> + <item name="removeDomainsCommand" xsi:type="object">Magento\Downloadable\Console\Command\DomainsRemoveCommand</item> + <item name="showDomainsCommand" xsi:type="object">Magento\Downloadable\Console\Command\DomainsShowCommand</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index 87427bf48396..6158f1c57972 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -118,3 +118,4 @@ Downloads,Downloads "Use Content-Disposition","Use Content-Disposition" "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." +"Host ""%value"" is not allowed.","Host ""%value"" is not allowed." diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 3e935e1d7ae9..8c82f2ed8453 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -9,6 +9,8 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; +use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Downloadable\Model\Link; use Magento\Store\Model\Store; use Magento\Store\Model\Website; @@ -22,6 +24,7 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; +use Symfony\Component\Console\Tester\CommandTester; /** * @magentoAppIsolation enabled @@ -55,6 +58,34 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract ], ]; + /** + * @inheritDoc + */ + protected function setUp() + { + parent::setUp(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var DomainsAddCommand $domainsAddCommand */ + $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); + $command = new CommandTester($domainsAddCommand); + $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com']]); + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + parent::tearDown(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var DomainsRemoveCommand $domainsRemoveCommand */ + $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); + $command = new CommandTester($domainsRemoveCommand); + $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['example.com']]); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/products_related.php */ @@ -607,6 +638,7 @@ public function testProductOptions() public function testProductWithMediaGallery() { $testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; + // @codingStandardsIgnoreLine $encodedImage = base64_encode(file_get_contents($testImagePath)); //create a product with media gallery $filename1 = 'tiny1' . time() . '.jpg'; @@ -731,11 +763,11 @@ public function testUpdateWithExtensionAttributes(): void protected function updateProduct($product) { if (isset($product['custom_attributes'])) { - for ($i=0; $i<sizeof($product['custom_attributes']); $i++) { - if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' - && !is_array($product['custom_attributes'][$i]['value']) + foreach ($product['custom_attributes'] as &$customAttribute) { + if ($customAttribute['attribute_code'] == 'category_ids' + && !is_array($customAttribute['value']) ) { - $product['custom_attributes'][$i]['value'] = [""]; + $customAttribute['value'] = [""]; } } } @@ -1152,11 +1184,11 @@ protected function getSimpleProductData($productData = []) protected function saveProduct($product, $storeCode = null) { if (isset($product['custom_attributes'])) { - for ($i=0; $i<sizeof($product['custom_attributes']); $i++) { - if ($product['custom_attributes'][$i]['attribute_code'] == 'category_ids' - && !is_array($product['custom_attributes'][$i]['value']) + foreach ($product['custom_attributes'] as &$customAttribute) { + if ($customAttribute['attribute_code'] == 'category_ids' + && !is_array($customAttribute['value']) ) { - $product['custom_attributes'][$i]['value'] = [""]; + $customAttribute['value'] = [""]; } } } diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index cf99b3420712..0415835f2dcb 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -7,8 +7,11 @@ namespace Magento\Downloadable\Api; use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Framework\Api\ExtensibleDataInterface; use Magento\TestFramework\TestCase\WebapiAbstract; +use Symfony\Component\Console\Tester\CommandTester; /** * Class ProductRepositoryTest for testing ProductRepository interface with Downloadable Product @@ -27,7 +30,15 @@ class ProductRepositoryTest extends WebapiAbstract protected function setUp() { + parent::setUp(); $this->testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg'; + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var DomainsAddCommand $domainsAddCommand */ + $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); + $command = new CommandTester($domainsAddCommand); + $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); } /** @@ -37,6 +48,13 @@ public function tearDown() { $this->deleteProductBySku(self::PRODUCT_SKU); parent::tearDown(); + + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + + /** @var DomainsRemoveCommand $domainsRemoveCommand */ + $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); + $command = new CommandTester($domainsRemoveCommand); + $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); } protected function getLinkData() diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php new file mode 100644 index 000000000000..294cc32e8f71 --- /dev/null +++ b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/EnvWhitelist.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Mtf\Util\Command\Cli; + +use Magento\Mtf\Util\Command\Cli; + +/** + * Adding and removing domain to whitelist for test execution. + */ +class EnvWhitelist extends Cli +{ + /** + * Parameter domain add command. + */ + const PARAM_DOMAINS = 'downloadable:domains'; + + /** + * Add host to the whitelist. + * + * @param string $host + */ + public function addHost($host) + { + parent::execute(EnvWhitelist::PARAM_DOMAINS . ':add ' . $host); + } + + /** + * Remove host from the whitelist. + * + * @param string $host + */ + public function removeHost($host) + { + parent::execute(EnvWhitelist::PARAM_DOMAINS . ':remove ' . $host); + } +} diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php index 90cd6bdb7632..b97accbf87a9 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/ProductTypeSwitchingOnUpdateTest.php @@ -12,6 +12,7 @@ use Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Section\Downloadable; use Magento\Mtf\Fixture\FixtureFactory; use Magento\Mtf\TestCase\Injectable; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Test Creation for ProductTypeSwitchingOnUpdating @@ -60,22 +61,32 @@ class ProductTypeSwitchingOnUpdateTest extends Injectable */ protected $fixtureFactory; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Injection data. * * @param CatalogProductIndex $catalogProductIndex * @param CatalogProductEdit $catalogProductEdit * @param FixtureFactory $fixtureFactory + * @param EnvWhitelist $envWhitelist * @return void */ public function __inject( CatalogProductIndex $catalogProductIndex, CatalogProductEdit $catalogProductEdit, - FixtureFactory $fixtureFactory + FixtureFactory $fixtureFactory, + EnvWhitelist $envWhitelist ) { $this->catalogProductIndex = $catalogProductIndex; $this->catalogProductEdit = $catalogProductEdit; $this->fixtureFactory = $fixtureFactory; + $this->envWhitelist = $envWhitelist; } /** @@ -89,6 +100,7 @@ public function __inject( public function test($productOrigin, $product, $actionName) { // Preconditions + $this->envWhitelist->addHost('example.com'); list($fixtureClass, $dataset) = explode('::', $productOrigin); $productOrigin = $this->fixtureFactory->createByCode(trim($fixtureClass), ['dataset' => trim($dataset)]); $productOrigin->persist(); @@ -144,5 +156,6 @@ protected function clearDownloadableData() $downloadableInfoTab = $this->catalogProductEdit->getProductForm()->getSection('downloadable_information'); $downloadableInfoTab->getDownloadableBlock('Links')->clearDownloadableData(); $downloadableInfoTab->setIsDownloadable('No'); + $this->envWhitelist->removeHost('example.com'); } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php index 7d6bd9318023..fba5a2b06234 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.php @@ -14,6 +14,7 @@ use Magento\Mtf\TestCase\Injectable; use Magento\Mtf\TestStep\TestStepFactory; use Magento\Mtf\Util\Command\Cli\Cache; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -99,6 +100,13 @@ class AddProductsToShoppingCartEntityTest extends Injectable */ private $cache; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare test data. * @@ -108,6 +116,7 @@ class AddProductsToShoppingCartEntityTest extends Injectable * @param CheckoutCart $cartPage * @param TestStepFactory $testStepFactory * @param Cache $cache + * @param EnvWhitelist $envWhitelist * @return void */ public function __prepare( @@ -116,7 +125,8 @@ public function __prepare( CatalogProductView $catalogProductView, CheckoutCart $cartPage, TestStepFactory $testStepFactory, - Cache $cache + Cache $cache, + EnvWhitelist $envWhitelist ) { $this->browser = $browser; $this->fixtureFactory = $fixtureFactory; @@ -124,6 +134,7 @@ public function __prepare( $this->cartPage = $cartPage; $this->testStepFactory = $testStepFactory; $this->cache = $cache; + $this->envWhitelist = $envWhitelist; } /** @@ -146,6 +157,7 @@ public function test( // Preconditions $this->configData = $configData; $this->flushCache = $flushCache; + $this->envWhitelist->addHost('example.com'); $this->testStepFactory->create( \Magento\Config\Test\TestStep\SetupConfigurationStep::class, @@ -224,7 +236,7 @@ public function tearDown() $_ENV['app_frontend_url'] = preg_replace('/(http[s]?)/', 'http', $_ENV['app_frontend_url']); $this->cache->flush(); } - + $this->envWhitelist->removeHost('example.com'); $this->testStepFactory->create( \Magento\Config\Test\TestStep\SetupConfigurationStep::class, ['configData' => $this->configData, 'rollback' => true, 'flushCache' => $this->flushCache] diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php index 54f59b03ef81..6f5512b2e829 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutOfflinePaymentMethodsTest.php @@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\TestCase; use Magento\Mtf\TestCase\Scenario; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -43,6 +44,23 @@ class OnePageCheckoutOfflinePaymentMethodsTest extends Scenario const SEVERITY = 'S0'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + + /** + * Perform needed injections + * + * @param EnvWhitelist $envWhitelist + */ + public function __inject(EnvWhitelist $envWhitelist) + { + $this->envWhitelist = $envWhitelist; + } + /** * Runs one page checkout test. * @@ -50,6 +68,17 @@ class OnePageCheckoutOfflinePaymentMethodsTest extends Scenario */ public function test() { + $this->envWhitelist->addHost('example.com'); $this->executeScenario(); } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php index af267cfa30ec..36b4f4b3eb39 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.php @@ -12,6 +12,7 @@ use Magento\Mtf\Fixture\FixtureInterface; use Magento\Mtf\TestCase\Injectable; use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -58,22 +59,32 @@ class UpdateProductFromMiniShoppingCartEntityTest extends Injectable */ protected $fixtureFactory; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Inject data. * * @param CmsIndex $cmsIndex * @param CatalogProductView $catalogProductView * @param FixtureFactory $fixtureFactory + * @param EnvWhitelist $envWhitelist * @return void */ public function __inject( CmsIndex $cmsIndex, CatalogProductView $catalogProductView, - FixtureFactory $fixtureFactory + FixtureFactory $fixtureFactory, + EnvWhitelist $envWhitelist ) { $this->cmsIndex = $cmsIndex; $this->catalogProductView = $catalogProductView; $this->fixtureFactory = $fixtureFactory; + $this->envWhitelist = $envWhitelist; } /** @@ -97,6 +108,7 @@ public function test( Customer $customer = null ) { // Preconditions: + $this->envWhitelist->addHost('example.com'); if ($customer !== null) { $customer->persist(); } @@ -162,4 +174,14 @@ protected function addToCart(FixtureInterface $product) ); $addToCartStep->run(); } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php index 01e43defde81..9eb13734531d 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/PrintOrderFrontendGuestTest.php @@ -8,6 +8,7 @@ use Magento\Mtf\Client\BrowserInterface; use Magento\Mtf\TestCase\Scenario; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -41,14 +42,25 @@ class PrintOrderFrontendGuestTest extends Scenario */ protected $browser; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare data. * * @param BrowserInterface $browser + * @param EnvWhitelist $envWhitelist */ - public function __prepare(BrowserInterface $browser) - { + public function __prepare( + BrowserInterface $browser, + EnvWhitelist $envWhitelist + ) { $this->browser = $browser; + $this->envWhitelist = $envWhitelist; } /** @@ -58,6 +70,7 @@ public function __prepare(BrowserInterface $browser) */ public function test() { + $this->envWhitelist->addHost('example.com'); $this->executeScenario(); } @@ -68,6 +81,7 @@ public function test() */ public function tearDown() { + $this->envWhitelist->removeHost('example.com'); $this->browser->closeWindow(); } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php index 9c5ffb9dd801..c12b2d099122 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/AddProductToWishlistEntityTest.php @@ -7,6 +7,7 @@ namespace Magento\Wishlist\Test\TestCase; use Magento\Customer\Test\Fixture\Customer; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Test Flow: @@ -30,15 +31,26 @@ class AddProductToWishlistEntityTest extends AbstractWishlistTest const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare data for test * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -53,6 +65,7 @@ public function __prepare(Customer $customer) */ public function test(Customer $customer, $product, $configure = true) { + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; // Steps: @@ -61,4 +74,14 @@ public function test(Customer $customer, $product, $configure = true) return ['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php index ee3bf77a1aa0..27c60281660b 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ConfigureProductInCustomerWishlistOnBackendTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Preconditions: @@ -35,15 +36,26 @@ class ConfigureProductInCustomerWishlistOnBackendTest extends AbstractWishlistTe const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Create customer. * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -64,6 +76,7 @@ public function test( CustomerIndexEdit $customerIndexEdit ) { // Preconditions + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; $this->loginCustomer($customer); $this->addToWishlist([$product]); @@ -80,4 +93,14 @@ public function test( return['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php index f81f87d5b622..1bba73cdf5e9 100644 --- a/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php +++ b/dev/tests/functional/tests/app/Magento/Wishlist/Test/TestCase/ViewProductInCustomerWishlistOnBackendTest.php @@ -9,6 +9,7 @@ use Magento\Customer\Test\Fixture\Customer; use Magento\Customer\Test\Page\Adminhtml\CustomerIndex; use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Test Flow: @@ -34,15 +35,26 @@ class ViewProductInCustomerWishlistOnBackendTest extends AbstractWishlistTest const MVP = 'no'; /* end tags */ + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Prepare customer for test. * * @param Customer $customer + * @param EnvWhitelist $envWhitelist * @return array */ - public function __prepare(Customer $customer) - { + public function __prepare( + Customer $customer, + EnvWhitelist $envWhitelist + ) { $customer->persist(); + $this->envWhitelist = $envWhitelist; return ['customer' => $customer]; } @@ -63,6 +75,7 @@ public function test( CustomerIndexEdit $customerIndexEdit ) { // Preconditions + $this->envWhitelist->addHost('example.com'); $product = $this->createProducts($product)[0]; $this->loginCustomer($customer); $this->addToWishlist([$product], true); @@ -74,4 +87,14 @@ public function test( return['product' => $product]; } + + /** + * Clean data after running test. + * + * @return void + */ + public function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php new file mode 100644 index 000000000000..4048c672037b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_downloadable_product_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreLine +require __DIR__ . '/../../../Magento/Downloadable/_files/product_downloadable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php new file mode 100644 index 000000000000..81ce83fc694b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php @@ -0,0 +1,93 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Downloadable\Model\Url; + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\App\DeploymentConfig; + +/** + * Test for Magento\Downloadable\Model\Url\DomainValidator + */ +class DomainValidatorTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var DomainValidator + */ + private $model; + + /** + * @var DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject + */ + private $deploymentConfig; + + protected function setUp() + { + $this->deploymentConfig = $this->createPartialMock( + DeploymentConfig::class, + ['get'] + ); + + $objectManager = Bootstrap::getObjectManager(); + + $this->model = $objectManager->create( + DomainValidator::class, + ['deploymentConfig' => $this->deploymentConfig] + ); + } + + /** + * @param string $urlInput + * @param array $envDomainWhitelist + * @param bool $isValid + * + * @magentoDataFixture Magento/Store/_files/second_store.php + * @magentoConfigFixture current_store web/unsecure/base_url http://example.com/ + * @magentoConfigFixture current_store web/secure/base_url https://secure.example.com/ + * @magentoConfigFixture fixture_second_store_store web/unsecure/base_url http://example2.com/ + * @magentoConfigFixture fixture_second_store_store web/secure/base_url https://secure.example2.com/ + * @dataProvider isValidDataProvider + */ + public function testIsValid(string $urlInput, array $envDomainWhitelist, bool $isValid) + { + $this->deploymentConfig + ->expects($this->any()) + ->method('get') + ->with(DomainValidator::PARAM_DOWNLOADABLE_DOMAINS) + ->willReturn($envDomainWhitelist); + + $this->assertEquals( + $isValid, + $this->model->isValid($urlInput), + 'Failed asserting is ' . ($isValid ? 'valid' : 'not valid') . ': ' . $urlInput . + PHP_EOL . + 'Domain whitelist: ' . implode(', ', $envDomainWhitelist) + ); + } + + public function isValidDataProvider() + { + return [ + ['http://example.com', ['example.co'], false], + [' http://example.com ', ['example.com'], false], + ['http://example.com', ['example.com'], true], + ['https://example.com', ['example.com'], true], + ['https://example.com/downloadable.pdf', ['example.com'], true], + ['https://example.com:8080/downloadable.pdf', ['example.com'], true], + ['http://secure.example.com', ['secure.example.com'], true], + ['https://secure.example.com', ['secure.example.com'], true], + ['https://ultra.secure.example.com', ['secure.example.com'], false], + ['http://example2.com', ['example2.com'], true], + ['https://example2.com', ['example2.com'], true], + ['http://subdomain.example2.com', ['example2.com'], false], + ['https://adobe.com', ['adobe.com'], true], + ['https://subdomain.adobe.com', ['adobe.com'], false], + ['https://ADOBE.COm', ['adobe.com'], true], + ['https://adobe.com', ['ADOBE.COm'], true], + ['http://127.0.0.1', ['127.0.0.1'], false], + ['http://[::1]', ['::1'], false], + ]; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php index 9c0b328fc166..df6d717ed101 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php @@ -3,10 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); + +use Magento\Downloadable\Console\Command\DomainsAddCommand; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com', 'sampleurl.com']]); + /** * @var \Magento\Catalog\Model\Product $product */ @@ -74,6 +80,7 @@ */ $sampleContent = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $sampleContent->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $sampleContent->setName('jellyfish_1_3.jpg'); @@ -92,10 +99,10 @@ */ $content = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_2_4.jpg'); -//$content->setName(''); $sampleLink->setLinkFileContent($content); $links[] = $sampleLink; @@ -146,6 +153,7 @@ \Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class )->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_1_4.jpg'); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php index 9ad910eed873..dbaf4ea6f67b 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php @@ -3,4 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsRemoveCommand $domainsRemoveCommand */ +$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); +$command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['sampleurl.com']]); + +// @codingStandardsIgnoreLine require __DIR__ . '/product_downloadable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php index 19cf449912b6..56277a75cd80 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php @@ -3,10 +3,27 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -/** - * @var \Magento\Catalog\Model\Product $product - */ -$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); + +use Magento\Downloadable\Console\Command\DomainsAddCommand; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute( + [ + DomainsAddCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + +/** @var \Magento\Catalog\Model\Product $product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); $product ->setTypeId(\Magento\Downloadable\Model\Product\Type::TYPE_DOWNLOADABLE) ->setId(1) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php index 996fbb01d72c..22619d25ee4e 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php @@ -3,23 +3,41 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Framework\Exception\NoSuchEntityException; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsRemoveCommand $domainsRemoveCommand */ +$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); +$command->execute( + [ + DomainsRemoveCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + /** @var \Magento\Framework\Registry $registry */ -$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); +$registry = $objectManager->get(\Magento\Framework\Registry::class); $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ -$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() +$productRepository = $objectManager ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); try { $product = $productRepository->get('downloadable-product', false, null, true); $productRepository->delete($product); -} catch (NoSuchEntityException $e) { +} catch (NoSuchEntityException $e) { // @codingStandardsIgnoreLine } $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php index 86aa61a99e1e..47eb6c450e9e 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php @@ -4,8 +4,25 @@ * See COPYING.txt for license details. */ +use Magento\Downloadable\Console\Command\DomainsAddCommand; + \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var DomainsAddCommand $domainsAddCommand */ +$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); +$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); +$command->execute( + [ + DomainsAddCommand::INPUT_KEY_DOMAINS => [ + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' + ] + ] +); + /** * @var \Magento\Catalog\Model\Product $product */ @@ -81,10 +98,10 @@ */ $content = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_2_4.jpg'); -//$content->setName(''); $link->setLinkFileContent($content); /** @@ -92,6 +109,7 @@ */ $sampleContent = $objectManager->create(\Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class)->create(); $sampleContent->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $sampleContent->setName('jellyfish_1_3.jpg'); @@ -136,6 +154,7 @@ \Magento\Downloadable\Api\Data\File\ContentInterfaceFactory::class )->create(); $content->setFileData( + // @codingStandardsIgnoreLine base64_encode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . 'test_image.jpg')) ); $content->setName('jellyfish_1_4.jpg'); From a4a636212042681b97b3a3713ea11811ee7b8c25 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Wed, 17 Jul 2019 08:52:54 +0300 Subject: [PATCH 0165/1172] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/File/Upload.php | 6 ++-- .../Checkout/Test/Block/Cart/Sidebar/Item.php | 18 ++++++++++ .../Adminhtml/Downloadable/FileTest.php | 35 ++++++++++++++----- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php index c8f7a4ff4a50..a7c32eed8bb1 100644 --- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php +++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php @@ -81,11 +81,11 @@ public function execute() try { $type = $this->getRequest()->getParam('type'); $tmpPath = ''; - if ($type == 'samples') { + if ($type === 'samples') { $tmpPath = $this->_sample->getBaseTmpPath(); - } elseif ($type == 'links') { + } elseif ($type === 'links') { $tmpPath = $this->_link->getBaseTmpPath(); - } elseif ($type == 'link_samples') { + } elseif ($type === 'link_samples') { $tmpPath = $this->_link->getBaseSampleTmpPath(); } else { throw new LocalizedException(__('Upload type can not be determined.')); diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php index c00687d91c1e..038c41176896 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php @@ -62,6 +62,7 @@ class Item extends Sidebar */ public function removeItemFromMiniCart() { + $this->waitForDeleteButtonVisible(); $this->_rootElement->find($this->removeItem)->click(); $element = $this->browser->find($this->confirmModal); /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */ @@ -70,6 +71,23 @@ public function removeItemFromMiniCart() $modal->waitModalWindowToDisappear(); } + /** + * Wait for Delete button is visible in the block. + * + * @return bool|null + */ + private function waitForDeleteButtonVisible() + { + $rootElement = $this->_rootElement; + $deleteButtonSelector = $this->removeItem; + return $rootElement->waitUntil( + function () use ($rootElement, $deleteButtonSelector) { + $element = $rootElement->find($deleteButtonSelector); + return $element->isVisible() ? true : null; + } + ); + } + /** * Click "Edit item" button. * diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index ac35fa9a23b1..20e36e659463 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -7,36 +7,53 @@ namespace Magento\Downloadable\Controller\Adminhtml\Downloadable; use Magento\Framework\Serialize\Serializer\Json; -use Magento\TestFramework\Helper\Bootstrap; /** * Magento\Downloadable\Controller\Adminhtml\Downloadable\File * * @magentoAppArea adminhtml - * - * phpcs:disable Magento2.Functions.DiscouragedFunction - * phpcs:disable Magento2.Security.Superglobal */ class FileTest extends \Magento\TestFramework\TestCase\AbstractBackendController { + /** + * @var Json + */ + private $jsonSerializer; + + /** + * @inheritdoc + */ + protected function setUp() + { + parent::setUp(); + + $this->jsonSerializer = $this->_objectManager->get(Json::class); + } + /** * @inheritdoc */ protected function tearDown() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $filePath = dirname(__DIR__) . '/_files/sample.tmp'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (is_file($filePath)) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction unlink($filePath); } } public function testUploadAction() { + // phpcs:ignore Magento2.Functions.DiscouragedFunction copy(dirname(__DIR__) . '/_files/sample.txt', dirname(__DIR__) . '/_files/sample.tmp'); + // phpcs:ignore Magento2.Security.Superglobal $_FILES = [ 'samples' => [ 'name' => 'sample.txt', 'type' => 'text/plain', + // phpcs:ignore Magento2.Functions.DiscouragedFunction 'tmp_name' => dirname(__DIR__) . '/_files/sample.tmp', 'error' => 0, 'size' => 0, @@ -46,7 +63,7 @@ public function testUploadAction() $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload/type/samples'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); $this->assertEquals(0, $result['error']); } @@ -58,9 +75,11 @@ public function testUploadAction() */ public function testUploadProhibitedExtensions($fileName) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $path = dirname(__DIR__) . '/_files/'; + // phpcs:ignore Magento2.Functions.DiscouragedFunction copy($path . 'sample.txt', $path . 'sample.tmp'); - + // phpcs:ignore Magento2.Security.Superglobal $_FILES = [ 'samples' => [ 'name' => $fileName, @@ -74,7 +93,7 @@ public function testUploadProhibitedExtensions($fileName) $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload/type/samples'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); self::assertArrayHasKey('errorcode', $result); self::assertEquals(0, $result['errorcode']); @@ -113,7 +132,7 @@ public function testUploadWrongUploadType(): void $this->getRequest()->setMethod('POST'); $this->dispatch('backend/admin/downloadable_file/upload'); $body = $this->getResponse()->getBody(); - $result = Bootstrap::getObjectManager()->get(Json::class)->unserialize($body); + $result = $this->jsonSerializer->unserialize($body); $this->assertEquals('Upload type can not be determined.', $result['error']); $this->assertEquals(0, $result['errorcode']); } From 88dd934c0a18875c3caf700f2c999e1938085915 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 09:51:31 -0500 Subject: [PATCH 0166/1172] MC-17700: Downloadable Product links --- .../Magento/Catalog/Api/ProductRepositoryInterfaceTest.php | 4 ++-- .../Magento/Downloadable/Model/Url/DomainValidatorTest.php | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index 8c82f2ed8453..b9afaf1518b8 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -65,7 +65,7 @@ protected function setUp() { parent::setUp(); - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var DomainsAddCommand $domainsAddCommand */ $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); $command = new CommandTester($domainsAddCommand); @@ -79,7 +79,7 @@ protected function tearDown() { parent::tearDown(); - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var DomainsRemoveCommand $domainsRemoveCommand */ $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); $command = new CommandTester($domainsRemoveCommand); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php index 81ce83fc694b..970b8add3e52 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php @@ -53,7 +53,6 @@ protected function setUp() public function testIsValid(string $urlInput, array $envDomainWhitelist, bool $isValid) { $this->deploymentConfig - ->expects($this->any()) ->method('get') ->with(DomainValidator::PARAM_DOWNLOADABLE_DOMAINS) ->willReturn($envDomainWhitelist); From 76b829fcc8928fd60b6548924b00a257821bdbdb Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 10:25:47 -0500 Subject: [PATCH 0167/1172] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Model/Link/ContentValidator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index 08345c8079dd..e9ed4920a24b 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -42,19 +42,19 @@ class ContentValidator /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param DomainValidator $domainValidator * @param File|null $fileHelper - * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null, - DomainValidator $domainValidator = null + DomainValidator $domainValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->domainValidator = $domainValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); - $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** From f93bdedf6d363733b841d1393f943ea839d48c86 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 11:33:57 -0500 Subject: [PATCH 0168/1172] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index d63d28256809..b467a88e1a91 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -76,7 +76,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_link'), ['link_url'] - )->where('link_type = ?', 'url'); + ) + ->where('link_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['link_url']); @@ -87,7 +88,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_link'), ['sample_url'] - )->where('sample_type = ?', 'url'); + ) + ->where('sample_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['sample_url']); @@ -100,7 +102,8 @@ public function apply() ->from( $this->moduleDataSetup->getTable('downloadable_sample'), ['sample_url'] - )->where('sample_type = ?', 'url'); + ) + ->where('sample_type = ?', 'url'); foreach ($this->moduleDataSetup->getConnection()->fetchAll($select) as $link) { $this->addHost($link['sample_url']); From c855748d577dcd1603a66ead27014f30ae2b1eba Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 11:46:04 -0500 Subject: [PATCH 0169/1172] MC-17700: Downloadable Product links --- .../Downloadable/Model/Sample/ContentValidator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7b8c65580f16..7c53a228f27c 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -42,19 +42,19 @@ class ContentValidator /** * @param FileContentValidator $fileContentValidator * @param UrlValidator $urlValidator + * @param DomainValidator $domainValidator * @param File|null $fileHelper - * @param DomainValidator|null $domainValidator */ public function __construct( FileContentValidator $fileContentValidator, UrlValidator $urlValidator, - File $fileHelper = null, - DomainValidator $domainValidator = null + DomainValidator $domainValidator, + File $fileHelper = null ) { $this->fileContentValidator = $fileContentValidator; $this->urlValidator = $urlValidator; + $this->domainValidator = $domainValidator; $this->fileHelper = $fileHelper ?? ObjectManager::getInstance()->get(File::class); - $this->domainValidator = $domainValidator ?? ObjectManager::getInstance()->get(DomainValidator::class); } /** From 74a9c24a7fc90c96365db51cc0263246c2e7ae2e Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 13:43:11 -0500 Subject: [PATCH 0170/1172] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/Url/DomainValidator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 5cdd954edb15..66e4365564d6 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -19,12 +19,12 @@ class DomainValidator extends \Zend_Validate_Abstract /** * Invalid host message key */ - const INVALID_HOST = 'invalidHost'; + private const INVALID_HOST = 'invalidHost'; /** * Path to the allowed domains in the deployment config */ - const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; + public const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; /** * @var IpValidator From 64427a9d0fdf07b78043c6d1780d69b1493ce919 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 13:48:03 -0500 Subject: [PATCH 0171/1172] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Console/Command/DomainsAddCommand.php | 2 +- .../Downloadable/Console/Command/DomainsRemoveCommand.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index 8158296678de..015314b722fe 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -25,7 +25,7 @@ class DomainsAddCommand extends Command /** * Name of domains input argument */ - const INPUT_KEY_DOMAINS = 'domains'; + public const INPUT_KEY_DOMAINS = 'domains'; /** * @var ConfigWriter diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 1fa02ae6359b..0ad812d3bd71 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -25,7 +25,7 @@ class DomainsRemoveCommand extends Command /** * Name of domains input argument */ - const INPUT_KEY_DOMAINS = 'domains'; + public const INPUT_KEY_DOMAINS = 'domains'; /** * @var ConfigWriter From ff9a9dda4cdc3f499603ab4bbafee95d0c9b6d29 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov <ikolesov@magento.com> Date: Wed, 17 Jul 2019 13:57:38 -0500 Subject: [PATCH 0172/1172] MC-17700: Downloadable Product links - CR changes --- .../Api/DomainManagerInterface.php | 36 +++++++ .../Console/Command/DomainsAddCommand.php | 52 +++------ .../Console/Command/DomainsRemoveCommand.php | 52 +++------ .../Console/Command/DomainsShowCommand.php | 26 ++--- .../Downloadable/Model/DomainManager.php | 100 ++++++++++++++++++ .../Model/Url/DomainValidator.php | 24 ++--- .../Patch/Data/AddDownloadableHostsConfig.php | 26 ++--- app/code/Magento/Downloadable/etc/di.xml | 1 + 8 files changed, 185 insertions(+), 132 deletions(-) create mode 100644 app/code/Magento/Downloadable/Api/DomainManagerInterface.php create mode 100644 app/code/Magento/Downloadable/Model/DomainManager.php diff --git a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php new file mode 100644 index 000000000000..9174d81621b1 --- /dev/null +++ b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Downloadable\Api; + +/** + * Interface DomainManagerInterface + * Manage downloadable domains whitelist in the environment config. + */ +interface DomainManagerInterface +{ + /** + * Get the whitelist. + * + * @return array + */ + public function getEnvDomainWhitelist(); + + /** + * Add host to the whitelist. + * + * @param array $hosts + * @return void + */ + public function addEnvDomains($hosts); + + /** + * Remove host from the whitelist. + * + * @param array $hosts + * @return void + */ + public function removeEnvDomains($hosts); +} diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index 015314b722fe..e230d24b2ca7 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -10,10 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; -use Magento\Framework\Config\File\ConfigFilePool; /** * Class DomainsAddCommand @@ -28,27 +26,18 @@ class DomainsAddCommand extends Command public const INPUT_KEY_DOMAINS = 'domains'; /** - * @var ConfigWriter + * @var DomainManager */ - private $configWriter; - - /** - * @var DomainValidator - */ - private $domainValidator; + private $domainManager; /** * DomainsAddCommand constructor. - * - * @param ConfigWriter $configWriter - * @param DomainValidator $domainValidator + * @param DomainManager $domainManager */ public function __construct( - ConfigWriter $configWriter, - DomainValidator $domainValidator + DomainManager $domainManager ) { - $this->configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -80,33 +69,18 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); - $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; - foreach ($newDomains as $newDomain) { - if (in_array($newDomain, $whitelist)) { - $output->writeln( - "$newDomain is already in the whitelist" - ); - continue; - } else { - array_push($whitelist, $newDomain); - $output->writeln( - "$newDomain was added to the whitelist" - ); - } - } + $this->domainManager->addEnvDomains($newDomains); - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist - ] - ] - ); + foreach (array_diff($this->domainManager->getEnvDomainWhitelist(), $whitelistBefore) as $newHost) { + $output->writeln( + $newHost . ' was added to the whitelist.' + ); + } } - } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 0ad812d3bd71..74c0803e3d9a 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -10,10 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; -use Magento\Framework\Config\File\ConfigFilePool; /** * Class DomainsRemoveCommand @@ -28,27 +26,19 @@ class DomainsRemoveCommand extends Command public const INPUT_KEY_DOMAINS = 'domains'; /** - * @var ConfigWriter + * @var DomainManager */ - private $configWriter; - - /** - * @var DomainValidator - */ - private $domainValidator; + private $domainManager; /** * DomainsRemoveCommand constructor. * - * @param ConfigWriter $configWriter - * @param DomainValidator $domainValidator + * @param DomainManager $domainManager */ public function __construct( - ConfigWriter $configWriter, - DomainValidator $domainValidator + DomainManager $domainManager ) { - $this->configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -80,35 +70,17 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { + $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); + $this->domainManager->removeEnvDomains($removeDomains); - $whitelist = $this->domainValidator->getEnvDomainWhitelist() ?: []; - foreach ($removeDomains as $removeDomain) { - if (in_array($removeDomain, $whitelist)) { - $index = array_search($removeDomain, $whitelist); - unset($whitelist[$index]); - $output->writeln( - "$removeDomain was removed from the whitelist" - ); - continue; - } else { - $output->writeln( - "$removeDomain is absent in the whitelist" - ); - } + foreach (array_diff($whitelistBefore, $this->domainManager->getEnvDomainWhitelist()) as $removedHost) { + $output->writeln( + $removedHost . ' was removed from the whitelist.' + ); } - - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - $this->domainValidator::PARAM_DOWNLOADABLE_DOMAINS => $whitelist - ] - ], - true - ); } - } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index 70e031eb3e41..dbeb3c7fdd2e 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -9,9 +9,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputInterface; - -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; /** * Class DomainsAddCommand @@ -21,27 +19,18 @@ class DomainsShowCommand extends Command { /** - * @var ConfigWriter + * @var DomainManager */ - private $configWriter; - - /** - * @var DomainValidator - */ - private $domainValidator; + private $domainManager; /** * DomainsShowCommand constructor. - * - * @param ConfigWriter $configWriter - * @param DomainValidator $domainValidator + * @param DomainManager $domainManager */ public function __construct( - ConfigWriter $configWriter, - DomainValidator $domainValidator + DomainManager $domainManager ) { - $this->configWriter = $configWriter; - $this->domainValidator = $domainValidator; + $this->domainManager = $domainManager; parent::__construct(); } @@ -63,11 +52,10 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $whitelist = implode("\n", $this->domainValidator->getEnvDomainWhitelist() ?: []); + $whitelist = implode("\n", $this->domainManager->getEnvDomainWhitelist()); $output->writeln( "Downloadable domains whitelist:\n$whitelist" ); - } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php new file mode 100644 index 000000000000..77abfa24e43c --- /dev/null +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Downloadable\Model; + +use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; +use Magento\Downloadable\Api\DomainManagerInterface; +use Magento\Framework\App\DeploymentConfig; +use Magento\Framework\Config\File\ConfigFilePool; + +/** + * Class DomainManager + * Manage downloadable domains whitelist in the environment config. + */ +class DomainManager implements DomainManagerInterface +{ + /** + * Path to the allowed domains in the deployment config + */ + private const PARAM_DOWNLOADABLE_DOMAINS = 'downloadable_domains'; + + /** + * @var ConfigWriter + */ + private $configWriter; + + /** + * @var DeploymentConfig + */ + private $deploymentConfig; + + /** + * DomainManager constructor. + * + * @param ConfigWriter $configWriter + * @param DeploymentConfig $deploymentConfig + */ + public function __construct( + ConfigWriter $configWriter, + DeploymentConfig $deploymentConfig + ) { + $this->configWriter = $configWriter; + $this->deploymentConfig = $deploymentConfig; + } + + /** + * @inheritdoc + */ + public function getEnvDomainWhitelist(): array + { + return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); + } + + /** + * @inheritdoc + */ + public function addEnvDomains($hosts) { + $whitelist = $this->getEnvDomainWhitelist(); + foreach (array_map('strtolower', $hosts) as $host) { + if (!in_array($host, $whitelist)) { + array_push($whitelist, $host); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + self::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } + + /** + * @inheritdoc + */ + public function removeEnvDomains($hosts) { + $whitelist = $this->getEnvDomainWhitelist(); + foreach (array_map('strtolower', $hosts) as $host) { + if (in_array($host, $whitelist)) { + $index = array_search($host, $whitelist); + unset($whitelist[$index]); + } + } + + $this->configWriter->saveConfig( + [ + ConfigFilePool::APP_ENV => [ + self::PARAM_DOWNLOADABLE_DOMAINS => $whitelist + ] + ], + true + ); + } +} diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 66e4365564d6..2d118cd062f5 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -7,7 +7,7 @@ namespace Magento\Downloadable\Model\Url; -use Magento\Framework\App\DeploymentConfig; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Validator\Ip as IpValidator; use Zend\Uri\Uri as UriHandler; @@ -37,21 +37,21 @@ class DomainValidator extends \Zend_Validate_Abstract private $uriHandler; /** - * @var DeploymentConfig + * @var DomainManager */ - private $deploymentConfig; + private $domainManager; /** - * @param DeploymentConfig $deploymentConfig + * @param DomainManager $domainManager * @param IpValidator $ipValidator * @param UriHandler $uriHandler */ public function __construct( - DeploymentConfig $deploymentConfig, + DomainManager $domainManager, IpValidator $ipValidator, UriHandler $uriHandler ) { - $this->deploymentConfig = $deploymentConfig; + $this->domainManager = $domainManager; $this->ipValidator = $ipValidator; $this->uriHandler = $uriHandler; @@ -71,7 +71,7 @@ public function isValid($value): bool $host = $this->getHost($value); $isIpAddress = $this->ipValidator->isValid($host); - $isValid = !$isIpAddress && in_array($host, $this->getEnvDomainWhitelist()); + $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); if (!$isValid) { $this->_error(self::INVALID_HOST, $host); @@ -80,16 +80,6 @@ public function isValid($value): bool return $isValid; } - /** - * Get environment whitelist - * - * @return array - */ - public function getEnvDomainWhitelist(): array - { - return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); - } - /** * Extract host from url * diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index b467a88e1a91..8bddfb232b33 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -10,9 +10,7 @@ use Magento\Framework\Setup\Patch\DataPatchInterface; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; -use Magento\Framework\App\DeploymentConfig\Writer as ConfigWriter; -use Magento\Downloadable\Model\Url\DomainValidator; -use Magento\Framework\Config\File\ConfigFilePool; +use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Setup\ModuleDataSetupInterface; /** @@ -31,14 +29,14 @@ class AddDownloadableHostsConfig implements DataPatchInterface private $scopeResolver; /** - * @var ConfigWriter + * @var ModuleDataSetupInterface */ - private $configWriter; + private $moduleDataSetup; /** - * @var ModuleDataSetupInterface + * @var DomainManager */ - private $moduleDataSetup; + private $domainManager; /** * @var array @@ -50,18 +48,18 @@ class AddDownloadableHostsConfig implements DataPatchInterface * * @param UriHandler $uriHandler * @param ScopeResolverInterface $scopeResolver - * @param ConfigWriter $configWriter + * @param DomainManager $domainManager * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct( UriHandler $uriHandler, ScopeResolverInterface $scopeResolver, - ConfigWriter $configWriter, + DomainManager $domainManager, ModuleDataSetupInterface $moduleDataSetup ) { $this->uriHandler = $uriHandler; $this->scopeResolver = $scopeResolver; - $this->configWriter = $configWriter; + $this->domainManager = $domainManager; $this->moduleDataSetup = $moduleDataSetup; } @@ -114,13 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->configWriter->saveConfig( - [ - ConfigFilePool::APP_ENV => [ - DomainValidator::PARAM_DOWNLOADABLE_DOMAINS => array_unique($this->whitelist) - ] - ] - ); + $this->domainManager->addEnvDomains(array_unique($this->whitelist)); } /** diff --git a/app/code/Magento/Downloadable/etc/di.xml b/app/code/Magento/Downloadable/etc/di.xml index 8ee05029333b..a932e5598f8a 100644 --- a/app/code/Magento/Downloadable/etc/di.xml +++ b/app/code/Magento/Downloadable/etc/di.xml @@ -92,6 +92,7 @@ <preference for="Magento\Downloadable\Api\Data\File\ContentUploaderInterface" type="Magento\Downloadable\Model\File\ContentUploader" /> <preference for="Magento\Downloadable\Model\Product\TypeHandler\TypeHandlerInterface" type="Magento\Downloadable\Model\Product\TypeHandler\TypeHandler" /> <preference for="Magento\Downloadable\Api\Data\DownloadableOptionInterface" type="Magento\Downloadable\Model\DownloadableOption" /> + <preference for="Magento\Downloadable\Api\DomainManagerInterface" type="Magento\Downloadable\Model\DomainManager"/> <type name="Magento\Framework\EntityManager\Operation\ExtensionPool"> <arguments> <argument name="extensionActions" xsi:type="array"> From 4d92c81a066ed0bb00ecdadf992267820150e6f8 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 14:45:12 -0500 Subject: [PATCH 0173/1172] MC-17700: Downloadable Product links --- .../Model/Url/DomainValidator.php | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 2d118cd062f5..3d44d073af20 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -14,13 +14,8 @@ /** * Class is responsible for checking if downloadable product link domain is allowed. */ -class DomainValidator extends \Zend_Validate_Abstract +class DomainValidator { - /** - * Invalid host message key - */ - private const INVALID_HOST = 'invalidHost'; - /** * Path to the allowed domains in the deployment config */ @@ -54,8 +49,6 @@ public function __construct( $this->domainManager = $domainManager; $this->ipValidator = $ipValidator; $this->uriHandler = $uriHandler; - - $this->initMessageTemplates(); } /** @@ -73,10 +66,6 @@ public function isValid($value): bool $isIpAddress = $this->ipValidator->isValid($host); $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); - if (!$isValid) { - $this->_error(self::INVALID_HOST, $host); - } - return $isValid; } @@ -97,18 +86,4 @@ private function getHost($url): string // ipv6 hosts are brace-delimited in url; they are removed here for subsequent validation return trim($host, '[] '); } - - /** - * Initialize message templates with translating - * - * @return void - */ - private function initMessageTemplates() - { - if (!$this->_messageTemplates) { - $this->_messageTemplates = [ - self::INVALID_HOST => __('Host "%value%" is not allowed.'), - ]; - } - } } From 1a51a17a4f70961151def3799b1aa53295bb2c03 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 14:59:33 -0500 Subject: [PATCH 0174/1172] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/DomainManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index 77abfa24e43c..f343fa2e2470 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -58,7 +58,8 @@ public function getEnvDomainWhitelist(): array /** * @inheritdoc */ - public function addEnvDomains($hosts) { + public function addEnvDomains($hosts) + { $whitelist = $this->getEnvDomainWhitelist(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { From eafcff6c7a584455f1c08e9439804fca5e25a112 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 15:00:04 -0500 Subject: [PATCH 0175/1172] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/Model/DomainManager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index f343fa2e2470..b3f9cce23cac 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -80,7 +80,8 @@ public function addEnvDomains($hosts) /** * @inheritdoc */ - public function removeEnvDomains($hosts) { + public function removeEnvDomains($hosts) + { $whitelist = $this->getEnvDomainWhitelist(); foreach (array_map('strtolower', $hosts) as $host) { if (in_array($host, $whitelist)) { From 30cfd33b96dc124989cfd38f24811e0ed3a6079b Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 17 Jul 2019 15:14:41 -0500 Subject: [PATCH 0176/1172] MC-17700: Downloadable Product links --- .../Downloadable/Model/Url/DomainValidatorTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php index 970b8add3e52..86b5bf3ed05c 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Model/Url/DomainValidatorTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Downloadable\Model\Url; +use Magento\Downloadable\Model\DomainManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\App\DeploymentConfig; @@ -25,16 +26,21 @@ class DomainValidatorTest extends \PHPUnit\Framework\TestCase protected function setUp() { + $objectManager = Bootstrap::getObjectManager(); + $this->deploymentConfig = $this->createPartialMock( DeploymentConfig::class, ['get'] ); - $objectManager = Bootstrap::getObjectManager(); + $domainManager = $objectManager->create( + DomainManager::class, + ['deploymentConfig' => $this->deploymentConfig] + ); $this->model = $objectManager->create( DomainValidator::class, - ['deploymentConfig' => $this->deploymentConfig] + ['domainManager' => $domainManager] ); } From b0c53ba72e57134025bc55e1e6b7e099c6cfccbc Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Thu, 18 Jul 2019 10:21:08 +0300 Subject: [PATCH 0177/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Fix for checkout address. --- ...AffectOnShippingAddressAfterUpdateTest.xml | 148 ------------------ .../view/frontend/web/js/view/shipping.js | 15 +- 2 files changed, 10 insertions(+), 153 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml deleted file mode 100644 index 9b2958a190be..000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Test/BillingAddressFormAffectOnShippingAddressAfterUpdateTest.xml +++ /dev/null @@ -1,148 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="BillingAddressFormAffectOnShippingAddressAfterUpdateTest"> - <annotations> - <features value="Checkout"/> - <title value="Billing address form does not affect shipping address after update"/> - <description value="Billing address form does not affect shipping address after update"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-16961"/> - <useCaseId value="MC-15507"/> - <group value="checkout"/> - </annotations> - <before> - <!-- Login as Admin --> - <comment userInput="Login as Admin" stepKey="commentLoginAsAdmin"/> - <actionGroup ref="LoginAsAdmin" stepKey="login"/> - <!-- Create simple product and add to category --> - <comment userInput="Create simple product and add to category" stepKey="commentAddProductToCategory"/> - <createData entity="_defaultCategory" stepKey="createCategory"/> - <createData entity="SimpleProduct" stepKey="createProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - <!-- Create customer --> - <comment userInput="Create customer" stepKey="commentCreateCustomer"/> - <createData entity="Simple_US_Customer_Without_Default_Address" stepKey="createCustomer"/> - </before> - <after> - <!-- Log out --> - <comment userInput="Log out" stepKey="commentLogOut"/> - <actionGroup ref="logout" stepKey="logout"/> - <!-- Delete data --> - <comment userInput="Delete data" stepKey="commentDeleteData"/> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> - <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <!-- Set default configurations --> - <comment userInput="Set default configurations" stepKey="commentSetDefaultConfigurations"/> - <magentoCLI command="config:set checkout/options/enable_address_search 0" stepKey="setDefaultEnableAddressSearch"/> - <magentoCLI command="config:set checkout/options/customer_address_limit 10" stepKey="setDefaultCount"/> - </after> - <!-- Login to the Storefront as created customer --> - <comment userInput="Login to the Storefront as created customer" stepKey="commentLoginAsCustomer"/> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> - <argument name="Customer" value="$$createCustomer$$"/> - </actionGroup> - <!-- Add 3 addresses to Address book--> - <comment userInput="Add 3 addresses to Address book" stepKey="commentAddAddresses"/> - <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressFirst"> - <argument name="Address" value="US_Address_NY"/> - </actionGroup> - <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressSecond"> - <argument name="Address" value="US_Address_CA"/> - </actionGroup> - <actionGroup ref="StorefrontAddNewCustomerAddressActionGroup" stepKey="AddNewAddressThird"> - <argument name="Address" value="US_Address_TX"/> - </actionGroup> - <!-- Add product to the Shopping Cart --> - <comment userInput="Add product to the Shopping Cart" stepKey="commentAddProductToTheCart"/> - <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnStorefrontProductFirstPage"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCart"> - <argument name="product" value="$$createProduct$$"/> - <argument name="productCount" value="1"/> - </actionGroup> - <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckout"/> - <click selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="changeShippingAddressButton"/> - <waitForElement selector="{{CheckoutShippingMethodsSection.next}}" time="30" stepKey="waitForNext"/> - <!-- Click next button to open payment section --> - <comment userInput="Click next button to open payment section" stepKey="commentClickToNextButton"/> - <click selector="{{CheckoutShippingGuestInfoSection.next}}" stepKey="clickNext"/> - <waitForPageLoad stepKey="waitForShipmentPageLoad"/> - <uncheckOption selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="selectPaymentSolution"/> - <waitForElement selector="{{CheckoutPaymentSection.billingAddressSelectShared}}" time="30" stepKey="waitForAddressField"/> - <selectOption selector="{{CheckoutPaymentSection.billingAddressSelectShared}}" userInput="New Address" stepKey="chooseNewAddress"/> - <waitForPageLoad stepKey="waitForNewAddressPageLoad"/> - <actionGroup ref="CheckoutFillNewBillingAddressActionGroup" stepKey="guestCheckoutFillingBillingAddress"> - <argument name="customerVar" value="CustomerEntityOne"/> - <argument name="customerAddressVar" value="CustomerAddressSimple"/> - </actionGroup> - <click selector="{{CheckoutPaymentSection.update}}" stepKey="clickUpdateButton"/> - <waitForPageLoad stepKey="waitForProcessing"/> - <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickToPlaceOrder"/> - <see userInput="Thank you for your purchase!" stepKey="seeSuccessMessage"/> - <waitForPageLoad stepKey="waitForSuccess"/> - <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> - <!-- Go to my Orders page --> - <comment userInput="Go to my Orders page" stepKey="commentOpenMyOrders"/> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="onMyAccount"/> - <waitForPageLoad stepKey="waitForAccountPage"/> - <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickOnMyOrders"/> - <waitForPageLoad stepKey="waitForOrdersLoad"/> - <!-- Click 'View Order' link on order --> - <comment userInput="Click 'View Order' link on order" stepKey="commentViewOrder"/> - <click selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabOrderNumber})}}" stepKey="clickOrderView"/> - <waitForPageLoad stepKey="waitForOrderPageLoad"/> - <see selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" userInput="New York" stepKey="seeNewYorkInShippingSection"/> - <!-- Set configurations --> - <comment userInput="Set configurations" stepKey="commentSetConfigurations"/> - <magentoCLI command="config:set checkout/options/enable_address_search 1" stepKey="setEnableAddressSearch"/> - <magentoCLI command="config:set checkout/options/customer_address_limit 2" stepKey="setCount"/> - <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnStorefrontProductFirstPageSecond"/> - <waitForPageLoad stepKey="waitForPageLoadSecond"/> - <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCartSecond"> - <argument name="product" value="$$createProduct$$"/> - <argument name="productCount" value="1"/> - </actionGroup> - <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutSecond"/> - <click selector="{{CheckoutShippingSection.changeAddressButton}}" stepKey="clickToChangeShippingAddress"/> - <waitForPageLoad stepKey="waitForPopupLoad"/> - <fillField selector="{{SelectBillingAddressPopupSection.shippingAddressSearch}}" userInput="California" stepKey="fillAddressSearchField"/> - <waitForPageLoad stepKey="waitForAddressPopupLoad"/> - <waitForElementVisible selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="waitForShipHereButton"/> - <click selector="{{CheckoutShippingMethodsSection.shipHereButton}}" stepKey="changeShippingAddress"/> - <waitForElementVisible selector="{{CheckoutShippingMethodsSection.next}}" stepKey="waitForNextButton"/> - <click selector="{{CheckoutShippingMethodsSection.next}}" stepKey="clickToNextButtonSecond"/> - <waitForPageLoad stepKey="waitForNextPageLoadSecond"/> - <click selector="{{CheckoutPaymentSection.changeAddressButton('2')}}" stepKey="clickToChangePaymentAddress"/> - <waitForPageLoad stepKey="waitForPaymentAddressPopupLoad"/> - <fillField selector="{{SelectBillingAddressPopupSection.shippingAddressSearchParametrised('2')}}" userInput="New York" stepKey="fillPaymentAddressSearchField"/> - <waitForPageLoad stepKey="waitForAddressPopup"/> - <waitForElementVisible selector="{{SelectBillingAddressPopupSection.selectButton}}" stepKey="waitForSelectButton"/> - <click selector="{{SelectBillingAddressPopupSection.selectButton}}" stepKey="clickToSelectButtonSecond"/> - <waitForPageLoad stepKey="waitForPaymentLoading"/> - <click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickToPlaceOrderButton"/> - <waitForPageLoad stepKey="waitForSuccessMessage"/> - <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderId"/> - <!-- Go to my Orders page --> - <comment userInput="Go to my Orders page" stepKey="commentGoToMyOrders"/> - <amOnPage url="{{StorefrontCustomerDashboardPage.url}}" stepKey="openMyAccount"/> - <waitForPageLoad stepKey="waitForAccountPageLoad"/> - <click selector="{{StorefrontCustomerSidebarSection.sidebarTab('My Orders')}}" stepKey="clickToMyOrders"/> - <waitForPageLoad stepKey="waitForOrderLoad"/> - <!-- Click 'View Order' link on order from preconditions --> - <click selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabOrderId})}}" stepKey="clickToOrderViewButton"/> - <waitForPageLoad stepKey="waitForOrderPage"/> - <comment userInput="Click 'View Order' link on order" stepKey="commentClickToViewOrder"/> - <see selector="{{StorefrontCustomerOrderViewSection.shippingAddress}}" userInput="California" stepKey="seeCaliforniaInShippingSection"/> - <see selector="{{StorefrontCustomerOrderViewSection.billingAddress}}" userInput="New York" stepKey="seeNewYorkInBillingSection"/> - </test> -</tests> diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js index 71cdf9bd8324..d5098dbc6f73 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js @@ -246,14 +246,19 @@ define([ * Set shipping information handler */ setShippingInformation: function () { - var checkoutProvider = registry.get('checkoutProvider'); if (this.validateShippingInformation()) { quote.billingAddress(null); checkoutDataResolver.resolveBillingAddress(); - checkoutProvider.set( - 'shippingAddress', - $.extend(true, {}, checkoutProvider.get('shippingAddress'), quote.shippingAddress()) - ); + registry.async('checkoutProvider')(function (checkoutProvider) { + var shippingAddressData = checkoutData.getShippingAddressFromData(); + + if (shippingAddressData) { + checkoutProvider.set( + 'shippingAddress', + $.extend(true, {}, checkoutProvider.get('shippingAddress'), shippingAddressData) + ); + } + }); setShippingInformationAction().done( function () { stepNavigator.next(); From 2763ce536d0597782d2da64b565c3ddb1bf220ea Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Thu, 18 Jul 2019 14:40:32 +0300 Subject: [PATCH 0178/1172] MC-18099: Changes in Downloadable product upload controller --- .../Adminhtml/Downloadable/FileTest.php | 28 ++++++--- .../Magento/Framework/File/Uploader.php | 57 ++++++++++++++++++- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php index 20e36e659463..6333d60da3cf 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/Controller/Adminhtml/Downloadable/FileTest.php @@ -117,23 +117,35 @@ public function extensionsDataProvider() } /** + * @dataProvider uploadWrongUploadTypeDataProvider * @return void */ - public function testUploadWrongUploadType(): void + public function testUploadWrongUploadType($postData): void { - $postData = [ - 'type' => [ - 'tmp_name' => 'test.txt', - 'name' => 'result.txt', - ], - ]; $this->getRequest()->setPostValue($postData); - $this->getRequest()->setMethod('POST'); + $this->dispatch('backend/admin/downloadable_file/upload'); + $body = $this->getResponse()->getBody(); $result = $this->jsonSerializer->unserialize($body); $this->assertEquals('Upload type can not be determined.', $result['error']); $this->assertEquals(0, $result['errorcode']); } + + public function uploadWrongUploadTypeDataProvider(): array + { + return [ + [ + ['type' => 'test'], + ], + [ + [ + 'type' => [ + 'type1' => 'test', + ], + ], + ], + ]; + } } diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index af19c619ae68..a6ad3096ff20 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -5,6 +5,7 @@ */ namespace Magento\Framework\File; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Validation\ValidationException; @@ -14,6 +15,8 @@ * ATTENTION! This class must be used like abstract class and must added * validation by protected file extension list to extended class * + * @SuppressWarnings(PHPMD.TooManyFields) + * * @api */ class Uploader @@ -160,17 +163,27 @@ class Uploader */ protected $_result; + /** + * @var DirectoryList + */ + private $directoryList; + /** * Init upload * * @param string|array $fileId * @param \Magento\Framework\File\Mime|null $fileMime + * @param DirectoryList|null $directoryList * @throws \DomainException */ public function __construct( $fileId, - Mime $fileMime = null + Mime $fileMime = null, + DirectoryList $directoryList = null ) { + $this->directoryList= $directoryList ?: \Magento\Framework\App\ObjectManager::getInstance() + ->get(DirectoryList::class); + $this->_setUploadFileId($fileId); if (!file_exists($this->_file['tmp_name'])) { $code = empty($this->_file['tmp_name']) ? self::TMP_NAME_EMPTY : 0; @@ -550,7 +563,7 @@ private function _getMimeType() */ private function _setUploadFileId($fileId) { - if (is_array($fileId)) { + if (is_array($fileId) && $this->isValidFileId($fileId)) { $this->_uploadType = self::MULTIPLE_STYLE; $this->_file = $fileId; } else { @@ -584,6 +597,46 @@ private function _setUploadFileId($fileId) } } + /** + * Check if $fileId has correct 'tmp_name' field. + * + * @param array $fileId + * @return bool + * @throws \InvalidArgumentException + */ + private function isValidFileId(array $fileId): bool + { + $isValid = false; + if (isset($fileId['tmp_name'])) { + $tmpName = trim($fileId['tmp_name']); + + if (mb_strpos($tmpName, '..') === false) { + $allowedFolders = [ + sys_get_temp_dir(), + $this->directoryList->getPath(DirectoryList::MEDIA), + $this->directoryList->getPath(DirectoryList::VAR_DIR), + $this->directoryList->getPath(DirectoryList::TMP), + $this->directoryList->getPath(DirectoryList::UPLOAD), + ]; + + foreach ($allowedFolders as $allowedFolder) { + if (stripos($tmpName, $allowedFolder) !== false) { + $isValid = true; + break; + } + } + } + } + + if (!$isValid) { + throw new \InvalidArgumentException( + 'Invalid parameter given. A valid $fileId[tmp_name] is expected.' + ); + } + + return $isValid; + } + /** * Create destination folder * From a76a120b60dec8b0664cec98df515ddd3f9feb72 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 18 Jul 2019 10:26:30 -0500 Subject: [PATCH 0179/1172] MC-17700: Downloadable Product links --- .../Downloadable/Api/LinkRepositoryTest.php | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 0eb3da755c5f..7fdfc71227e7 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -470,6 +470,58 @@ public function testCreateThrowsExceptionIfLinkUrlHasWrongFormat() $this->_webApiCall($this->createServiceInfo, $requestData); } + /** + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Link URL must have valid format. + */ + public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://notAnywhereInEnv.com/', + 'sample_type' => 'url', + 'sample_url' => 'http://www.example.com/', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + + /** + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @expectedException \Exception + * @expectedExceptionMessage Sample URL must have valid format. + */ + public function testCreateThrowsExceptionIfSampleUrlUsesDomainNotInWhitelist() + { + $requestData = [ + 'isGlobalScopeContent' => false, + 'sku' => 'downloadable-product', + 'link' => [ + 'title' => 'Link Title', + 'sort_order' => 1, + 'price' => 10, + 'is_shareable' => 1, + 'number_of_downloads' => 100, + 'link_type' => 'url', + 'link_url' => 'http://example.com/', + 'sample_type' => 'url', + 'sample_url' => 'http://www.notAnywhereInEnv.com/', + ], + ]; + + $this->_webApiCall($this->createServiceInfo, $requestData); + } + /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception From 8e94e71c71c15215593d17dc9ca81747c6f2fdd4 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 18 Jul 2019 12:27:44 -0500 Subject: [PATCH 0180/1172] MC-17700: Downloadable Product links --- .../AdminCreateDownloadableProductWithDefaultSetLinksTest.xml | 2 +- .../Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index d9b4e8087cbc..2fcc87b71bbb 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateDownloadableProductWithLinkTest"> + <test name="AdminCreateDownloadableProductWithDefaultSetLinksTest"> <annotations> <features value="Catalog"/> <stories value="Create Downloadable Product"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml index 8b38f91f8719..e43b8f94c7a3 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithLinkTest.xml @@ -8,7 +8,7 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCreateDownloadableProductWithDefaultSetLinksTest"> + <test name="AdminCreateDownloadableProductWithLinkTest"> <annotations> <features value="Catalog"/> <stories value="Create Downloadable Product"/> From 7c199167a89cc0c35ff20bf28aad5771f4ebd17a Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 18 Jul 2019 14:25:05 -0500 Subject: [PATCH 0181/1172] MC-18125: Email template improvement --- lib/internal/Magento/Framework/Filter/Template.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index 4881a16b055e..c330e4d13009 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -79,7 +79,19 @@ class Template implements \Zend_Filter_Interface 'gettemplateprocessor', 'vardirective', 'delete', - 'getdatausingmethod' + 'getdatausingmethod', + '__destruct', + '__call', + '__callStatic', + '__set', + '__unset', + '__sleep', + '__wakeup', + '__invoke', + '__set_state', + '__debugInfo', + '___callParent', + '___callPlugins' ]; /** From 03510d2b455f60c9a2839a1f75dd768a2cf08c1c Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov <ikolesov@magento.com> Date: Thu, 18 Jul 2019 14:32:05 -0500 Subject: [PATCH 0182/1172] MC-17700: Downloadable Product links - CR changes --- .../Downloadable/Api/DomainManagerInterface.php | 8 ++++---- .../Downloadable/Console/Command/DomainsAddCommand.php | 6 +++--- .../Console/Command/DomainsRemoveCommand.php | 6 +++--- .../Console/Command/DomainsShowCommand.php | 2 +- app/code/Magento/Downloadable/Model/DomainManager.php | 10 +++++----- .../Magento/Downloadable/Model/Url/DomainValidator.php | 2 +- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php index 9174d81621b1..ca98f18e36c3 100644 --- a/app/code/Magento/Downloadable/Api/DomainManagerInterface.php +++ b/app/code/Magento/Downloadable/Api/DomainManagerInterface.php @@ -7,7 +7,7 @@ /** * Interface DomainManagerInterface - * Manage downloadable domains whitelist in the environment config. + * Manage downloadable domains whitelist. */ interface DomainManagerInterface { @@ -16,7 +16,7 @@ interface DomainManagerInterface * * @return array */ - public function getEnvDomainWhitelist(); + public function getDomains(): array; /** * Add host to the whitelist. @@ -24,7 +24,7 @@ public function getEnvDomainWhitelist(); * @param array $hosts * @return void */ - public function addEnvDomains($hosts); + public function addDomains(array $hosts): void; /** * Remove host from the whitelist. @@ -32,5 +32,5 @@ public function addEnvDomains($hosts); * @param array $hosts * @return void */ - public function removeEnvDomains($hosts); + public function removeDomains(array $hosts): void; } diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index e230d24b2ca7..285bf38eb45b 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -69,13 +69,13 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { - $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); + $whitelistBefore = $this->domainManager->getDomains(); $newDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $newDomains = array_filter(array_map('trim', $newDomains), 'strlen'); - $this->domainManager->addEnvDomains($newDomains); + $this->domainManager->addDomains($newDomains); - foreach (array_diff($this->domainManager->getEnvDomainWhitelist(), $whitelistBefore) as $newHost) { + foreach (array_diff($this->domainManager->getDomains(), $whitelistBefore) as $newHost) { $output->writeln( $newHost . ' was added to the whitelist.' ); diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 74c0803e3d9a..936126c7a21f 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -70,12 +70,12 @@ protected function execute(InputInterface $input, OutputInterface $output) { try { if ($input->getArgument(self::INPUT_KEY_DOMAINS)) { - $whitelistBefore = $this->domainManager->getEnvDomainWhitelist(); + $whitelistBefore = $this->domainManager->getDomains(); $removeDomains = $input->getArgument(self::INPUT_KEY_DOMAINS); $removeDomains = array_filter(array_map('trim', $removeDomains), 'strlen'); - $this->domainManager->removeEnvDomains($removeDomains); + $this->domainManager->removeDomains($removeDomains); - foreach (array_diff($whitelistBefore, $this->domainManager->getEnvDomainWhitelist()) as $removedHost) { + foreach (array_diff($whitelistBefore, $this->domainManager->getDomains()) as $removedHost) { $output->writeln( $removedHost . ' was removed from the whitelist.' ); diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index dbeb3c7fdd2e..a2a705373bb7 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -52,7 +52,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { try { - $whitelist = implode("\n", $this->domainManager->getEnvDomainWhitelist()); + $whitelist = implode("\n", $this->domainManager->getDomains()); $output->writeln( "Downloadable domains whitelist:\n$whitelist" ); diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index b3f9cce23cac..3c1c295b296b 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -50,7 +50,7 @@ public function __construct( /** * @inheritdoc */ - public function getEnvDomainWhitelist(): array + public function getDomains(): array { return array_map('strtolower', $this->deploymentConfig->get(self::PARAM_DOWNLOADABLE_DOMAINS) ?? []); } @@ -58,9 +58,9 @@ public function getEnvDomainWhitelist(): array /** * @inheritdoc */ - public function addEnvDomains($hosts) + public function addDomains(array $hosts): void { - $whitelist = $this->getEnvDomainWhitelist(); + $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { array_push($whitelist, $host); @@ -80,9 +80,9 @@ public function addEnvDomains($hosts) /** * @inheritdoc */ - public function removeEnvDomains($hosts) + public function removeDomains(array $hosts): void { - $whitelist = $this->getEnvDomainWhitelist(); + $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (in_array($host, $whitelist)) { $index = array_search($host, $whitelist); diff --git a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php index 3d44d073af20..cab7fb134ea3 100644 --- a/app/code/Magento/Downloadable/Model/Url/DomainValidator.php +++ b/app/code/Magento/Downloadable/Model/Url/DomainValidator.php @@ -64,7 +64,7 @@ public function isValid($value): bool $host = $this->getHost($value); $isIpAddress = $this->ipValidator->isValid($host); - $isValid = !$isIpAddress && in_array($host, $this->domainManager->getEnvDomainWhitelist()); + $isValid = !$isIpAddress && in_array($host, $this->domainManager->getDomains()); return $isValid; } diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 8bddfb232b33..a6534fa1717f 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -112,7 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->domainManager->addEnvDomains(array_unique($this->whitelist)); + $this->domainManager->addDomains(array_unique($this->whitelist)); } /** From 38182ec65b7d6da2158adb5b11fbb2a9f2404ca9 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 18 Jul 2019 15:14:37 -0500 Subject: [PATCH 0183/1172] MC-17700: Downloadable Product links --- .../AdminDownloadableProductActionGroup.xml | 17 ++++---- ...bleProductWithInvalidDomainLinkUrlTest.xml | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml index 363911daa41e..91114e54cb42 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml @@ -40,17 +40,18 @@ <actionGroup name="addDownloadableProductLink"> <arguments> <argument name="link" defaultValue="downloadableLink"/> + <argument name="index" type="string" defaultValue="1"/> </arguments> <click selector="{{AdminProductDownloadableSection.linksAddLinkButton}}" stepKey="clickLinkAddLinkButton"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <fillField userInput="{{link.title}}" selector="{{AdminProductDownloadableSection.addLinkTitleInput('1')}}" stepKey="fillDownloadableLinkTitle"/> - <fillField userInput="{{link.price}}" selector="{{AdminProductDownloadableSection.addLinkPriceInput('1')}}" stepKey="fillDownloadableLinkPrice"/> - <selectOption userInput="{{link.file_type}}" selector="{{AdminProductDownloadableSection.addLinkFileTypeSelector('1')}}" stepKey="selectDownloadableLinkFileType"/> - <selectOption userInput="{{link.sample_type}}" selector="{{AdminProductDownloadableSection.addLinkSampleTypeSelector('1')}}" stepKey="selectDownloadableLinkSampleType"/> - <selectOption userInput="{{link.shareable}}" selector="{{AdminProductDownloadableSection.addLinkShareableSelector('1')}}" stepKey="selectDownloadableLinkShareable"/> - <checkOption selector="{{AdminProductDownloadableSection.addLinkIsUnlimitedDownloads('1')}}" stepKey="checkDownloadableLinkUnlimited"/> - <fillField userInput="{{link.file}}" selector="{{AdminProductDownloadableSection.addLinkFileUrlInput('1')}}" stepKey="fillDownloadableLinkFileUrl"/> - <attachFile userInput="{{link.sample}}" selector="{{AdminProductDownloadableSection.addLinkSampleUploadFile('1')}}" stepKey="attachDownloadableLinkUploadSample"/> + <fillField userInput="{{link.title}}" selector="{{AdminProductDownloadableSection.addLinkTitleInput(index)}}" stepKey="fillDownloadableLinkTitle"/> + <fillField userInput="{{link.price}}" selector="{{AdminProductDownloadableSection.addLinkPriceInput(index)}}" stepKey="fillDownloadableLinkPrice"/> + <selectOption userInput="{{link.file_type}}" selector="{{AdminProductDownloadableSection.addLinkFileTypeSelector(index)}}" stepKey="selectDownloadableLinkFileType"/> + <selectOption userInput="{{link.sample_type}}" selector="{{AdminProductDownloadableSection.addLinkSampleTypeSelector(index)}}" stepKey="selectDownloadableLinkSampleType"/> + <selectOption userInput="{{link.shareable}}" selector="{{AdminProductDownloadableSection.addLinkShareableSelector(index)}}" stepKey="selectDownloadableLinkShareable"/> + <checkOption selector="{{AdminProductDownloadableSection.addLinkIsUnlimitedDownloads(index)}}" stepKey="checkDownloadableLinkUnlimited"/> + <fillField userInput="{{link.file}}" selector="{{AdminProductDownloadableSection.addLinkFileUrlInput(index)}}" stepKey="fillDownloadableLinkFileUrl"/> + <attachFile userInput="{{link.sample}}" selector="{{AdminProductDownloadableSection.addLinkSampleUploadFile(index)}}" stepKey="attachDownloadableLinkUploadSample"/> </actionGroup> <!--Add a downloadable sample file--> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml new file mode 100644 index 000000000000..0291b0bb3110 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest" extends="AdminCreateDownloadableProductWithLinkTest"> + <annotations> + <features value="Catalog"/> + <stories value="Create Downloadable Product"/> + <title value="Create Downloadable Product with invalid domain link url"/> + <description value="Admin should not be able to create downloadable product with invalid domain link url"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-18282"/> + <group value="Downloadable"/> + <group value="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest"/> + </annotations> + <before> + <remove keyForRemoval="addDownloadableDomain" /> + </before> + <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLink"> + <argument name="link" value="downloadableLink"/> + <argument name="index" value="0"/> + </actionGroup> + <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL must have valid format." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> + <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> + <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> + <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> + <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLinkAgain" after="checkIsLinksPurchasedSeparately"> + <argument name="link" value="downloadableLink"/> + <argument name="index" value="0"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveProductAfterAddingDomainToWhitelist" after="addDownloadableProductLinkAgain" /> + </test> +</tests> From 2453496dfc827e29f4e9d6f2db050085dcf445d2 Mon Sep 17 00:00:00 2001 From: Ievgen Kolesov <ikolesov@magento.com> Date: Thu, 18 Jul 2019 16:33:53 -0500 Subject: [PATCH 0184/1172] MC-17700: Downloadable Product links - CR changes --- .../Console/Command/DomainsShowCommand.php | 2 +- .../Api/ProductRepositoryInterfaceTest.php | 18 +++++++----------- .../Api/ProductRepositoryTest.php | 17 ++++++----------- ...able_product_with_files_and_sample_url.php | 9 ++++----- ...uct_with_files_and_sample_url_rollback.php | 9 ++++----- .../_files/product_downloadable.php | 19 ++++++++----------- .../_files/product_downloadable_rollback.php | 19 ++++++++----------- .../product_downloadable_with_files.php | 19 ++++++++----------- 8 files changed, 46 insertions(+), 66 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php index a2a705373bb7..eb4488353a09 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsShowCommand.php @@ -12,7 +12,7 @@ use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; /** - * Class DomainsAddCommand + * Class DomainsShowCommand * * Command for listing allowed downloadable domains */ diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php index b9afaf1518b8..2772e8049027 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php @@ -9,8 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\Data\StockItemInterface; -use Magento\Downloadable\Console\Command\DomainsAddCommand; -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Downloadable\Model\Link; use Magento\Store\Model\Store; use Magento\Store\Model\Website; @@ -24,7 +23,6 @@ use Magento\Framework\Api\SortOrderBuilder; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; -use Symfony\Component\Console\Tester\CommandTester; /** * @magentoAppIsolation enabled @@ -66,10 +64,9 @@ protected function setUp() parent::setUp(); $objectManager = Bootstrap::getObjectManager(); - /** @var DomainsAddCommand $domainsAddCommand */ - $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); - $command = new CommandTester($domainsAddCommand); - $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->addDomains(['example.com']); } /** @@ -80,10 +77,9 @@ protected function tearDown() parent::tearDown(); $objectManager = Bootstrap::getObjectManager(); - /** @var DomainsRemoveCommand $domainsRemoveCommand */ - $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); - $command = new CommandTester($domainsRemoveCommand); - $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->removeDomains(['example.com']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php index 0415835f2dcb..c2393d0a5ad2 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/ProductRepositoryTest.php @@ -7,11 +7,8 @@ namespace Magento\Downloadable\Api; use Magento\Catalog\Api\Data\ProductInterface; -use Magento\Downloadable\Console\Command\DomainsAddCommand; -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; use Magento\Framework\Api\ExtensibleDataInterface; use Magento\TestFramework\TestCase\WebapiAbstract; -use Symfony\Component\Console\Tester\CommandTester; /** * Class ProductRepositoryTest for testing ProductRepository interface with Downloadable Product @@ -35,10 +32,9 @@ protected function setUp() $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var DomainsAddCommand $domainsAddCommand */ - $domainsAddCommand = $objectManager->get(DomainsAddCommand::class); - $command = new CommandTester($domainsAddCommand); - $command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->addDomains(['www.example.com']); } /** @@ -51,10 +47,9 @@ public function tearDown() $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - /** @var DomainsRemoveCommand $domainsRemoveCommand */ - $domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); - $command = new CommandTester($domainsRemoveCommand); - $command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['www.example.com']]); + /** @var DomainManagerInterface $domainManager */ + $domainManager = $objectManager->get(DomainManagerInterface::class); + $domainManager->removeDomains(['www.example.com']); } protected function getLinkData() diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php index df6d717ed101..e312d973aeb1 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url.php @@ -4,14 +4,13 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute([DomainsAddCommand::INPUT_KEY_DOMAINS => ['example.com', 'sampleurl.com']]); +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains(['example.com', 'sampleurl.com']); /** * @var \Magento\Catalog\Model\Product $product diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php index dbaf4ea6f67b..48d6966fb90d 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/downloadable_product_with_files_and_sample_url_rollback.php @@ -4,14 +4,13 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsRemoveCommand $domainsRemoveCommand */ -$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); -$command->execute([DomainsRemoveCommand::INPUT_KEY_DOMAINS => ['sampleurl.com']]); +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->removeDomains(['sampleurl.com']); // @codingStandardsIgnoreLine require __DIR__ . '/product_downloadable_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php index 56277a75cd80..25344ea447d9 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php @@ -4,21 +4,18 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains( [ - DomainsAddCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php index 22619d25ee4e..9a2e1c74fcd3 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_rollback.php @@ -4,24 +4,21 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsRemoveCommand; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Framework\Exception\NoSuchEntityException; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsRemoveCommand $domainsRemoveCommand */ -$domainsRemoveCommand = $objectManager->get(DomainsRemoveCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsRemoveCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->removeDomains( [ - DomainsRemoveCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php index 47eb6c450e9e..a6c58c586ea1 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_files.php @@ -4,22 +4,19 @@ * See COPYING.txt for license details. */ -use Magento\Downloadable\Console\Command\DomainsAddCommand; +use Magento\Downloadable\Api\DomainManagerInterface; \Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize(); $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -/** @var DomainsAddCommand $domainsAddCommand */ -$domainsAddCommand = $objectManager->get(DomainsAddCommand::class); -$command = new \Symfony\Component\Console\Tester\CommandTester($domainsAddCommand); -$command->execute( +/** @var DomainManagerInterface $domainManager */ +$domainManager = $objectManager->get(DomainManagerInterface::class); +$domainManager->addDomains( [ - DomainsAddCommand::INPUT_KEY_DOMAINS => [ - 'example.com', - 'www.example.com', - 'www.sample.example.com', - 'google.com' - ] + 'example.com', + 'www.example.com', + 'www.sample.example.com', + 'google.com' ] ); From 4293a7e85f466be422d37a195c5d258f4ae8d810 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 18 Jul 2019 17:27:00 -0500 Subject: [PATCH 0185/1172] MC-17700: Downloadable Product links --- ...minCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 0291b0bb3110..d75c666cb0cb 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -10,14 +10,12 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest" extends="AdminCreateDownloadableProductWithLinkTest"> <annotations> - <features value="Catalog"/> <stories value="Create Downloadable Product"/> <title value="Create Downloadable Product with invalid domain link url"/> <description value="Admin should not be able to create downloadable product with invalid domain link url"/> <severity value="CRITICAL"/> <testCaseId value="MC-18282"/> <group value="Downloadable"/> - <group value="AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest"/> </annotations> <before> <remove keyForRemoval="addDownloadableDomain" /> From 241271e8417c4264d44682169aa2032e955d6942 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 12:01:10 +0300 Subject: [PATCH 0186/1172] MC-18099: Changes in Downloadable product upload controller --- .../Magento/Framework/File/UploaderTest.php | 105 ++++++++++++++++++ .../Magento/Framework/File/Uploader.php | 28 +++-- 2 files changed, 124 insertions(+), 9 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php new file mode 100644 index 000000000000..952df02822a3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\File; + +use Magento\Framework\App\Filesystem\DirectoryList; + +/** + * Test for \Magento\Framework\File\Uploader + */ +class UploaderTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\MediaStorage\Model\File\UploaderFactory + */ + private $uploaderFactory; + + /** + * @var \Magento\Framework\Filesystem + */ + private $filesystem; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->uploaderFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\MediaStorage\Model\File\UploaderFactory::class); + + $this->filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class); + } + + /** + * @return void + */ + public function testUploadFileFromAllowedFolder(): void + { + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); + + $fileName = 'text.txt'; + $tmpDir = 'tmp'; + $filePath = $tmpDirectory->getAbsolutePath($fileName); + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $type = [ + 'tmp_name' => $filePath, + 'name' => $fileName, + ]; + + $uploader = $this->uploaderFactory->create(['fileId' => $type]); + $uploader->save($mediaDirectory->getAbsolutePath($tmpDir)); + + $this->assertTrue(is_file($mediaDirectory->getAbsolutePath($tmpDir . DIRECTORY_SEPARATOR . $fileName))); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Invalid parameter given. A valid $fileId[tmp_name] is expected. + * + * @return void + */ + public function testUploadFileFromNotAllowedFolder(): void + { + $fileName = 'text.txt'; + $tmpDir = 'tmp'; + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $directoryPath = $tmpDirectory->getAbsolutePath() . $tmpDir; + if (!is_dir($directoryPath)) { + mkdir($directoryPath, 0777, true); + } + $filePath = $directoryPath . DIRECTORY_SEPARATOR . $fileName; + $file = fopen($filePath, "wb"); + fwrite($file, 'just a text'); + + $type = [ + 'tmp_name' => $filePath, + 'name' => $fileName, + ]; + + $this->uploaderFactory->create(['fileId' => $type]); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + parent::tearDown(); + + $tmpDir = 'tmp'; + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory->delete($tmpDir); + + $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory->delete($tmpDir); + } +} diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php index a6ad3096ff20..f9b41709ec7c 100644 --- a/lib/internal/Magento/Framework/File/Uploader.php +++ b/lib/internal/Magento/Framework/File/Uploader.php @@ -563,7 +563,8 @@ private function _getMimeType() */ private function _setUploadFileId($fileId) { - if (is_array($fileId) && $this->isValidFileId($fileId)) { + if (is_array($fileId)) { + $this->validateFileId($fileId); $this->_uploadType = self::MULTIPLE_STYLE; $this->_file = $fileId; } else { @@ -598,19 +599,19 @@ private function _setUploadFileId($fileId) } /** - * Check if $fileId has correct 'tmp_name' field. + * Validates explicitly given uploaded file data. * * @param array $fileId - * @return bool + * @return void * @throws \InvalidArgumentException */ - private function isValidFileId(array $fileId): bool + private function validateFileId(array $fileId): void { $isValid = false; if (isset($fileId['tmp_name'])) { $tmpName = trim($fileId['tmp_name']); - if (mb_strpos($tmpName, '..') === false) { + if (preg_match('/\.\.(\\\|\/)/', $tmpName) !== 1) { $allowedFolders = [ sys_get_temp_dir(), $this->directoryList->getPath(DirectoryList::MEDIA), @@ -619,22 +620,31 @@ private function isValidFileId(array $fileId): bool $this->directoryList->getPath(DirectoryList::UPLOAD), ]; + $disallowedFolders = [ + $this->directoryList->getPath(DirectoryList::LOG), + ]; + foreach ($allowedFolders as $allowedFolder) { - if (stripos($tmpName, $allowedFolder) !== false) { + if (stripos($tmpName, $allowedFolder) === 0) { $isValid = true; break; } } + + foreach ($disallowedFolders as $disallowedFolder) { + if (stripos($tmpName, $disallowedFolder) === 0) { + $isValid = false; + break; + } + } } } if (!$isValid) { throw new \InvalidArgumentException( - 'Invalid parameter given. A valid $fileId[tmp_name] is expected.' + __('Invalid parameter given. A valid $fileId[tmp_name] is expected.') ); } - - return $isValid; } /** From 1647eb46ece170b89e058c69a8a5f95ff2d02de6 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 14:08:02 +0300 Subject: [PATCH 0187/1172] MC-18099: Changes in Downloadable product upload controller --- .../Magento/Framework/File/UploaderTest.php | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php index 952df02822a3..e38c6a5e81c0 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -47,8 +47,8 @@ public function testUploadFileFromAllowedFolder(): void $fileName = 'text.txt'; $tmpDir = 'tmp'; $filePath = $tmpDirectory->getAbsolutePath($fileName); - $file = fopen($filePath, "wb"); - fwrite($file, 'just a text'); + + $tmpDirectory->writeFile($fileName, 'just a text'); $type = [ 'tmp_name' => $filePath, @@ -58,7 +58,7 @@ public function testUploadFileFromAllowedFolder(): void $uploader = $this->uploaderFactory->create(['fileId' => $type]); $uploader->save($mediaDirectory->getAbsolutePath($tmpDir)); - $this->assertTrue(is_file($mediaDirectory->getAbsolutePath($tmpDir . DIRECTORY_SEPARATOR . $fileName))); + $this->assertTrue($mediaDirectory->isFile($tmpDir . DIRECTORY_SEPARATOR . $fileName)); } /** @@ -72,13 +72,9 @@ public function testUploadFileFromNotAllowedFolder(): void $fileName = 'text.txt'; $tmpDir = 'tmp'; $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); - $directoryPath = $tmpDirectory->getAbsolutePath() . $tmpDir; - if (!is_dir($directoryPath)) { - mkdir($directoryPath, 0777, true); - } - $filePath = $directoryPath . DIRECTORY_SEPARATOR . $fileName; - $file = fopen($filePath, "wb"); - fwrite($file, 'just a text'); + $filePath = $tmpDirectory->getAbsolutePath() . $tmpDir . DIRECTORY_SEPARATOR . $fileName; + + $tmpDirectory->writeFile($tmpDir . DIRECTORY_SEPARATOR . $fileName, 'just a text'); $type = [ 'tmp_name' => $filePath, @@ -91,15 +87,17 @@ public function testUploadFileFromNotAllowedFolder(): void /** * @inheritdoc */ - protected function tearDown() + public static function tearDownAfterClass() { - parent::tearDown(); + parent::tearDownAfterClass(); + $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Framework\Filesystem::class); $tmpDir = 'tmp'; - $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete($tmpDir); - $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory = $filesystem->getDirectoryWrite(DirectoryList::LOG); $logDirectory->delete($tmpDir); } } From 6989a910db2c297beb23bfc7629662dd3bab59d5 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 19 Jul 2019 15:43:10 +0300 Subject: [PATCH 0188/1172] MC-18099: Changes in Downloadable product upload controller --- .../testsuite/Magento/Framework/File/UploaderTest.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php index e38c6a5e81c0..15e52f5b1756 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/File/UploaderTest.php @@ -87,17 +87,15 @@ public function testUploadFileFromNotAllowedFolder(): void /** * @inheritdoc */ - public static function tearDownAfterClass() + protected function tearDown() { - parent::tearDownAfterClass(); - $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->get(\Magento\Framework\Filesystem::class); + parent::tearDown(); $tmpDir = 'tmp'; - $mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); $mediaDirectory->delete($tmpDir); - $logDirectory = $filesystem->getDirectoryWrite(DirectoryList::LOG); + $logDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::LOG); $logDirectory->delete($tmpDir); } } From 90772dd77c57d7afed71e1af4d0e5869d0c60210 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 08:42:56 -0500 Subject: [PATCH 0189/1172] MC-17700: Downloadable Product links --- .../Magento/Downloadable/Console/Command/DomainsAddCommand.php | 1 - .../Downloadable/Console/Command/DomainsRemoveCommand.php | 1 - app/code/Magento/Downloadable/Model/DomainManager.php | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php index 285bf38eb45b..76d9a13f70f1 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsAddCommand.php @@ -12,7 +12,6 @@ use Symfony\Component\Console\Input\InputArgument; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; - /** * Class DomainsAddCommand * diff --git a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php index 936126c7a21f..a30e99a24859 100644 --- a/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php +++ b/app/code/Magento/Downloadable/Console/Command/DomainsRemoveCommand.php @@ -12,7 +12,6 @@ use Symfony\Component\Console\Input\InputArgument; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; - /** * Class DomainsRemoveCommand * diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index 3c1c295b296b..e4c5948fa9cd 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -14,6 +14,7 @@ /** * Class DomainManager + * * Manage downloadable domains whitelist in the environment config. */ class DomainManager implements DomainManagerInterface From a2a47a5e9eb81ad98dd3a1bb54530124cd730455 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 09:35:01 -0500 Subject: [PATCH 0190/1172] MC-17700: Downloadable Product links --- ...inCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index d75c666cb0cb..5aa00e3ef48e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -34,5 +34,8 @@ <argument name="index" value="0"/> </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveProductAfterAddingDomainToWhitelist" after="addDownloadableProductLinkAgain" /> + <scrollTo selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" stepKey="scrollToLinks"/> + <click selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" stepKey="selectProductLink"/> + <see selector="{{CheckoutCartProductSection.ProductPriceByName(DownloadableProduct.name)}}" userInput="$52.99" stepKey="assertProductPriceInCart"/> </test> </tests> From 411523e00466128e9b59666064275015318fd0e6 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 19 Jul 2019 14:43:09 -0500 Subject: [PATCH 0191/1172] MC-17700: Downloadable Product links --- .../Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml index 91114e54cb42..e60e6f6887d0 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/ActionGroup/AdminDownloadableProductActionGroup.xml @@ -52,6 +52,7 @@ <checkOption selector="{{AdminProductDownloadableSection.addLinkIsUnlimitedDownloads(index)}}" stepKey="checkDownloadableLinkUnlimited"/> <fillField userInput="{{link.file}}" selector="{{AdminProductDownloadableSection.addLinkFileUrlInput(index)}}" stepKey="fillDownloadableLinkFileUrl"/> <attachFile userInput="{{link.sample}}" selector="{{AdminProductDownloadableSection.addLinkSampleUploadFile(index)}}" stepKey="attachDownloadableLinkUploadSample"/> + <waitForPageLoad stepKey="waitForPageLoadAfterFillingOutForm" /> </actionGroup> <!--Add a downloadable sample file--> From f03348b6eb4f2cbaa120f03d0b967fc829d00d7a Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 10:48:50 -0500 Subject: [PATCH 0192/1172] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index a6534fa1717f..b42d126a9c30 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -112,7 +112,7 @@ public function apply() $this->addHost($scope->getBaseUrl()); } - $this->domainManager->addDomains(array_unique($this->whitelist)); + $this->domainManager->addDomains($this->whitelist); } /** From f57f4d2e845f90a83d7aee8508753fda6f81f956 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 11:35:54 -0500 Subject: [PATCH 0193/1172] MC-17700: Downloadable Product links --- ...dminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 5aa00e3ef48e..ea7dc8c51388 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -15,6 +15,7 @@ <description value="Admin should not be able to create downloadable product with invalid domain link url"/> <severity value="CRITICAL"/> <testCaseId value="MC-18282"/> + <useCaseId value="MC-17700"/> <group value="Downloadable"/> </annotations> <before> From 61010964f018362057ae164d2c4cf509a68fe284 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 22 Jul 2019 14:11:16 -0500 Subject: [PATCH 0194/1172] MC-17700: Downloadable Product links --- .../Downloadable/Model/Link/ContentValidator.php | 16 ++++++++++------ .../Model/Sample/ContentValidator.php | 7 +++++-- ...adableProductWithInvalidDomainLinkUrlTest.xml | 2 +- app/code/Magento/Downloadable/i18n/en_US.csv | 3 ++- .../Downloadable/Api/LinkRepositoryTest.php | 4 ++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php index e9ed4920a24b..28d61986a4f5 100644 --- a/app/code/Magento/Downloadable/Model/Link/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Link/ContentValidator.php @@ -100,11 +100,13 @@ public function isValid(LinkInterface $link, $validateLinkContent = true, $valid protected function validateLinkResource(LinkInterface $link) { if ($link->getLinkType() === 'url') { - if (!$this->urlValidator->isValid($link->getLinkUrl()) - || !$this->domainValidator->isValid($link->getLinkUrl()) - ) { + if (!$this->urlValidator->isValid($link->getLinkUrl())) { throw new InputException(__('Link URL must have valid format.')); } + + if (!$this->domainValidator->isValid($link->getLinkUrl())) { + throw new InputException(__('Link URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($link->getLinkFileContent()) { if (!$this->fileContentValidator->isValid($link->getLinkFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); @@ -124,11 +126,13 @@ protected function validateLinkResource(LinkInterface $link) protected function validateSampleResource(LinkInterface $link) { if ($link->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($link->getSampleUrl()) - || !$this->domainValidator->isValid($link->getSampleUrl()) - ) { + if (!$this->urlValidator->isValid($link->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } + + if (!$this->domainValidator->isValid($link->getSampleUrl())) { + throw new InputException(__('Sample URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($link->getSampleFileContent()) { if (!$this->fileContentValidator->isValid($link->getSampleFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); diff --git a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php index 7c53a228f27c..697878017ee8 100644 --- a/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php +++ b/app/code/Magento/Downloadable/Model/Sample/ContentValidator.php @@ -88,10 +88,13 @@ public function isValid(SampleInterface $sample, $validateSampleContent = true) protected function validateSampleResource(SampleInterface $sample) { if ($sample->getSampleType() === 'url') { - if (!$this->urlValidator->isValid($sample->getSampleUrl()) - || !$this->domainValidator->isValid($sample->getSampleUrl())) { + if (!$this->urlValidator->isValid($sample->getSampleUrl())) { throw new InputException(__('Sample URL must have valid format.')); } + + if (!$this->domainValidator->isValid($sample->getSampleUrl())) { + throw new InputException(__('Sample URL\'s domain is not in list of downloadable_domains in env.php.')); + } } elseif ($sample->getSampleFileContent()) { if (!$this->fileContentValidator->isValid($sample->getSampleFileContent())) { throw new InputException(__('Provided file content must be valid base64 encoded data.')); diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index ea7dc8c51388..4eb6b82b6591 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -26,7 +26,7 @@ <argument name="index" value="0"/> </actionGroup> <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> - <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL must have valid format." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> + <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL's domain is not in list of downloadable_domains in env.php." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index 6158f1c57972..d5607d7f536c 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -118,4 +118,5 @@ Downloads,Downloads "Use Content-Disposition","Use Content-Disposition" "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." -"Host ""%value"" is not allowed.","Host ""%value"" is not allowed." +"Link URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." +"Sample URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php index 7fdfc71227e7..3a24aab30cb6 100644 --- a/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Api/LinkRepositoryTest.php @@ -473,7 +473,7 @@ public function testCreateThrowsExceptionIfLinkUrlHasWrongFormat() /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception - * @expectedExceptionMessage Link URL must have valid format. + * @expectedExceptionMessage Link URL's domain is not in list of downloadable_domains in env.php. */ public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() { @@ -499,7 +499,7 @@ public function testCreateThrowsExceptionIfLinkUrlUsesDomainNotInWhitelist() /** * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php * @expectedException \Exception - * @expectedExceptionMessage Sample URL must have valid format. + * @expectedExceptionMessage Sample URL's domain is not in list of downloadable_domains in env.php. */ public function testCreateThrowsExceptionIfSampleUrlUsesDomainNotInWhitelist() { From 7375716d7ddd8269a0bff29d86bc67c5c6815dd4 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 22 Jul 2019 15:47:46 -0500 Subject: [PATCH 0195/1172] MC-15298: Allow admin to opt out of admin analytics tracking --- .../Magento/AdminAnalytics/Block/Metadata.php | 84 +++++++++++ app/code/Magento/AdminAnalytics/README.md | 1 + .../SelectAdminUsageSettingActionGroup.xml | 19 +++ .../Test/Mftf/Section/AdminHeaderSection.xml | 15 ++ .../Mftf/Section/AdminUsageConfigSection.xml | 16 ++ .../Test/Mftf/Test/TrackingScriptTest.xml | 137 ++++++++++++++++++ app/code/Magento/AdminAnalytics/composer.json | 26 ++++ .../AdminAnalytics/etc/adminhtml/system.xml | 21 +++ .../Magento/AdminAnalytics/etc/config.xml | 18 +++ .../Magento/AdminAnalytics/etc/module.xml | 10 ++ .../Magento/AdminAnalytics/registration.php | 9 ++ .../view/adminhtml/layout/default.xml | 19 +++ .../view/adminhtml/templates/tracking.phtml | 15 ++ 13 files changed, 390 insertions(+) create mode 100644 app/code/Magento/AdminAnalytics/Block/Metadata.php create mode 100644 app/code/Magento/AdminAnalytics/README.md create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml create mode 100644 app/code/Magento/AdminAnalytics/composer.json create mode 100644 app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/module.xml create mode 100644 app/code/Magento/AdminAnalytics/registration.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php new file mode 100644 index 000000000000..e89d09ab100e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -0,0 +1,84 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Template\Context; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\App\State; + +/** + * Gets user version and mode + * + * @api + */ +class Metadata extends Template +{ + /** + * @var State + */ + private $appState; + + /** + * @var Session + */ + private $authSession; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @param Context $context + * @param ProductMetadataInterface $productMetadata + * @param Session $authSession + * @param State $appState + * @param array $data + */ + public function __construct( + Context $context, + ProductMetadataInterface $productMetadata, + Session $authSession, + State $appState, + array $data = [] + ) { + $this->productMetadata = $productMetadata; + $this->authSession = $authSession; + $this->appState = $appState; + parent::__construct($context, $data); + } + + /** + * Get product version + * + * @return string + */ + public function getMagentoVersion() :string + { + return $this->productMetadata->getVersion(); + } + + /** + * Get current user id (hash generated from email) + * + * @return string + */ + public function getCurrentUser() :string + { + return hash('sha512', 'ADMIN_USER' . $this->authSession->getUser()->getEmail()); + } + /** + * Get Magento mode + * + * @return string + */ + public function getMode() :string + { + return $this->appState->getMode(); + } +} diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md new file mode 100644 index 000000000000..1280e0fcef10 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/README.md @@ -0,0 +1 @@ +The purpose of Magento\AdminAnalytics module is gather information on which features the users uses and sends it to adobe analytics \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml new file mode 100644 index 000000000000..3b302fe5be18 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/SelectAdminUsageSettingActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="SelectAdminUsageSetting"> + <arguments> + <argument name="adminUsageValue" type="string" defaultValue="0"/> + </arguments> + <conditionalClick selector="{{AdminUsageConfigSection.adminUsageHeader}}" dependentSelector="{{AdminUsageConfigSection.adminUsageOptions}}" visible="false" stepKey="clickOnAdminUsageHeader"/> + <selectOption selector="{{AdminUsageConfigSection.adminUsageOptions}}" userInput="{{adminUsageValue}}" stepKey="selectOption"/> + <click selector="{{AdminNewStoreGroupActionsSection.saveButton}}" stepKey="clickSaveButton"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml new file mode 100644 index 000000000000..cc9f495a6002 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminHeaderSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminHeaderSection"> + <element name="adminTrackingScript" type="text" selector="script[src*='//assets.adobedtm.com/launch']"/> + <element name="adminTrackingMetaData" type="text" selector="//*script[contains('adminAnalyticsMetadata')]"/> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml new file mode 100644 index 000000000000..ddb89f0bfb72 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUsageConfigSection"> + + <element name="adminUsageHeader" type="text" selector="#admin_usage-head"/> + <element name="adminUsageOptions" type="select" selector="#admin_usage_enabled"/> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml new file mode 100644 index 000000000000..da0d5041a6e3 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -0,0 +1,137 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="TrackingScriptTest"> + <annotations> + <features value="Backend"/> + <stories value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <title value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <description value="Checks to see if the tracking script is in the dom of admin and if setting is turned to no it checks if the tracking script in the dom was removed"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-18192"/> + <group value="backend"/> + <group value="login"/> + </annotations> + + <!-- Logging in Magento admin and checking for tracking script in dashboard --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <closeAdminNotification stepKey="closeAdminNotification"/> + + <!-- Navigating to advance settings --> + <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/> + <waitForPageLoad stepKey="waitForAdvanceSettings"/> + + <!-- Changing usage setting to Yes --> + <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes"> + <argument name="adminUsageValue" value="1"/> + </actionGroup> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/> + + <!-- Checking for tracking script in salesOrderPage --> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/> + <waitForPageLoad stepKey="waitForSalesOrderPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/> + + <!-- Checking for tracking script in catalogProductsPage --> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/> + <waitForPageLoad stepKey="waitForCatalogProductsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/> + + <!-- Checking for tracking script in customersAllCustomersPage --> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/> + <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/> + + <!-- Checking for tracking script in marketingCatalogPriceRulePage --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/> + <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/> + + <!-- Checking for tracking script in contentBlocksPage --> + <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/> + <waitForPageLoad stepKey="waitForContentBlocksPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/> + + <!-- Checking for tracking script in reportsSearchTermsPage --> + <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/> + <waitForPageLoad stepKey="waitForSearchTermsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/> + + <!-- Checking for tracking script in storesAllStoresPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/> + <waitForPageLoad stepKey="waitForStoresAllStoresPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/> + + <!-- Checking for tracking script in systemImportPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/> + <waitForPageLoad stepKey="waitForSystemImportPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/> + + <!-- Checking for tracking script in findPartnersAndExtensionsPage --> + <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPage"/> + <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPage"/> + <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlFindPartnersAndExtensions"/> + + <!-- Navigating to advance settings --> + <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/> + <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/> + + <!-- Changing usage setting back to No --> + <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo"> + <argument name="adminUsageValue" value="0"/> + </actionGroup> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/> + + <!-- Checking for removed tracking script in salesOrderPage --> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/> + <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/> + + <!-- Checking for removed tracking script in catalogProductsPage --> + <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/> + <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/> + + <!-- Checking for removed tracking script in customersAllCustomersPage --> + <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/> + <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/> + + <!-- Checking for removed tracking script in marketingCatalogPriceRulePage --> + <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/> + <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/> + + <!-- Checking for removed tracking script in contentBlocksPage --> + <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/> + <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/> + + <!-- Checking for removed tracking script in reportsSearchTermsPage --> + <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/> + <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/> + + <!-- Checking for removed tracking script in storesAllStoresPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/> + <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/> + + <!-- Checking for removed tracking script in systemImportPage --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/> + <waitForPageLoad stepKey="waitForSystemImportPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/> + + <!-- Checking for removed tracking script in findPartnersAndExtensionsPage --> + <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPageAgain"/> + <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPageAgain"/> + <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlFindPartnersTest"/> + </test> +</tests> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json new file mode 100644 index 000000000000..085d258c72b5 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-admin-analytics", + "description": "N/A", + "config": { + "sort-packages": true + }, + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-backend": "*" + }, + "type": "magento2-module", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\AdminAnalytics\\": "" + } + } +} + diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml new file mode 100644 index 000000000000..97372e1cca08 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> + <system> + <section id="admin"> + <group id="usage" translate="label" type="text" sortOrder="2000" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Admin Usage</label> + <field id="enabled" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0"> + <label>Enable Admin Usage Tracking</label> + <source_model>Magento\Config\Model\Config\Source\Yesno</source_model> + <comment>Allow Magento to track admin usage in order to improve the quality and user experience.</comment> + </field> + </group> + </section> + </system> +</config> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 000000000000..85b6b6879f08 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 0 + </enabled> + </usage> + </admin> + </default> +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml new file mode 100644 index 000000000000..f0990b114e25 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -0,0 +1,10 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_AdminAnalytics"/> +</config> diff --git a/app/code/Magento/AdminAnalytics/registration.php b/app/code/Magento/AdminAnalytics/registration.php new file mode 100644 index 000000000000..65c9955d396a --- /dev/null +++ b/app/code/Magento/AdminAnalytics/registration.php @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use \Magento\Framework\Component\ComponentRegistrar; + +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_AdminAnalytics', __DIR__); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml new file mode 100644 index 000000000000..8ec8ac3bfaf5 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" > + <body> + <referenceContainer name="header"> + <block class="Magento\AdminAnalytics\Block\Metadata" name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> + <arguments> + <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> + </arguments> + </block> + </referenceContainer> + </body> +</page> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml new file mode 100644 index 000000000000..e4acd77b1335 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -0,0 +1,15 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<script src="<?= $block->escapeUrl($block->getTrackingUrl()) ?>" async></script> +<script> + var adminAnalyticsMetadata = { + "version": "<?= $block->escapeJs($block->getMagentoVersion()) ?>", + "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", + "mode": "<?= $block->escapeJs($block->getMode()) ?>" + }; +</script> \ No newline at end of file From 11f7f3954132512dd9d8fbc0a70e81e48de7a4ba Mon Sep 17 00:00:00 2001 From: Jamie Saunders <jamie@wearec3.co.uk> Date: Tue, 23 Jul 2019 08:15:31 +0100 Subject: [PATCH 0196/1172] Fixes #23824: User data serialised multiple times on save when loaded via loadByUsername. Unserialises the extra data when loading a user using the loadByUsername method of the User model. --- app/code/Magento/User/Model/User.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index d8040b0bbaaa..674dabb7ff16 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -671,6 +671,10 @@ public function loadByUsername($username) { $data = $this->getResource()->loadByUsername($username); if ($data !== false) { + if (is_string($data['extra'])) { + $data['extra'] = $this->serializer->unserialize($data['extra']); + } + $this->setData($data); $this->setOrigData(); } From 114a25dd9c3936d1b80121343df1c9c95dec94bc Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 09:28:33 -0500 Subject: [PATCH 0197/1172] MC-17700: Downloadable Product links --- app/code/Magento/Downloadable/i18n/en_US.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/i18n/en_US.csv b/app/code/Magento/Downloadable/i18n/en_US.csv index d5607d7f536c..1e96413aa08a 100644 --- a/app/code/Magento/Downloadable/i18n/en_US.csv +++ b/app/code/Magento/Downloadable/i18n/en_US.csv @@ -119,4 +119,4 @@ Downloads,Downloads "Disable Guest Checkout if Cart Contains Downloadable Items","Disable Guest Checkout if Cart Contains Downloadable Items" "Guest checkout will only work with shareable.","Guest checkout will only work with shareable." "Link URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." -"Sample URL's domain is not in list of downloadable_domains in env.php.","Link URL's domain is not in list of downloadable_domains in env.php." +"Sample URL's domain is not in list of downloadable_domains in env.php.","Sample URL's domain is not in list of downloadable_domains in env.php." From 19341f41d6cf385bcbdc41d6d900232fae66c9ed Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 11:12:17 -0500 Subject: [PATCH 0198/1172] MC-17700: Downloadable Product links --- .../Downloadable/Model/DomainManager.php | 4 ++- .../Patch/Data/AddDownloadableHostsConfig.php | 28 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Downloadable/Model/DomainManager.php b/app/code/Magento/Downloadable/Model/DomainManager.php index e4c5948fa9cd..e1f275902b03 100644 --- a/app/code/Magento/Downloadable/Model/DomainManager.php +++ b/app/code/Magento/Downloadable/Model/DomainManager.php @@ -64,7 +64,7 @@ public function addDomains(array $hosts): void $whitelist = $this->getDomains(); foreach (array_map('strtolower', $hosts) as $host) { if (!in_array($host, $whitelist)) { - array_push($whitelist, $host); + $whitelist[] = $host; } } @@ -91,6 +91,8 @@ public function removeDomains(array $hosts): void } } + $whitelist = array_values($whitelist); // reindex whitelist to prevent non-sequential keying + $this->configWriter->saveConfig( [ ConfigFilePool::APP_ENV => [ diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index b42d126a9c30..575a6a4d7180 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -7,11 +7,14 @@ namespace Magento\Downloadable\Setup\Patch\Data; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Store\Model\ScopeInterface; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Backend\App\Area\FrontNameResolver; /** * Adding base url as allowed downloadable domain. @@ -28,6 +31,11 @@ class AddDownloadableHostsConfig implements DataPatchInterface */ private $scopeResolver; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + /** * @var ModuleDataSetupInterface */ @@ -48,17 +56,20 @@ class AddDownloadableHostsConfig implements DataPatchInterface * * @param UriHandler $uriHandler * @param ScopeResolverInterface $scopeResolver + * @param ScopeConfigInterface $scopeConfig * @param DomainManager $domainManager * @param ModuleDataSetupInterface $moduleDataSetup */ public function __construct( UriHandler $uriHandler, ScopeResolverInterface $scopeResolver, + ScopeConfigInterface $scopeConfig, DomainManager $domainManager, ModuleDataSetupInterface $moduleDataSetup ) { $this->uriHandler = $uriHandler; $this->scopeResolver = $scopeResolver; + $this->scopeConfig = $scopeConfig; $this->domainManager = $domainManager; $this->moduleDataSetup = $moduleDataSetup; } @@ -68,6 +79,19 @@ public function __construct( */ public function apply() { + foreach ($this->scopeResolver->getScopes() as $scope) { + $this->addHost($scope->getBaseUrl()); + } + + $customAdminUrl = $this->scopeConfig->getValue( + FrontNameResolver::XML_PATH_CUSTOM_ADMIN_URL, + ScopeInterface::SCOPE_STORE + ); + + if ($customAdminUrl) { + $this->addHost($customAdminUrl); + } + if ($this->moduleDataSetup->tableExists('downloadable_link')) { $select = $this->moduleDataSetup->getConnection() ->select() @@ -108,10 +132,6 @@ public function apply() } } - foreach ($this->scopeResolver->getScopes() as $scope) { - $this->addHost($scope->getBaseUrl()); - } - $this->domainManager->addDomains($this->whitelist); } From 52a1316151042ad68bc6cd1b15da7f4abe4dc499 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 15:20:47 -0500 Subject: [PATCH 0199/1172] MC-17700: Downloadable Product links --- .../Import/Product/Type/Downloadable.php | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index e03964bd2c38..48ff56184a3a 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -8,6 +8,7 @@ namespace Magento\DownloadableImportExport\Model\Import\Product\Type; use Magento\CatalogImportExport\Model\Import\Product as ImportProduct; +use Magento\Downloadable\Model\Url\DomainValidator; use Magento\Framework\EntityManager\MetadataPool; use \Magento\Store\Model\Store; @@ -101,6 +102,8 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ const ERROR_COLS_IS_EMPTY = 'emptyOptions'; + private const ERROR_NOT_IN_DOMAIN_WHITELIST = 'notInDomainWhitelist'; + /** * Validation failure message template definitions * @@ -111,7 +114,8 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ self::ERROR_GROUP_TITLE_NOT_FOUND => 'Group titles not found for downloadable products', self::ERROR_OPTION_NO_TITLE => 'Option no title', self::ERROR_MOVE_FILE => 'Error move file', - self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product' + self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product', + self::ERROR_NOT_IN_DOMAIN_WHITELIST => 'Link URL' ]; /** @@ -244,6 +248,11 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ */ protected $downloadableHelper; + /** + * @var DomainValidator + */ + private $domainValidator; + /** * Downloadable constructor * @@ -262,12 +271,14 @@ public function __construct( array $params, \Magento\DownloadableImportExport\Helper\Uploader $uploaderHelper, \Magento\DownloadableImportExport\Helper\Data $downloadableHelper, + DomainValidator $domainValidator, MetadataPool $metadataPool = null ) { parent::__construct($attrSetColFac, $prodAttrColFac, $resource, $params, $metadataPool); $this->parameters = $this->_entityModel->getParameters(); $this->_resource = $resource; $this->uploaderHelper = $uploaderHelper; + $this->domainValidator = $domainValidator; $this->downloadableHelper = $downloadableHelper; } @@ -345,7 +356,20 @@ protected function isRowValidSample(array $rowData) } if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '') { - $result = $this->isTitle($this->prepareSampleData($rowData[self::COL_DOWNLOADABLE_SAMPLES])); + $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); + + $result = $this->isTitle($sampleData); + foreach ($sampleData as $link) { + if (isset($link['sample_type']) && + $link['sample_type'] === 'url' && + isset($link['sample_url']) && + strlen($link['sample_url']) && + !$this->domainValidator->isValid($link['sample_url']) + ) { + $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + } } return $result; } @@ -369,7 +393,20 @@ protected function isRowValidLink(array $rowData) if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && $rowData[self::COL_DOWNLOADABLE_LINKS] != '' ) { - $result = $this->isTitle($this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS])); + $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); + $result = $this->isTitle($linkData); + + foreach ($linkData as $link) { + if (isset($link['link_type']) && + $link['link_type'] === 'url' && + isset($link['link_url']) && + strlen($link['link_url']) && + !$this->domainValidator->isValid($link['link_url']) + ) { + $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + } } return $result; } From 96a3f238f979af9fb01b4e4bb2c1715db2de00d5 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 23 Jul 2019 16:12:28 -0500 Subject: [PATCH 0200/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 48ff56184a3a..db4747c01b44 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -16,6 +16,7 @@ * Class Downloadable * * @SuppressWarnings(PHPMD.TooManyFields) + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { @@ -102,7 +103,9 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ const ERROR_COLS_IS_EMPTY = 'emptyOptions'; - private const ERROR_NOT_IN_DOMAIN_WHITELIST = 'notInDomainWhitelist'; + private const ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST = 'linkUrlNotInDomainWhitelist'; + + private const ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST = 'sampleUrlNotInDomainWhitelist'; /** * Validation failure message template definitions @@ -115,7 +118,10 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ self::ERROR_OPTION_NO_TITLE => 'Option no title', self::ERROR_MOVE_FILE => 'Error move file', self::ERROR_COLS_IS_EMPTY => 'Missing sample and links data for the downloadable product', - self::ERROR_NOT_IN_DOMAIN_WHITELIST => 'Link URL' + self::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST => + 'Link URL\'s domain is not in list of downloadable_domains in env.php.', + self::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST => + 'Sample URL\'s domain is not in list of downloadable_domains in env.php.' ]; /** @@ -344,6 +350,7 @@ public function isRowValid(array $rowData, $rowNum, $isNewProduct = true) * * @param array $rowData * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidSample(array $rowData) { @@ -366,7 +373,7 @@ protected function isRowValidSample(array $rowData) strlen($link['sample_url']) && !$this->domainValidator->isValid($link['sample_url']) ) { - $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } } @@ -379,6 +386,7 @@ protected function isRowValidSample(array $rowData) * * @param array $rowData * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidLink(array $rowData) { @@ -403,7 +411,7 @@ protected function isRowValidLink(array $rowData) strlen($link['link_url']) && !$this->domainValidator->isValid($link['link_url']) ) { - $this->_entityModel->addRowError(static::ERROR_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } } From 707e50167e3ded4e6dfa979b27685c03699b0106 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 09:07:52 -0500 Subject: [PATCH 0201/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index db4747c01b44..8f7797ea5d1d 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -268,6 +268,7 @@ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Typ * @param array $params * @param \Magento\DownloadableImportExport\Helper\Uploader $uploaderHelper * @param \Magento\DownloadableImportExport\Helper\Data $downloadableHelper + * @param DomainValidator $domainValidator * @param MetadataPool $metadataPool */ public function __construct( @@ -874,6 +875,7 @@ protected function parseSampleOption($values) /** * Uploading files into the "downloadable/files" media folder. + * * Return a new file name if the same file is already exists. * * @param string $fileName From 6493df9e3c0167d5489aee91db3b29a1af5c953c Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 09:38:30 -0500 Subject: [PATCH 0202/1172] MC-17700: Downloadable Product links --- .../Import/Product/Type/DownloadableTest.php | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index 776ec9f990f5..fe0f0ebf4839 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -5,6 +5,7 @@ */ namespace Magento\DownloadableImportExport\Model\Import\Product\Type; +use Magento\Downloadable\Api\DomainManagerInterface; use Magento\Framework\App\Filesystem\DirectoryList; /** @@ -32,6 +33,11 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ const TEST_PRODUCT_SAMPLES_GROUP_NAME = 'TEST Import Samples'; + /** + * @var DomainManagerInterface + */ + private $domainManager; + /** * @var \Magento\CatalogImportExport\Model\Import\Product */ @@ -47,6 +53,9 @@ class DownloadableTest extends \PHPUnit\Framework\TestCase */ protected $productMetadata; + /** + * @inheritDoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -56,6 +65,17 @@ protected function setUp() /** @var \Magento\Framework\EntityManager\MetadataPool $metadataPool */ $metadataPool = $this->objectManager->get(\Magento\Framework\EntityManager\MetadataPool::class); $this->productMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); + + $this->domainManager = $this->objectManager->get(DomainManagerInterface::class); + $this->domainManager->addDomains(['www.google.com', 'www.yahoo.com']); + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + $this->domainManager->removeDomains(['www.google.com', 'www.yahoo.com']); } /** @@ -112,7 +132,7 @@ public function testDownloadableImport() $downloadableSamples = $product->getDownloadableSamples(); //TODO: Track Fields: id, link_id, link_file and sample_file) - $expectedLinks= [ + $expectedLinks = [ 'file' => [ 'title' => 'TEST Import Link Title File', 'sort_order' => '78', @@ -154,7 +174,7 @@ public function testDownloadableImport() } //TODO: Track Fields: id, sample_id and sample_file) - $expectedSamples= [ + $expectedSamples = [ 'file' => [ 'title' => 'TEST Import Sample File', 'sort_order' => '178', From 733f55e793da46d5b3fbd9c0c7089a46dc49da64 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 10:33:00 -0500 Subject: [PATCH 0203/1172] MC-17700: Downloadable Product links --- .../Import/Product/Type/Downloadable.php | 102 ++++++++++-------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 8f7797ea5d1d..b69b8ddacdfc 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -16,7 +16,6 @@ * Class Downloadable * * @SuppressWarnings(PHPMD.TooManyFields) - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ class Downloadable extends \Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType { @@ -351,34 +350,34 @@ public function isRowValid(array $rowData, $rowNum, $isNewProduct = true) * * @param array $rowData * @return bool - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidSample(array $rowData) { - $result = false; - if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) - && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '' - && $this->sampleGroupTitle($rowData) == '') { - $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); + $hasSampleLinkData = ( + isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) && + $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '' + ); + + if (!$hasSampleLinkData) { + return false; + } + + $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); + + if ($this->sampleGroupTitle($rowData) == '') { $result = true; + $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); } - if (isset($rowData[self::COL_DOWNLOADABLE_SAMPLES]) - && $rowData[self::COL_DOWNLOADABLE_SAMPLES] != '') { - $sampleData = $this->prepareSampleData($rowData[static::COL_DOWNLOADABLE_SAMPLES]); - - $result = $this->isTitle($sampleData); - foreach ($sampleData as $link) { - if (isset($link['sample_type']) && - $link['sample_type'] === 'url' && - isset($link['sample_url']) && - strlen($link['sample_url']) && - !$this->domainValidator->isValid($link['sample_url']) - ) { - $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); - $result = true; - } + + $result = $result ?? $this->isTitle($sampleData); + + foreach ($sampleData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; } } + return $result; } @@ -387,36 +386,34 @@ protected function isRowValidSample(array $rowData) * * @param array $rowData * @return bool - * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function isRowValidLink(array $rowData) { - $result = false; - if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && - $rowData[self::COL_DOWNLOADABLE_LINKS] != '' && - $this->linksAdditionalAttributes($rowData, 'group_title', self::DEFAULT_GROUP_TITLE) == '' - ) { + $hasLinkData = ( + isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && + $rowData[self::COL_DOWNLOADABLE_LINKS] != '' + ); + + if (!$hasLinkData) { + return false; + } + + $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); + + if ($this->linksAdditionalAttributes($rowData, 'group_title', self::DEFAULT_GROUP_TITLE) == '') { $this->_entityModel->addRowError(self::ERROR_GROUP_TITLE_NOT_FOUND, $this->rowNum); $result = true; } - if (isset($rowData[self::COL_DOWNLOADABLE_LINKS]) && - $rowData[self::COL_DOWNLOADABLE_LINKS] != '' - ) { - $linkData = $this->prepareLinkData($rowData[self::COL_DOWNLOADABLE_LINKS]); - $result = $this->isTitle($linkData); - - foreach ($linkData as $link) { - if (isset($link['link_type']) && - $link['link_type'] === 'url' && - isset($link['link_url']) && - strlen($link['link_url']) && - !$this->domainValidator->isValid($link['link_url']) - ) { - $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); - $result = true; - } + + $result = $result ?? $this->isTitle($linkData); + + foreach ($linkData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'link_type', 'link_url')) { + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; } } + return $result; } @@ -908,4 +905,21 @@ protected function clear() $this->productIds = []; return $this; } + + /** + * @param array $link + * @param string $linkTypeKey + * @param string $linkUrlKey + * @return bool + */ + private function hasDomainNotInWhitelist(array $link, string $linkTypeKey, string $linkUrlKey): bool + { + return ( + isset($link[$linkTypeKey]) && + $link[$linkTypeKey] === 'url' && + isset($link[$linkUrlKey]) && + strlen($link[$linkUrlKey]) && + !$this->domainValidator->isValid($link[$linkUrlKey]) + ); + } } From fb4ad49f8e22339229241c3a654ab12f9b313b7f Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 11:22:05 -0500 Subject: [PATCH 0204/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index b69b8ddacdfc..0528f2759c4e 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -907,6 +907,8 @@ protected function clear() } /** + * Does link contain url not in whitelist? + * * @param array $link * @param string $linkTypeKey * @param string $linkUrlKey From 1a548a201b1b3afca20d1700e3b07f4dd0acd0bd Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 12:52:21 -0500 Subject: [PATCH 0205/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/DownloadableTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index fe0f0ebf4839..a3230d61e262 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -10,6 +10,7 @@ /** * @magentoAppArea adminhtml + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class DownloadableTest extends \PHPUnit\Framework\TestCase { From a5eb4fc57817fb79c1e8409aaa0d8602bada75c4 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 13:14:02 -0500 Subject: [PATCH 0206/1172] MC-17700: Downloadable Product links --- ...CreateDownloadableProductWithInvalidDomainLinkUrlTest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml index 4eb6b82b6591..f2e4bdfb4890 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithInvalidDomainLinkUrlTest.xml @@ -28,7 +28,10 @@ <actionGroup ref="SaveProductFormNoSuccessCheck" stepKey="saveProduct"/> <see selector="{{AdminProductMessagesSection.errorMessage}}" userInput="Link URL's domain is not in list of downloadable_domains in env.php." stepKey="seeLinkUrlInvalidMessage" after="saveProduct" /> <magentoCLI stepKey="addDownloadableDomain2" command="downloadable:domains:add static.magento.com" after="seeLinkUrlInvalidMessage" /> - <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="addDownloadableDomain2"/> + <actionGroup ref="fillMainProductFormNoWeight" stepKey="fillDownloadableProductFormAgain" after="addDownloadableDomain2"> + <argument name="product" value="DownloadableProduct"/> + </actionGroup> + <checkOption selector="{{AdminProductDownloadableSection.isDownloadableProduct}}" stepKey="checkIsDownloadable" after="fillDownloadableProductFormAgain"/> <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" stepKey="checkIsLinksPurchasedSeparately" after="checkIsDownloadable"/> <actionGroup ref="addDownloadableProductLink" stepKey="addDownloadableProductLinkAgain" after="checkIsLinksPurchasedSeparately"> <argument name="link" value="downloadableLink"/> From b60fead6de598f78c6811a2d30fdede49d3c773c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 24 Jul 2019 15:24:58 -0500 Subject: [PATCH 0207/1172] Allow admin to opt out of admin analytics tracking - created modal, database table --- .../Magento/AdminAnalytics/Block/Setting.php | 52 +++++++++ .../Adminhtml/Config/DisableAdminUsage.php | 100 +++++++++++++++++ .../Adminhtml/Config/EnableAdminUsage.php | 100 +++++++++++++++++ .../Adminhtml/Config/MarkUserNotified.php | 95 ++++++++++++++++ .../Model/Condition/CanViewNotification.php | 104 +++++++++++++++++ .../Model/ContentProviderInterface.php | 24 ++++ .../Model/ResourceModel/Viewer/Logger.php | 106 ++++++++++++++++++ .../AdminAnalytics/Model/Viewer/Log.php | 54 +++++++++ .../AdminAnalytics/etc/adminhtml/routes.xml | 14 +++ .../Magento/AdminAnalytics/etc/config.xml | 18 --- .../Magento/AdminAnalytics/etc/db_schema.xml | 30 +++++ .../etc/db_schema_whitelist.json | 15 +++ .../view/adminhtml/layout/default.xml | 2 + .../adminhtml/templates/confirm_popup.phtml | 86 ++++++++++++++ 14 files changed, 782 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Block/Setting.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php create mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php create mode 100644 app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php create mode 100644 app/code/Magento/AdminAnalytics/Model/Viewer/Log.php create mode 100644 app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml delete mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/db_schema.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml diff --git a/app/code/Magento/AdminAnalytics/Block/Setting.php b/app/code/Magento/AdminAnalytics/Block/Setting.php new file mode 100644 index 000000000000..516c854c2933 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Block/Setting.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Template\Context; +use Magento\Config\Model\Config\Factory; + +class Setting extends Template +{ + private $configFactory; + /** + * @param Context $context + * @param Factory $configFactory + * @param array $data + */ + public function __construct( + Context $context, + Factory $configFactory, + array $data = [] + ) { + $this->configFactory = $configFactory; + parent::__construct($context, $data); + } + + /** + * Sets the admin usage's configuration setting to yes + */ + public function enableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 1); + $configModel->save(); + } + + /** + * Sets the admin usage's configuration setting to no + */ + public function disableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 0); + $configModel->save(); + } + + public function showModal() { + return false; + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php new file mode 100644 index 000000000000..eced53d960e0 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; +use Magento\Config\Model\Config\Factory; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class DisableAdminUsage extends Action +{ + + + private $configFactory; + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + Factory $configFactory, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->configFactory = $configFactory; + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + public function disableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 0); + $configModel->save(); + } + + public function markUserNotified() + { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion(), + 0 + ), + 'error_message' => '' + ]; + + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + $this->disableAdminUsage(); + $this->markUserNotified(); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php new file mode 100644 index 000000000000..ea93212dbc2d --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; +use Magento\Config\Model\Config\Factory; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class EnableAdminUsage extends Action +{ + + + private $configFactory; + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + Factory $configFactory, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->configFactory = $configFactory; + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + public function enableAdminUsage() + { + $configModel = $this->configFactory->create(); + $configModel->setDataByPath('admin/usage/enabled', 1); + $configModel->save(); + } + + public function markUserNotified() + { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion(), + 1 + ), + 'error_message' => '' + ]; + + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + $this->enableAdminUsage(); + $this->markUserNotified(); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php new file mode 100644 index 000000000000..4c252329d07a --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; + +use Magento\Backend\App\Action; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Controller\ResultFactory; +use Magento\ReleaseNotification\Model\ResourceModel\Viewer\Logger as NotificationLogger; +use Magento\Framework\App\ProductMetadataInterface; +use Psr\Log\LoggerInterface; + +/** + * Controller to record that the current admin user has seen the release notification content + */ +class MarkUserNotified extends Action +{ + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var NotificationLogger + */ + private $notificationLogger; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * MarkUserNotified constructor. + * + * @param Action\Context $context + * @param ProductMetadataInterface $productMetadata + * @param NotificationLogger $notificationLogger + * @param LoggerInterface $logger + */ + public function __construct( + Action\Context $context, + ProductMetadataInterface $productMetadata, + NotificationLogger $notificationLogger, + LoggerInterface $logger + ) { + parent::__construct($context); + $this->productMetadata = $productMetadata; + $this->notificationLogger = $notificationLogger; + $this->logger = $logger; + } + + /** + * Log information about the last shown advertisement + * + * @return \Magento\Framework\Controller\ResultInterface + */ + public function execute() + { + try { + $responseContent = [ + 'success' => $this->notificationLogger->log( + $this->_auth->getUser()->getId(), + $this->productMetadata->getVersion() + ), + 'error_message' => '' + ]; + } catch (LocalizedException $e) { + $this->logger->error($e->getMessage()); + $responseContent = [ + 'success' => false, + 'error_message' => $e->getMessage() + ]; + } catch (\Exception $e) { + $this->logger->error($e->getMessage()); + $responseContent = [ + 'success' => false, + 'error_message' => __('It is impossible to log user action') + ]; + } + $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); + return $resultJson->setData($responseContent); + } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php new file mode 100644 index 000000000000..31311dc01549 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\Condition; + +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; +use Magento\Backend\Model\Auth\Session; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; +use Magento\Framework\App\CacheInterface; + +/** + * Dynamic validator for UI release notification, manage UI component visibility. + * Return true if the logged in user has not seen the notification. + */ +class CanViewNotification implements VisibilityConditionInterface +{ + /** + * Unique condition name. + * + * @var string + */ + private static $conditionName = 'can_view_notification'; + + /** + * Prefix for cache + * + * @var string + */ + private static $cachePrefix = 'release-notification-popup-'; + + /** + * @var Logger + */ + private $viewerLogger; + + /** + * @var Session + */ + private $session; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var CacheInterface + */ + private $cacheStorage; + + /** + * CanViewNotification constructor. + * + * @param Logger $viewerLogger + * @param Session $session + * @param ProductMetadataInterface $productMetadata + * @param CacheInterface $cacheStorage + */ + public function __construct( + Logger $viewerLogger, + Session $session, + ProductMetadataInterface $productMetadata, + CacheInterface $cacheStorage + ) { + $this->viewerLogger = $viewerLogger; + $this->session = $session; + $this->productMetadata = $productMetadata; + $this->cacheStorage = $cacheStorage; + } + + /** + * Validate if notification popup can be shown and set the notification flag + * + * @inheritdoc + */ + public function isVisible(array $arguments) + { + $userId = $this->session->getUser()->getId(); + $cacheKey = self::$cachePrefix . $userId; + $value = $this->cacheStorage->load($cacheKey); + if ($value === false) { + $value = version_compare( + $this->viewerLogger->get($userId)->getLastViewVersion(), + $this->productMetadata->getVersion(), + '<' + ); + $this->cacheStorage->save(false, $cacheKey); + } + return (bool)$value; + } + + /** + * Get condition name + * + * @return string + */ + public function getName() + { + return self::$conditionName; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php new file mode 100644 index 000000000000..ea67be7019e1 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Model; + +/** + * Requests the release notification content data from a defined service + */ +interface ContentProviderInterface +{ + /** + * Retrieves the release notification content data. + * + * @param string $version + * @param string $edition + * @param string $locale + * + * @return string|false + */ + public function getContent($version, $edition, $locale); +} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php new file mode 100644 index 000000000000..ac5d7b1f94db --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -0,0 +1,106 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\AdminAnalytics\Model\ResourceModel\Viewer; + +use Magento\ReleaseNotification\Model\Viewer\Log; +use Magento\ReleaseNotification\Model\Viewer\LogFactory; +use Magento\Framework\App\ResourceConnection; + +/** + * Release notification viewer log data logger. + * + * Saves and retrieves release notification viewer log data. + */ +class Logger +{ + /** + * Log table name + */ + const LOG_TABLE_NAME = 'admin_usage_viewer_log'; + + /** + * @var Resource + */ + private $resource; + + /** + * @var LogFactory + */ + private $logFactory; + + /** + * Logger constructor. + * @param ResourceConnection $resource + * @param LogFactory $logFactory + */ + public function __construct( + ResourceConnection $resource, + LogFactory $logFactory + ) { + $this->resource = $resource; + $this->logFactory = $logFactory; + } + + /** + * Save (insert new or update existing) log. + * + * @param int $viewerId + * @param string $lastViewVersion + * @param int $isAdminUsageEnabled + * @return bool + */ + public function log(int $viewerId, string $lastViewVersion, int $isAdminUsageEnabled) : bool + { + /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ + $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); + $connection->insertOnDuplicate( + $this->resource->getTableName(self::LOG_TABLE_NAME), + [ + 'viewer_id' => $viewerId, + 'last_view_version' => $lastViewVersion, + 'is_admin_usage_enabled' => $isAdminUsageEnabled + ], + [ + 'last_view_version', + 'is_admin_usage_enabled' + ] + ); + return true; + } + + /** + * Get log by viewer Id. + * + * @param int $viewerId + * @return Log + */ + public function get(int $viewerId) : Log + { + return $this->logFactory->create(['data' => $this->loadLogData($viewerId)]); + } + + /** + * Load release notification viewer log data by viewer id + * + * @param int $viewerId + * @return array + */ + private function loadLogData(int $viewerId) : array + { + $connection = $this->resource->getConnection(); + $select = $connection->select() + ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) + ->where('viewer_id = ?', $viewerId); + + $data = $connection->fetchRow($select); + if (!$data) { + $data = []; + } + return $data; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php new file mode 100644 index 000000000000..28621b36d9b7 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -0,0 +1,54 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\Viewer; + +use Magento\Framework\DataObject; + +/** + * Release notification viewer log resource + */ +class Log extends DataObject +{ + /** + * Get log id + * + * @return int + */ + public function getId() + { + return $this->getData('id'); + } + + /** + * Get viewer id + * + * @return int + */ + public function getViewerId() + { + return $this->getData('viewer_id'); + } + + /** + * Get last viewed product version + * + * @return string + */ + public function getLastViewVersion() + { + return $this->getData('last_view_version'); + } + + /** + * Get admin usage enabled + * + * @return int + */ + public function getIsAdminUsageEnabled() + { + return $this->getData('is_admin_usage_enabled'); + } +} diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml new file mode 100644 index 000000000000..e1024b12bc42 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> + <router id="admin"> + <route id="adminAnalytics" frontName="adminAnalytics"> + <module name="Magento_AdminAnalytics" /> + </route> + </router> +</config> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml deleted file mode 100644 index 85b6b6879f08..000000000000 --- a/app/code/Magento/AdminAnalytics/etc/config.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> - <default> - <admin> - <usage> - <enabled> - 0 - </enabled> - </usage> - </admin> - </default> -</config> diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml new file mode 100644 index 000000000000..d640c6af4528 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> + <table name="admin_usage_viewer_log" resource="default" engine="innodb" + comment="Admin Notification Viewer Log Table"> + <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" + comment="Log ID"/> + <column xsi:type="int" name="viewer_id" padding="10" unsigned="true" nullable="false" identity="false" + comment="Viewer admin user ID"/> + <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" + comment="Viewer last view on product version"/> + <column xsi:type="smallint" name="is_admin_usage_enabled" padding="5" unsigned="true" nullable="false" identity="false" + default="0" comment="Flag if admin usage is enabled"/> + <constraint xsi:type="primary" referenceId="PRIMARY"> + <column name="id"/> + </constraint> + <constraint xsi:type="foreign" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" + table="admin_notification_viewer_log" column="viewer_id" referenceTable="admin_user" + referenceColumn="user_id" onDelete="CASCADE"/> + <constraint xsi:type="unique" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> + <column name="viewer_id"/> + </constraint> + </table> +</schema> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json new file mode 100644 index 000000000000..01fb68d4b58f --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -0,0 +1,15 @@ +{ + "admin_usage_viewer_log": { + "column": { + "id": true, + "viewer_id": true, + "last_view_version": true, + "is_admin_usage_enabled": true + }, + "constraint": { + "PRIMARY": true, + "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID": true, + "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID": true + } + } +} \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 8ec8ac3bfaf5..86de70f75f75 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -13,6 +13,8 @@ <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> </arguments> </block> + + <block name="confirm_popup_block" template="Magento_AdminAnalytics::confirm_popup.phtml"/> </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml new file mode 100644 index 000000000000..59b972fd5b53 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<div class="confirmation-modal-content"> + <p>Help us improve Magento Admin by allowing us to collect usage data.</p> + <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> +</div> + +<script> + require([ + 'jquery', + 'Magento_Ui/js/modal/modal' + ], function ($) { + 'use strict'; + + $('.confirmation-modal-content').modal({ + imports: { + logAction: '${ $.provider }:data.logAction' + }, + title: 'Allow admin usage data collection', + autoOpen: true, + type: 'popup', + clickableOverlay: false, + responsive: true, + keyEventHandlers: { + escapeKey: function(){} + }, + opened: function($Event){ + $('.modal-header button.action-close', $Event.srcElement).hide(); + }, + buttons: [ + { + text: $.mage.__(`Don't Allow`), + class: 'action', + click: function(){ + console.log(`I clicked Don't Allow`); + + + var data = { + 'form_key': window.FORM_KEY + }; + console.log(data.logAction) + $.ajax({ + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', + data: data, + showLoader: true + }).done(function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + }).fail(this.onError); + this.closeModal(); + }, + }, + { + text: $.mage.__('Ok'), + class: 'action', + click: function(){ + console.log("I clicked Ok"); + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax({ + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', + data: data, + showLoader: true + }).done(function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + }).fail(this.onError); + + this.closeModal(); + }, + } + ], + }); + }); +</script> From 999f2b3cfd31dab579fcbcb51b614a956f8d08dd Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Wed, 24 Jul 2019 16:55:35 -0500 Subject: [PATCH 0208/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/Downloadable.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php index 0528f2759c4e..fbee9c093b04 100644 --- a/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php +++ b/app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php @@ -372,6 +372,11 @@ protected function isRowValidSample(array $rowData) $result = $result ?? $this->isTitle($sampleData); foreach ($sampleData as $link) { + if ($this->hasDomainNotInWhitelist($link, 'link_type', 'link_url')) { + $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; @@ -412,6 +417,11 @@ protected function isRowValidLink(array $rowData) $this->_entityModel->addRowError(static::ERROR_LINK_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); $result = true; } + + if ($this->hasDomainNotInWhitelist($link, 'sample_type', 'sample_url')) { + $this->_entityModel->addRowError(static::ERROR_SAMPLE_URL_NOT_IN_DOMAIN_WHITELIST, $this->rowNum); + $result = true; + } } return $result; From dad6118554bce879499686848257875f95d349f6 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 25 Jul 2019 14:33:42 -0500 Subject: [PATCH 0209/1172] MC-17700: Downloadable Product links --- .../Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 19477fb80484..0e7396541e75 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -115,7 +115,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> From a242f2dc1b8c6e84a8ee569e6a3bcf0f74881c05 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Thu, 25 Jul 2019 15:43:44 -0500 Subject: [PATCH 0210/1172] MC-17147: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails --- .../Catalog/Model/Product/Compare/ListCompare.php | 2 +- .../Model/Product/Compare/ListCompareTest.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php index 12dbaf0c29f4..0cf36214e4c3 100644 --- a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php @@ -90,7 +90,7 @@ public function addProduct($product) $this->_addVisitorToItem($item); $item->loadByProduct($product); - if (!$item->getId()) { + if (!$item->getId() && $item->getProductId()) { $item->addProductData($product); $item->save(); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php index 3fa02aebe917..24bba7c77c98 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php @@ -44,6 +44,9 @@ protected function tearDown() $this->_session->setCustomerId(null); } + /** + * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + */ public function testAddProductWithSession() { $this->_session->setCustomerId(1); @@ -51,8 +54,15 @@ public function testAddProductWithSession() $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\Product::class) ->load(1); - $this->_model->addProduct($product); + /** @var $product2 \Magento\Catalog\Model\Product */ + $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\Product::class) + ->load(6); + $this->_model->addProducts([$product->getId(), $product2->getId(), 'none', 99]); $this->assertTrue($this->_model->hasItems(1, $this->_visitor->getId())); + $this->assertTrue($this->_model->hasItems(6, $this->_visitor->getId())); + $this->assertFalse($this->_model->hasItems('none', $this->_visitor->getId())); + $this->assertFalse($this->_model->hasItems(99, $this->_visitor->getId())); } public function testAddProductWithoutSession() From 098f26290834b05abedfdc246c7a42c6fab3aaff Mon Sep 17 00:00:00 2001 From: David Haecker <dhaecker@magento.com> Date: Thu, 25 Jul 2019 15:47:02 -0500 Subject: [PATCH 0211/1172] MC-17700: Downloadable Product links - Fixing mftf cli cmds --- .../Test/Mftf/Test/SearchEntityResultsTest.xml | 2 +- ...DownloadableProductFromShoppingCartTest.xml | 2 +- .../OnePageCheckoutWithAllProductTypesTest.xml | 2 +- ...ddDownloadableProductToShoppingCartTest.xml | 2 +- ...loadableProductFromMiniShoppingCartTest.xml | 2 +- .../StorefrontClearAllCompareProductsTest.xml | 2 +- ...nAddDefaultVideoDownloadableProductTest.xml | 4 ++-- ...ableProductAndAssignItToCustomStoreTest.xml | 4 ++-- ...ownloadableProductWithCustomOptionsTest.xml | 2 +- ...nloadableProductWithDefaultSetLinksTest.xml | 2 +- ...teDownloadableProductWithGroupPriceTest.xml | 2 +- ...eDownloadableProductWithManageStockTest.xml | 2 +- ...loadableProductWithOutOfStockStatusTest.xml | 2 +- ...DownloadableProductWithSpecialPriceTest.xml | 2 +- ...ateDownloadableProductWithTierPriceText.xml | 6 ------ ...oductWithoutFillingQuantityAndStockTest.xml | 2 +- ...ownloadableProductWithoutTaxClassIdTest.xml | 2 +- .../AdminDeleteDownloadableProductTest.xml | 2 +- ...moveDefaultVideoDownloadableProductTest.xml | 4 ++-- ...nceCatalogSearchDownloadableProductTest.xml | 18 +++++++++--------- ...nloadableProductFromGuestToCustomerTest.xml | 2 +- ...oductsListWidgetDownloadableProductTest.xml | 4 ++-- 22 files changed, 33 insertions(+), 39 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index f98e715963d2..9a2103ee75a7 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -378,9 +378,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="goToFrontPage"/> <actionGroup ref="StorefrontCheckQuickSearchStringActionGroup" stepKey="searchStorefront"> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml index 1eee2d510e7b..e16ef70c23e3 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/DeleteDownloadableProductFromShoppingCartTest.xml @@ -31,9 +31,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete downloadable product --> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteDownloadableProduct"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add downloadable product to the cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml index 56d1b97974bb..e85a47ab7a91 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/OnePageCheckoutWithAllProductTypesTest.xml @@ -91,6 +91,7 @@ <magentoCLI command="indexer:reindex" stepKey="reindex"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -110,7 +111,6 @@ <!-- Logout customer --> <actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogoutStorefront"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Add Simple Product to cart --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml index 9d595510811a..ec9852a6a939 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontAddDownloadableProductToShoppingCartTest.xml @@ -32,9 +32,9 @@ <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml index 852e46541c4f..0fa503e1783b 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontDeleteDownloadableProductFromMiniShoppingCartTest.xml @@ -31,9 +31,9 @@ <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!-- Open Downloadable Product page --> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index 3069ea89099e..374a4be581bc 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -109,6 +109,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin1"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Logout --> <actionGroup ref="logout" stepKey="logoutOfAdmin1"/> @@ -122,7 +123,6 @@ <deleteData createDataKey="createBundleProduct1" stepKey="deleteBundleProduct1"/> <deleteData createDataKey="createGroupedProduct1" stepKey="deleteGroupedProduct1"/> <deleteData createDataKey="createDownloadableProduct1" stepKey="deleteDownloadableProduct1"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer1"> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml index 4bbd815e8db0..d95ddaf12470 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultVideoDownloadableProductTest.xml @@ -19,10 +19,10 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="enableAdminAccountSharing"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="setStoreDefaultConfig"/> </after> <!-- Create a downloadable product --> <!-- Replacing steps in base AdminAddDefaultVideoSimpleProductTest --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml index fc638633fbf3..4f07334640cf 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductAndAssignItToCustomStoreTest.xml @@ -20,14 +20,15 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> <!-- Create category --> <createData entity="SimpleSubCategory" stepKey="createCategory"/> <!-- Login as admin --> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -41,7 +42,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create store view --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml index f45e5f1a47e4..54a2ff606f38 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithCustomOptionsTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml index 2fcc87b71bbb..8194e600673c 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithDefaultSetLinksTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml index afac869d69c3..06cf31b763f1 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithGroupPriceTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml index 081230760e1d..fb6a48254fa8 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithManageStockTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml index a815d838c29d..5e3fe6836f7e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithOutOfStockStatusTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create Downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml index f0cc503f74c4..fb59d51831ba 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithSpecialPriceTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml index f6455766a090..ca4e560506ad 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithTierPriceText.xml @@ -19,12 +19,6 @@ <group value="Downloadable"/> <group value="mtf_migrated"/> </annotations> - <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> - </before> - <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> - </after> <remove keyForRemoval="addCustomerGroupPrice"/> <!-- Add tier price to product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml index 6e29fe13d85e..af9487e3e6a2 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutFillingQuantityAndStockTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml index 757ac7958f5c..dd7e3331a0ed 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminCreateDownloadableProductWithoutTaxClassIdTest.xml @@ -28,6 +28,7 @@ <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> <!-- Delete category --> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> @@ -38,7 +39,6 @@ <!-- Log out --> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> </after> <!-- Create downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml index 83e0c587c078..07124ea4846b 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminDeleteDownloadableProductTest.xml @@ -32,9 +32,9 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <actionGroup ref="logout" stepKey="logout"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteDownloadableProductFilteredBySkuAndName"> <argument name="product" value="$$createDownloadableProduct$$"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml index bc929cd3a68c..0d98862d9a5e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultVideoDownloadableProductTest.xml @@ -19,10 +19,10 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="enableAdminAccountSharing"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="setStoreDefaultConfig"/> </after> <!-- Create a downloadable product --> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 0e7396541e75..2a320fa674e7 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -19,7 +19,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -29,7 +29,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableBySkuTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> @@ -43,7 +43,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -53,7 +53,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> @@ -67,7 +67,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -77,7 +77,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByShortDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> @@ -91,7 +91,7 @@ <group value="Downloadable"/> </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="product"/> <createData entity="ApiDownloadableProduct" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> @@ -101,7 +101,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchDownloadableByPriceTest" extends="AdvanceCatalogSearchSimpleProductByPriceTest"> @@ -125,7 +125,7 @@ </createData> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="delete"/> </after> </test> </tests> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml index 25dfe1adcb7c..b9773415059e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/LinkDownloadableProductFromGuestToCustomerTest.xml @@ -29,10 +29,10 @@ </createData> </before> <after> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> <magentoCLI command="config:set {{DisableGuestCheckoutWithDownloadableItems.path}} {{DisableGuestCheckoutWithDownloadableItems.value}}" stepKey="disableGuestCheckoutWithDownloadableItems" /> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove example.com static.magento.com"/> </after> <!--Step 1: Go to Storefront as Guest--> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnStorefrontPage"/> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml index 9fed2d68c98c..94fca6f50763 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/NewProductsListWidgetDownloadableProductTest.xml @@ -21,10 +21,10 @@ </annotations> <before> - <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com"/> + <magentoCLI stepKey="addDownloadableDomain" command="downloadable:domains:add static.magento.com" before="loginAsAdmin"/> </before> <after> - <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com"/> + <magentoCLI stepKey="removeDownloadableDomain" command="downloadable:domains:remove static.magento.com" before="logout"/> </after> <!-- A Cms page containing the New Products Widget gets created here via extends --> From fa604dc7b68c2cbbf94b8379c9a5140c8606a990 Mon Sep 17 00:00:00 2001 From: Roman Hanin <rganin@adobe.com> Date: Thu, 25 Jul 2019 16:24:04 -0500 Subject: [PATCH 0212/1172] MC-17147: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails --- .../Model/Product/Compare/ListCompare.php | 35 +++++++++++++++++-- .../Model/Product/Compare/ListCompareTest.php | 31 +++++++++++----- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php index 0cf36214e4c3..bfd36360ee55 100644 --- a/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php +++ b/app/code/Magento/Catalog/Model/Product/Compare/ListCompare.php @@ -5,7 +5,10 @@ */ namespace Magento\Catalog\Model\Product\Compare; +use Magento\Catalog\Model\ProductRepository; use Magento\Catalog\Model\ResourceModel\Product\Compare\Item\Collection; +use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\NoSuchEntityException; /** * Product Compare List Model @@ -51,6 +54,11 @@ class ListCompare extends \Magento\Framework\DataObject */ protected $_compareItemFactory; + /** + * @var ProductRepository + */ + private $productRepository; + /** * Constructor * @@ -60,6 +68,7 @@ class ListCompare extends \Magento\Framework\DataObject * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\Visitor $customerVisitor * @param array $data + * @param ProductRepository|null $productRepository */ public function __construct( \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory, @@ -67,13 +76,15 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Product\Compare\Item $catalogProductCompareItem, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Model\Visitor $customerVisitor, - array $data = [] + array $data = [], + ProductRepository $productRepository = null ) { $this->_compareItemFactory = $compareItemFactory; $this->_itemCollectionFactory = $itemCollectionFactory; $this->_catalogProductCompareItem = $catalogProductCompareItem; $this->_customerSession = $customerSession; $this->_customerVisitor = $customerVisitor; + $this->productRepository = $productRepository ?: ObjectManager::getInstance()->create(ProductRepository::class); parent::__construct($data); } @@ -82,6 +93,7 @@ public function __construct( * * @param int|\Magento\Catalog\Model\Product $product * @return $this + * @throws \Exception */ public function addProduct($product) { @@ -90,7 +102,7 @@ public function addProduct($product) $this->_addVisitorToItem($item); $item->loadByProduct($product); - if (!$item->getId() && $item->getProductId()) { + if (!$item->getId() && $this->productExists($product)) { $item->addProductData($product); $item->save(); } @@ -98,6 +110,25 @@ public function addProduct($product) return $this; } + /** + * Check product exists. + * + * @param int|\Magento\Catalog\Model\Product $product + * @return bool + */ + private function productExists($product) + { + if ($product instanceof \Magento\Catalog\Model\Product && $product->getId()) { + return true; + } + try { + $product = $this->productRepository->getById((int)$product); + return !empty($product->getId()); + } catch (NoSuchEntityException $e) { + return false; + } + } + /** * Add products to compare list * diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php index 24bba7c77c98..98b264a8991b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Compare/ListCompareTest.php @@ -6,10 +6,6 @@ namespace Magento\Catalog\Model\Product\Compare; -/** - * @magentoDataFixture Magento/Catalog/_files/product_simple.php - * @magentoDataFixture Magento/Customer/_files/customer.php - */ class ListCompareTest extends \PHPUnit\Framework\TestCase { /** @@ -45,7 +41,8 @@ protected function tearDown() } /** - * @magentoDataFixture Magento/Catalog/_files/second_product_simple.php + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php */ public function testAddProductWithSession() { @@ -58,13 +55,29 @@ public function testAddProductWithSession() $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\Product::class) ->load(6); - $this->_model->addProducts([$product->getId(), $product2->getId(), 'none', 99]); + $products = [$product->getId(), $product2->getId()]; + $this->_model->addProducts($products); + $this->assertTrue($this->_model->hasItems(1, $this->_visitor->getId())); - $this->assertTrue($this->_model->hasItems(6, $this->_visitor->getId())); - $this->assertFalse($this->_model->hasItems('none', $this->_visitor->getId())); - $this->assertFalse($this->_model->hasItems(99, $this->_visitor->getId())); } + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php + */ + public function testAddProductWithSessionNeg() + { + $this->_session->setCustomerId(1); + $products = ['none', 99]; + $this->_model->addProducts($products); + + $this->assertFalse($this->_model->hasItems(1, $this->_visitor->getId())); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Customer/_files/customer.php + */ public function testAddProductWithoutSession() { /** @var $product \Magento\Catalog\Model\Product */ From 2976918d75f2b2e78904e05d81073f17831f17ca Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 25 Jul 2019 17:02:37 -0500 Subject: [PATCH 0213/1172] MC-15298: Allow admin to opt out of admin analytics tracking - UI added --- .../Adminhtml/Config/DisableAdminUsage.php | 1 + .../Adminhtml/Config/EnableAdminUsage.php | 1 - .../Model/Condition/CanViewNotification.php | 28 +- .../Http/HttpContentProvider.php | 108 ++++++++ .../Model/ContentProvider/Http/UrlBuilder.php | 64 +++++ .../Model/ResourceModel/Viewer/Logger.php | 4 +- .../DataProvider/Modifier/Notifications.php | 246 ++++++++++++++++++ .../DataProvider/NotificationDataProvider.php | 214 +++++++++++++++ .../Ui/Renderer/NotificationRenderer.php | 208 +++++++++++++++ .../view/adminhtml/layout/default.xml | 7 +- .../adminhtml/templates/confirm_popup.phtml | 5 - .../ui_component/admin_usage_notification.xml | 122 +++++++++ .../view/adminhtml/web/js/modal/component.js | 90 +++++++ 13 files changed, 1075 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php create mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php create mode 100644 app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eced53d960e0..b81c60e4b3ad 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -22,6 +22,7 @@ class DisableAdminUsage extends Action private $configFactory; + /** * @var ProductMetadataInterface */ diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index ea93212dbc2d..d1b879ae927a 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -20,7 +20,6 @@ class EnableAdminUsage extends Action { - private $configFactory; /** * @var ProductMetadataInterface diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 31311dc01549..b33677ea05f2 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -22,14 +22,14 @@ class CanViewNotification implements VisibilityConditionInterface * * @var string */ - private static $conditionName = 'can_view_notification'; + private static $conditionName = 'can_view_admin_usage_notification'; /** * Prefix for cache * * @var string */ - private static $cachePrefix = 'release-notification-popup-'; + private static $cachePrefix = 'admin-usage-notification-popup-'; /** * @var Logger @@ -78,18 +78,18 @@ public function __construct( */ public function isVisible(array $arguments) { - $userId = $this->session->getUser()->getId(); - $cacheKey = self::$cachePrefix . $userId; - $value = $this->cacheStorage->load($cacheKey); - if ($value === false) { - $value = version_compare( - $this->viewerLogger->get($userId)->getLastViewVersion(), - $this->productMetadata->getVersion(), - '<' - ); - $this->cacheStorage->save(false, $cacheKey); - } - return (bool)$value; +// $userId = $this->session->getUser()->getId(); +// $cacheKey = self::$cachePrefix . $userId; +// $value = $this->cacheStorage->load($cacheKey); +// if ($value === false) { +// $value = version_compare( +// $this->viewerLogger->get($userId)->getLastViewVersion(), +// $this->productMetadata->getVersion(), +// '<' +// ); +// $this->cacheStorage->save(false, $cacheKey); +// } + return true; } /** diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php new file mode 100644 index 000000000000..930cf8996693 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Model\ContentProvider\Http; + +use Magento\AdminAnalytics\Model\ContentProviderInterface; +use Magento\Setup\Module\I18n\Locale; +use Psr\Log\LoggerInterface; +use Magento\Framework\HTTP\ClientInterface; + +/** + * Requests the release notification content data via an HTTP call to a REST API + */ +class HttpContentProvider implements ContentProviderInterface +{ + /** + * @var ClientInterface + */ + private $httpClient; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var UrlBuilder + */ + private $urlBuilder; + + /** + * HttpContentProvider constructor. + * @param ClientInterface $httpClient + * @param UrlBuilder $urlBuilder + * @param LoggerInterface $logger + */ + public function __construct( + ClientInterface $httpClient, + UrlBuilder $urlBuilder, + LoggerInterface $logger + ) { + $this->httpClient = $httpClient; + $this->urlBuilder = $urlBuilder; + $this->logger = $logger; + } + + /** + * @inheritdoc + */ + public function getContent($version, $edition, $locale) + { + $result = false; + + try { + $result = $this->retrieveContent($version, $edition, $locale); + if (!$result) { + $result = $this->retrieveContent($version, $edition, Locale::DEFAULT_SYSTEM_LOCALE); + if (!$result) { + $result = $this->retrieveContent($version, '', 'default'); + } + } + } catch (\Exception $e) { + $this->logger->warning( + sprintf( + 'Failed to retrieve the release notification content. The response is: %s', + empty($result) ? 'Response body is empty.' : $result + ) + ); + } + + return $result; + } + + /** + * Retrieve content from given url + * + * @param string $version + * @param string $edition + * @param string $locale + * @return bool|string + */ + private function retrieveContent($version, $edition, $locale) + { + $url = $this->urlBuilder->getUrl($version, $edition, $locale); + return empty($url) ? false : $this->getResponse($url); + } + + /** + * Returns the response body from the HTTP client + * + * @param $url + * @return string + */ + private function getResponse($url) + { + $this->httpClient->get($url); + $responseBody = $this->httpClient->getBody(); + + if ($this->httpClient->getStatus() === 200 && !empty($responseBody)) { + return $responseBody; + } + + return false; + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php new file mode 100644 index 000000000000..3898fb82f4ac --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Model\ContentProvider\Http; + +use Magento\Framework\App\Config\ScopeConfigInterface; + +/** + * Builder to build Url to retrieve the notification content. + */ +class UrlBuilder +{ + /** + * Path to the configuration value which contains an URL that provides the release notification data. + * + * @var string + */ + private static $notificationContentUrlConfigPath = 'system/release_notification/content_url'; + + /** + * Path to the configuration value indicates if use https in notification content request. + * + * @var string + */ + private static $useHttpsFlagConfigPath = 'system/release_notification/use_https'; + + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @param ScopeConfigInterface $config + */ + public function __construct(ScopeConfigInterface $config) + { + $this->config = $config; + } + + /** + * Builds the URL to request the release notification content data based on passed parameters. + * + * @param string $version + * @param string $edition + * @param string $locale + * @return string + */ + public function getUrl($version, $edition, $locale) + { + $scheme = $this->config->isSetFlag(self::$useHttpsFlagConfigPath) ? 'https://' : 'http://'; + $baseUrl = $this->config->getValue(self::$notificationContentUrlConfigPath); + if (empty($baseUrl)) { + return ''; + } else { + $url = $scheme . $baseUrl; + $url .= empty($version) ? '' : '/' . $version; + $url .= empty($edition) ? '' : '/' . $edition; + $url .= empty($locale) ? '' : '/' . $locale; + return $url . '.json'; + } + } +} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index ac5d7b1f94db..5b67d4dfffec 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -7,8 +7,8 @@ namespace Magento\AdminAnalytics\Model\ResourceModel\Viewer; -use Magento\ReleaseNotification\Model\Viewer\Log; -use Magento\ReleaseNotification\Model\Viewer\LogFactory; +use Magento\AdminAnalytics\Model\Viewer\Log; +use Magento\AdminAnalytics\Model\Viewer\LogFactory; use Magento\Framework\App\ResourceConnection; /** diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php new file mode 100644 index 000000000000..f93cb1e00f01 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php @@ -0,0 +1,246 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\DataProvider\Modifier; + +use Magento\AdminAnalytics\Model\ContentProviderInterface; +use Magento\AdminAnalytics\Ui\Renderer\NotificationRenderer; +use Magento\Ui\DataProvider\Modifier\ModifierInterface; +use Magento\Framework\Serialize\SerializerInterface; +use Magento\Framework\App\CacheInterface; +use Magento\Ui\Component; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Backend\Model\Auth\Session; +use Psr\Log\LoggerInterface; + +/** + * Modifies the metadata returning to the Release Notification data provider + */ +class Notifications implements ModifierInterface +{ + /** + * @var ContentProviderInterface + */ + private $contentProvider; + + /** + * @var NotificationRenderer + */ + private $renderer; + + /** + * Prefix for cache + * + * @var string + */ + private static $cachePrefix = 'release-notification-content-'; + + /** + * @var CacheInterface + */ + private $cacheStorage; + + /** + * @var SerializerInterface + */ + private $serializer; + + /** + * @var ProductMetadataInterface + */ + private $productMetadata; + + /** + * @var Session + */ + private $session; + + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @param ContentProviderInterface $contentProvider + * @param NotificationRenderer $render + * @param CacheInterface $cacheStorage + * @param SerializerInterface $serializer + * @param ProductMetadataInterface $productMetadata + * @param Session $session + * @param LoggerInterface $logger + */ + public function __construct( + ContentProviderInterface $contentProvider, + NotificationRenderer $render, + CacheInterface $cacheStorage, + SerializerInterface $serializer, + ProductMetadataInterface $productMetadata, + Session $session, + LoggerInterface $logger + ) { + $this->contentProvider = $contentProvider; + $this->renderer = $render; + $this->cacheStorage = $cacheStorage; + $this->serializer = $serializer; + $this->productMetadata = $productMetadata; + $this->session = $session; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function modifyData(array $data) + { + return $data; + } + + /** + * {@inheritdoc} + */ + public function modifyMeta(array $meta) + { + $modalContent = $this->getNotificationContent(); + + if ($modalContent) { + $pages = $modalContent['pages']; + $pageCount = count($pages); + $counter = 1; + + foreach ($pages as $page) { + $meta = $this->buildNotificationMeta($meta, $page, $counter++ == $pageCount); + } + } else { + $meta = $this->hideNotification($meta); + } + + return $meta; + } + + /** + * Builds the notification modal by modifying $meta for the ui component + * + * @param array $meta + * @param array $page + * @param bool $isLastPage + * @return array + */ + private function buildNotificationMeta(array $meta, array $page, $isLastPage) + { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config'] = [ + 'isTemplate' => false, + 'componentType' => Component\Modal::NAME + ]; + + $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] + ['notification_text']['arguments']['data']['config'] = [ + 'text' => $this->renderer->getNotificationContent($page) + ]; + + if ($isLastPage) { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ + 'title' => $this->renderer->getNotificationTitle($page), + 'buttons' => [ + [ + 'text' => 'Done', + 'actions' => [ + [ + 'targetName' => '${ $.name }', + 'actionName' => 'closeReleaseNotes' + ] + ], + 'class' => 'release-notification-button-next' + ] + ], + ]; + + $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] + ['notification_buttons']['children']['notification_button_next']['arguments']['data']['config'] = [ + 'buttonClasses' => 'hide-release-notification' + ]; + } else { + $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ + 'title' => $this->renderer->getNotificationTitle($page) + ]; + } + + return $meta; + } + + /** + * Sets the modal to not display if no content is available. + * + * @param array $meta + * @return array + */ + private function hideNotification(array $meta) + { + $meta['notification_modal_1']['arguments']['data']['config']['options'] = [ + 'autoOpen' => false + ]; + + return $meta; + } + + /** + * Returns the notification modal content data + * + * @returns array|false + */ + private function getNotificationContent() + { + $version = strtolower($this->getTargetVersion()); + $edition = strtolower($this->productMetadata->getEdition()); + $locale = strtolower($this->session->getUser()->getInterfaceLocale()); + + $cacheKey = self::$cachePrefix . $version . "-" . $edition . "-" . $locale; + $modalContent = $this->cacheStorage->load($cacheKey); + if ($modalContent === false) { + $modalContent = $this->contentProvider->getContent($version, $edition, $locale); + $this->cacheStorage->save($modalContent, $cacheKey); + } + + return !$modalContent ? $modalContent : $this->unserializeContent($modalContent); + } + + /** + * Unserializes the notification modal content to be used for rendering + * + * @param string $modalContent + * @return array|false + */ + private function unserializeContent($modalContent) + { + $result = false; + + try { + $result = $this->serializer->unserialize($modalContent); + } catch (\InvalidArgumentException $e) { + $this->logger->warning( + sprintf( + 'Failed to unserialize the release notification content. The error is: %s', + $e->getMessage() + ) + ); + } + + return $result; + } + + /** + * Returns the current Magento version used to retrieve the release notification content. + * Version information after the dash (-) character is removed (ex. -dev or -rc). + * + * @return string + */ + private function getTargetVersion() + { + $metadataVersion = $this->productMetadata->getVersion(); + $version = strstr($metadataVersion, '-', true); + + return !$version ? $metadataVersion : $version; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php new file mode 100644 index 000000000000..104d902d3dc9 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -0,0 +1,214 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\DataProvider; + +use Magento\Framework\Api\Search\SearchCriteriaInterface; +use Magento\Framework\Api\Search\SearchResultInterface; +use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; +use Magento\Ui\DataProvider\Modifier\ModifierInterface; +use Magento\Ui\DataProvider\Modifier\PoolInterface; + +/** + * Data Provider for the Release Notifications UI component. + */ +class NotificationDataProvider implements DataProviderInterface +{ + /** + * @var PoolInterface + */ + private $pool; + + /** + * Search result object. + * + * @var SearchResultInterface + */ + private $searchResult; + + /** + * Search criteria object. + * + * @var SearchCriteriaInterface + */ + private $searchCriteria; + + /** + * Own name of this provider. + * + * @var string + */ + private $name; + + /** + * Provider configuration data. + * + * @var array + */ + private $data; + + /** + * Provider configuration meta. + * + * @var array + */ + private $meta; + + /** + * @param string $name + * @param SearchResultInterface $searchResult + * @param SearchCriteriaInterface $searchCriteria + * @param PoolInterface $pool + * @param array $meta + * @param array $data + */ + public function __construct( + $name, + SearchResultInterface $searchResult, + SearchCriteriaInterface $searchCriteria, + PoolInterface $pool, + array $meta = [], + array $data = [] + ) { + $this->name = $name; + $this->searchResult = $searchResult; + $this->searchCriteria = $searchCriteria; + $this->pool = $pool; + $this->meta = $meta; + $this->data = $data; + } + + /** + * @inheritdoc + */ + public function getData() + { + /** @var ModifierInterface $modifier */ + foreach ($this->pool->getModifiersInstances() as $modifier) { + $this->data = $modifier->modifyData($this->data); + } + + return $this->data; + } + + /** + * @inheritdoc + */ + public function getMeta() + { + /** @var ModifierInterface $modifier */ + foreach ($this->pool->getModifiersInstances() as $modifier) { + $this->meta = $modifier->modifyMeta($this->meta); + } + return $this->meta; + } + + /** + * @inheritdoc + */ + public function getName() + { + return $this->name; + } + + /** + * @inheritdoc + */ + public function getConfigData() + { + return $this->data['config'] ?? []; + } + + /** + * @inheritdoc + */ + public function setConfigData($config) + { + $this->data['config'] = $config; + + return true; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldMetaInfo($fieldSetName, $fieldName) + { + return []; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldSetMetaInfo($fieldSetName) + { + return []; + } + + /** + * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function getFieldsMetaInfo($fieldSetName) + { + return []; + } + + /** + * @inheritdoc + */ + public function getPrimaryFieldName() + { + return 'release_notification'; + } + + /** + * @inheritdoc + */ + public function getRequestFieldName() + { + return 'release_notification'; + } + + /** + * @inheritdoc + */ + public function addFilter(\Magento\Framework\Api\Filter $filter) + { + } + + /** + * @inheritdoc + */ + public function addOrder($field, $direction) + { + } + + /** + * @inheritdoc + */ + public function setLimit($offset, $size) + { + } + + /** + * @inheritdoc + */ + public function getSearchCriteria() + { + return $this->searchCriteria; + } + + /** + * @inheritdoc + */ + public function getSearchResult() + { + return $this->searchResult; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php new file mode 100644 index 000000000000..b66e213670f7 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php @@ -0,0 +1,208 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\Ui\Renderer; + +use Magento\Framework\Escaper; + +/** + * Builds the HTML for the release notification modals + */ +class NotificationRenderer +{ + /** + * @var Escaper + */ + private $escaper; + + /** + * @param Escaper $escaper + */ + public function __construct( + Escaper $escaper + ) { + $this->escaper = $escaper; + } + + /** + * Returns the HTML for notification's title to the ui component + * + * @param array $page + * @return string + */ + public function getNotificationTitle(array $page) + { + $title = $this->escaper->escapeHtml($page['mainContent']['title']); + $imageUrl = $this->escaper->escapeUrl($page['mainContent']['imageUrl']); + $content = ""; + + if (!empty($imageUrl)) { + $content .= "<div class='release-notification-title-with-image' style='background-image: url(\"" . $imageUrl + . "\")'>"; + $content .= $title; + $content .= "</div>"; + } else { + $content = $title; + } + + return $content; + } + + /** + * Returns the HTML for the content in the notification ui component + * + * @param array $page + * @return string + */ + public function getNotificationContent(array $page) + { + $content = $this->buildMainContent($page['mainContent']); + $content .= $this->buildSubHeadings($page['subHeading']); + $content .= $this->buildFooter($page['footer']); + + return $content; + } + + /** + * Builds the HTML for the main content in the notification ui component + * + * @param array $mainContent + * @return string + */ + private function buildMainContent(array $mainContent) + { + $content = $this->buildContentTextAreas($mainContent['content']); + $content .= $this->buildLists($mainContent['lists']); + + return $this->formatContentWithLinks($content); + } + + /** + * Builds the HTML for the main text areas in the notification ui component + * + * @param array $contentAreas + * @return string + */ + private function buildContentTextAreas(array $contentAreas) + { + $content = ""; + $lastContentArea = end($contentAreas); + + foreach ($contentAreas as $contentArea) { + $content .= "<p>"; + $content .= $this->escaper->escapeHtml($contentArea['text']); + $content .= "</p>"; + if ($contentArea != $lastContentArea) { + $content .= "<br />"; + } + } + + return $content; + } + + /** + * Builds the HTML for the bullet list content in the notification ui component + * + * @param array $lists + * @return string + */ + private function buildLists(array $lists) + { + $content = "<ul>"; + + foreach ($lists as $listItem) { + $content .= "<li><span>"; + $content .= $this->escaper->escapeHtml($listItem['text']); + $content .= "</span></li>"; + } + + $content .= "</ul>"; + + return $content; + } + + /** + * Builds the HTML for the highlighted sub heads for the overview page in the notification ui component + * + * @param array $subHeadings + * @return string + */ + private function buildSubHeadings(array $subHeadings) + { + $content = ""; + + foreach ($subHeadings as $subHeading) { + if (!empty($subHeading['imageUrl'])) { + $content .= "<div class='highlight-item' style='background-image: url(\"" + . $this->escaper->escapeUrl($subHeading['imageUrl']) . "\")'>"; + } else { + $content .= "<div class='highlight-item-no-image'>"; + } + + $content .= "<h3>"; + $content .= $this->escaper->escapeHtml($subHeading['title']); + $content .= "</h3>"; + $content .= "<p>"; + $content .= $this->formatContentWithLinks($subHeading['content']); + $content .= "</p>"; + $content .= "</div>"; + } + + return $content; + } + + /** + * Builds the HTML for the footer content in the notification ui component + * + * @param array $footer + * @return string + */ + private function buildFooter(array $footer) + { + $content = "<p>"; + $content .= $this->escaper->escapeHtml($footer['content']); + $content .= "</p>"; + + return $this->formatContentWithLinks($content); + } + + /** + * Searches a given string for a URL, formats it to an HTML anchor tag, and returns the original string in the + * correct HTML format. + * + * @param string $content + * @return string + */ + private function formatContentWithLinks($content) + { + $urlRegex = '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#'; + $urlTextRegex = '/\[(.*?)\]/'; + + preg_match_all($urlRegex, $content, $urlMatches); + preg_match_all($urlTextRegex, $content, $urlTextMatches); + + foreach ($urlMatches[0] as $key => $urlMatch) { + if (!empty($urlTextMatches[0])) { + $linkMatch = $urlMatch . " " . $urlTextMatches[0][$key]; + $content = str_replace( + $linkMatch, + "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> + {$this->escaper->escapeHtml($urlTextMatches[1][$key])}</a>", + $content + ); + } else { + $content = str_replace( + $urlMatch, + "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> + {$this->escaper->escapeUrl($urlMatch)}</a>", + $content + ); + } + } + + return $content; + } +} diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 86de70f75f75..5339fbc894a4 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -14,8 +14,13 @@ </arguments> </block> - <block name="confirm_popup_block" template="Magento_AdminAnalytics::confirm_popup.phtml"/> + </referenceContainer> + <referenceContainer name="content"> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml index 59b972fd5b53..ddd9b7acf03d 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml @@ -38,13 +38,9 @@ text: $.mage.__(`Don't Allow`), class: 'action', click: function(){ - console.log(`I clicked Don't Allow`); - - var data = { 'form_key': window.FORM_KEY }; - console.log(data.logAction) $.ajax({ type: 'POST', url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', @@ -62,7 +58,6 @@ text: $.mage.__('Ok'), class: 'action', click: function(){ - console.log("I clicked Ok"); var data = { 'form_key': window.FORM_KEY }; diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml new file mode 100644 index 000000000000..6f9cca869601 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="provider" xsi:type="string">admin_usage_notification.admin_usage_notification_data_source</item> + </item> + <item name="label" xsi:type="string" translate="true">Release Notification</item> + <item name="template" xsi:type="string">templates/form/collapsible</item> + </argument> + <settings> + <namespace>admin_usage_notification</namespace> + <dataScope>data</dataScope> + <deps> + <dep>admin_usage_notification.admin_usage_notification_data_source</dep> + </deps> + </settings> + <dataSource name="admin_usage_notification_data_source"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> + </item> + </argument> + <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\NotificationDataProvider" name="admin_usage_notification_data_source"> + <settings> + <requestFieldName>id</requestFieldName> + <primaryFieldName>entity_id</primaryFieldName> + </settings> + </dataProvider> + </dataSource> + <modal name="notification_modal_1" component="Magento_AdminAnalytics/js/modal/component"> + <settings> + <state>true</state> + <options> + <option name="modalClass" xsi:type="string">admin-usage-notification</option> + <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> + <option name="autoOpen" xsi:type="boolean">true</option> + <option name="type" xsi:type="string">popup</option> + <option name="clickableOverlay" xsi:type="boolean">false</option> + <option name="responsive" xsi:type="boolean">true</option> + <option name="innerScroll" xsi:type="boolean">false</option> + + </options> + </settings> + <fieldset name="notification_fieldset"> + <settings> + <label/> + </settings> + <container name="notification_text" template="ui/form/components/complex"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="label" xsi:type="string"/> + <item name="additionalClasses" xsi:type="string">release-notification-text</item> + <item name="text" xsi:type="string" translate="true"><![CDATA[ + <p>Help us improve Magento Admin by allowing us to collect usage data.</p> + <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> +]]></item> + </item> + </argument> + </container> + <container name="notification_buttons"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="onCancel" xsi:type="string">actionCancel</item> + <item name="options" xsi:type="array"> + <item name="buttons" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="text" xsi:type="string">Don't Allow</item> + <item name="class" xsi:type="string">action-secondary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">actionCancel</item> + </item> + </item> + <item name="2" xsi:type="array"> + <item name="text" xsi:type="string">Allow</item> + <item name="class" xsi:type="string">action-primary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">actionDone</item> + </item> + </item> + </item> + </item> + </item> + </argument> + + <button name="dont_allow_modal_button"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string">Don't Allow</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> + <item name="actionName" xsi:type="string">dontAllow</item> + </item> + </item> + </item> + </argument> + </button> + <button name="allow_modal_button"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="title" xsi:type="string">Allow</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> + <item name="actionName" xsi:type="string">actionDone</item> + </item> + </item> + </item> + </argument> + </button> + </container> + </fieldset> + </modal> + +</form> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js new file mode 100644 index 000000000000..db203f6fe800 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -0,0 +1,90 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define( + [ + 'jquery', + 'Magento_Ui/js/modal/modal-component' + ], + function ($, Modal) { + 'use strict'; + + console.log('Hello two'); + + return Modal.extend( + { + defaults: { + imports: { + logAction: '${ $.provider }:data.logAction' + } + }, + keyEventHandlers: { + escapeKey: function (){} + }, + opened: function ($Event) { + $('.modal-header button.action-close', $Event.srcElement).hide(); + }, + + dontAllow: function(){ + console.log("Clicked") + }, + actionDone: function() { + console.log("Clicked") + }, + buttons: [ + { + text: $.mage.__(`Don't Allow`), + class: 'action', + click: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + } + ).fail(this.onError); + this.closeModal(); + }, + }, + { + text: $.mage.__('Ok'), + class: 'action', + click: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); + } + } + ).fail(this.onError); + + this.closeModal(); + }, + } + ], + } + ); + } +); From d63c892696be93bd9ab024518a66900c6186fe15 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 09:47:01 -0500 Subject: [PATCH 0214/1172] MC-15978: Catalog Product Attribute Set Name --- .../DataProvider/Product/Form/Modifier/AttributeSet.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 0733d21bf47d..3420965597c5 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -78,7 +78,13 @@ public function getOptions() \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::SORT_ORDER_ASC ); - return $collection->getData(); + $collectionData = $collection->getData(); + + array_walk($collectionData, function (&$attribute) { + $attribute['__disableTmpl'] = true; + }); + + return $collectionData; } /** From 90fe08e2d0710f5e48b5c9b2b8f6c63d7e917396 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 11:06:19 -0500 Subject: [PATCH 0215/1172] MC-17700: Downloadable Product links --- .../Model/Import/Product/Type/DownloadableTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php index a3230d61e262..15dd157a3154 100644 --- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php +++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/Import/Product/Type/DownloadableTest.php @@ -68,7 +68,7 @@ protected function setUp() $this->productMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $this->domainManager = $this->objectManager->get(DomainManagerInterface::class); - $this->domainManager->addDomains(['www.google.com', 'www.yahoo.com']); + $this->domainManager->addDomains(['www.bing.com', 'www.google.com', 'www.yahoo.com']); } /** @@ -76,7 +76,7 @@ protected function setUp() */ protected function tearDown() { - $this->domainManager->removeDomains(['www.google.com', 'www.yahoo.com']); + $this->domainManager->removeDomains(['www.bing.com', 'www.google.com', 'www.yahoo.com']); } /** From c4ee9853403f287be94b26ffea1a2bb75fb8a671 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 26 Jul 2019 11:09:25 -0500 Subject: [PATCH 0216/1172] MC-17700: Downloadable Product links --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a95..3b7273e08810 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 1c8cb1e0d3f4fa00749e98a767a3467f5d0a9498 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 26 Jul 2019 12:55:09 -0500 Subject: [PATCH 0217/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Added dialog box, opt out feature --- .../Model/Condition/CanViewNotification.php | 26 +++-- .../ui_component/admin_usage_notification.xml | 85 +++++--------- .../view/adminhtml/web/js/modal/component.js | 104 ++++++++---------- 3 files changed, 86 insertions(+), 129 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index b33677ea05f2..f6dd6ecb9ff3 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -78,18 +78,20 @@ public function __construct( */ public function isVisible(array $arguments) { -// $userId = $this->session->getUser()->getId(); -// $cacheKey = self::$cachePrefix . $userId; -// $value = $this->cacheStorage->load($cacheKey); -// if ($value === false) { -// $value = version_compare( -// $this->viewerLogger->get($userId)->getLastViewVersion(), -// $this->productMetadata->getVersion(), -// '<' -// ); -// $this->cacheStorage->save(false, $cacheKey); -// } - return true; + $userId = $this->session->getUser()->getId(); + $cacheKey = self::$cachePrefix . $userId; + $value = $this->cacheStorage->load($cacheKey); + if ($value === false) { + $value = version_compare( + $this->viewerLogger->get($userId)->getLastViewVersion(), + $this->productMetadata->getVersion(), + '<' + ); + $this->cacheStorage->save(false, $cacheKey); + } + + return (bool)$value; + } /** diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 6f9cca869601..f9d11d2a6a7f 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -10,7 +10,7 @@ <item name="js_config" xsi:type="array"> <item name="provider" xsi:type="string">admin_usage_notification.admin_usage_notification_data_source</item> </item> - <item name="label" xsi:type="string" translate="true">Release Notification</item> + <item name="label" xsi:type="string" translate="true">Admin Usage Notification</item> <item name="template" xsi:type="string">templates/form/collapsible</item> </argument> <settings> @@ -21,6 +21,17 @@ </deps> </settings> <dataSource name="admin_usage_notification_data_source"> + <argument name="dataProvider" xsi:type="configurableObject"> + <argument name="data" xsi:type="array"> + <item name="config" xsi:type="array"> + <item name="data" xsi:type="array"> + <item name="enableLogAction" xsi:type="url" path="adminAnalytics/config/enableAdminUsage"/> + <item name="disableLogAction" xsi:type="url" path="adminAnalytics/config/disableAdminUsage"/> + + </item> + </item> + </argument> + </argument> <argument name="data" xsi:type="array"> <item name="js_config" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> @@ -39,12 +50,27 @@ <options> <option name="modalClass" xsi:type="string">admin-usage-notification</option> <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> - <option name="autoOpen" xsi:type="boolean">true</option> + <option name="autoOpen" xsi:type="array">true</option> <option name="type" xsi:type="string">popup</option> <option name="clickableOverlay" xsi:type="boolean">false</option> <option name="responsive" xsi:type="boolean">true</option> <option name="innerScroll" xsi:type="boolean">false</option> - + <option name="buttons" xsi:type="array"> + <item name="0" xsi:type="array"> + <item name="text" xsi:type="string" translate="true">Don't Allow</item> + <item name="class" xsi:type="string">action-secondary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">disableAdminUsage</item> + </item> + </item> + <item name="1" xsi:type="array"> + <item name="text" xsi:type="string" translate="true">Allow</item> + <item name="class" xsi:type="string">action-primary</item> + <item name="actions" xsi:type="array"> + <item name="0" xsi:type="string">enableAdminUsage</item> + </item> + </item> + </option> </options> </settings> <fieldset name="notification_fieldset"> @@ -64,59 +90,6 @@ </item> </argument> </container> - <container name="notification_buttons"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="onCancel" xsi:type="string">actionCancel</item> - <item name="options" xsi:type="array"> - <item name="buttons" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="text" xsi:type="string">Don't Allow</item> - <item name="class" xsi:type="string">action-secondary</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="string">actionCancel</item> - </item> - </item> - <item name="2" xsi:type="array"> - <item name="text" xsi:type="string">Allow</item> - <item name="class" xsi:type="string">action-primary</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="string">actionDone</item> - </item> - </item> - </item> - </item> - </item> - </argument> - - <button name="dont_allow_modal_button"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string">Don't Allow</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> - <item name="actionName" xsi:type="string">dontAllow</item> - </item> - </item> - </item> - </argument> - </button> - <button name="allow_modal_button"> - <argument name="data" xsi:type="array"> - <item name="config" xsi:type="array"> - <item name="title" xsi:type="string">Allow</item> - <item name="actions" xsi:type="array"> - <item name="0" xsi:type="array"> - <item name="targetName" xsi:type="string">${ $.parentName}.notification_modal_1</item> - <item name="actionName" xsi:type="string">actionDone</item> - </item> - </item> - </item> - </argument> - </button> - </container> </fieldset> </modal> - </form> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index db203f6fe800..6c449e45f7aa 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -11,80 +11,62 @@ define( function ($, Modal) { 'use strict'; - console.log('Hello two'); - return Modal.extend( { defaults: { imports: { - logAction: '${ $.provider }:data.logAction' + enableLogAction: '${ $.provider }:data.enableLogAction', + disableLogAction: '${ $.provider }:data.disableLogAction' } }, keyEventHandlers: { - escapeKey: function (){} - }, - opened: function ($Event) { - $('.modal-header button.action-close', $Event.srcElement).hide(); - }, - - dontAllow: function(){ - console.log("Clicked") + escapeKey: function () { + } }, - actionDone: function() { - console.log("Clicked") + opened: function () { + $('.modal-header button.action-close').hide(); }, - buttons: [ - { - text: $.mage.__(`Don't Allow`), - class: 'action', - click: function () { - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax( - { - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', - data: data, - showLoader: true - } - ).done( - function (xhr) { - if (xhr.error) { - self.onError(xhr); - } + enableAdminUsage: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: this.enableLogAction, + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); } - ).fail(this.onError); - this.closeModal(); - }, + } + ).fail(this.onError); + this.closeModal(); }, - { - text: $.mage.__('Ok'), - class: 'action', - click: function () { - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax( - { - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', - data: data, - showLoader: true + disableAdminUsage: function () { + var data = { + 'form_key': window.FORM_KEY + }; + $.ajax( + { + type: 'POST', + url: this.disableLogAction, + data: data, + showLoader: true + } + ).done( + function (xhr) { + if (xhr.error) { + self.onError(xhr); } - ).done( - function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - } - ).fail(this.onError); - - this.closeModal(); - }, + } + ).fail(this.onError); + this.closeModal(); } - ], } - ); + ) } ); From 660c9891c7bbfbbdaf64e76b205c73546a57b6e5 Mon Sep 17 00:00:00 2001 From: Vinai Kopp <vinai@netzarbeiter.com> Date: Sun, 21 Jul 2019 12:52:59 -0400 Subject: [PATCH 0218/1172] Fix loss of page_cache cache_dir setting from di.xml Additionally fixed follow up issues: * Clean category pages from the built in page cache when categories are moved * Improve test isolation for GraphQl controller tests * Add tests to check caching queries actually works --- .../Observer/FlushCategoryPagesCache.php | 60 +++++ .../Magento/Catalog/etc/adminhtml/events.xml | 3 + .../Framework/App/Cache/Frontend/PoolTest.php | 55 +++++ .../Controller/AbstractGraphqlCacheTest.php | 136 +++++++++--- .../CategoriesWithProductsCacheTest.php | 35 +-- .../Controller/Catalog/CategoryCacheTest.php | 22 +- .../DeepNestedCategoriesAndProductsTest.php | 21 +- .../Controller/Catalog/ProductsCacheTest.php | 81 +++++-- .../Controller/Cms/BlockCacheTest.php | 91 +++----- .../Controller/Cms/CmsPageCacheTest.php | 175 ++++++--------- .../AllEntitiesUrlResolverCacheTest.php | 206 +++++++++--------- .../Framework/App/Cache/Frontend/Pool.php | 21 +- .../App/Test/Unit/Cache/Frontend/PoolTest.php | 34 ++- 13 files changed, 537 insertions(+), 403 deletions(-) create mode 100644 app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php create mode 100644 dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php diff --git a/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php b/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php new file mode 100644 index 000000000000..751fa3fdfad8 --- /dev/null +++ b/app/code/Magento/Catalog/Observer/FlushCategoryPagesCache.php @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Observer; + +use Magento\Catalog\Model\Category; +use Magento\Framework\Event\Observer as Event; +use Magento\Framework\Event\ObserverInterface; +use Magento\PageCache\Model\Cache\Type as PageCache; +use Magento\PageCache\Model\Config as CacheConfig; + +/** + * Flush the built in page cache when a category is moved + */ +class FlushCategoryPagesCache implements ObserverInterface +{ + + /** + * @var CacheConfig + */ + private $cacheConfig; + + /** + * + * @var PageCache + */ + private $pageCache; + + /** + * FlushCategoryPagesCache constructor. + * + * @param CacheConfig $cacheConfig + * @param PageCache $pageCache + */ + public function __construct(CacheConfig $cacheConfig, PageCache $pageCache) + { + $this->cacheConfig = $cacheConfig; + $this->pageCache = $pageCache; + } + + /** + * Clean the category page cache if built in cache page cache is used. + * + * The built in cache requires cleaning all pages that contain the top category navigation menu when a + * category is moved. This is because the built in cache does not support ESI blocks. + * + * @param Event $event + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function execute(Event $event) + { + if ($this->cacheConfig->getType() == CacheConfig::BUILT_IN && $this->cacheConfig->isEnabled()) { + $this->pageCache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, [Category::CACHE_TAG]); + } + } +} diff --git a/app/code/Magento/Catalog/etc/adminhtml/events.xml b/app/code/Magento/Catalog/etc/adminhtml/events.xml index ad83f5898237..ab1a8348d290 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/events.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/events.xml @@ -12,4 +12,7 @@ <event name="catalog_category_change_products"> <observer name="category_product_indexer" instance="Magento\Catalog\Observer\CategoryProductIndexer"/> </event> + <event name="category_move"> + <observer name="clean_cagegory_page_cache" instance="Magento\Catalog\Observer\FlushCategoryPagesCache" /> + </event> </config> diff --git a/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php new file mode 100644 index 000000000000..3324da008a84 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/App/Cache/Frontend/PoolTest.php @@ -0,0 +1,55 @@ +<?php declare(strict_types=1); + +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\App\Cache\Frontend; + +use Magento\Framework\ObjectManager\ConfigInterface as ObjectManagerConfig; +use Magento\TestFramework\ObjectManager; +use PHPUnit\Framework\TestCase; + +/** + * This superfluous comment can be removed as soon as the sniffs have been updated to match the coding guide lines. + */ +class PoolTest extends TestCase +{ + public function testPageCacheNotSameAsDefaultCacheDirectory(): void + { + /** @var ObjectManagerConfig $diConfig */ + $diConfig = ObjectManager::getInstance()->get(ObjectManagerConfig::class); + $argumentConfig = $diConfig->getArguments(\Magento\Framework\App\Cache\Frontend\Pool::class); + + $pageCacheDir = $argumentConfig['frontendSettings']['page_cache']['backend_options']['cache_dir'] ?? null; + $defaultCacheDir = $argumentConfig['frontendSettings']['default']['backend_options']['cache_dir'] ?? null; + + $noPageCacheMessage = "No default page_cache directory set in di.xml: \n" . var_export($argumentConfig, true); + $this->assertNotEmpty($pageCacheDir, $noPageCacheMessage); + + $sameCacheDirMessage = 'The page_cache and default cache storages share the same cache directory'; + $this->assertNotSame($pageCacheDir, $defaultCacheDir, $sameCacheDirMessage); + } + + /** + * @covers \Magento\Framework\App\Cache\Frontend\Pool::_getCacheSettings + * @depends testPageCacheNotSameAsDefaultCacheDirectory + */ + public function testCleaningDefaultCachePreservesPageCache() + { + $testData = 'test data'; + $testKey = 'test-key'; + + /** @var \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool */ + $cacheFrontendPool = ObjectManager::getInstance()->get(\Magento\Framework\App\Cache\Frontend\Pool::class); + + $pageCache = $cacheFrontendPool->get('page_cache'); + $pageCache->save($testData, $testKey); + + $defaultCache = $cacheFrontendPool->get('default'); + $defaultCache->clean(); + + $this->assertSame($testData, $pageCache->load($testKey)); + } +} diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php index f25144c308c6..862a924f6579 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/AbstractGraphqlCacheTest.php @@ -7,9 +7,15 @@ namespace Magento\GraphQlCache\Controller; -use PHPUnit\Framework\TestCase; -use Magento\TestFramework\ObjectManager; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\App\Response\HttpInterface as HttpResponse; +use Magento\Framework\Registry; +use Magento\GraphQl\Controller\GraphQl as GraphQlController; +use Magento\GraphQlCache\Model\CacheableQuery; +use Magento\PageCache\Model\Cache\Type as PageCache; use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use PHPUnit\Framework\TestCase; /** * Abstract test class for Graphql cache tests @@ -21,40 +27,114 @@ abstract class AbstractGraphqlCacheTest extends TestCase */ protected $objectManager; - /** - * @inheritdoc - */ protected function setUp(): void { $this->objectManager = Bootstrap::getObjectManager(); + $this->enablePageCachePlugin(); + $this->enableCachebleQueryTestProxy(); + } + + protected function tearDown(): void + { + $this->disableCacheableQueryTestProxy(); + $this->disablePageCachePlugin(); + $this->flushPageCache(); + } + + protected function enablePageCachePlugin(): void + { + /** @var $registry Registry */ + $registry = $this->objectManager->get(Registry::class); + $registry->register('use_page_cache_plugin', true, true); + } + + protected function disablePageCachePlugin(): void + { + /** @var $registry Registry */ + $registry = $this->objectManager->get(Registry::class); + $registry->unregister('use_page_cache_plugin'); + } + + protected function flushPageCache(): void + { + /** @var PageCache $fullPageCache */ + $fullPageCache = $this->objectManager->get(PageCache::class); + $fullPageCache->clean(); } /** - * Prepare a query and return a request to be used in the same test end to end + * Regarding the SuppressWarnings annotation below: the nested class below triggers a false rule match. * - * @param string $query - * @return \Magento\Framework\App\Request\Http + * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ - protected function prepareRequest(string $query) : \Magento\Framework\App\Request\Http - { - $cacheableQuery = $this->objectManager->get(\Magento\GraphQlCache\Model\CacheableQuery::class); - $cacheableQueryReflection = new \ReflectionProperty( - $cacheableQuery, - 'cacheTags' - ); - $cacheableQueryReflection->setAccessible(true); - $cacheableQueryReflection->setValue($cacheableQuery, []); - - /** @var \Magento\Framework\UrlInterface $urlInterface */ - $urlInterface = $this->objectManager->create(\Magento\Framework\UrlInterface::class); - //set unique URL - $urlInterface->setQueryParam('query', $query); - - $request = $this->objectManager->get(\Magento\Framework\App\Request\Http::class); - $request->setUri($urlInterface->getUrl('graphql')); + private function enableCachebleQueryTestProxy(): void + { + $cacheableQueryProxy = new class($this->objectManager) extends CacheableQuery { + /** @var CacheableQuery */ + private $delegate; + + public function __construct(ObjectManager $objectManager) + { + $this->reset($objectManager); + } + + public function reset(ObjectManager $objectManager): void + { + $this->delegate = $objectManager->create(CacheableQuery::class); + } + + public function getCacheTags(): array + { + return $this->delegate->getCacheTags(); + } + + public function addCacheTags(array $cacheTags): void + { + $this->delegate->addCacheTags($cacheTags); + } + + public function isCacheable(): bool + { + return $this->delegate->isCacheable(); + } + + public function setCacheValidity(bool $cacheable): void + { + $this->delegate->setCacheValidity($cacheable); + } + + public function shouldPopulateCacheHeadersWithTags(): bool + { + return $this->delegate->shouldPopulateCacheHeadersWithTags(); + } + }; + $this->objectManager->addSharedInstance($cacheableQueryProxy, CacheableQuery::class); + } + + private function disableCacheableQueryTestProxy(): void + { + $this->resetQueryCacheTags(); + $this->objectManager->removeSharedInstance(CacheableQuery::class); + } + + protected function resetQueryCacheTags(): void + { + $this->objectManager->get(CacheableQuery::class)->reset($this->objectManager); + } + + protected function dispatchGraphQlGETRequest(array $queryParams): HttpResponse + { + $this->resetQueryCacheTags(); + + /** @var HttpRequest $request */ + $request = $this->objectManager->get(HttpRequest::class); + $request->setPathInfo('/graphql'); $request->setMethod('GET'); - //set the actual GET query - $request->setQueryValue('query', $query); - return $request; + $request->setParams($queryParams); + + // required for \Magento\Framework\App\PageCache\Identifier to generate the correct cache key + $request->setUri(implode('?', [$request->getPathInfo(), http_build_query($queryParams)])); + + return $this->objectManager->create(GraphQlController::class)->dispatch($request); } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php index fd97399992c1..287353bbd2b8 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoriesWithProductsCacheTest.php @@ -9,8 +9,6 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\App\Request\Http; -use Magento\GraphQl\Controller\GraphQl; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -22,31 +20,12 @@ */ class CategoriesWithProductsCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; - - /** - * @var Http - */ - private $request; - - /** - * @inheritdoc - */ - protected function setUp(): void - { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - $this->request = $this->objectManager->create(Http::class); - } /** * Test cache tags and debug header for category with products querying for products and category * * @magentoDataFixture Magento/Catalog/_files/category_product.php */ - public function testToCheckRequestCacheTagsForCategoryWithProducts(): void + public function testRequestCacheTagsForCategoryWithProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -91,17 +70,7 @@ public function testToCheckRequestCacheTagsForCategoryWithProducts(): void 'operationName' => 'GetCategoryWithProducts' ]; - /** @var \Magento\Framework\UrlInterface $urlInterface */ - $urlInterface = $this->objectManager->create(\Magento\Framework\UrlInterface::class); - //set unique URL - $urlInterface->setQueryParam('query', $queryParams['query']); - $urlInterface->setQueryParam('variables', $queryParams['variables']); - $urlInterface->setQueryParam('operationName', $queryParams['operationName']); - $this->request->setUri($urlInterface->getUrl('graphql')); - $this->request->setPathInfo('/graphql'); - $this->request->setMethod('GET'); - $this->request->setParams($queryParams); - $response = $this->graphqlController->dispatch($this->request); + $response = $this->dispatchGraphQlGETRequest($queryParams); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'cat_p','cat_p_' . $product->getId(),'FPC']; $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php index be920fb200ff..90bdc4f75825 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryCacheTest.php @@ -7,8 +7,6 @@ namespace Magento\GraphQlCache\Controller\Catalog; -use Magento\Framework\App\Request\Http; -use Magento\GraphQl\Controller\GraphQl; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -20,25 +18,12 @@ */ class CategoryCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; - - /** - * @inheritdoc - */ - protected function setUp(): void - { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - } /** * Test cache tags and debug header for category and querying only for category * * @magentoDataFixture Magento/Catalog/_files/category_product.php */ - public function testToCheckRequestCacheTagsForForCategory(): void + public function testRequestCacheTagsForCategory(): void { $categoryId ='333'; $query @@ -53,11 +38,10 @@ public function testToCheckRequestCacheTagsForForCategory(): void } } QUERY; - $request = $this->prepareRequest($query); - $response = $this->graphqlController->dispatch($request); + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId,'FPC']; + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index 746b37a88770..e2f16e06d8b9 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -9,7 +9,6 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Api\CategoryRepositoryInterface; -use Magento\Framework\App\Request\Http; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -20,24 +19,11 @@ */ class DeepNestedCategoriesAndProductsTest extends AbstractGraphqlCacheTest { - /** @var \Magento\GraphQl\Controller\GraphQl */ - private $graphql; - - /** - * @inheritdoc - */ - protected function setUp(): void - { - parent::setUp(); - $this->graphql = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - } - /** * Test cache tags and debug header for deep nested queries involving category and products * * @magentoCache all enabled * @magentoDataFixture Magento/Catalog/_files/product_in_multiple_categories.php - * */ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void { @@ -102,14 +88,13 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void $uniqueCategoryIds = array_unique($resolvedCategoryIds); $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; foreach ($uniqueProductIds as $uniqueProductId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_'.$uniqueProductId]); + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_' . $uniqueProductId]); } foreach ($uniqueCategoryIds as $uniqueCategoryId) { - $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_'.$uniqueCategoryId]); + $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_' . $uniqueCategoryId]); } - $request = $this->prepareRequest($query); - $response = $this->graphql->dispatch($request); + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $this->assertEmpty( diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php index 335067f8408d..038a8c725581 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/ProductsCacheTest.php @@ -8,7 +8,6 @@ namespace Magento\GraphQlCache\Controller\Catalog; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\GraphQl\Controller\GraphQl; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -20,26 +19,12 @@ */ class ProductsCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; - - /** - * @inheritdoc - */ - protected function setUp(): void - { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - } - /** * Test request is dispatched and response is checked for debug headers and cache tags * * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php */ - public function testToCheckRequestCacheTagsForProducts(): void + public function testRequestCacheTagsForProducts(): void { /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); @@ -63,8 +48,7 @@ public function testToCheckRequestCacheTagsForProducts(): void } QUERY; - $request = $this->prepareRequest($query); - $response = $this->graphqlController->dispatch($request); + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; @@ -74,7 +58,7 @@ public function testToCheckRequestCacheTagsForProducts(): void /** * Test request is checked for debug headers and no cache tags for not existing product */ - public function testToCheckRequestNoTagsForProducts(): void + public function testRequestNoTagsForNonExistingProducts(): void { $query = <<<QUERY @@ -93,11 +77,66 @@ public function testToCheckRequestNoTagsForProducts(): void } QUERY; - $request = $this->prepareRequest($query); - $response = $this->graphqlController->dispatch($request); + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); $expectedCacheTags = ['FPC']; $this->assertEquals($expectedCacheTags, $actualCacheTags); } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php + */ + public function testConsecutiveRequestsAreServedFromThePageCache(): void + { + $query + = <<<QUERY +{ + products(filter: {sku: {eq: "simple1"}}) + { + items { + id + name + sku + description { + html + } + } + } +} +QUERY; + $response1 = $this->dispatchGraphQlGETRequest(['query' => $query]); + $response2 = $this->dispatchGraphQlGETRequest(['query' => $query]); + + $this->assertEquals('MISS', $response1->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $this->assertEquals('HIT', $response2->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php + */ + public function testDifferentProductsRequestsUseDifferentPageCacheRecords(): void + { + $queryTemplate + = <<<QUERY +{ + products(filter: {sku: {eq: "%s"}}) + { + items { + id + name + sku + description { + html + } + } + } +} +QUERY; + $responseProduct1 = $this->dispatchGraphQlGETRequest(['query' => sprintf($queryTemplate, 'simple1')]); + $responseProduct2 = $this->dispatchGraphQlGETRequest(['query' => sprintf($queryTemplate, 'simple2')]); + + $this->assertEquals('MISS', $responseProduct1->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $this->assertEquals('MISS', $responseProduct2->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php index c9dca2a5a837..bcc7c623eb18 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/BlockCacheTest.php @@ -7,8 +7,9 @@ namespace Magento\GraphQlCache\Controller\Cms; +use Magento\Cms\Api\Data\BlockInterface; use Magento\Cms\Model\BlockRepository; -use Magento\GraphQl\Controller\GraphQl; +use Magento\Framework\App\Response\HttpInterface as HttpResponse; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** @@ -20,23 +21,27 @@ */ class BlockCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; + private function assertPageCacheMissWithTagsForCmsBlock(HttpResponse $response, BlockInterface $block): void + { + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $this->assertCmsBlockCacheTags($response, $block); + } - /** - * @inheritdoc - */ - protected function setUp(): void + private function assertPageCacheHitWithTagsForCmsBlock(HttpResponse $response, BlockInterface $block): void + { + $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $this->assertCmsBlockCacheTags($response, $block); + } + + private function assertCmsBlockCacheTags(HttpResponse $response, BlockInterface $block): void { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); + $expectedCacheTags = ['cms_b', 'cms_b_' . $block->getId(), 'cms_b_' . $block->getIdentifier(), 'FPC']; + $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); + $actualCacheTags = explode(',', $rawActualCacheTags); + $this->assertEquals($expectedCacheTags, $actualCacheTags); } /** - * Test that the correct cache tags get added to request for cmsBlocks - * * @magentoDataFixture Magento/Cms/_files/block.php * @magentoDataFixture Magento/Cms/_files/blocks.php */ @@ -46,9 +51,9 @@ public function testCmsBlocksRequestHasCorrectTags(): void $blockRepository = $this->objectManager->get(BlockRepository::class); $block1Identifier = 'fixture_block'; - $block1 = $blockRepository->getById($block1Identifier); + $block1 = $blockRepository->getById($block1Identifier); $block2Identifier = 'enabled_block'; - $block2 = $blockRepository->getById($block2Identifier); + $block2 = $blockRepository->getById($block2Identifier); $queryBlock1 = <<<QUERY @@ -77,60 +82,30 @@ public function testCmsBlocksRequestHasCorrectTags(): void QUERY; // check to see that the first entity gets a MISS when called the first time - $request = $this->prepareRequest($queryBlock1); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]); + $this->assertPageCacheMissWithTagsForCmsBlock($response, $block1); - // check to see that the second entity gets a miss when called the first time - $request = $this->prepareRequest($queryBlock2); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block2->getId(), 'cms_b_' . $block2->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + // check to see that the second entity gets a MISS when called the first time + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock2]); + $this->assertPageCacheMissWithTagsForCmsBlock($response, $block2); // check to see that the first entity gets a HIT when called the second time - $request = $this->prepareRequest($queryBlock1); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]); + $this->assertPageCacheHitWithTagsForCmsBlock($response, $block1); // check to see that the second entity gets a HIT when called the second time - $request = $this->prepareRequest($queryBlock2); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block2->getId(), 'cms_b_' . $block2->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock2]); + $this->assertPageCacheHitWithTagsForCmsBlock($response, $block2); $block1->setTitle('something else that causes invalidation'); $blockRepository->save($block1); // check to see that the first entity gets a MISS and it was invalidated - $request = $this->prepareRequest($queryBlock1); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]); + $this->assertPageCacheMissWithTagsForCmsBlock($response, $block1); // check to see that the first entity gets a HIT when called the second time - $request = $this->prepareRequest($queryBlock1); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_b', 'cms_b_' . $block1->getId(), 'cms_b_' . $block1->getIdentifier(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $queryBlock1]); + $this->assertPageCacheHitWithTagsForCmsBlock($response, $block1); } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php index 0248f870a5f1..60d84947d87c 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Cms/CmsPageCacheTest.php @@ -7,13 +7,14 @@ namespace Magento\GraphQlCache\Controller\Cms; +use Magento\Cms\Api\Data\PageInterface; use Magento\Cms\Model\GetPageByIdentifier; use Magento\Cms\Model\PageRepository; -use Magento\GraphQl\Controller\GraphQl; +use Magento\Framework\App\Response\HttpInterface as HttpResponse; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; /** - * Test caching works for CMS page + * Test caching works for CMS pages * * @magentoAppArea graphql * @magentoCache full_page enabled @@ -22,123 +23,34 @@ */ class CmsPageCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; - - /** - * @inheritdoc - */ - protected function setUp(): void - { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(\Magento\GraphQl\Controller\GraphQl::class); - } - - /** - * Test that the correct cache tags get added to request for cmsPage query - * - * @magentoDataFixture Magento/Cms/_files/pages.php - */ - public function testToCheckCmsPageRequestCacheTags(): void + private function assertPageCacheMissWithTagsForCmsPage(string $pageId, string $name, HttpResponse $response): void { - $cmsPage100 = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0); - $pageId100 = $cmsPage100->getId(); - - $cmsPageBlank = $this->objectManager->get(GetPageByIdentifier::class)->execute('page_design_blank', 0); - $pageIdBlank = $cmsPageBlank->getId(); - - $queryCmsPage100 = $this->getQuery($pageId100); - $queryCmsPageBlank = $this->getQuery($pageIdBlank); - - // check to see that the first entity gets a MISS when called the first time - $request = $this->prepareRequest($queryCmsPage100); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals( - 'MISS', - $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected MISS on page page100 id {$queryCmsPage100}" - ); - $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC']; - $this->assertEquals($expectedCacheTags, $requestedCacheTags); - - // check to see that the second entity gets a miss when called the first time - $request = $this->prepareRequest($queryCmsPageBlank); - $response = $this->graphqlController->dispatch($request); $this->assertEquals( 'MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected MISS on page pageBlank id {$pageIdBlank}" - ); - $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageIdBlank , 'FPC']; - $this->assertEquals($expectedCacheTags, $requestedCacheTags); - - // check to see that the first entity gets a HIT when called the second time - $request = $this->prepareRequest($queryCmsPage100); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals( - 'HIT', - $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected HIT on page page100 id {$queryCmsPage100}" - ); - $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC']; - $this->assertEquals($expectedCacheTags, $requestedCacheTags); - - // check to see that the second entity gets a HIT when called the second time - $request = $this->prepareRequest($queryCmsPageBlank); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals( - 'HIT', - $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected HIT on page pageBlank id {$pageIdBlank}" + "expected MISS on page {$name} id {$pageId}" ); - $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageIdBlank , 'FPC']; - $this->assertEquals($expectedCacheTags, $requestedCacheTags); - - /** @var PageRepository $pageRepository */ - $pageRepository = $this->objectManager->get(PageRepository::class); - - $page = $pageRepository->getById($pageId100); - $page->setTitle('something else that causes invalidation'); - $pageRepository->save($page); - - // check to see that the first entity gets a MISS and it was invalidated - $request = $this->prepareRequest($queryCmsPage100); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals( - 'MISS', - $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected MISS on page page100 id {$queryCmsPage100}" - ); - $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC']; - $this->assertEquals($expectedCacheTags, $requestedCacheTags); + $this->assertCmsPageCacheTags($pageId, $response); + } - // check to see that the first entity gets a HIT when called the second time - $request = $this->prepareRequest($queryCmsPage100); - $response = $this->graphqlController->dispatch($request); + private function assertPageCacheHitWithTagsForCmsPage(string $pageId, string $name, HttpResponse $response): void + { $this->assertEquals( 'HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue(), - "expected MISS on page page100 id {$queryCmsPage100}" + "expected HIT on page {$name} id {$pageId}" ); + $this->assertCmsPageCacheTags($pageId, $response); + } + + private function assertCmsPageCacheTags(string $pageId, HttpResponse $response): void + { $requestedCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); - $expectedCacheTags = ['cms_p', 'cms_p_' .$pageId100 , 'FPC']; + $expectedCacheTags = ['cms_p', 'cms_p_' . $pageId, 'FPC']; $this->assertEquals($expectedCacheTags, $requestedCacheTags); } - /** - * Get cms query - * - * @param string $id - * @return string - */ - private function getQuery(string $id) : string + private function buildQuery(string $id): string { $queryCmsPage = <<<QUERY { @@ -156,4 +68,57 @@ private function getQuery(string $id) : string QUERY; return $queryCmsPage; } + + private function updateCmsPageTitle(string $pageId100, string $newTitle): void + { + /** @var PageRepository $pageRepository */ + $pageRepository = $this->objectManager->get(PageRepository::class); + $page = $pageRepository->getById($pageId100); + $page->setTitle($newTitle); + $pageRepository->save($page); + } + + /** + * @magentoDataFixture Magento/Cms/_files/pages.php + */ + public function testCmsPageRequestCacheTags(): void + { + /** @var PageInterface $cmsPage100 */ + $cmsPage100 = $this->objectManager->get(GetPageByIdentifier::class)->execute('page100', 0); + $pageId100 = (string) $cmsPage100->getId(); + + /** @var PageInterface $cmsPageBlank */ + $cmsPageBlank = $this->objectManager->get(GetPageByIdentifier::class)->execute('page_design_blank', 0); + $pageIdBlank = (string) $cmsPageBlank->getId(); + + $queryCmsPage100 = $this->buildQuery($pageId100); + $queryCmsPageBlank = $this->buildQuery($pageIdBlank); + + // check to see that the first entity gets a MISS when called the first time + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]); + $this->assertPageCacheMissWithTagsForCmsPage($pageId100, 'page100', $response); + + // check to see that the second entity gets a MISS when called the first time + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]); + $this->assertPageCacheMissWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response); + + // check to see that the first entity gets a HIT when called the second time + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]); + $this->assertPageCacheHitWithTagsForCmsPage($pageId100, 'page100', $response); + + // check to see that the second entity gets a HIT when called the second time + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]); + $this->assertPageCacheHitWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response); + + // invalidate first entity + $this->updateCmsPageTitle($pageId100, 'something else that causes invalidation'); + + // check to see that the second entity gets a HIT to confirm only the first was invalidated + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPageBlank]); + $this->assertPageCacheHitWithTagsForCmsPage($pageIdBlank, 'pageBlank', $response); + + // check to see that the first entity gets a MISS because it was invalidated + $response = $this->dispatchGraphQlGETRequest(['query' => $queryCmsPage100]); + $this->assertPageCacheMissWithTagsForCmsPage($pageId100, 'page100', $response); + } } diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php index 7accb1d7d0b2..81a4988b8193 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/UrlRewrite/AllEntitiesUrlResolverCacheTest.php @@ -9,7 +9,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; -use Magento\GraphQl\Controller\GraphQl; +use Magento\Framework\App\Response\HttpInterface as HttpResponse; use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; use Magento\UrlRewrite\Model\UrlFinderInterface; use Magento\Cms\Api\Data\PageInterface; @@ -24,155 +24,153 @@ */ class AllEntitiesUrlResolverCacheTest extends AbstractGraphqlCacheTest { - /** - * @var GraphQl - */ - private $graphqlController; + private function assertCacheMISSWithTagsForCategory(string $categoryId, HttpResponse $response): void + { + $this->assertCacheMISS($response); + $this->assertCacheTags($categoryId, 'cat_c', $response); + } - /** - * @inheritdoc - */ - protected function setUp(): void + private function assertCacheMISSWithTagsForProduct(string $productId, HttpResponse $response): void + { + $this->assertCacheMISS($response); + $this->assertCacheTags($productId, 'cat_p', $response); + } + + private function assertCacheMISSWithTagsForCmsPage(string $pageId, HttpResponse $response): void + { + $this->assertCacheMISS($response); + $this->assertCacheTags($pageId, 'cms_p', $response); + } + + private function assertCacheHITWithTagsForCategory(string $categoryId, HttpResponse $response): void { - parent::setUp(); - $this->graphqlController = $this->objectManager->get(GraphQl::class); + $this->assertCacheHIT($response); + $this->assertCacheTags($categoryId, 'cat_c', $response); + } + + private function assertCacheHITWithTagsForProduct(string $productId, HttpResponse $response): void + { + $this->assertCacheHIT($response); + $this->assertCacheTags($productId, 'cat_p', $response); + } + + private function assertCacheHITWithTagsForCmsPage(string $pageId, HttpResponse $response): void + { + $this->assertCacheHIT($response); + $this->assertCacheTags($pageId, 'cms_p', $response); + } + + private function assertCacheMISS(HttpResponse $response): void + { + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + } + + private function assertCacheHIT(HttpResponse $response): void + { + $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + } + + private function assertCacheTags(string $entityId, string $entityCacheTag, HttpResponse $response) + { + $expectedCacheTags = [$entityCacheTag, $entityCacheTag . '_' . $entityId, 'FPC']; + $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); + $actualCacheTags = explode(',', $rawActualCacheTags); + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } + + private function buildQuery(string $requestPath): string + { + $resolverQuery = <<<QUERY +{ + urlResolver(url:"{$requestPath}") + { + id + relative_url + canonical_url + type + } +} +QUERY; + return $resolverQuery; } /** - * Tests that X-Magento-tags and cache debug headers are correct for category urlResolver + * Tests that X-Magento-Tags and cache debug headers are correct for category urlResolver * * @magentoDataFixture Magento/CatalogUrlRewrite/_files/product_with_category.php * @magentoDataFixture Magento/Cms/_files/pages.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ - public function testAllEntitiesUrlResolverRequestHasCorrectTags() + public function testAllEntitiesUrlResolverRequestHasCorrectTags(): void { $categoryUrlKey = 'cat-1.html'; - $productUrlKey = 'p002.html'; - $productSku = 'p002'; + $productUrlKey = 'p002.html'; + $productSku = 'p002'; /** @var ProductRepositoryInterface $productRepository */ $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); /** @var Product $product */ $product = $productRepository->get($productSku, false, null, true); - $storeId = $product->getStoreId(); + $storeId = (string) $product->getStoreId(); /** @var UrlFinderInterface $urlFinder */ - $urlFinder = $this->objectManager->get(UrlFinderInterface::class); - $actualUrls = $urlFinder->findOneByData( + $urlFinder = $this->objectManager->get(UrlFinderInterface::class); + $actualUrls = $urlFinder->findOneByData( [ 'request_path' => $categoryUrlKey, 'store_id' => $storeId ] ); - $categoryId = $actualUrls->getEntityId(); - $categoryQuery = $this->getQuery($categoryUrlKey); + $categoryId = (string) $actualUrls->getEntityId(); + $categoryQuery = $this->buildQuery($categoryUrlKey); - $productQuery = $this->getQuery($productUrlKey); + $productQuery = $this->buildQuery($productUrlKey); /** @var GetPageByIdentifierInterface $page */ $page = $this->objectManager->get(GetPageByIdentifierInterface::class); /** @var PageInterface $cmsPage */ - $cmsPage = $page->execute('page100', 0); - $cmsPageId = $cmsPage->getId(); + $cmsPage = $page->execute('page100', 0); + $cmsPageId = (string) $cmsPage->getId(); $requestPath = $cmsPage->getIdentifier(); - $pageQuery = $this->getQuery($requestPath); + $pageQuery = $this->buildQuery($requestPath); // query category for MISS - $request = $this->prepareRequest($categoryQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]); + $this->assertCacheMISSWithTagsForCategory($categoryId, $response); // query product for MISS - $request = $this->prepareRequest($productQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]); + $this->assertCacheMISSWithTagsForProduct((string) $product->getId(), $response); // query page for MISS - $request = $this->prepareRequest($pageQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_p','cms_p_' . $cmsPageId,'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $pageQuery]); + $this->assertCacheMISSWithTagsForCmsPage($cmsPageId, $response); // query category for HIT - $request = $this->prepareRequest($categoryQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]); + $this->assertCacheHITWithTagsForCategory($categoryId, $response); // query product for HIT - $request = $this->prepareRequest($productQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]); + $this->assertCacheHITWithTagsForProduct((string) $product->getId(), $response); - // query product for HIT - $request = $this->prepareRequest($pageQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('HIT', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cms_p','cms_p_' . $cmsPageId,'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + // query page for HIT + $response = $this->dispatchGraphQlGETRequest(['query' => $pageQuery]); + $this->assertCacheHITWithTagsForCmsPage($cmsPageId, $response); $product->setUrlKey('something-else-that-invalidates-the-cache'); $productRepository->save($product); - $productQuery = $this->getQuery('something-else-that-invalidates-the-cache.html'); + $productQuery = $this->buildQuery('something-else-that-invalidates-the-cache.html'); // query category for MISS - $request = $this->prepareRequest($categoryQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); + $response = $this->dispatchGraphQlGETRequest(['query' => $categoryQuery]); + $this->assertCacheMISSWithTagsForCategory($categoryId, $response); - // query product for HIT - $request = $this->prepareRequest($productQuery); - $response = $this->graphqlController->dispatch($request); - $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); - $expectedCacheTags = ['cat_p', 'cat_p_' . $product->getId(), 'FPC']; - $rawActualCacheTags = $response->getHeader('X-Magento-Tags')->getFieldValue(); - $actualCacheTags = explode(',', $rawActualCacheTags); - $this->assertEquals($expectedCacheTags, $actualCacheTags); - } + // query product for MISS + $response = $this->dispatchGraphQlGETRequest(['query' => $productQuery]); + $this->assertCacheMISSWithTagsForProduct((string) $product->getId(), $response); - /** - * Get urlResolver query - * - * @param string $id - * @return string - */ - private function getQuery(string $requestPath) : string - { - $resolverQuery = <<<QUERY -{ - urlResolver(url:"{$requestPath}") - { - id - relative_url - canonical_url - type - } -} -QUERY; - return $resolverQuery; + // query page for HIT + $response = $this->dispatchGraphQlGETRequest(['query' => $pageQuery]); + $this->assertCacheHITWithTagsForCmsPage($cmsPageId, $response); } } diff --git a/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php b/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php index 30cb4a67b9ed..a4c9fb438065 100644 --- a/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php +++ b/lib/internal/Magento/Framework/App/Cache/Frontend/Pool.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Framework\App\Cache\Frontend; use Magento\Framework\App\Cache\Type\FrontendPool; @@ -55,6 +56,7 @@ public function __construct( /** * Create instances of every cache frontend known to the system. + * * Method is to be used for delayed initialization of the iterator. * * @return void @@ -77,18 +79,21 @@ protected function _initialize() protected function _getCacheSettings() { /* - * Merging is intentionally implemented through array_merge() instead of array_replace_recursive() - * to avoid "inheritance" of the default settings that become irrelevant as soon as cache storage type changes + * Merging is intentionally implemented through array_replace_recursive() instead of array_merge(), because even + * though some settings may become irrelevant when the cache storage type is changed, they don't do any harm + * and can be overwritten when needed. + * Also array_merge leads to unexpected behavior, for for example by dropping the + * default cache_dir setting from di.xml when a cache id_prefix is configured in app/etc/env.php. */ $cacheInfo = $this->deploymentConfig->getConfigData(FrontendPool::KEY_CACHE); if (null !== $cacheInfo) { - return array_merge($this->_frontendSettings, $cacheInfo[FrontendPool::KEY_FRONTEND_CACHE]); + return array_replace_recursive($this->_frontendSettings, $cacheInfo[FrontendPool::KEY_FRONTEND_CACHE]); } return $this->_frontendSettings; } /** - * {@inheritdoc} + * @inheritdoc * * @return \Magento\Framework\Cache\FrontendInterface */ @@ -99,7 +104,7 @@ public function current() } /** - * {@inheritdoc} + * @inheritdoc */ public function key() { @@ -108,7 +113,7 @@ public function key() } /** - * {@inheritdoc} + * @inheritdoc */ public function next() { @@ -117,7 +122,7 @@ public function next() } /** - * {@inheritdoc} + * @inheritdoc */ public function rewind() { @@ -126,7 +131,7 @@ public function rewind() } /** - * {@inheritdoc} + * @inheritdoc */ public function valid() { diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php index bfa37311884b..5ec3dd658737 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Frontend/PoolTest.php @@ -8,6 +8,9 @@ use Magento\Framework\App\Cache\Frontend\Pool; use Magento\Framework\App\Cache\Type\FrontendPool; +/** + * And another docblock to make the sniff shut up. + */ class PoolTest extends \PHPUnit\Framework\TestCase { /** @@ -111,25 +114,38 @@ public function testInitializationParams( public function initializationParamsDataProvider() { return [ - 'default frontend, default settings' => [ + 'no deployment config, default settings' => [ ['frontend' => []], [Pool::DEFAULT_FRONTEND_ID => ['default_option' => 'default_value']], ['default_option' => 'default_value'], ], - 'default frontend, overridden settings' => [ + 'deployment config, default settings' => [ + ['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]], + [Pool::DEFAULT_FRONTEND_ID => ['default_option' => 'default_value']], + ['configured_option' => 'configured_value', 'default_option' => 'default_value'], + ], + 'deployment config, overridden settings' => [ ['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]], - [Pool::DEFAULT_FRONTEND_ID => ['ignored_option' => 'ignored_value']], + [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'default_value']], ['configured_option' => 'configured_value'], ], - 'custom frontend, default settings' => [ - ['frontend' => []], + 'deployment config, default settings, overridden settings' => [ + ['frontend' => [Pool::DEFAULT_FRONTEND_ID => ['configured_option' => 'configured_value']]], + [Pool::DEFAULT_FRONTEND_ID => [ + 'configured_option' => 'default_value', + 'default_setting' => 'default_value' + ]], + ['configured_option' => 'configured_value', 'default_setting' => 'default_value'], + ], + 'custom deployent config, default settings' => [ + ['frontend' => ['custom' => ['configured_option' => 'configured_value']]], ['custom' => ['default_option' => 'default_value']], - ['default_option' => 'default_value'], + ['configured_option' => 'configured_value', 'default_option' => 'default_value'], ], - 'custom frontend, overridden settings' => [ + 'custom deployent config, default settings, overridden settings' => [ ['frontend' => ['custom' => ['configured_option' => 'configured_value']]], - ['custom' => ['ignored_option' => 'ignored_value']], - ['configured_option' => 'configured_value'], + ['custom' => ['default_option' => 'default_value', 'configured_option' => 'default_value']], + ['configured_option' => 'configured_value', 'default_option' => 'default_value'], ] ]; } From d4cb1c8f71dadb784d495359c8bc524b7037ed96 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 26 Jul 2019 15:57:44 -0500 Subject: [PATCH 0219/1172] MC-15298: Allow admin to opt out of admin analytics tracking - cleaned up code --- .../Magento/AdminAnalytics/Block/Setting.php | 52 ---- .../Adminhtml/Config/DisableAdminUsage.php | 25 +- .../Adminhtml/Config/EnableAdminUsage.php | 23 +- .../Adminhtml/Config/MarkUserNotified.php | 95 ------- .../Model/Condition/CanViewNotification.php | 32 +-- .../Model/ResourceModel/Viewer/Logger.php | 31 +-- .../AdminAnalytics/Model/Viewer/Log.php | 24 +- .../DataProvider/Modifier/Notifications.php | 246 ------------------ .../DataProvider/NotificationDataProvider.php | 6 +- .../Ui/Renderer/NotificationRenderer.php | 208 --------------- .../Magento/AdminAnalytics/etc/db_schema.xml | 17 +- .../etc/db_schema_whitelist.json | 7 +- 12 files changed, 70 insertions(+), 696 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Block/Setting.php delete mode 100644 app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php delete mode 100644 app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php delete mode 100644 app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php diff --git a/app/code/Magento/AdminAnalytics/Block/Setting.php b/app/code/Magento/AdminAnalytics/Block/Setting.php deleted file mode 100644 index 516c854c2933..000000000000 --- a/app/code/Magento/AdminAnalytics/Block/Setting.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\AdminAnalytics\Block; - -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context; -use Magento\Config\Model\Config\Factory; - -class Setting extends Template -{ - private $configFactory; - /** - * @param Context $context - * @param Factory $configFactory - * @param array $data - */ - public function __construct( - Context $context, - Factory $configFactory, - array $data = [] - ) { - $this->configFactory = $configFactory; - parent::__construct($context, $data); - } - - /** - * Sets the admin usage's configuration setting to yes - */ - public function enableAdminUsage() - { - $configModel = $this->configFactory->create(); - $configModel->setDataByPath('admin/usage/enabled', 1); - $configModel->save(); - } - - /** - * Sets the admin usage's configuration setting to no - */ - public function disableAdminUsage() - { - $configModel = $this->configFactory->create(); - $configModel->setDataByPath('admin/usage/enabled', 0); - $configModel->save(); - } - - public function showModal() { - return false; - } -} diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index b81c60e4b3ad..eb31e54e8041 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -7,20 +7,18 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\Controller\ResultInterface; use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** - * Controller to record that the current admin user has seen the release notification content + * Controller to record Admin analytics usage log */ class DisableAdminUsage extends Action { - - private $configFactory; /** @@ -39,11 +37,12 @@ class DisableAdminUsage extends Action private $logger; /** - * MarkUserNotified constructor. + * DisableAdminUsage constructor. * * @param Action\Context $context * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger + * @param Factory $configFactory * @param LoggerInterface $logger */ public function __construct( @@ -59,6 +58,10 @@ public function __construct( $this->notificationLogger = $notificationLogger; $this->logger = $logger; } + + /** + * Changes the value of config/admin/usage/enabled + */ public function disableAdminUsage() { $configModel = $this->configFactory->create(); @@ -66,13 +69,16 @@ public function disableAdminUsage() $configModel->save(); } + /** + * Log information about the last admin usage selection + * + * @return ResultInterface + */ public function markUserNotified() { $responseContent = [ 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion(), - 0 + $this->productMetadata->getVersion() ), 'error_message' => '' ]; @@ -80,10 +86,11 @@ public function markUserNotified() $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); return $resultJson->setData($responseContent); } + /** * Log information about the last shown advertisement * - * @return \Magento\Framework\Controller\ResultInterface + * @return ResultInterface */ public function execute() { diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index d1b879ae927a..9ce119f0c424 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -7,15 +7,15 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\Controller\ResultInterface; use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** - * Controller to record that the current admin user has seen the release notification content + * Controller to record that the current admin user has responded to Admin Analytics notice */ class EnableAdminUsage extends Action { @@ -42,6 +42,7 @@ class EnableAdminUsage extends Action * @param Action\Context $context * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger + * @param Factory $configFactory * @param LoggerInterface $logger */ public function __construct( @@ -57,6 +58,10 @@ public function __construct( $this->notificationLogger = $notificationLogger; $this->logger = $logger; } + + /** + * Changes the value of config/admin/usage/enabled + */ public function enableAdminUsage() { $configModel = $this->configFactory->create(); @@ -64,13 +69,16 @@ public function enableAdminUsage() $configModel->save(); } + /** + * Log information about the last user response + * + * @return ResultInterface + */ public function markUserNotified() { $responseContent = [ 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion(), - 1 + $this->productMetadata->getVersion() ), 'error_message' => '' ]; @@ -78,6 +86,7 @@ public function markUserNotified() $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); return $resultJson->setData($responseContent); } + /** * Log information about the last shown advertisement * @@ -88,8 +97,10 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - + /** + * IsAllow allows function to be visible + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php deleted file mode 100644 index 4c252329d07a..000000000000 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/MarkUserNotified.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; - -use Magento\Backend\App\Action; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Controller\ResultFactory; -use Magento\ReleaseNotification\Model\ResourceModel\Viewer\Logger as NotificationLogger; -use Magento\Framework\App\ProductMetadataInterface; -use Psr\Log\LoggerInterface; - -/** - * Controller to record that the current admin user has seen the release notification content - */ -class MarkUserNotified extends Action -{ - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - - /** - * @var NotificationLogger - */ - private $notificationLogger; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * MarkUserNotified constructor. - * - * @param Action\Context $context - * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param LoggerInterface $logger - */ - public function __construct( - Action\Context $context, - ProductMetadataInterface $productMetadata, - NotificationLogger $notificationLogger, - LoggerInterface $logger - ) { - parent::__construct($context); - $this->productMetadata = $productMetadata; - $this->notificationLogger = $notificationLogger; - $this->logger = $logger; - } - - /** - * Log information about the last shown advertisement - * - * @return \Magento\Framework\Controller\ResultInterface - */ - public function execute() - { - try { - $responseContent = [ - 'success' => $this->notificationLogger->log( - $this->_auth->getUser()->getId(), - $this->productMetadata->getVersion() - ), - 'error_message' => '' - ]; - } catch (LocalizedException $e) { - $this->logger->error($e->getMessage()); - $responseContent = [ - 'success' => false, - 'error_message' => $e->getMessage() - ]; - } catch (\Exception $e) { - $this->logger->error($e->getMessage()); - $responseContent = [ - 'success' => false, - 'error_message' => __('It is impossible to log user action') - ]; - } - $resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON); - return $resultJson->setData($responseContent); - } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index f6dd6ecb9ff3..a8a6b58bffbf 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -10,9 +10,11 @@ use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; +use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** * Dynamic validator for UI release notification, manage UI component visibility. + * * Return true if the logged in user has not seen the notification. */ class CanViewNotification implements VisibilityConditionInterface @@ -36,11 +38,6 @@ class CanViewNotification implements VisibilityConditionInterface */ private $viewerLogger; - /** - * @var Session - */ - private $session; - /** * @var ProductMetadataInterface */ @@ -55,18 +52,15 @@ class CanViewNotification implements VisibilityConditionInterface * CanViewNotification constructor. * * @param Logger $viewerLogger - * @param Session $session * @param ProductMetadataInterface $productMetadata * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, - Session $session, ProductMetadataInterface $productMetadata, CacheInterface $cacheStorage ) { $this->viewerLogger = $viewerLogger; - $this->session = $session; $this->productMetadata = $productMetadata; $this->cacheStorage = $cacheStorage; } @@ -78,20 +72,18 @@ public function __construct( */ public function isVisible(array $arguments) { - $userId = $this->session->getUser()->getId(); - $cacheKey = self::$cachePrefix . $userId; + $currentProductVersion = $this->productMetadata->getVersion(); + $cacheKey = self::$cachePrefix.$currentProductVersion; $value = $this->cacheStorage->load($cacheKey); - if ($value === false) { - $value = version_compare( - $this->viewerLogger->get($userId)->getLastViewVersion(), - $this->productMetadata->getVersion(), - '<' - ); - $this->cacheStorage->save(false, $cacheKey); + if ($value != $currentProductVersion) { + $versionViewed = $this->viewerLogger->get($currentProductVersion)->getLastViewVersion(); + $versionExists = isset($versionViewed); + if ($versionExists) { + $this->cacheStorage->save($versionViewed, $cacheKey); + } + return !$versionExists; } - - return (bool)$value; - + return false; } /** diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 5b67d4dfffec..6c6a76365fbb 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -12,7 +12,7 @@ use Magento\Framework\App\ResourceConnection; /** - * Release notification viewer log data logger. + * Admin Analytics log data logger. * * Saves and retrieves release notification viewer log data. */ @@ -21,7 +21,7 @@ class Logger /** * Log table name */ - const LOG_TABLE_NAME = 'admin_usage_viewer_log'; + const LOG_TABLE_NAME = 'admin_analytics_usage_version_log'; /** * @var Resource @@ -49,53 +49,48 @@ public function __construct( /** * Save (insert new or update existing) log. * - * @param int $viewerId * @param string $lastViewVersion - * @param int $isAdminUsageEnabled * @return bool */ - public function log(int $viewerId, string $lastViewVersion, int $isAdminUsageEnabled) : bool + public function log(string $lastViewVersion) : bool { /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); $connection->insertOnDuplicate( $this->resource->getTableName(self::LOG_TABLE_NAME), [ - 'viewer_id' => $viewerId, - 'last_view_version' => $lastViewVersion, - 'is_admin_usage_enabled' => $isAdminUsageEnabled + 'last_viewed_in_version' => $lastViewVersion, ], [ - 'last_view_version', - 'is_admin_usage_enabled' + 'last_viewed_in_version', ] ); return true; } /** - * Get log by viewer Id. + * Get log by the last view version. * - * @param int $viewerId + * @param string $lastViewVersion * @return Log */ - public function get(int $viewerId) : Log + public function get(string $lastViewVersion) : Log { - return $this->logFactory->create(['data' => $this->loadLogData($viewerId)]); + return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); } /** - * Load release notification viewer log data by viewer id + * Load release notification viewer log data by last view version * - * @param int $viewerId + * @param string $lastViewVersion * @return array */ - private function loadLogData(int $viewerId) : array + private function loadLogData(string $lastViewVersion) : array { $connection = $this->resource->getConnection(); $select = $connection->select() ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) - ->where('viewer_id = ?', $viewerId); + ->where('last_viewed_in_version = ?', $lastViewVersion); $data = $connection->fetchRow($select); if (!$data) { diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index 28621b36d9b7..3ba1d15d716d 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -8,7 +8,7 @@ use Magento\Framework\DataObject; /** - * Release notification viewer log resource + * Admin Analytics log resource */ class Log extends DataObject { @@ -22,16 +22,6 @@ public function getId() return $this->getData('id'); } - /** - * Get viewer id - * - * @return int - */ - public function getViewerId() - { - return $this->getData('viewer_id'); - } - /** * Get last viewed product version * @@ -39,16 +29,6 @@ public function getViewerId() */ public function getLastViewVersion() { - return $this->getData('last_view_version'); - } - - /** - * Get admin usage enabled - * - * @return int - */ - public function getIsAdminUsageEnabled() - { - return $this->getData('is_admin_usage_enabled'); + return $this->getData('last_viewed_in_version'); } } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php deleted file mode 100644 index f93cb1e00f01..000000000000 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/Modifier/Notifications.php +++ /dev/null @@ -1,246 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Ui\DataProvider\Modifier; - -use Magento\AdminAnalytics\Model\ContentProviderInterface; -use Magento\AdminAnalytics\Ui\Renderer\NotificationRenderer; -use Magento\Ui\DataProvider\Modifier\ModifierInterface; -use Magento\Framework\Serialize\SerializerInterface; -use Magento\Framework\App\CacheInterface; -use Magento\Ui\Component; -use Magento\Framework\App\ProductMetadataInterface; -use Magento\Backend\Model\Auth\Session; -use Psr\Log\LoggerInterface; - -/** - * Modifies the metadata returning to the Release Notification data provider - */ -class Notifications implements ModifierInterface -{ - /** - * @var ContentProviderInterface - */ - private $contentProvider; - - /** - * @var NotificationRenderer - */ - private $renderer; - - /** - * Prefix for cache - * - * @var string - */ - private static $cachePrefix = 'release-notification-content-'; - - /** - * @var CacheInterface - */ - private $cacheStorage; - - /** - * @var SerializerInterface - */ - private $serializer; - - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - - /** - * @var Session - */ - private $session; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @param ContentProviderInterface $contentProvider - * @param NotificationRenderer $render - * @param CacheInterface $cacheStorage - * @param SerializerInterface $serializer - * @param ProductMetadataInterface $productMetadata - * @param Session $session - * @param LoggerInterface $logger - */ - public function __construct( - ContentProviderInterface $contentProvider, - NotificationRenderer $render, - CacheInterface $cacheStorage, - SerializerInterface $serializer, - ProductMetadataInterface $productMetadata, - Session $session, - LoggerInterface $logger - ) { - $this->contentProvider = $contentProvider; - $this->renderer = $render; - $this->cacheStorage = $cacheStorage; - $this->serializer = $serializer; - $this->productMetadata = $productMetadata; - $this->session = $session; - $this->logger = $logger; - } - - /** - * {@inheritdoc} - */ - public function modifyData(array $data) - { - return $data; - } - - /** - * {@inheritdoc} - */ - public function modifyMeta(array $meta) - { - $modalContent = $this->getNotificationContent(); - - if ($modalContent) { - $pages = $modalContent['pages']; - $pageCount = count($pages); - $counter = 1; - - foreach ($pages as $page) { - $meta = $this->buildNotificationMeta($meta, $page, $counter++ == $pageCount); - } - } else { - $meta = $this->hideNotification($meta); - } - - return $meta; - } - - /** - * Builds the notification modal by modifying $meta for the ui component - * - * @param array $meta - * @param array $page - * @param bool $isLastPage - * @return array - */ - private function buildNotificationMeta(array $meta, array $page, $isLastPage) - { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config'] = [ - 'isTemplate' => false, - 'componentType' => Component\Modal::NAME - ]; - - $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] - ['notification_text']['arguments']['data']['config'] = [ - 'text' => $this->renderer->getNotificationContent($page) - ]; - - if ($isLastPage) { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ - 'title' => $this->renderer->getNotificationTitle($page), - 'buttons' => [ - [ - 'text' => 'Done', - 'actions' => [ - [ - 'targetName' => '${ $.name }', - 'actionName' => 'closeReleaseNotes' - ] - ], - 'class' => 'release-notification-button-next' - ] - ], - ]; - - $meta['notification_modal_' . $page['name']]['children']['notification_fieldset']['children'] - ['notification_buttons']['children']['notification_button_next']['arguments']['data']['config'] = [ - 'buttonClasses' => 'hide-release-notification' - ]; - } else { - $meta['notification_modal_' . $page['name']]['arguments']['data']['config']['options'] = [ - 'title' => $this->renderer->getNotificationTitle($page) - ]; - } - - return $meta; - } - - /** - * Sets the modal to not display if no content is available. - * - * @param array $meta - * @return array - */ - private function hideNotification(array $meta) - { - $meta['notification_modal_1']['arguments']['data']['config']['options'] = [ - 'autoOpen' => false - ]; - - return $meta; - } - - /** - * Returns the notification modal content data - * - * @returns array|false - */ - private function getNotificationContent() - { - $version = strtolower($this->getTargetVersion()); - $edition = strtolower($this->productMetadata->getEdition()); - $locale = strtolower($this->session->getUser()->getInterfaceLocale()); - - $cacheKey = self::$cachePrefix . $version . "-" . $edition . "-" . $locale; - $modalContent = $this->cacheStorage->load($cacheKey); - if ($modalContent === false) { - $modalContent = $this->contentProvider->getContent($version, $edition, $locale); - $this->cacheStorage->save($modalContent, $cacheKey); - } - - return !$modalContent ? $modalContent : $this->unserializeContent($modalContent); - } - - /** - * Unserializes the notification modal content to be used for rendering - * - * @param string $modalContent - * @return array|false - */ - private function unserializeContent($modalContent) - { - $result = false; - - try { - $result = $this->serializer->unserialize($modalContent); - } catch (\InvalidArgumentException $e) { - $this->logger->warning( - sprintf( - 'Failed to unserialize the release notification content. The error is: %s', - $e->getMessage() - ) - ); - } - - return $result; - } - - /** - * Returns the current Magento version used to retrieve the release notification content. - * Version information after the dash (-) character is removed (ex. -dev or -rc). - * - * @return string - */ - private function getTargetVersion() - { - $metadataVersion = $this->productMetadata->getVersion(); - $version = strstr($metadataVersion, '-', true); - - return !$version ? $metadataVersion : $version; - } -} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php index 104d902d3dc9..a3acf279c7a9 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -13,7 +13,7 @@ use Magento\Ui\DataProvider\Modifier\PoolInterface; /** - * Data Provider for the Release Notifications UI component. + * Data Provider for the Admin usage UI component. */ class NotificationDataProvider implements DataProviderInterface { @@ -164,7 +164,7 @@ public function getFieldsMetaInfo($fieldSetName) */ public function getPrimaryFieldName() { - return 'release_notification'; + return 'admin_analytics'; } /** @@ -172,7 +172,7 @@ public function getPrimaryFieldName() */ public function getRequestFieldName() { - return 'release_notification'; + return 'admin_analytics'; } /** diff --git a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php b/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php deleted file mode 100644 index b66e213670f7..000000000000 --- a/app/code/Magento/AdminAnalytics/Ui/Renderer/NotificationRenderer.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Ui\Renderer; - -use Magento\Framework\Escaper; - -/** - * Builds the HTML for the release notification modals - */ -class NotificationRenderer -{ - /** - * @var Escaper - */ - private $escaper; - - /** - * @param Escaper $escaper - */ - public function __construct( - Escaper $escaper - ) { - $this->escaper = $escaper; - } - - /** - * Returns the HTML for notification's title to the ui component - * - * @param array $page - * @return string - */ - public function getNotificationTitle(array $page) - { - $title = $this->escaper->escapeHtml($page['mainContent']['title']); - $imageUrl = $this->escaper->escapeUrl($page['mainContent']['imageUrl']); - $content = ""; - - if (!empty($imageUrl)) { - $content .= "<div class='release-notification-title-with-image' style='background-image: url(\"" . $imageUrl - . "\")'>"; - $content .= $title; - $content .= "</div>"; - } else { - $content = $title; - } - - return $content; - } - - /** - * Returns the HTML for the content in the notification ui component - * - * @param array $page - * @return string - */ - public function getNotificationContent(array $page) - { - $content = $this->buildMainContent($page['mainContent']); - $content .= $this->buildSubHeadings($page['subHeading']); - $content .= $this->buildFooter($page['footer']); - - return $content; - } - - /** - * Builds the HTML for the main content in the notification ui component - * - * @param array $mainContent - * @return string - */ - private function buildMainContent(array $mainContent) - { - $content = $this->buildContentTextAreas($mainContent['content']); - $content .= $this->buildLists($mainContent['lists']); - - return $this->formatContentWithLinks($content); - } - - /** - * Builds the HTML for the main text areas in the notification ui component - * - * @param array $contentAreas - * @return string - */ - private function buildContentTextAreas(array $contentAreas) - { - $content = ""; - $lastContentArea = end($contentAreas); - - foreach ($contentAreas as $contentArea) { - $content .= "<p>"; - $content .= $this->escaper->escapeHtml($contentArea['text']); - $content .= "</p>"; - if ($contentArea != $lastContentArea) { - $content .= "<br />"; - } - } - - return $content; - } - - /** - * Builds the HTML for the bullet list content in the notification ui component - * - * @param array $lists - * @return string - */ - private function buildLists(array $lists) - { - $content = "<ul>"; - - foreach ($lists as $listItem) { - $content .= "<li><span>"; - $content .= $this->escaper->escapeHtml($listItem['text']); - $content .= "</span></li>"; - } - - $content .= "</ul>"; - - return $content; - } - - /** - * Builds the HTML for the highlighted sub heads for the overview page in the notification ui component - * - * @param array $subHeadings - * @return string - */ - private function buildSubHeadings(array $subHeadings) - { - $content = ""; - - foreach ($subHeadings as $subHeading) { - if (!empty($subHeading['imageUrl'])) { - $content .= "<div class='highlight-item' style='background-image: url(\"" - . $this->escaper->escapeUrl($subHeading['imageUrl']) . "\")'>"; - } else { - $content .= "<div class='highlight-item-no-image'>"; - } - - $content .= "<h3>"; - $content .= $this->escaper->escapeHtml($subHeading['title']); - $content .= "</h3>"; - $content .= "<p>"; - $content .= $this->formatContentWithLinks($subHeading['content']); - $content .= "</p>"; - $content .= "</div>"; - } - - return $content; - } - - /** - * Builds the HTML for the footer content in the notification ui component - * - * @param array $footer - * @return string - */ - private function buildFooter(array $footer) - { - $content = "<p>"; - $content .= $this->escaper->escapeHtml($footer['content']); - $content .= "</p>"; - - return $this->formatContentWithLinks($content); - } - - /** - * Searches a given string for a URL, formats it to an HTML anchor tag, and returns the original string in the - * correct HTML format. - * - * @param string $content - * @return string - */ - private function formatContentWithLinks($content) - { - $urlRegex = '#\bhttps?://[^,\s()<>]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#'; - $urlTextRegex = '/\[(.*?)\]/'; - - preg_match_all($urlRegex, $content, $urlMatches); - preg_match_all($urlTextRegex, $content, $urlTextMatches); - - foreach ($urlMatches[0] as $key => $urlMatch) { - if (!empty($urlTextMatches[0])) { - $linkMatch = $urlMatch . " " . $urlTextMatches[0][$key]; - $content = str_replace( - $linkMatch, - "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> - {$this->escaper->escapeHtml($urlTextMatches[1][$key])}</a>", - $content - ); - } else { - $content = str_replace( - $urlMatch, - "<a target='_blank' href='{$this->escaper->escapeUrl($urlMatch)}'> - {$this->escaper->escapeUrl($urlMatch)}</a>", - $content - ); - } - } - - return $content; - } -} diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml index d640c6af4528..b9607ce77d15 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema.xml +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -7,24 +7,17 @@ --> <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> - <table name="admin_usage_viewer_log" resource="default" engine="innodb" + <table name="admin_analytics_usage_version_log" resource="default" engine="innodb" comment="Admin Notification Viewer Log Table"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Log ID"/> - <column xsi:type="int" name="viewer_id" padding="10" unsigned="true" nullable="false" identity="false" - comment="Viewer admin user ID"/> - <column xsi:type="varchar" name="last_view_version" nullable="false" length="16" - comment="Viewer last view on product version"/> - <column xsi:type="smallint" name="is_admin_usage_enabled" padding="5" unsigned="true" nullable="false" identity="false" - default="0" comment="Flag if admin usage is enabled"/> + <column xsi:type="varchar" name="last_viewed_in_version" nullable="false" length="50" + comment="Viewer last viewed on product version"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> - <constraint xsi:type="foreign" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID" - table="admin_notification_viewer_log" column="viewer_id" referenceTable="admin_user" - referenceColumn="user_id" onDelete="CASCADE"/> - <constraint xsi:type="unique" referenceId="ADMIN_NOTIFICATION_VIEWER_LOG_VIEWER_ID"> - <column name="viewer_id"/> + <constraint xsi:type="unique" referenceId="ADMIN_ANALYTICS_USAGE_VERSION_LOG_LAST_VIEWED_IN_VERSION"> + <column name="last_viewed_in_version"/> </constraint> </table> </schema> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 01fb68d4b58f..26cd4e9c6bcf 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -2,14 +2,11 @@ "admin_usage_viewer_log": { "column": { "id": true, - "viewer_id": true, - "last_view_version": true, - "is_admin_usage_enabled": true + "last_viewed_in_version": true }, "constraint": { "PRIMARY": true, - "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID_ADMIN_USER_USER_ID": true, - "ADMIN_USAGE_VIEWER_LOG_VIEWER_ID": true + "ADMIN_ANALYTICS_USAGE_VERSION_LOG_LAST_VIEWED_IN_VERSION": true } } } \ No newline at end of file From e436ae6e4956fb1c6546ccc91af05d61011ceb76 Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Sat, 27 Jul 2019 05:10:52 +0300 Subject: [PATCH 0220/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Added integration test --- .../Controller/Adminhtml/CategoryTest.php | 62 ++++++++++++++++--- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index 1001d58ee8a6..bfe02f2aa2e1 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -3,14 +3,20 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml; +use Magento\Backend\App\Area\FrontNameResolver; +use Magento\Catalog\Model\ResourceModel\Product; use Magento\Framework\App\Request\Http as HttpRequest; -use Magento\TestFramework\Helper\Bootstrap; +use Magento\Framework\Message\MessageInterface; use Magento\Store\Model\Store; -use Magento\Catalog\Model\ResourceModel\Product; +use Magento\TestFramework\Helper\Bootstrap; /** + * Test class for \Magento\Catalog\Controller\Adminhtml\Category. + * * @magentoAppArea adminhtml */ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractBackendController @@ -36,6 +42,8 @@ protected function setUp() } /** + * Test save action. + * * @magentoDataFixture Magento/Store/_files/core_fixturestore.php * @magentoDbIsolation enabled * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 @@ -48,7 +56,7 @@ protected function setUp() public function testSaveAction($inputData, $defaultAttributes, $attributesSaved = [], $isSuccess = true) { /** @var $store \Magento\Store\Model\Store */ - $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); + $store = Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); $store->load('fixturestore', 'code'); $storeId = $store->getId(); @@ -61,14 +69,12 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved if ($isSuccess) { $this->assertSessionMessages( $this->equalTo(['You saved the category.']), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } /** @var $category \Magento\Catalog\Model\Category */ - $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Category::class - ); + $category = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Category::class); $category->setStoreId($storeId); $category->load(2); @@ -95,6 +101,8 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved } /** + * Test save action from product creation page. + * * @param array $postData * @dataProvider categoryCreatedFromProductCreationPageDataProvider * @magentoDbIsolation enabled @@ -377,11 +385,13 @@ public function testSaveActionCategoryWithDangerRequest() $this->dispatch('backend/catalog/category/save'); $this->assertSessionMessages( $this->equalTo(['The "Name" attribute value is empty. Set the attribute and try again.']), - \Magento\Framework\Message\MessageInterface::TYPE_ERROR + MessageInterface::TYPE_ERROR ); } /** + * Test move action. + * * @magentoDataFixture Magento/Catalog/_files/category_tree.php * @dataProvider moveActionDataProvider * @@ -433,6 +443,8 @@ public function moveActionDataProvider() } /** + * Test save category with product position. + * * @magentoDataFixture Magento/Catalog/_files/products_in_different_stores.php * @magentoDbIsolation disabled * @dataProvider saveActionWithDifferentWebsitesDataProvider @@ -541,7 +553,7 @@ public function saveActionWithDifferentWebsitesDataProvider() } /** - * Get items count from catalog_category_product + * Get items count from catalog_category_product. * * @return int */ @@ -555,4 +567,36 @@ private function getCategoryProductsCount(): int $this->productResource->getConnection()->fetchAll($oldCategoryProducts) ); } + + /** + * Verify that the category cannot be saved if the category url matches the admin url. + * + * @magentoConfigFixture admin/url/use_custom_path 1 + * @magentoConfigFixture admin/url/custom_path backend + */ + public function testSaveWithCustomBackendNameAction() + { + $frontNameResolver = Bootstrap::getObjectManager()->create(FrontNameResolver::class); + $urlKey = $frontNameResolver->getFrontName(); + $inputData = [ + 'id' => '2', + 'url_key' => $urlKey, + 'use_config' => [ + 'available_sort_by' => 1, + 'default_sort_by' => 1 + ] + ]; + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->getRequest()->setPostValue($inputData); + $this->dispatch('backend/catalog/category/save'); + $this->assertSessionMessages( + $this->equalTo( + [ + 'URL key "backend" conflicts with reserved endpoint names: ' + . 'admin, soap, rest, graphql, backend. Try another url key.' + ] + ), + MessageInterface::TYPE_ERROR + ); + } } From e0a00fbeec82bc173844608b9f95b3b6d646ffa7 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Mon, 29 Jul 2019 09:33:44 +0300 Subject: [PATCH 0221/1172] MC-18699: Fixing integration test --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a95..3b7273e08810 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 234945755b8701b2ee9b651837701e5d14d6886c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 08:29:13 -0500 Subject: [PATCH 0222/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added block --- app/code/Magento/AdminAnalytics/Block/Metadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php index e89d09ab100e..2a669829a821 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -73,7 +73,7 @@ public function getCurrentUser() :string return hash('sha512', 'ADMIN_USER' . $this->authSession->getUser()->getEmail()); } /** - * Get Magento mode + * Get Magento mode that the user is using * * @return string */ From 3a7554b281103ac506e406bb8c1b9a1b53db2419 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 08:34:02 -0500 Subject: [PATCH 0223/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added routes,system,module --- app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml | 2 +- app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml | 2 +- app/code/Magento/AdminAnalytics/etc/module.xml | 1 + .../Magento/AdminAnalytics/view/adminhtml/layout/default.xml | 1 + .../AdminAnalytics/view/adminhtml/templates/tracking.phtml | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml index e1024b12bc42..5b5f2b52210b 100644 --- a/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/routes.xml @@ -11,4 +11,4 @@ <module name="Magento_AdminAnalytics" /> </route> </router> -</config> \ No newline at end of file +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml index 97372e1cca08..d6867e74c476 100644 --- a/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml +++ b/app/code/Magento/AdminAnalytics/etc/adminhtml/system.xml @@ -18,4 +18,4 @@ </group> </section> </system> -</config> \ No newline at end of file +</config> diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml index f0990b114e25..e27c90db11e2 100644 --- a/app/code/Magento/AdminAnalytics/etc/module.xml +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -8,3 +8,4 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magento_AdminAnalytics"/> </config> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 5339fbc894a4..62a9dda8b090 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -24,3 +24,4 @@ </body> </page> + diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml index e4acd77b1335..03c4c848aa44 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -12,4 +12,4 @@ "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", "mode": "<?= $block->escapeJs($block->getMode()) ?>" }; -</script> \ No newline at end of file +</script> From 7ade44e833f918a8f3429b25e0531dd95387f65f Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 29 Jul 2019 13:09:35 -0500 Subject: [PATCH 0224/1172] MC-18721: Customer Inline editor option error - Resolved incorrect template disabling - Updated template render logic during recursive render --- app/code/Magento/Ui/view/base/web/js/grid/editing/record.js | 5 ----- lib/web/mage/utils/template.js | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js index 14bed73a694c..9b8998368c5f 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/editing/record.js @@ -134,11 +134,6 @@ define([ field = utils.extend({}, fields.base, field); - field.__disableTmpl = { - label: true, - options: true - }; - return utils.template(field, { record: this, column: column diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 4032c9387904..08d6ea42306a 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -136,7 +136,9 @@ define([ cycles = 0; while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { - tmpl = template(tmpl, data); + if (!isTmplIgnored(tmpl, data)) { + tmpl = template(tmpl, data); + } if (tmpl === last) { break; From c2e3a90d7a4b3cb9ca7bdeb7dc4f36d1f537ad6e Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 29 Jul 2019 14:34:30 -0500 Subject: [PATCH 0225/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added test --- .../Section/AdminUsageNotificationSection.xml | 16 ++ .../Test/Mftf/Test/TrackingScriptTest.xml | 221 +++++++++--------- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 13 +- .../Config/Test/Mftf/Page/AdminConfigPage.xml | 3 + .../Test/Mftf/Page/ReportsSearchTermsPage.xml | 12 + 6 files changed, 150 insertions(+), 117 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml create mode 100644 app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml new file mode 100644 index 000000000000..0a28e5f19866 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminUsageNotificationSection"> + <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> + <element name="adminUsageAllowButton" type="text" selector="//*[@id='html-body']/div[4]/aside[2]/div[2]/footer/button[2]"/> +<!-- <element name="adminUsageDontAllowButton" type="text" selector="//*button[contains('Don't Allow')]"/>--> + </section> +</sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml index da0d5041a6e3..f2ed558ea883 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -21,117 +21,114 @@ </annotations> <!-- Logging in Magento admin and checking for tracking script in dashboard --> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <closeAdminNotification stepKey="closeAdminNotification"/> - - <!-- Navigating to advance settings --> - <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/> - <waitForPageLoad stepKey="waitForAdvanceSettings"/> - - <!-- Changing usage setting to Yes --> - <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes"> - <argument name="adminUsageValue" value="1"/> - </actionGroup> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/> - - <!-- Checking for tracking script in salesOrderPage --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/> - <waitForPageLoad stepKey="waitForSalesOrderPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/> - - <!-- Checking for tracking script in catalogProductsPage --> - <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/> - <waitForPageLoad stepKey="waitForCatalogProductsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/> - - <!-- Checking for tracking script in customersAllCustomersPage --> - <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/> - <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/> - - <!-- Checking for tracking script in marketingCatalogPriceRulePage --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/> - <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/> - - <!-- Checking for tracking script in contentBlocksPage --> - <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/> - <waitForPageLoad stepKey="waitForContentBlocksPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/> - - <!-- Checking for tracking script in reportsSearchTermsPage --> - <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/> - <waitForPageLoad stepKey="waitForSearchTermsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/> - - <!-- Checking for tracking script in storesAllStoresPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/> - <waitForPageLoad stepKey="waitForStoresAllStoresPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/> - - <!-- Checking for tracking script in systemImportPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/> - <waitForPageLoad stepKey="waitForSystemImportPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/> - - <!-- Checking for tracking script in findPartnersAndExtensionsPage --> - <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPage"/> - <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPage"/> - <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlFindPartnersAndExtensions"/> - - <!-- Navigating to advance settings --> - <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/> - <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/> - - <!-- Changing usage setting back to No --> - <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo"> - <argument name="adminUsageValue" value="0"/> - </actionGroup> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/> - - <!-- Checking for removed tracking script in salesOrderPage --> - <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/> - <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/> - - <!-- Checking for removed tracking script in catalogProductsPage --> - <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/> - <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/> - - <!-- Checking for removed tracking script in customersAllCustomersPage --> - <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/> - <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/> - - <!-- Checking for removed tracking script in marketingCatalogPriceRulePage --> - <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/> - <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/> - - <!-- Checking for removed tracking script in contentBlocksPage --> - <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/> - <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/> - - <!-- Checking for removed tracking script in reportsSearchTermsPage --> - <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/> - <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/> - - <!-- Checking for removed tracking script in storesAllStoresPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/> - <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/> - - <!-- Checking for removed tracking script in systemImportPage --> - <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/> - <waitForPageLoad stepKey="waitForSystemImportPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/> - - <!-- Checking for removed tracking script in findPartnersAndExtensionsPage --> - <amOnPage url="{{FindPartnersAndExtensionsPage.url}}" stepKey="goToFindPartnersAndExtensionsPageAgain"/> - <waitForPageLoad stepKey="waitForFindPartnersAndExtensionsPageAgain"/> - <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlFindPartnersTest"/> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + + <wait time="10" stepKey="waitTenSecondsAgainAgain"/> + + <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/> + <wait time="10" stepKey="waitTenSecondsAgain"/> + <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" stepKey="seeAllowButton"/> +<!-- <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/>--> + <wait time="10" stepKey="waitTenSeconds"/> + +<!-- <!– Navigating to advance settings –>--> +<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/>--> +<!-- <waitForPageLoad stepKey="waitForAdvanceSettings"/>--> + +<!-- <!– Changing usage setting to Yes –>--> +<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes">--> +<!-- <argument name="adminUsageValue" value="1"/>--> +<!-- </actionGroup>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/>--> + +<!-- <!– Checking for tracking script in salesOrderPage –>--> +<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSalesOrderPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/>--> + +<!-- <!– Checking for tracking script in catalogProductsPage –>--> +<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/>--> +<!-- <waitForPageLoad stepKey="waitForCatalogProductsPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/>--> + +<!-- <!– Checking for tracking script in customersAllCustomersPage –>--> +<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/>--> +<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/>--> + +<!-- <!– Checking for tracking script in marketingCatalogPriceRulePage –>--> +<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/>--> +<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/>--> + +<!-- <!– Checking for tracking script in contentBlocksPage –>--> +<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/>--> +<!-- <waitForPageLoad stepKey="waitForContentBlocksPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/>--> + +<!-- <!– Checking for tracking script in reportsSearchTermsPage –>--> +<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSearchTermsPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/>--> + +<!-- <!– Checking for tracking script in storesAllStoresPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/>--> +<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/>--> + +<!-- <!– Checking for tracking script in systemImportPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/>--> +<!-- <waitForPageLoad stepKey="waitForSystemImportPage"/>--> +<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/>--> + +<!-- <!– Navigating to advance settings –>--> +<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/>--> + +<!-- <!– Changing usage setting back to No –>--> +<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo">--> +<!-- <argument name="adminUsageValue" value="0"/>--> +<!-- </actionGroup>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/>--> + +<!-- <!– Checking for removed tracking script in salesOrderPage –>--> +<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/>--> + +<!-- <!– Checking for removed tracking script in catalogProductsPage –>--> +<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/>--> + +<!-- <!– Checking for removed tracking script in customersAllCustomersPage –>--> +<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/>--> + +<!-- <!– Checking for removed tracking script in marketingCatalogPriceRulePage –>--> +<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/>--> + +<!-- <!– Checking for removed tracking script in contentBlocksPage –>--> +<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/>--> + +<!-- <!– Checking for removed tracking script in reportsSearchTermsPage –>--> +<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/>--> + +<!-- <!– Checking for removed tracking script in storesAllStoresPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/>--> + +<!-- <!– Checking for removed tracking script in systemImportPage –>--> +<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/>--> +<!-- <waitForPageLoad stepKey="waitForSystemImportPageAgain"/>--> +<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/>--> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index f9d11d2a6a7f..7c6d1d43006d 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -50,7 +50,7 @@ <options> <option name="modalClass" xsi:type="string">admin-usage-notification</option> <option name="title" xsi:type="string" translate="true">Allow admin usage data collection</option> - <option name="autoOpen" xsi:type="array">true</option> + <option name="autoOpen" xsi:type="boolean">true</option> <option name="type" xsi:type="string">popup</option> <option name="clickableOverlay" xsi:type="boolean">false</option> <option name="responsive" xsi:type="boolean">true</option> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 6c449e45f7aa..2cf9df87196f 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -17,13 +17,18 @@ define( imports: { enableLogAction: '${ $.provider }:data.enableLogAction', disableLogAction: '${ $.provider }:data.disableLogAction' + }, + options: { + keyEventHandlers: { + escapeKey: function () { return; } + } } }, - keyEventHandlers: { - escapeKey: function () { - } + initModal: function () { + this.options.opened = this.onOpened.bind(this); + this._super(); }, - opened: function () { + onOpened: function () { $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { diff --git a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml index 7a62dfff8323..688623b612c2 100644 --- a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml +++ b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml @@ -21,4 +21,7 @@ <page name="AdminConfigGeneralPage" url="admin/system_config/edit/section/general/" area="admin" module="Magento_Config"> <section name="GeneralSection"/> </page> + <page name="AdminConfigAdvancedAdmin" url="admin/system_config/edit/section/admin/" area="admin" module="Magento_Config"> + <section name="AdvanceAdminSection"/> + </page> </pages> diff --git a/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml b/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml new file mode 100644 index 000000000000..e9e60c6d6dcc --- /dev/null +++ b/app/code/Magento/Reports/Test/Mftf/Page/ReportsSearchTermsPage.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="ReportsSearchTermPage" url="search/term/report/" area="admin" module="Magento_Reports"> + <section name="ReportsSearchTermSection"/> + </page> +</pages> From 6ce7e16641a225a22ac0e1e78a0e34b232f08b6d Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 29 Jul 2019 14:49:23 -0500 Subject: [PATCH 0226/1172] MC-15978: Catalog Product Attribute Set Name --- .../Ui/DataProvider/Product/Form/Modifier/AttributeSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 3420965597c5..474b13981026 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -78,7 +78,7 @@ public function getOptions() \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::SORT_ORDER_ASC ); - $collectionData = $collection->getData(); + $collectionData = $collection->getData() ?? []; array_walk($collectionData, function (&$attribute) { $attribute['__disableTmpl'] = true; From 60bee1108ee49ae6317f0ef4f5a150523949e8a8 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Mon, 29 Jul 2019 14:53:38 -0500 Subject: [PATCH 0227/1172] MC-15978: Catalog Product Attribute Set Name --- .../testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php index 59ad82334a95..3b7273e08810 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php @@ -736,7 +736,7 @@ public function testValidateUploadFileExceptionDataProvider() ], 'image_empty' => [ 'fileName' => 'empty.png', - 'expectedErrorMsg' => 'Disallowed file type.', + 'expectedErrorMsg' => 'Wrong file size.', 'useFixture' => true ], 'notanimage' => [ From 615da2c895f97e07e311f4e2c277641ac9d2d3ca Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Mon, 29 Jul 2019 15:59:20 -0500 Subject: [PATCH 0228/1172] MC-18125: Email template improvement --- lib/internal/Magento/Framework/Filter/Template.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php index c330e4d13009..0cd2935a24b1 100644 --- a/lib/internal/Magento/Framework/Filter/Template.php +++ b/lib/internal/Magento/Framework/Filter/Template.php @@ -82,16 +82,16 @@ class Template implements \Zend_Filter_Interface 'getdatausingmethod', '__destruct', '__call', - '__callStatic', + '__callstatic', '__set', '__unset', '__sleep', '__wakeup', '__invoke', '__set_state', - '__debugInfo', - '___callParent', - '___callPlugins' + '__debuginfo', + '___callparent', + '___callplugins' ]; /** From febabea0d40b52d53553ac98b68b8a300e8195f8 Mon Sep 17 00:00:00 2001 From: Hwashiang Yu <hwyu@adobe.com> Date: Mon, 29 Jul 2019 18:39:55 -0500 Subject: [PATCH 0229/1172] MC-18721: Customer Inline editor option error - Resolved funtional test failures --- lib/web/mage/utils/template.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/mage/utils/template.js b/lib/web/mage/utils/template.js index 08d6ea42306a..e954ca50bac8 100644 --- a/lib/web/mage/utils/template.js +++ b/lib/web/mage/utils/template.js @@ -40,7 +40,7 @@ define([ * To limit recursion for a specific property add __disableTmpl: {propertyName: numberOfCycles}. * * @param {String} tmpl - * @param {Object} target + * @param {Object | undefined} target * @returns {Boolean|Object} */ function isTmplIgnored(tmpl, target) { @@ -136,7 +136,7 @@ define([ cycles = 0; while (~tmpl.indexOf(opener) && (typeof maxCycles === 'undefined' || cycles < maxCycles)) { - if (!isTmplIgnored(tmpl, data)) { + if (!isTmplIgnored(tmpl)) { tmpl = template(tmpl, data); } From 264e7c6b7b4f045857c3a8364840034a115d9a85 Mon Sep 17 00:00:00 2001 From: Ani Tumanyan <ani_tumanyan@epam.com> Date: Tue, 30 Jul 2019 14:42:55 +0400 Subject: [PATCH 0230/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Updated automated test script --- .../Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml | 2 +- .../Checkout/Test/Mftf/Section/CheckoutShippingSection.xml | 2 +- .../Test/Mftf/Section/SelectShippingAddressPopupSection.xml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index e8119798bea4..0ebe78e44e7a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -60,6 +60,6 @@ <element name="billingAddressSelectShared" type="select" selector=".checkout-billing-address select[name='billing_address_id']"/> <element name="discount" type="block" selector="tr.totals.discount"/> <element name="discountPrice" type="text" selector=".discount .price"/> - <element name="changeAddressButton" type="button" selector="(//button[@class='action action-additional'][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> + <element name="changeAddressButton" type="button" selector="(//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 90df0c3475c4..6c2615083292 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -44,6 +44,6 @@ <element name="addressFieldValidationError" type="text" selector="div.address div.field .field-error"/> <element name="textFieldAttrRequireMessage" type="text" selector="//input[@name='custom_attributes[{{attribute}}]']/ancestor::div[contains(@class, 'control')]/div/span" parameterized="true" timeout="30"/> <element name="textFieldAttribute" type="input" selector="[name*='custom_attributes[{{attribute}}]']" parameterized="true" timeout="30"/> - <element name="changeAddressButton" type="button" selector="//button[@class='action action-additional'][contains(@data-bind,'openAddressSelection')]"/> + <element name="changeAddressButton" type="button" selector="//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')]"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml index ff1431ab33ba..965ee4f4b10d 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml @@ -9,8 +9,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="SelectBillingAddressPopupSection"> - <element name="shippingAddressSearch" type="input" selector="//input[@class='admin__control-text admin__action-multiselect-search']"/> - <element name="selectButton" type="button" selector="//button[@class='action-primary action-select-billing-item']"/> - <element name="shippingAddressSearchParametrised" type="input" selector="(//input[@class='admin__control-text admin__action-multiselect-search'])[{{index}}]" parameterized="true"/> + <element name="shippingAddressSearch" type="input" selector="//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')]"/> + <element name="selectButton" type="button" selector="//button[contains(@class,'action-primary') and contains(@class, 'action-select-billing-item')]"/> + <element name="shippingAddressSearchParametrised" type="input" selector="(//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')])[{{index}}]" parameterized="true"/> </section> </sections> From 525ddef7eb4d0fa849c6111f47bf4eace338b8cf Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Tue, 30 Jul 2019 09:07:53 -0500 Subject: [PATCH 0231/1172] MC-15978: Catalog Product Attribute Set Name --- .../Product/Form/Modifier/AttributeSet.php | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php index 474b13981026..53c9595b59e7 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AttributeSet.php @@ -80,15 +80,18 @@ public function getOptions() $collectionData = $collection->getData() ?? []; - array_walk($collectionData, function (&$attribute) { - $attribute['__disableTmpl'] = true; - }); + array_walk( + $collectionData, + function (&$attribute) { + $attribute['__disableTmpl'] = true; + } + ); return $collectionData; } /** - * {@inheritdoc} + * @inheritdoc * @since 101.0.0 */ public function modifyMeta(array $meta) @@ -122,17 +125,20 @@ public function modifyMeta(array $meta) } /** - * {@inheritdoc} + * @inheritdoc * @since 101.0.0 */ public function modifyData(array $data) { - return array_replace_recursive($data, [ - $this->locator->getProduct()->getId() => [ - self::DATA_SOURCE_DEFAULT => [ - 'attribute_set_id' => $this->locator->getProduct()->getAttributeSetId() - ], + return array_replace_recursive( + $data, + [ + $this->locator->getProduct()->getId() => [ + self::DATA_SOURCE_DEFAULT => [ + 'attribute_set_id' => $this->locator->getProduct()->getAttributeSetId() + ], + ] ] - ]); + ); } } From cf29d0de077caae296bfc6151aecd4a9fd082d5a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 30 Jul 2019 11:38:38 -0500 Subject: [PATCH 0232/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added conditionalClick to action groups --- .../CloseAllDialogBoxesActionGroup.xml | 20 ++++ .../Section/AdminUsageNotificationSection.xml | 9 +- .../Test/Mftf/Test/TrackingScriptTest.xml | 112 +----------------- .../LoginAdminWithCredentialsActionGroup.xml | 1 + .../ActionGroup/LoginAsAdminActionGroup.xml | 1 + 5 files changed, 31 insertions(+), 112 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml new file mode 100644 index 000000000000..4fd7fd17c57e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="CloseAllDialogBoxes"> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml index 0a28e5f19866..388214df275a 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -10,7 +10,12 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageNotificationSection"> <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> - <element name="adminUsageAllowButton" type="text" selector="//*[@id='html-body']/div[4]/aside[2]/div[2]/footer/button[2]"/> -<!-- <element name="adminUsageDontAllowButton" type="text" selector="//*button[contains('Don't Allow')]"/>--> + <element name="adminUsageAllowButton" type="text" selector=".modal-popup .action-secondary"/> + <element name="releaseNotificationCloseButton1" type="text" selector="//aside[1]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton2" type="text" selector="//aside[2]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton3" type="text" selector="//aside[3]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton4" type="text" selector="//aside[4]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton5" type="text" selector="//aside[5]/div[2]/header/button"/> + <element name="releaseNotificationCloseButton6" type="text" selector="//aside[6]/div[2]/header/button"/> </section> </sections> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml index f2ed558ea883..58bcacc190cf 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Test/TrackingScriptTest.xml @@ -20,115 +20,7 @@ <group value="login"/> </annotations> - <!-- Logging in Magento admin and checking for tracking script in dashboard --> - <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> - - <wait time="10" stepKey="waitTenSecondsAgainAgain"/> - - <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/> - <wait time="10" stepKey="waitTenSecondsAgain"/> - <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" stepKey="seeAllowButton"/> -<!-- <seeElementInDOM selector="{{AdminUsageNotificationSection.adminUsageDialogBox}}" stepKey="seeDialogBox"/>--> - <wait time="10" stepKey="waitTenSeconds"/> - -<!-- <!– Navigating to advance settings –>--> -<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettings"/>--> -<!-- <waitForPageLoad stepKey="waitForAdvanceSettings"/>--> - -<!-- <!– Changing usage setting to Yes –>--> -<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToYes">--> -<!-- <argument name="adminUsageValue" value="1"/>--> -<!-- </actionGroup>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrl"/>--> - -<!-- <!– Checking for tracking script in salesOrderPage –>--> -<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSalesOrderPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSalesOrder"/>--> - -<!-- <!– Checking for tracking script in catalogProductsPage –>--> -<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPage"/>--> -<!-- <waitForPageLoad stepKey="waitForCatalogProductsPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCatalogProducts"/>--> - -<!-- <!– Checking for tracking script in customersAllCustomersPage –>--> -<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPage"/>--> -<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlCustomersAllCustomers"/>--> - -<!-- <!– Checking for tracking script in marketingCatalogPriceRulePage –>--> -<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePage"/>--> -<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlMarketingCatalogPriceRule"/>--> - -<!-- <!– Checking for tracking script in contentBlocksPage –>--> -<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPage"/>--> -<!-- <waitForPageLoad stepKey="waitForContentBlocksPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlContentBlocks"/>--> - -<!-- <!– Checking for tracking script in reportsSearchTermsPage –>--> -<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSearchTermsPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlReportsSearchTerms"/>--> - -<!-- <!– Checking for tracking script in storesAllStoresPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPage"/>--> -<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlStoresAllStores"/>--> - -<!-- <!– Checking for tracking script in systemImportPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPage"/>--> -<!-- <waitForPageLoad stepKey="waitForSystemImportPage"/>--> -<!-- <seeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="seeTrackingUrlSystemImport"/>--> - -<!-- <!– Navigating to advance settings –>--> -<!-- <amOnPage url="{{AdminConfigAdvancedAdmin.url}}" stepKey="goToAdminSettingsAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForAdvanceSettingsAgain"/>--> - -<!-- <!– Changing usage setting back to No –>--> -<!-- <actionGroup ref="SelectAdminUsageSetting" stepKey="changeAdminUsageSettingToNo">--> -<!-- <argument name="adminUsageValue" value="0"/>--> -<!-- </actionGroup>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlTest"/>--> - -<!-- <!– Checking for removed tracking script in salesOrderPage –>--> -<!-- <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToSalesOrderPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSalesOrderPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSalesOrderTest"/>--> - -<!-- <!– Checking for removed tracking script in catalogProductsPage –>--> -<!-- <amOnPage url="{{ProductCatalogPage.url}}" stepKey="goToCatalogProductsPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForCatalogProductsPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCatalogProductsTest"/>--> - -<!-- <!– Checking for removed tracking script in customersAllCustomersPage –>--> -<!-- <amOnPage url="{{AdminCustomerPage.url}}" stepKey="goToCustomersAllCustomersPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForCustomersAllCustomersPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlCustomersAllCustomersTest"/>--> - -<!-- <!– Checking for removed tracking script in marketingCatalogPriceRulePage –>--> -<!-- <amOnPage url="{{CatalogRulePage.url}}" stepKey="goToMarketingCatalogPriceRulePageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForMarketingCatalogPriceRulePageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlMarketingCatalogTest"/>--> - -<!-- <!– Checking for removed tracking script in contentBlocksPage –>--> -<!-- <amOnPage url="{{CmsBlocksPage.url}}" stepKey="goToContentBlocksPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForContentBlocksPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlContentBlocksTest"/>--> - -<!-- <!– Checking for removed tracking script in reportsSearchTermsPage –>--> -<!-- <amOnPage url="{{ReportsSearchTermPage.url}}" stepKey="goToReportsSearchTermsPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSearchTermsPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlReportsSearchTest"/>--> - -<!-- <!– Checking for removed tracking script in storesAllStoresPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToStoresAllStoresPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForStoresAllStoresPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlStoresAllStoresTest"/>--> - -<!-- <!– Checking for removed tracking script in systemImportPage –>--> -<!-- <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="goToSystemImportPageAgain"/>--> -<!-- <waitForPageLoad stepKey="waitForSystemImportPageAgain"/>--> -<!-- <dontSeeElementInDOM selector="{{AdminHeaderSection.adminTrackingScript}}" stepKey="dontSeeTrackingUrlSystemsImportTest"/>--> + <!-- Logging in Magento admin --> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index 6aaa612b249b..b5510404c963 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -16,6 +16,7 @@ <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/> <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml index b2fbadcbe38e..9c1963119d38 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -16,6 +16,7 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser.username}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminUser.password}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> From e9394a35e9bf9ed0871563d85592a803e6ca516c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 30 Jul 2019 12:57:46 -0500 Subject: [PATCH 0233/1172] MC-15298: Allow admin to opt out of admin analytics tracking - fixed conditionalClick --- .../Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index b5510404c963..e423c68dd938 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -16,8 +16,8 @@ <amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/> <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> From 04a9f107c0aa55d100001efdaa0d22cba79c3755 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 26 Jul 2019 11:11:25 -0500 Subject: [PATCH 0234/1172] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update to show all products regardless of status --- app/code/Magento/Catalog/Model/ProductLink/Search.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 8750345aa222..2ad838fc6c01 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -58,7 +58,6 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); - $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); From fa4844dfd36b14fd9a3f5f6f00209522bbf79c31 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 26 Jul 2019 14:17:43 -0500 Subject: [PATCH 0235/1172] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Magento/Catalog/Model/ProductLink/Search.php | 4 +++- .../Controller/Adminhtml/Product/SearchTest.php | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 2ad838fc6c01..ad7f3370ab3f 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -10,7 +10,9 @@ use Magento\Catalog\Api\Data\ProductInterface; -/** Returns collection of product visible in catalog by search key */ +/** + * Returns collection of product visible in catalog by search key + */ class Search { /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 8a33543e9343..cdc2b4ca55e6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -57,6 +57,20 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $this->assertContains('"total":1}', $responseBody); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php + */ + public function testExecuteEnabledAndDisabledProducts() : void + { + $this->getRequest() + ->setPostValue('searchKey', 'simple') + ->setPostValue('page', 1) + ->setPostValue('limit', 50); + $this->dispatch('backend/catalog/product/search'); + $responseBody = $this->getResponse()->getBody(); + $this->assertContains('"total":3}', $responseBody); } } From f641a988ae56f463fbac39dd56a19feaaf325606 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 11:57:05 -0500 Subject: [PATCH 0236/1172] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index cdc2b4ca55e6..ee9ed5f65608 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,8 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEmpty($jsonResponse['options']); } /** @@ -57,7 +58,8 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('"total":1}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEquals(1, $jsonResponse['total']); } /** @@ -71,6 +73,7 @@ public function testExecuteEnabledAndDisabledProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('"total":3}', $responseBody); + $jsonResponse = json_decode($responseBody); + $this->assertEquals(7, $jsonResponse['total']); } } From cf9e61f56998189c9cc6eccd5fbf95c60dfe1ce8 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 13:36:35 -0500 Subject: [PATCH 0237/1172] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index ee9ed5f65608..875c7f87d600 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -60,6 +60,7 @@ public function testExecuteNotVisibleIndividuallyProducts() : void $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody); $this->assertEquals(1, $jsonResponse['total']); + $this->assertCount(1, $jsonResponse['options']); } /** @@ -75,5 +76,6 @@ public function testExecuteEnabledAndDisabledProducts() : void $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody); $this->assertEquals(7, $jsonResponse['total']); + $this->assertCount(7, $jsonResponse['options']); } } From 9c4c61dac3b04e3819b3d4c4fff41ea6836b412c Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Mon, 29 Jul 2019 15:50:23 -0500 Subject: [PATCH 0238/1172] MC-18009: Disabled Products Do Not Appear in Search Results of Link Attribute - update tests --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 875c7f87d600..0704d59a1431 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,7 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEmpty($jsonResponse['options']); } @@ -58,7 +58,7 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEquals(1, $jsonResponse['total']); $this->assertCount(1, $jsonResponse['options']); } @@ -74,7 +74,7 @@ public function testExecuteEnabledAndDisabledProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody); + $jsonResponse = json_decode($responseBody, true); $this->assertEquals(7, $jsonResponse['total']); $this->assertCount(7, $jsonResponse['options']); } From 564f4411775cc0495a8dd8bffc6a110989c75b7d Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 31 Jul 2019 10:34:53 +0300 Subject: [PATCH 0239/1172] MC-17878: Fix delete attribute behavior --- .../Model/ResourceModel/Entity/Attribute.php | 21 ++++++++++- .../Api/ProductAttributeRepositoryTest.php | 20 +++++++++- .../Indexer/Product/Flat/ProcessorTest.php | 25 +++++++------ .../Filter/_files/attribute_with_option.php | 1 + .../Model/ResourceModel/Eav/AttributeTest.php | 10 ++++- .../Catalog/_files/category_attribute.php | 3 +- .../Catalog/_files/product_attribute.php | 3 +- .../_files/product_system_attribute.php | 16 ++++++++ .../product_system_attribute_rollback.php | 37 +++++++++++++++++++ .../Search/_files/date_attribute.php | 1 + .../Search/_files/filterable_attribute.php | 2 + .../Search/_files/filterable_attributes.php | 1 + .../Swatches/_files/swatch_attribute.php | 1 + 13 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php index 0e7a46125d87..364e4d31d4d1 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php @@ -11,7 +11,9 @@ use Magento\Eav\Model\Entity\Attribute as EntityAttribute; use Magento\Framework\App\ObjectManager; use Magento\Framework\DB\Select; +use Magento\Framework\Exception\CouldNotDeleteException; use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; /** * EAV attribute resource model @@ -20,7 +22,7 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ -class Attribute extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb +class Attribute extends AbstractDb { /** * Eav Entity attributes cache @@ -189,6 +191,23 @@ protected function _beforeSave(AbstractModel $object) return parent::_beforeSave($object); } + /** + * @inheritdoc + * + * @param AbstractModel $attribute + * @return AbstractDb + * @throws CouldNotDeleteException + */ + protected function _beforeDelete(AbstractModel $attribute) + { + /** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ + if ($attribute->getId() && !$attribute->getIsUserDefined()) { + throw new CouldNotDeleteException(__("The system attribute can't be deleted.")); + } + + return parent::_beforeDelete($attribute); + } + /** * Save additional attribute data after save attribute * diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php index 386bd9fc9aee..42aa92652a5f 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php @@ -4,12 +4,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Catalog\Api; use Magento\Framework\Webapi\Exception as HTTPExceptionCodes; -use Magento\TestFramework\Helper\Bootstrap; +/** + * API tests for \Magento\Catalog\Model\Product\Attribute\Repository. + */ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract { const SERVICE_NAME = 'catalogProductAttributeRepositoryV1'; @@ -130,6 +131,7 @@ public function testCreateWithExceptionIfAttributeAlreadyExists() try { $this->createAttribute($attributeCode); $this->fail("Expected exception"); + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\SoapFault $e) { //Expects soap exception } catch (\Exception $e) { @@ -320,6 +322,20 @@ public function testDeleteById() $this->assertTrue($this->deleteAttribute($attributeCode)); } + /** + * Trying to delete system attribute. + * + * @magentoApiDataFixture Magento/Catalog/_files/product_system_attribute.php + * @expectedException \Exception + * @expectedExceptionMessage The system attribute can't be deleted. + * @return void + */ + public function testDeleteSystemAttributeById(): void + { + $attributeCode = 'test_attribute_code_333'; + $this->deleteAttribute($attributeCode); + } + /** * @return void */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php index bbaf45393870..9ae9cc6b6629 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Flat/ProcessorTest.php @@ -5,8 +5,10 @@ */ namespace Magento\Catalog\Model\Indexer\Product\Flat; +use Magento\Catalog\Model\Product\Attribute\Repository; + /** - * Class FullTest + * Integration tests for \Magento\Catalog\Model\Indexer\Product\Flat\Processor. */ class ProcessorTest extends \Magento\TestFramework\Indexer\TestCase { @@ -64,22 +66,23 @@ public function testSaveAttribute() } /** - * @magentoDbIsolation enabled + * @magentoDbIsolation disabled * @magentoAppIsolation enabled * @magentoAppArea adminhtml - * @magentoDataFixture Magento/Catalog/_files/multiple_products.php + * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_attribute_in_flat.php * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 */ public function testDeleteAttribute() { - /** @var $product \Magento\Catalog\Model\Product */ - $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Product::class - ); - - /** @var \Magento\Catalog\Model\ResourceModel\Product $productResource */ - $productResource = $product->getResource(); - $productResource->getAttribute('media_gallery')->delete(); + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $model */ + $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); + /** @var Repository $productAttributeRepository */ + $productAttributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(Repository::class); + $productAttrubute = $productAttributeRepository->get('flat_attribute'); + $productAttributeId = $productAttrubute->getAttributeId(); + $model->load($productAttributeId)->delete(); $this->assertTrue($this->_processor->getIndexer()->isInvalid()); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php index 833d1b114a0b..b4431678b201 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php @@ -20,6 +20,7 @@ 'is_global' => 1, 'frontend_input' => 'select', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => ['value' => ['option_0' => [0 => 'Option Label']]], 'backend_type' => 'int', ] diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php index 349853c8a393..498c3167ed73 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Eav/AttributeTest.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model\ResourceModel\Eav; +/** + * Test for \Magento\Catalog\Model\ResourceModel\Eav\Attribute. + */ class AttributeTest extends \PHPUnit\Framework\TestCase { /** @@ -19,6 +22,11 @@ protected function setUp() ); } + /** + * Test Create -> Read -> Update -> Delete attribute operations. + * + * @return void + */ public function testCRUD() { $this->_model->setAttributeCode( @@ -31,7 +39,7 @@ public function testCRUD() )->getId() )->setFrontendLabel( 'test' - ); + )->setIsUserDefined(1); $crud = new \Magento\TestFramework\Entity($this->_model, ['frontend_label' => uniqid()]); $crud->testCrud(); } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php index 37398abdb8f7..29b4a05c4dcb 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/category_attribute.php @@ -9,5 +9,6 @@ ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); $attribute->setAttributeCode('test_attribute_code_666') ->setEntityTypeId(3) - ->setIsGlobal(1); + ->setIsGlobal(1) + ->setIsUserDefined(1); $attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php index b5187d5d8076..b59675c5a28a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_attribute.php @@ -10,5 +10,6 @@ $attribute->setAttributeCode('test_attribute_code_333') ->setEntityTypeId(4) ->setIsGlobal(1) - ->setPrice(95); + ->setPrice(95) + ->setIsUserDefined(1); $attribute->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php new file mode 100644 index 000000000000..1e7429cc831f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute.php @@ -0,0 +1,16 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +// phpcs:ignore Magento2.Security.IncludeFile +require __DIR__ . '/product_attribute.php'; +/** @var $attributeRepository \Magento\Catalog\Model\Product\Attribute\Repository */ +$attributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Attribute\Repository::class); +/** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ +$attribute = $attributeRepository->get('test_attribute_code_333'); + +$attributeRepository->save($attribute->setIsUserDefined(0)); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php new file mode 100644 index 000000000000..0f997ff4b494 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_system_attribute_rollback.php @@ -0,0 +1,37 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Exception\NoSuchEntityException; + +/** @var $attributeRepository \Magento\Catalog\Model\Product\Attribute\Repository */ +$attributeRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get(\Magento\Catalog\Model\Product\Attribute\Repository::class); + +try { + /** @var $attribute \Magento\Eav\Api\Data\AttributeInterface */ + $attribute = $attributeRepository->get('test_attribute_code_333'); + $attributeRepository->save($attribute->setIsUserDefined(1)); + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch +} catch (NoSuchEntityException $e) { +} +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +try { + $attribute = $attributeRepository->get('test_attribute_code_333'); + if ($attribute->getId()) { + $attribute->delete(); + } + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch +} catch (\Exception $e) { +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php index c7e118f4a4e2..d11248a47a0c 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/date_attribute.php @@ -25,6 +25,7 @@ 'entity_type_id' => $installer->getEntityTypeId('catalog_product'), 'is_global' => 1, 'is_filterable' => 1, + 'is_user_defined' => 1, 'backend_type' => 'datetime', 'frontend_input' => 'date', 'frontend_label' => 'Test Date', diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php index 9188bb965763..a74669e9890a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attribute.php @@ -21,6 +21,7 @@ 'is_global' => 1, 'frontend_input' => 'select', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => [ 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], 'order' => ['option_0' => 1, 'option_1' => 2], @@ -48,6 +49,7 @@ 'is_global' => 1, 'frontend_input' => 'multiselect', 'is_filterable' => 1, + 'is_user_defined' => 1, 'option' => [ 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], 'order' => ['option_0' => 1, 'option_1' => 2], diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php index f4f3337a253c..03269b88ee2a 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Search/_files/filterable_attributes.php @@ -78,6 +78,7 @@ 'entity_type_id' => $productEntityTypeId, 'is_global' => 1, 'is_filterable' => 1, + 'is_user_defined' => 1, 'backend_type' => 'datetime', 'frontend_input' => 'date', 'frontend_label' => 'Test Date', diff --git a/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php b/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php index 182f4781a963..202fd0a8c73d 100644 --- a/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Swatches/_files/swatch_attribute.php @@ -16,6 +16,7 @@ 'backend_type' => '', 'is_searchable' => 0, 'is_filterable' => 0, + 'is_user_defined' => 1, 'is_filterable_in_search' => 0, 'frontend_label' => 'Attribute ', 'entity_type_id' => 4 From 98f99ae4cec56ab6b567c7430a15e5f78c52af85 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 31 Jul 2019 16:09:19 +0300 Subject: [PATCH 0240/1172] MC-18750: Failed function test Magento\FunctionalTestingFramework.functional.StorefrontUKCustomerCheckoutWithCouponTest --- .../Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml index ebf24e710fe3..13928dd91ec7 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml @@ -18,6 +18,7 @@ </annotations> <before> + <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"> <field key="price">20.00</field> @@ -38,6 +39,7 @@ </createData> </before> <after> + <magentoCLI command="downloadable:domains:remove" arguments="example.com static.magento.com" stepKey="removeDownloadableDomain"/> <deleteData createDataKey="createDownloadableProduct" stepKey="deleteProduct"/> <deleteData createDataKey="virtualProduct" stepKey="deleteVirtualProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> @@ -127,4 +129,4 @@ <see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$15.00" stepKey="seeGrandTotal"/> <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Pending" stepKey="seeOrderStatus"/> </test> -</tests> \ No newline at end of file +</tests> From 3f0cac5163284b87c00b80f1cc69db1b74180724 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 08:21:33 -0500 Subject: [PATCH 0241/1172] MC-15298: Allow admin to opt out of admin analytics tracking - --- .../Adminhtml/Config/DisableAdminUsage.php | 10 +--------- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 12 +----------- .../ActionGroup/CloseAllDialogBoxesActionGroup.xml | 8 +------- .../Mftf/Section/AdminUsageNotificationSection.xml | 8 +------- .../AdminAnalytics/etc/db_schema_whitelist.json | 2 +- .../view/adminhtml/web/js/modal/component.js | 4 +++- 6 files changed, 8 insertions(+), 36 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eb31e54e8041..73635ddfee31 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Log information about the last shown advertisement + * Changes the admin usage to no, and marks user notified * * @return ResultInterface */ @@ -97,12 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9ce119f0c424..e2ecb700e2b4 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Log information about the last shown advertisement + * Changes the admin usage to yes, and marks user notified * * @return \Magento\Framework\Controller\ResultInterface */ @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * IsAllow allows function to be visible - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml index 4fd7fd17c57e..71c039773f6b 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -9,12 +9,6 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="CloseAllDialogBoxes"> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> - <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml index 388214df275a..8bd6263d35e3 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageNotificationSection.xml @@ -10,12 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageNotificationSection"> <element name="adminUsageDialogBox" type="text" selector="//*[@class='modal-inner-wrap'][last()]"/> - <element name="adminUsageAllowButton" type="text" selector=".modal-popup .action-secondary"/> - <element name="releaseNotificationCloseButton1" type="text" selector="//aside[1]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton2" type="text" selector="//aside[2]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton3" type="text" selector="//aside[3]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton4" type="text" selector="//aside[4]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton5" type="text" selector="//aside[5]/div[2]/header/button"/> - <element name="releaseNotificationCloseButton6" type="text" selector="//aside[6]/div[2]/header/button"/> + <element name="adminUsageDontAllowButton" type="text" selector=".modal-popup .action-secondary"/> </section> </sections> diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 26cd4e9c6bcf..626e3ec14bc9 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_usage_viewer_log": { + "admin_analytics_usage_version_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 2cf9df87196f..17cffb33f043 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -20,7 +20,8 @@ define( }, options: { keyEventHandlers: { - escapeKey: function () { return; } + escapeKey: function () { + return; } } } }, @@ -32,6 +33,7 @@ define( $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { + var data = { 'form_key': window.FORM_KEY }; From 254676a98582dbd1c3894a3a5e3c9d84179894a4 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 31 Jul 2019 16:22:13 +0300 Subject: [PATCH 0242/1172] MC-18749: Failed funtional test Magento\FunctionalTestingFramework.functional.StorefrontPrintOrderGuestTest --- .../Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml index 5c0d40510246..0bd8ab4855e9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/StorefrontPrintOrderGuestTest.xml @@ -19,6 +19,7 @@ <group value="mtf_migrated"/> </annotations> <before> + <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> <createData entity="ApiCategory" stepKey="createCategory"/> @@ -207,6 +208,7 @@ <actionGroup ref="orderSelectFlatRateShipping" stepKey="selectFlatRate"/> </before> <after> + <magentoCLI command="downloadable:domains:remove" arguments="example.com static.magento.com" stepKey="removeDownloadableDomain"/> <deleteData createDataKey="downloadableProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> @@ -275,4 +277,4 @@ <see userInput="Flat Rate - Fixed" selector="{{StorefrontOrderDetailsSection.shippingMethod}}" stepKey="assertShippingMethodOnPrintOrder"/> <switchToPreviousTab stepKey="switchToPreviousTab"/> </test> -</tests> \ No newline at end of file +</tests> From c2cc4ec892db647e348841b8eab1c7c3edabd81b Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 10:25:04 -0500 Subject: [PATCH 0243/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Added UI component --- .../Adminhtml/Config/DisableAdminUsage.php | 10 +++- .../Adminhtml/Config/EnableAdminUsage.php | 12 +++- .../AdminAnalytics/ViewModel/Notification.php | 56 +++++++++++++++++++ .../etc/db_schema_whitelist.json | 2 +- .../view/adminhtml/layout/default.xml | 15 +++-- .../view/adminhtml/requirejs-config.js | 14 +++++ .../adminhtml/templates/notification.phtml | 16 ++++++ .../view/adminhtml/web/js/modal/component.js | 29 ++++++---- .../modal/component-mixin.js | 29 ++++++++++ 9 files changed, 164 insertions(+), 19 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/ViewModel/Notification.php create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 73635ddfee31..eb31e54e8041 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Changes the admin usage to no, and marks user notified + * Log information about the last shown advertisement * * @return ResultInterface */ @@ -97,4 +97,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index e2ecb700e2b4..9ce119f0c424 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -88,7 +88,7 @@ public function markUserNotified() } /** - * Changes the admin usage to yes, and marks user notified + * Log information about the last shown advertisement * * @return \Magento\Framework\Controller\ResultInterface */ @@ -97,4 +97,14 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * IsAllow allows function to be visible + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php new file mode 100644 index 000000000000..5b4a51c5b653 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\AdminAnalytics\ViewModel; + +/** + * Class Notification + */ +class Notification implements \Magento\Framework\View\Element\Block\ArgumentInterface +{ + /** + * @var \Magento\AdminAnalytics\Model\Condition\CanViewNotification + */ + private $canViewNotificationAnalytics; + + /** + * @var \Magento\ReleaseNotification\Model\Condition\CanViewNotification + */ + private $canViewNotificationRelease; + + /** + * Notification constructor. + * @param \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics + * @param \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + */ + public function __construct( + \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics, + \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + ) { + $this->canViewNotificationAnalytics = $canViewNotificationAnalytics; + $this->canViewNotificationRelease = $canViewNotificationRelease; + } + + /** + * Determine if the analytics popup is visible + * + * @return bool + */ + public function isAnalyticsVisible(): bool + { + return $this->canViewNotificationAnalytics->isVisible([]); + } + + /** + * Determine if the release popup is visible + * + * @return bool + */ + public function isReleaseVisible(): bool + { + return $this->canViewNotificationRelease->isVisible([]); + } +} diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 626e3ec14bc9..26cd4e9c6bcf 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_analytics_usage_version_log": { + "admin_usage_viewer_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 62a9dda8b090..688bbc1e4188 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -13,14 +13,17 @@ <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> </arguments> </block> - - </referenceContainer> <referenceContainer name="content"> - <uiComponent name="admin_usage_notification"> - <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> - </uiComponent> - </referenceContainer> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> + <arguments> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + </arguments> + </block> + </referenceContainer> </body> </page> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js b/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js new file mode 100644 index 000000000000..136121092978 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/requirejs-config.js @@ -0,0 +1,14 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +var config = { + config: { + mixins: { + 'Magento_ReleaseNotification/js/modal/component': { + 'Magento_AdminAnalytics/js/release-notification/modal/component-mixin': true + } + } + } +}; diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml new file mode 100644 index 000000000000..4b1f97167018 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/notification.phtml @@ -0,0 +1,16 @@ + +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +?> + +<script> + define('analyticsPopupConfig', function () { + return { + analyticsVisible: <?= $block->getNotification()->isAnalyticsVisible() ? 1 : 0; ?>, + releaseVisible: <?= $block->getNotification()->isReleaseVisible() ? 1 : 0; ?>, + } + }); +</script> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 17cffb33f043..8afa4861dd15 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -3,12 +3,14 @@ * See COPYING.txt for license details. */ -define( - [ +define([ + 'underscore', 'jquery', - 'Magento_Ui/js/modal/modal-component' - ], - function ($, Modal) { + 'Magento_Ui/js/modal/modal-component', + 'uiRegistry', + 'analyticsPopupConfig' +], + function (_, $, Modal, registry, analyticsPopupConfig) { 'use strict'; return Modal.extend( @@ -20,10 +22,10 @@ define( }, options: { keyEventHandlers: { - escapeKey: function () { - return; } + escapeKey: function () { return; } } - } + }, + notificationWindow: null, }, initModal: function () { this.options.opened = this.onOpened.bind(this); @@ -33,7 +35,6 @@ define( $('.modal-header button.action-close').hide(); }, enableAdminUsage: function () { - var data = { 'form_key': window.FORM_KEY }; @@ -51,6 +52,7 @@ define( } } ).fail(this.onError); + this.openReleasePopup(); this.closeModal(); }, disableAdminUsage: function () { @@ -71,8 +73,15 @@ define( } } ).fail(this.onError); + this.openReleasePopup(); this.closeModal(); - } + }, + openReleasePopup: function () { + if (analyticsPopupConfig.releaseVisible) { + var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + notificationModal.initializeContentAfterAnalytics(); + } + }, } ) } diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js new file mode 100644 index 000000000000..342046986186 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -0,0 +1,29 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { + 'use strict'; + + var deferred = $.Deferred(); + var mixin = { + initializeContent: function () { + var initializeContent = this._super.bind(this); + if (!analyticsPopupConfig.analyticsVisible) { + initializeContent(); + } else { + deferred.then(function () { + initializeContent(); + }); + } + }, + initializeContentAfterAnalytics: function () { + deferred.resolve(); + } + }; + + return function (target) { + return target.extend(mixin); + }; +}); From ad9293979e0c2afd02000fd540f1f4a20a7c3312 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 11:46:20 -0500 Subject: [PATCH 0244/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added function that allows admin usage notification to be shown first --- .../Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml index 71c039773f6b..4fd7fd17c57e 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/CloseAllDialogBoxesActionGroup.xml @@ -9,6 +9,12 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="CloseAllDialogBoxes"> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton1}}" visible="true" stepKey="clickCloseButtonIfVisible1"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton2}}" visible="true" stepKey="clickCloseButtonIfVisible2"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton3}}" visible="true" stepKey="clickCloseButtonIfVisible3"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton4}}" visible="true" stepKey="clickCloseButtonIfVisible4"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton5}}" visible="true" stepKey="clickCloseButtonIfVisible5"/> + <conditionalClick selector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" dependentSelector="{{AdminUsageNotificationSection.releaseNotificationCloseButton6}}" visible="true" stepKey="clickCloseButtonIfVisible6"/> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageAllowButton}}" visible="true" stepKey="clickAllowButtonIfVisible"/> </actionGroup> </actionGroups> From f1840ce0c8b42310b11c0a9e16eaf9d4129df0d1 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 15:34:43 -0500 Subject: [PATCH 0245/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Fixed static errors --- .../Adminhtml/Config/DisableAdminUsage.php | 16 ++++------------ .../Adminhtml/Config/EnableAdminUsage.php | 18 ++++-------------- .../Model/Condition/CanViewNotification.php | 4 ++-- .../etc/db_schema_whitelist.json | 2 +- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 7 +++++-- .../modal/component-mixin.js | 1 + 7 files changed, 18 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index eb31e54e8041..82d8ac6480b0 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -39,11 +39,11 @@ class DisableAdminUsage extends Action /** * DisableAdminUsage constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory - * @param LoggerInterface $logger + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory + * @param LoggerInterface $logger */ public function __construct( Action\Context $context, @@ -97,12 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9ce119f0c424..899d05d317e6 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -39,11 +39,11 @@ class EnableAdminUsage extends Action /** * MarkUserNotified constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory - * @param LoggerInterface $logger + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory + * @param LoggerInterface $logger */ public function __construct( Action\Context $context, @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * IsAllow allows function to be visible - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index a8a6b58bffbf..861fb0a385f9 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -51,9 +51,9 @@ class CanViewNotification implements VisibilityConditionInterface /** * CanViewNotification constructor. * - * @param Logger $viewerLogger + * @param Logger $viewerLogger * @param ProductMetadataInterface $productMetadata - * @param CacheInterface $cacheStorage + * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json index 26cd4e9c6bcf..626e3ec14bc9 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json +++ b/app/code/Magento/AdminAnalytics/etc/db_schema_whitelist.json @@ -1,5 +1,5 @@ { - "admin_usage_viewer_log": { + "admin_analytics_usage_version_log": { "column": { "id": true, "last_viewed_in_version": true diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 7c6d1d43006d..090259af427b 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -85,7 +85,7 @@ <item name="text" xsi:type="string" translate="true"><![CDATA[ <p>Help us improve Magento Admin by allowing us to collect usage data.</p> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a></p> ]]></item> </item> </argument> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 8afa4861dd15..55335f17139a 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -38,6 +38,7 @@ define([ var data = { 'form_key': window.FORM_KEY }; + $.ajax( { type: 'POST', @@ -59,6 +60,7 @@ define([ var data = { 'form_key': window.FORM_KEY }; + $.ajax( { type: 'POST', @@ -77,12 +79,13 @@ define([ this.closeModal(); }, openReleasePopup: function () { + var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + if (analyticsPopupConfig.releaseVisible) { - var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); notificationModal.initializeContentAfterAnalytics(); } }, } - ) + ); } ); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index 342046986186..fdfb85dd1181 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -10,6 +10,7 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { var mixin = { initializeContent: function () { var initializeContent = this._super.bind(this); + if (!analyticsPopupConfig.analyticsVisible) { initializeContent(); } else { From 12f6ed91d8281780412cab46b0b8e3028f9c6b45 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 21:19:36 -0500 Subject: [PATCH 0246/1172] MC-15298: Allow admin to opt out of admin analytics tracking - corrected static errors --- .../Model/Condition/CanViewNotification.php | 31 ++--- .../Http/HttpContentProvider.php | 108 ------------------ .../Model/ContentProvider/Http/UrlBuilder.php | 64 ----------- .../Model/ResourceModel/Viewer/Logger.php | 17 ++- .../Condition/CanViewNotificationTest.php | 87 ++++++++++++++ .../DataProvider/NotificationDataProvider.php | 3 + app/code/Magento/AdminAnalytics/composer.json | 2 +- .../view/adminhtml/web/js/modal/component.js | 8 +- 8 files changed, 120 insertions(+), 200 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php create mode 100644 app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 861fb0a385f9..1af8702e5510 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -6,8 +6,6 @@ namespace Magento\AdminAnalytics\Model\Condition; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; -use Magento\Backend\Model\Auth\Session; -use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; use function Magento\PAT\Reports\Utils\readResponseTimeReport; @@ -31,18 +29,13 @@ class CanViewNotification implements VisibilityConditionInterface * * @var string */ - private static $cachePrefix = 'admin-usage-notification-popup-'; + private static $cachePrefix = 'admin-usage-notification-popup'; /** * @var Logger */ private $viewerLogger; - /** - * @var ProductMetadataInterface - */ - private $productMetadata; - /** * @var CacheInterface */ @@ -51,37 +44,33 @@ class CanViewNotification implements VisibilityConditionInterface /** * CanViewNotification constructor. * - * @param Logger $viewerLogger - * @param ProductMetadataInterface $productMetadata - * @param CacheInterface $cacheStorage + * @param Logger $viewerLogger + * @param CacheInterface $cacheStorage */ public function __construct( Logger $viewerLogger, - ProductMetadataInterface $productMetadata, CacheInterface $cacheStorage ) { $this->viewerLogger = $viewerLogger; - $this->productMetadata = $productMetadata; $this->cacheStorage = $cacheStorage; } /** * Validate if notification popup can be shown and set the notification flag * + * @param array $arguments Attributes from element node. * @inheritdoc */ public function isVisible(array $arguments) { - $currentProductVersion = $this->productMetadata->getVersion(); - $cacheKey = self::$cachePrefix.$currentProductVersion; + $cacheKey = self::$cachePrefix; $value = $this->cacheStorage->load($cacheKey); - if ($value != $currentProductVersion) { - $versionViewed = $this->viewerLogger->get($currentProductVersion)->getLastViewVersion(); - $versionExists = isset($versionViewed); - if ($versionExists) { - $this->cacheStorage->save($versionViewed, $cacheKey); + if ($value !== 'log-exists') { + $logExists = $this->viewerLogger->checkLogExists(); + if ($logExists) { + $this->cacheStorage->save('log-exists', $cacheKey); } - return !$versionExists; + return !$logExists; } return false; } diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php deleted file mode 100644 index 930cf8996693..000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/HttpContentProvider.php +++ /dev/null @@ -1,108 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Model\ContentProvider\Http; - -use Magento\AdminAnalytics\Model\ContentProviderInterface; -use Magento\Setup\Module\I18n\Locale; -use Psr\Log\LoggerInterface; -use Magento\Framework\HTTP\ClientInterface; - -/** - * Requests the release notification content data via an HTTP call to a REST API - */ -class HttpContentProvider implements ContentProviderInterface -{ - /** - * @var ClientInterface - */ - private $httpClient; - - /** - * @var LoggerInterface - */ - private $logger; - - /** - * @var UrlBuilder - */ - private $urlBuilder; - - /** - * HttpContentProvider constructor. - * @param ClientInterface $httpClient - * @param UrlBuilder $urlBuilder - * @param LoggerInterface $logger - */ - public function __construct( - ClientInterface $httpClient, - UrlBuilder $urlBuilder, - LoggerInterface $logger - ) { - $this->httpClient = $httpClient; - $this->urlBuilder = $urlBuilder; - $this->logger = $logger; - } - - /** - * @inheritdoc - */ - public function getContent($version, $edition, $locale) - { - $result = false; - - try { - $result = $this->retrieveContent($version, $edition, $locale); - if (!$result) { - $result = $this->retrieveContent($version, $edition, Locale::DEFAULT_SYSTEM_LOCALE); - if (!$result) { - $result = $this->retrieveContent($version, '', 'default'); - } - } - } catch (\Exception $e) { - $this->logger->warning( - sprintf( - 'Failed to retrieve the release notification content. The response is: %s', - empty($result) ? 'Response body is empty.' : $result - ) - ); - } - - return $result; - } - - /** - * Retrieve content from given url - * - * @param string $version - * @param string $edition - * @param string $locale - * @return bool|string - */ - private function retrieveContent($version, $edition, $locale) - { - $url = $this->urlBuilder->getUrl($version, $edition, $locale); - return empty($url) ? false : $this->getResponse($url); - } - - /** - * Returns the response body from the HTTP client - * - * @param $url - * @return string - */ - private function getResponse($url) - { - $this->httpClient->get($url); - $responseBody = $this->httpClient->getBody(); - - if ($this->httpClient->getStatus() === 200 && !empty($responseBody)) { - return $responseBody; - } - - return false; - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php b/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php deleted file mode 100644 index 3898fb82f4ac..000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProvider/Http/UrlBuilder.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\AdminAnalytics\Model\ContentProvider\Http; - -use Magento\Framework\App\Config\ScopeConfigInterface; - -/** - * Builder to build Url to retrieve the notification content. - */ -class UrlBuilder -{ - /** - * Path to the configuration value which contains an URL that provides the release notification data. - * - * @var string - */ - private static $notificationContentUrlConfigPath = 'system/release_notification/content_url'; - - /** - * Path to the configuration value indicates if use https in notification content request. - * - * @var string - */ - private static $useHttpsFlagConfigPath = 'system/release_notification/use_https'; - - /** - * @var ScopeConfigInterface - */ - private $config; - - /** - * @param ScopeConfigInterface $config - */ - public function __construct(ScopeConfigInterface $config) - { - $this->config = $config; - } - - /** - * Builds the URL to request the release notification content data based on passed parameters. - * - * @param string $version - * @param string $edition - * @param string $locale - * @return string - */ - public function getUrl($version, $edition, $locale) - { - $scheme = $this->config->isSetFlag(self::$useHttpsFlagConfigPath) ? 'https://' : 'http://'; - $baseUrl = $this->config->getValue(self::$notificationContentUrlConfigPath); - if (empty($baseUrl)) { - return ''; - } else { - $url = $scheme . $baseUrl; - $url .= empty($version) ? '' : '/' . $version; - $url .= empty($edition) ? '' : '/' . $edition; - $url .= empty($locale) ? '' : '/' . $locale; - return $url . '.json'; - } - } -} diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 6c6a76365fbb..505257f05147 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -79,18 +79,29 @@ public function get(string $lastViewVersion) : Log return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); } + /** + * Get log by the last view version. + * + * @return boolean + */ + public function checkLogExists() : bool + { + $data = $this->logFactory->create(['data' => $this->loadLogData()]); + $lastViewedVersion = $data->getLastViewVersion(); + return isset($lastViewedVersion); + } + /** * Load release notification viewer log data by last view version * - * @param string $lastViewVersion * @return array */ - private function loadLogData(string $lastViewVersion) : array + private function loadLogData() : array { $connection = $this->resource->getConnection(); $select = $connection->select() ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) - ->where('last_viewed_in_version = ?', $lastViewVersion); + ->limit(['count' => 1]); $data = $connection->fetchRow($select); if (!$data) { diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php new file mode 100644 index 000000000000..75306ddcd85e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\AdminAnalytics\Test\Unit\Model\Condition; + +use Magento\AdminAnalytics\Model\Condition\CanViewNotification; +use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; +use Magento\AdminAnalytics\Model\Viewer\Log; +use Magento\Framework\App\ProductMetadataInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Framework\App\CacheInterface; + +class CanViewNotificationTest extends \PHPUnit\Framework\TestCase +{ + /** @var CanViewNotification */ + private $canViewNotification; + + /** @var Logger|\PHPUnit_Framework_MockObject_MockObject */ + private $viewerLoggerMock; + + /** @var ProductMetadataInterface|\PHPUnit_Framework_MockObject_MockObject */ + private $productMetadataMock; + + /** @var Log|\PHPUnit_Framework_MockObject_MockObject */ + private $logMock; + + /** @var $cacheStorageMock \PHPUnit_Framework_MockObject_MockObject|CacheInterface */ + private $cacheStorageMock; + + public function setUp() + { + $this->cacheStorageMock = $this->getMockBuilder(CacheInterface::class) + ->getMockForAbstractClass(); + $this->logMock = $this->getMockBuilder(Log::class) + ->getMock(); + $this->viewerLoggerMock = $this->getMockBuilder(Logger::class) + ->disableOriginalConstructor() + ->getMock(); + $this->productMetadataMock = $this->getMockBuilder(ProductMetadataInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManager = new ObjectManager($this); + $this->canViewNotification = $objectManager->getObject( + CanViewNotification::class, + [ + 'viewerLogger' => $this->viewerLoggerMock, + 'productMetadata' => $this->productMetadataMock, + 'cacheStorage' => $this->cacheStorageMock, + ] + ); + } + + /** + * @param $expected + * @param $cacheResponse + * @param $logExists + * @dataProvider isVisibleProvider + */ + public function testIsVisibleLoadDataFromLog($expected, $cacheResponse, $logExists) + { + $this->cacheStorageMock->expects($this->once()) + ->method('load') + ->with('admin-usage-notification-popup') + ->willReturn($cacheResponse); + $this->viewerLoggerMock + ->method('checkLogExists') + ->willReturn($logExists); + $this->cacheStorageMock + ->method('save') + ->with('log-exists', 'admin-usage-notification-popup'); + $this->assertEquals($expected, $this->canViewNotification->isVisible([])); + } + + /** + * @return array + */ + public function isVisibleProvider() + { + return [ + [true, false, false], + [false, 'log-exists', true], + [false, false, true], + ]; + } +} diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php index a3acf279c7a9..8b3e25e2a6d2 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php @@ -180,6 +180,7 @@ public function getRequestFieldName() */ public function addFilter(\Magento\Framework\Api\Filter $filter) { + return null; } /** @@ -187,6 +188,7 @@ public function addFilter(\Magento\Framework\Api\Filter $filter) */ public function addOrder($field, $direction) { + return null; } /** @@ -194,6 +196,7 @@ public function addOrder($field, $direction) */ public function setLimit($offset, $size) { + return null; } /** diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 085d258c72b5..7fa6c721d44c 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -5,7 +5,7 @@ "sort-packages": true }, "require": { - "php": "~7.1.3||~7.2.0", + "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", "magento/module-backend": "*" }, diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 55335f17139a..091098a059a9 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -22,7 +22,9 @@ define([ }, options: { keyEventHandlers: { - escapeKey: function () { return; } + escapeKey: function () { + return; + } } }, notificationWindow: null, @@ -79,10 +81,10 @@ define([ this.closeModal(); }, openReleasePopup: function () { - var notificationModal = registry.get('release_notification.release_notification.notification_modal_1'); + var notifiModal = registry.get('release_notification.release_notification.notification_modal_1'); if (analyticsPopupConfig.releaseVisible) { - notificationModal.initializeContentAfterAnalytics(); + notifiModal.initializeContentAfterAnalytics(); } }, } From 6d966b9f8998bc46db0a8b3bcea6d636d3c586db Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 31 Jul 2019 21:31:01 -0500 Subject: [PATCH 0247/1172] MC-15298: Allow admin to opt out of admin analytics tracking - corrected composer.json --- app/code/Magento/AdminAnalytics/composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 7fa6c721d44c..0c930560425f 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -7,7 +7,10 @@ "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", - "magento/module-backend": "*" + "magento/module-backend": "*", + "magento/Config": "*", + "magento/Ui": "*", + "magento/ReleaseNotification": "*" }, "type": "magento2-module", "license": [ From 923198b5d1c4ae9bc053a3451b8e03eaa47d846b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 1 Aug 2019 10:26:02 +0300 Subject: [PATCH 0248/1172] MC-18750: Failed function test Magento\FunctionalTestingFramework.functional.StorefrontUKCustomerCheckoutWithCouponTest --- .../Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml index 13928dd91ec7..482e2fb6233a 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontUKCustomerCheckoutWithCouponTest.xml @@ -19,7 +19,6 @@ <before> <magentoCLI command="downloadable:domains:add" arguments="example.com static.magento.com" stepKey="addDownloadableDomain"/> - <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> <createData entity="ApiDownloadableProduct" stepKey="createDownloadableProduct"> <field key="price">20.00</field> </createData> @@ -44,6 +43,7 @@ <deleteData createDataKey="virtualProduct" stepKey="deleteVirtualProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> <deleteData createDataKey="createSalesRule" stepKey="deleteSalesRule"/> + <actionGroup ref="AdminOrdersGridClearFiltersActionGroup" stepKey="clearOrderFilters"/> <actionGroup ref="logout" stepKey="logout"/> </after> @@ -108,6 +108,9 @@ <seeElement selector="{{StorefrontMiniCartSection.emptyMiniCart}}" stepKey="assertEmptyCart" /> <grabTextFrom selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="orderId"/> + <!-- Login to Admin Page --> + <actionGroup ref="LoginAsAdmin" stepKey="loginToAdminPanel"/> + <!-- Open Order Index Page --> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToOrders"/> <waitForPageLoad stepKey="waitForPageLoad5"/> From ae388490572ba10eddb5ba598ebc057326b4943c Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 1 Aug 2019 19:17:29 +0300 Subject: [PATCH 0249/1172] MC-18830: [FT] [MFTF] AdminCreateCustomerWithCountryUSATest fluky because of bad design --- .../Mftf/Section/AdminCustomerAddressesGridActionsSection.xml | 1 + .../Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml index e743c4af66d9..3ecbf5ff450c 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerAddressesGridActionsSection.xml @@ -17,5 +17,6 @@ <element name="filters" type="button" selector="button[data-action='grid-filter-expand']" timeout="30"/> <element name="ok" type="button" selector="//button[@data-role='action']//span[text()='OK']" timeout="30"/> <element name="headerRow" type="text" selector=".admin__data-grid-header-row.row.row-gutter"/> + <element name="clearFilter" type="button" selector=".admin__data-grid-header .admin__data-grid-filters-current button.action-clear" timeout="30"/> </section> </sections> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml index 43f2aa7f8de9..a487571c4353 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerWithCountryUSATest.xml @@ -85,6 +85,7 @@ <see selector="{{AdminCustomerAddressesDefaultBillingSection.addressDetails}}" userInput="{{US_Address_CA.telephone}}" stepKey="seePhoneNumberInDefaultAddressSection"/> <!--Assert Customer Address Grid --> + <conditionalClick selector="{{AdminCustomerAddressesGridActionsSection.clearFilter}}" dependentSelector="{{AdminCustomerAddressesGridActionsSection.clearFilter}}" visible="true" stepKey="clearAddressesGridFilter"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.street}}" stepKey="seeStreetAddress"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.city}}" stepKey="seeCity"/> <see selector="{{AdminCustomerAddressesGridSection.customerAddressGrid}}" userInput="{{US_Address_CA.country}}" stepKey="seeCountry"/> From ec58fb1e25978d6866e0254eb12b31859a5787e7 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 11:43:53 -0500 Subject: [PATCH 0250/1172] MC-17700: Downloadable Product links --- .../Patch/Data/AddDownloadableHostsConfig.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 575a6a4d7180..8393c9f8551f 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -9,7 +9,9 @@ use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; +use Magento\Framework\UrlInterface; use Magento\Store\Model\ScopeInterface; +use Magento\Store\Model\Store; use Zend\Uri\Uri as UriHandler; use Magento\Framework\Url\ScopeResolverInterface; use Magento\Downloadable\Api\DomainManagerInterface as DomainManager; @@ -80,7 +82,17 @@ public function __construct( public function apply() { foreach ($this->scopeResolver->getScopes() as $scope) { - $this->addHost($scope->getBaseUrl()); + /** @var $scope Store */ + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); } $customAdminUrl = $this->scopeConfig->getValue( From dd170ed0a01a0653ab44f43998de4c9f9597a275 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 12:20:45 -0500 Subject: [PATCH 0251/1172] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 8393c9f8551f..4bb0c38ce4c1 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -7,6 +7,7 @@ namespace Magento\Downloadable\Setup\Patch\Data; +use Magento\Config\Model\Config\Backend\Admin\Custom; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\UrlInterface; @@ -81,7 +82,11 @@ public function __construct( */ public function apply() { - foreach ($this->scopeResolver->getScopes() as $scope) { + $customStoreScope = $this->scopeResolver->getScope(Custom::CONFIG_SCOPE_ID); + $storeScopes = $this->scopeResolver->getScopes(); + $allStoreScopes = array_merge($storeScopes, [$customStoreScope]); + + foreach ($allStoreScopes as $scope) { /** @var $scope Store */ $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); From 6e8b5943de72bb2a6570ec240c737e6f5aa5ff8d Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Thu, 1 Aug 2019 14:33:38 -0500 Subject: [PATCH 0252/1172] MC-17700: Downloadable Product links --- .../Patch/Data/AddDownloadableHostsConfig.php | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 4bb0c38ce4c1..958a9f58153a 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -9,6 +9,7 @@ use Magento\Config\Model\Config\Backend\Admin\Custom; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Framework\UrlInterface; use Magento\Store\Model\ScopeInterface; @@ -87,17 +88,7 @@ public function apply() $allStoreScopes = array_merge($storeScopes, [$customStoreScope]); foreach ($allStoreScopes as $scope) { - /** @var $scope Store */ - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + $this->addStoreAndWebsiteUrlsFromScope($scope); } $customAdminUrl = $this->scopeConfig->getValue( @@ -152,6 +143,42 @@ public function apply() $this->domainManager->addDomains($this->whitelist); } + /** + * Add stores and website urls from store scope + * + * @param Store $scope + */ + private function addStoreAndWebsiteUrlsFromScope(Store $scope) + { + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_WEB, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + + try { + $website = $scope->getWebsite(); + } catch (NoSuchEntityException $e) { + return; + } + + if ($website) { + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_LINK_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_LINK_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_MEDIA_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_MEDIA_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_SECURE_BASE_STATIC_URL)); + $this->addHost($website->getConfig(Store::XML_PATH_UNSECURE_BASE_STATIC_URL)); + } + } + /** * Add host to whitelist * @@ -159,6 +186,10 @@ public function apply() */ private function addHost($url) { + if (!is_string($url)) { + return; + } + $host = $this->uriHandler->parse($url)->getHost(); if ($host && !in_array($host, $this->whitelist)) { $this->whitelist[] = $host; From d713dac0293adc342826e2e6999b4b770a662166 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Thu, 1 Aug 2019 16:29:17 -0500 Subject: [PATCH 0253/1172] MC-18115: Email template preview bugfix --- .../Block/Adminhtml/Template/Preview.php | 12 +- .../Adminhtml/Email/Template/Popup.php | 4 +- .../Adminhtml/Email/Template/Preview.php | 9 +- .../Block/Adminhtml/Template/PreviewTest.php | 21 --- .../Adminhtml/Email/Template/PreviewTest.php | 15 +- .../ViewModel/Template/Preview/FormTest.php | 154 ++++++++++++++++++ .../Email/ViewModel/Template/Preview/Form.php | 71 ++++++++ .../adminhtml_email_template_preview.xml | 6 +- .../templates/preview/iframeswitcher.phtml | 31 +++- .../adminhtml/templates/template/edit.phtml | 3 +- 10 files changed, 268 insertions(+), 58 deletions(-) create mode 100644 app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php create mode 100644 app/code/Magento/Email/ViewModel/Template/Preview/Form.php diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php index 5fabc584403b..ec5596e2194a 100644 --- a/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php +++ b/app/code/Magento/Email/Block/Adminhtml/Template/Preview.php @@ -3,12 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -/** - * Adminhtml system template preview block - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Email\Block\Adminhtml\Template; /** @@ -55,16 +51,12 @@ public function __construct( * Prepare html output * * @return string - * @throws \Magento\Framework\Exception\LocalizedException + * @throws \Exception */ protected function _toHtml() { $request = $this->getRequest(); - if (!$request instanceof \Magento\Framework\App\RequestSafetyInterface || !$request->isSafeMethod()) { - throw new \Magento\Framework\Exception\LocalizedException(__('Wrong request.')); - } - $storeId = $this->getAnyStoreView()->getId(); /** @var $template \Magento\Email\Model\Template */ $template = $this->_emailFactory->create(); diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php index 31d172935da7..4f36eedd09b8 100644 --- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php +++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Popup.php @@ -7,12 +7,12 @@ namespace Magento\Email\Controller\Adminhtml\Email\Template; -use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Rendering popup email template. */ -class Popup extends \Magento\Backend\App\Action implements HttpGetActionInterface +class Popup extends \Magento\Backend\App\Action implements HttpPostActionInterface { /** * @var \Magento\Framework\View\Result\PageFactory diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php index c1a8eec07e46..a92836b2995a 100644 --- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php +++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php @@ -4,19 +4,21 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Email\Controller\Adminhtml\Email\Template; +use Magento\Email\Controller\Adminhtml\Email\Template; use Magento\Framework\App\Action\HttpGetActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; /** * Rendering email template preview. */ -class Preview extends \Magento\Email\Controller\Adminhtml\Email\Template implements HttpGetActionInterface +class Preview extends Template implements HttpGetActionInterface, HttpPostActionInterface { /** * Preview transactional email action. - * - * @return void */ public function execute() { @@ -24,7 +26,6 @@ public function execute() $this->_view->loadLayout(); $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Email Preview')); $this->_view->renderLayout(); - $this->getResponse()->setHeader('Content-Security-Policy', "script-src 'self'"); } catch (\Exception $e) { $this->messageManager->addErrorMessage( __('An error occurred. The email template can not be opened for preview.') diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php index 83eda7e39a81..4d168ffbf2bd 100644 --- a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/PreviewTest.php @@ -152,9 +152,6 @@ protected function setUp() */ public function testToHtml($requestParamMap) { - $this->request->expects($this->atLeastOnce()) - ->method('isSafeMethod') - ->willReturn(true); $this->request->expects($this->any()) ->method('getParam') ->willReturnMap($requestParamMap); @@ -171,24 +168,6 @@ public function testToHtml($requestParamMap) $this->assertEquals(self::MALICIOUS_TEXT, $this->preview->toHtml()); } - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - */ - public function testToHtmlWithException() - { - $this->request->expects($this->atLeastOnce()) - ->method('isSafeMethod') - ->willReturn(false); - $this->template - ->expects($this->never()) - ->method('getDesignConfig'); - $this->expectException(\Magento\Framework\Exception\LocalizedException::class); - $this->expectExceptionMessage( - (string)__('Wrong request.') - ); - $this->preview->toHtml(); - } - /** * Data provider * diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php index 9a67bf59dd4b..d4584ce86dff 100644 --- a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php +++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/PreviewTest.php @@ -54,11 +54,6 @@ class PreviewTest extends \PHPUnit\Framework\TestCase */ protected $pageTitleMock; - /** - * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $responseMock; - protected function setUp() { $objectManager = new ObjectManager($this); @@ -84,16 +79,11 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->responseMock = $this->getMockBuilder(\Magento\Framework\App\ResponseInterface::class) - ->setMethods(['setHeader']) - ->getMockForAbstractClass(); - $this->context = $objectManager->getObject( \Magento\Backend\App\Action\Context::class, [ 'request' => $this->requestMock, - 'view' => $this->viewMock, - 'response' => $this->responseMock + 'view' => $this->viewMock ] ); $this->object = $objectManager->getObject( @@ -118,9 +108,6 @@ public function testExecute() $this->pageTitleMock->expects($this->once()) ->method('prepend') ->willReturnSelf(); - $this->responseMock->expects($this->once()) - ->method('setHeader') - ->with('Content-Security-Policy', "script-src 'self'"); $this->assertNull($this->object->execute()); } diff --git a/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php b/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php new file mode 100644 index 000000000000..88c323c923c4 --- /dev/null +++ b/app/code/Magento/Email/Test/Unit/ViewModel/Template/Preview/FormTest.php @@ -0,0 +1,154 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Email\Test\Unit\ViewModel\Template\Preview; + +use Magento\Email\ViewModel\Template\Preview\Form; +use Magento\Framework\App\Request\Http; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class FormTest + * + * @covers \Magento\Email\ViewModel\Template\Preview\Form + */ +class FormTest extends \PHPUnit\Framework\TestCase +{ + /** @var Form */ + protected $form; + + /** @var Http|\PHPUnit_Framework_MockObject_MockObject */ + protected $requestMock; + + protected function setUp() + { + $this->requestMock = $this->createPartialMock( + Http::class, + ['getParam', 'getMethod'] + ); + + $objectManagerHelper = new ObjectManager($this); + + $this->form = $objectManagerHelper->getObject( + Form::class, + ['request'=> $this->requestMock] + ); + } + + /** + * Tests that the form is created with the expected fields based on the request type. + * + * @dataProvider getFormFieldsDataProvider + * @param string $httpMethod + * @param array $httpParams + * @param array $expectedFields + * @throws LocalizedException + */ + public function testGetFormFields(string $httpMethod, array $httpParams, array $expectedFields) + { + $this->requestMock->expects($this->once()) + ->method('getMethod') + ->willReturn($httpMethod); + + $this->requestMock->expects($this->any()) + ->method('getParam') + ->willReturnMap($httpParams); + + $actualFields = $this->form->getFormFields(); + + $this->assertEquals($expectedFields, $actualFields); + } + + /** + * Tests that an exception is thrown when a required parameter is missing for the request type. + * + * @dataProvider getFormFieldsInvalidDataProvider + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Missing expected parameter + * @param string $httpMethod + * @param array $httpParams + */ + public function testGetFormFieldsMissingParameter(string $httpMethod, array $httpParams) + { + $this->requestMock->expects($this->once()) + ->method('getMethod') + ->willReturn($httpMethod); + + $this->requestMock->expects($this->once()) + ->method('getParam') + ->willReturnMap($httpParams); + + $this->form->getFormFields(); + } + + /** + * @return array + */ + public function getFormFieldsDataProvider() + { + return [ + 'get_request_valid' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['id', null, 1] + ], + 'expectedFields' => [ + 'id' => 1 + ] + ], + 'get_request_valid_ignore_params' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['id', null, 1], + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ], + 'expectedFields' => [ + 'id' => 1 + ] + ], + 'post_request_valid' => [ + 'httpMethod' => 'POST', + 'httpParams' => [ + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ], + 'expectedFields' => [ + 'text' => 'Hello World', + 'type' => 2, + 'styles' => '' + ] + ] + ]; + } + + /** + * @return array + */ + public function getFormFieldsInvalidDataProvider() + { + return [ + 'get_request_missing_id' => [ + 'httpMethod' => 'GET', + 'httpParams' => [ + ['text', null, 'Hello World'], + ['type', null, 2], + ['styles', null, ''] + ] + ], + 'post_request_missing_text' => [ + 'httpMethod' => 'POST', + 'httpParams' => [ + ['type', null, 2], + ['styles', null, ''] + ] + ] + ]; + } +} diff --git a/app/code/Magento/Email/ViewModel/Template/Preview/Form.php b/app/code/Magento/Email/ViewModel/Template/Preview/Form.php new file mode 100644 index 000000000000..9db93cb94a29 --- /dev/null +++ b/app/code/Magento/Email/ViewModel/Template/Preview/Form.php @@ -0,0 +1,71 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Email\ViewModel\Template\Preview; + +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Element\Block\ArgumentInterface; + +/** + * Class Form + */ +class Form implements ArgumentInterface +{ + private $expectedParamsGetRequest = [ + 'id' + ]; + + private $expectedParamsPostRequest = [ + 'text', + 'type', + 'styles' + ]; + + /** + * @var RequestInterface + */ + private $request; + + /** + * @param RequestInterface $request + */ + public function __construct(RequestInterface $request) + { + $this->request = $request; + } + + /** + * Gets the fields to be included in the email preview form. + * + * @return array + * @throws LocalizedException + */ + public function getFormFields() + { + $params = $fields = []; + $method = $this->request->getMethod(); + + if ($method === 'GET') { + $params = $this->expectedParamsGetRequest; + } elseif ($method === 'POST') { + $params = $this->expectedParamsPostRequest; + } + + foreach ($params as $paramName) { + $fieldValue = $this->request->getParam($paramName); + if ($fieldValue === null) { + throw new LocalizedException( + __("Missing expected parameter \"$paramName\" while attempting to generate template preview.") + ); + } + $fields[$paramName] = $fieldValue; + } + + return $fields; + } +} diff --git a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml index 97f31c618f9b..e7cbc675ce38 100644 --- a/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml +++ b/app/code/Magento/Email/view/adminhtml/layout/adminhtml_email_template_preview.xml @@ -12,7 +12,11 @@ <referenceContainer name="backend.page" remove="true"/> <referenceContainer name="menu.wrapper" remove="true"/> <referenceContainer name="root"> - <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml"/> + <block name="preview.page.content" class="Magento\Backend\Block\Page" template="Magento_Email::preview/iframeswitcher.phtml"> + <arguments> + <argument name="preview_form_view_model" xsi:type="object">Magento\Email\ViewModel\Template\Preview\Form</argument> + </arguments> + </block> </referenceContainer> </body> </page> diff --git a/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml b/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml index 4d26b59b093e..29ceb71a138e 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/preview/iframeswitcher.phtml @@ -7,13 +7,34 @@ /** @var \Magento\Backend\Block\Page $block */ ?> <div id="preview" class="cms-revision-preview"> - <iframe - name="preview_iframe" + <iframe name="preview_iframe" id="preview_iframe" frameborder="0" title="<?= $block->escapeHtmlAttr(__('Preview')) ?>" width="100%" - sandbox="allow-forms allow-pointer-lock" - src="<?= $block->escapeUrl($block->getUrl('*/*/popup', ['_current' => true])) ?>" - /> + sandbox="allow-same-origin allow-pointer-lock" + ></iframe> + <form id="preview_form" + action="<?= $block->escapeUrl($block->getUrl('*/*/popup')) ?>" + method="post" + target="preview_iframe" + > + <input type="hidden" name="form_key" value="<?= /* @noEscape */ $block->getFormKey() ?>" /> + <?php foreach ($block->getPreviewFormViewModel()->getFormFields() as $name => $value) : ?> + <input type="hidden" name="<?= $block->escapeHtmlAttr($name) ?>" value="<?= $block->escapeHtmlAttr($value) ?>"/> + <?php endforeach; ?> + </form> </div> +<script> +require([ + 'jquery' +], function($) { + $(document).ready(function() { + $('#preview_form').submit(); + }); + + $('#preview_iframe').load(function() { + $(this).height($(this).contents().height()); + }); +}); +</script> diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 9653156e85e8..d99a2703e3f9 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -48,7 +48,7 @@ use Magento\Framework\App\TemplateTypesInterface; <?= /* @noEscape */ $block->getFormHtml() ?> </form> -<form action="<?= $block->escapeUrl($block->getPreviewUrl()) ?>" method="get" id="email_template_preview_form" target="_blank"> +<form action="<?= $block->escapeUrl($block->getPreviewUrl()) ?>" method="post" id="email_template_preview_form" target="_blank"> <?= /* @noEscape */ $block->getBlockHtml('formkey') ?> <div class="no-display"> <input type="hidden" id="preview_type" name="type" value="<?= /* @noEscape */ $block->isTextType() ? 1 : 2 ?>" /> @@ -148,6 +148,7 @@ require([ } else { $('preview_type').value = <?= (int) $block->getTemplateType() ?>; } + if (typeof tinyMCE == 'undefined' || !tinyMCE.get('template_text')) { $('preview_text').value = $('template_text').value; } else { From 2f1860b9876094d7933bac3cf2ab7595f4bca0a4 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 1 Aug 2019 16:37:22 -0500 Subject: [PATCH 0254/1172] MC-17648: Registration email confirmation bugfix --- .../Customer/Api/AccountManagementMeTest.php | 27 ++++++++++--- .../Customer/Api/AccountManagementTest.php | 38 +++++++++++-------- 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 31894c1332ad..3c5a5a6770f5 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -215,6 +215,15 @@ public function testGetCustomerData() public function testGetCustomerActivateCustomer() { + // Update the customer's confirmation key to a known value + $this->customerData = $this->customerHelper->updateSampleCustomer( + $this->customerData[Customer::ID], + [ + 'id' => $this->customerData[Customer::ID], + 'confirmation' => CustomerHelper::CONFIRMATION + ] + ); + $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/activate', @@ -228,14 +237,22 @@ public function testGetCustomerActivateCustomer() 'token' => $this->token ] ]; - $requestData = ['confirmationKey' => $this->customerData[CustomerInterface::CONFIRMATION]]; + + $requestData = ['confirmationKey' => CustomerHelper::CONFIRMATION]; if (TESTS_WEB_API_ADAPTER === 'soap') { $requestData['customerId'] = 0; } - $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); - $this->assertEquals($this->customerData[CustomerInterface::ID], $customerResponseData[CustomerInterface::ID]); - // Confirmation key is removed after confirmation - $this->assertFalse(isset($customerResponseData[CustomerInterface::CONFIRMATION])); + + try { + $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals( + $this->customerData[CustomerInterface::ID], + $customerResponseData[CustomerInterface::ID] + ); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } + } /** diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php index b2276d79f5ec..a93bbcbdf04b 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php @@ -249,7 +249,15 @@ public function testCreateCustomerWithoutOptionalFields() public function testActivateCustomer() { $customerData = $this->_createCustomer(); - $this->assertNotNull($customerData[Customer::CONFIRMATION], 'Customer activation is not required'); + + // Update the customer's confirmation key to a known value + $customerData = $this->customerHelper->updateSampleCustomer( + $customerData[Customer::ID], + [ + 'id' => $customerData[Customer::ID], + 'confirmation' => CustomerHelper::CONFIRMATION + ] + ); $serviceInfo = [ 'rest' => [ @@ -265,16 +273,15 @@ public function testActivateCustomer() $requestData = [ 'email' => $customerData[Customer::EMAIL], - 'confirmationKey' => $customerData[Customer::CONFIRMATION], + 'confirmationKey' => CustomerHelper::CONFIRMATION ]; - $result = $this->_webApiCall($serviceInfo, $requestData); - - $this->assertEquals($customerData[Customer::ID], $result[Customer::ID], 'Wrong customer!'); - $this->assertTrue( - !isset($result[Customer::CONFIRMATION]) || $result[Customer::CONFIRMATION] === null, - 'Customer is not activated!' - ); + try { + $result = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals($customerData[Customer::ID], $result[Customer::ID], 'Wrong customer!'); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } } public function testGetCustomerActivateCustomer() @@ -294,14 +301,15 @@ public function testGetCustomerActivateCustomer() ]; $requestData = [ 'email' => $customerData[Customer::EMAIL], - 'confirmationKey' => $customerData[Customer::CONFIRMATION], + 'confirmationKey' => CustomerHelper::CONFIRMATION ]; - $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); - - $this->assertEquals($customerData[Customer::ID], $customerResponseData[Customer::ID]); - // Confirmation key is removed after confirmation - $this->assertFalse(isset($customerResponseData[Customer::CONFIRMATION])); + try { + $customerResponseData = $this->_webApiCall($serviceInfo, $requestData); + $this->assertEquals($customerData[Customer::ID], $customerResponseData[Customer::ID]); + } catch (\Exception $e) { + $this->fail('Customer is not activated.'); + } } public function testValidateResetPasswordLinkToken() From a282e764dcaaa44942dba29835aa5b6efd3745d5 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 1 Aug 2019 16:56:56 -0500 Subject: [PATCH 0255/1172] MC-17648: Registration email confirmation bugfix * Removed extra newline --- .../testsuite/Magento/Customer/Api/AccountManagementMeTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 3c5a5a6770f5..f3c981f74b83 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -252,7 +252,6 @@ public function testGetCustomerActivateCustomer() } catch (\Exception $e) { $this->fail('Customer is not activated.'); } - } /** From 48e7462eae84d7be2b50fda21935e8d5dea05826 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Fri, 2 Aug 2019 09:23:04 +0300 Subject: [PATCH 0256/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-6328 --- .../Controller/Adminhtml/ProductTest.php | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index acec996d0c40..90b03510044d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml; use Magento\Framework\App\Request\DataPersistorInterface; @@ -10,8 +12,12 @@ use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\Message\MessageInterface; +use Magento\Catalog\Model\Product; +use Magento\TestFramework\Helper\CacheCleaner; /** + * Test class for Product adminhtml actions + * * @magentoAppArea adminhtml */ class ProductTest extends \Magento\TestFramework\TestCase\AbstractBackendController @@ -58,11 +64,10 @@ public function testSaveActionAndNew() */ public function testSaveActionAndDuplicate() { - $this->getRequest()->setPostValue(['back' => 'duplicate']); $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); + /** @var Product $product */ $product = $repository->get('simple'); - $this->getRequest()->setMethod(HttpRequest::METHOD_POST); - $this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId()); + $this->assertSaveAndDuplicateAction($product); $this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/edit/')); $this->assertRedirect( $this->logicalNot( @@ -71,14 +76,30 @@ public function testSaveActionAndDuplicate() ) ) ); - $this->assertSessionMessages( - $this->contains('You saved the product.'), - MessageInterface::TYPE_SUCCESS - ); - $this->assertSessionMessages( - $this->contains('You duplicated the product.'), - MessageInterface::TYPE_SUCCESS - ); + } + + /** + * Test saving and duplicate existing product after the script execution. + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testSaveActionAndDuplicateWithUrlPathAttribute() + { + $repository = $this->_objectManager->create(\Magento\Catalog\Model\ProductRepository::class); + /** @var Product $product */ + $product = $repository->get('simple'); + + // set url_path attribute and check it + $product->setData('url_path', $product->getSku()); + $repository->save($product); + $urlPathAttribute = $product->getCustomAttribute('url_path'); + $this->assertEquals($urlPathAttribute->getValue(), $product->getSku()); + + // clean cache + CacheCleaner::cleanAll(); + + // dispatch Save&Duplicate action and check it + $this->assertSaveAndDuplicateAction($product); } /** @@ -355,4 +376,24 @@ private function getProductData(array $tierPrice) unset($product['entity_id']); return $product; } + + /** + * Dispatch Save&Duplicate action and check it + * + * @param Product $product + */ + private function assertSaveAndDuplicateAction(Product $product) + { + $this->getRequest()->setPostValue(['back' => 'duplicate']); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId()); + $this->assertSessionMessages( + $this->contains('You saved the product.'), + MessageInterface::TYPE_SUCCESS + ); + $this->assertSessionMessages( + $this->contains('You duplicated the product.'), + MessageInterface::TYPE_SUCCESS + ); + } } From a1cedf1558e7b23583aa4968acdbcd4958f9355a Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Fri, 2 Aug 2019 10:09:38 +0300 Subject: [PATCH 0257/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../Sales/Model/Order/ShipmentTest.php | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index 1d04a79ae3f8..9c0024480d16 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -117,9 +117,12 @@ public function testAddComment() $saved = $this->shipmentRepository->save($shipment); $comments = $saved->getComments(); - $actual = array_map(function (CommentInterface $comment) { - return $comment->getComment(); - }, $comments); + $actual = array_map( + function (CommentInterface $comment) { + return $comment->getComment(); + }, + $comments + ); self::assertEquals(2, count($actual)); self::assertEquals([$message1, $message2], $actual); } @@ -144,4 +147,33 @@ private function getOrder(string $incrementId): OrderInterface return array_pop($items); } + + /** + * Check that getTracksCollection() returns only order related tracks. + */ + public function testGetTracksCollection() + { + $order = $this->getOrder('100000001'); + $items = []; + foreach ($order->getItems() as $item) { + $items[$item->getId()] = $item->getQtyOrdered(); + } + /** @var \Magento\Sales\Model\Order\Shipment $shipment */ + $shipment = $this->objectManager->get(ShipmentFactory::class) + ->create($order, $items); + + $tracks = $shipment->getTracksCollection(); + self::assertTrue(empty($tracks->getItems())); + + /** @var ShipmentTrackInterface $track */ + $track = $this->objectManager->create(ShipmentTrackInterface::class); + $track->setNumber('Test Number') + ->setTitle('Test Title') + ->setCarrierCode('Test CODE'); + + $shipment->addTrack($track); + $this->shipmentRepository->save($shipment); + $saved = $shipment->getTracksCollection(); + self::assertTrue(in_array($track->getId(), $saved->getColumnValues('id'))); + } } From 42a5f9d6df6f7e323fbe7c47a8987ca8990319df Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Fri, 2 Aug 2019 16:20:17 +0300 Subject: [PATCH 0258/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-11232 --- .../Controller/Adminhtml/CategoryTest.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index 1001d58ee8a6..5e91d8b2092d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -3,14 +3,21 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml; +use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Helper\Bootstrap; use Magento\Store\Model\Store; use Magento\Catalog\Model\ResourceModel\Product; /** + * Test for category backend actions + * * @magentoAppArea adminhtml */ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractBackendController @@ -36,6 +43,8 @@ protected function setUp() } /** + * Test save action + * * @magentoDataFixture Magento/Store/_files/core_fixturestore.php * @magentoDbIsolation enabled * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 @@ -95,6 +104,44 @@ public function testSaveAction($inputData, $defaultAttributes, $attributesSaved } /** + * Check default value for category url path + * + * @magentoDbIsolation enabled + * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php + * @throws NoSuchEntityException + */ + public function testDefaultValueForCategoryUrlPath() + { + $repository = $this->_objectManager->get(CategoryRepositoryInterface::class); + $categoryId = 3; + $category = $repository->get($categoryId); + $newUrlPath = 'test_url_path'; + $defaultUrlPath = $category->getData('url_path'); + + // update url_path and check it + $category->setStoreId(1); + $category->setUrlKey($newUrlPath); + $category->setUrlPath($newUrlPath); + $repository->save($category); + $this->assertEquals($newUrlPath, $category->getUrlPath()); + + // set default url_path and check it + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $postData = $category->getData(); + $postData['use_default'] = [ + 'available_sort_by' => 1, + 'default_sort_by' => 1, + 'url_key' => 1, + ]; + $this->getRequest()->setPostValue($postData); + $this->dispatch('backend/catalog/category/save'); + $category = $repository->get($categoryId); + $this->assertEquals($defaultUrlPath, $category->getData('url_path')); + } + + /** + * Test save action from product form page + * * @param array $postData * @dataProvider categoryCreatedFromProductCreationPageDataProvider * @magentoDbIsolation enabled @@ -130,6 +177,8 @@ public function testSaveActionFromProductCreationPage($postData) } /** + * Get category post data + * * @static * @return array */ @@ -174,6 +223,8 @@ public function testSuggestCategoriesActionNoSuggestions() } /** + * Save action data provider + * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @return array */ @@ -382,6 +433,8 @@ public function testSaveActionCategoryWithDangerRequest() } /** + * Test move Action + * * @magentoDataFixture Magento/Catalog/_files/category_tree.php * @dataProvider moveActionDataProvider * @@ -420,6 +473,8 @@ public function testMoveAction($parentId, $childId, $childUrlKey, $grandChildId, } /** + * Move action data provider + * * @return array */ public function moveActionDataProvider() @@ -433,6 +488,8 @@ public function moveActionDataProvider() } /** + * Test save action + * * @magentoDataFixture Magento/Catalog/_files/products_in_different_stores.php * @magentoDbIsolation disabled * @dataProvider saveActionWithDifferentWebsitesDataProvider @@ -460,6 +517,8 @@ public function testSaveCategoryWithProductPosition(array $postData) } /** + * Save action data provider + * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @return array */ From d18dfe8554e158282b59870c75f64bdef3492301 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 2 Aug 2019 08:39:13 -0500 Subject: [PATCH 0259/1172] MC-17700: Downloadable Product links --- .../Setup/Patch/Data/AddDownloadableHostsConfig.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php index 958a9f58153a..0e88bd166b60 100644 --- a/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php +++ b/app/code/Magento/Downloadable/Setup/Patch/Data/AddDownloadableHostsConfig.php @@ -158,8 +158,11 @@ private function addStoreAndWebsiteUrlsFromScope(Store $scope) $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_DIRECT_LINK, true)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, false)); $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_MEDIA, true)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); - $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + + try { + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, false)); + $this->addHost($scope->getBaseUrl(UrlInterface::URL_TYPE_STATIC, true)); + } catch (\UnexpectedValueException $e) {} //@codingStandardsIgnoreLine try { $website = $scope->getWebsite(); From d1144d42126167b284edf08e859ac87bb3766df3 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Fri, 2 Aug 2019 08:49:02 -0500 Subject: [PATCH 0260/1172] MC-17648: Registration email confirmation bugfix --- .../Magento/Customer/Api/AccountManagementMeTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index f3c981f74b83..808906c64a5b 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -217,9 +217,9 @@ public function testGetCustomerActivateCustomer() { // Update the customer's confirmation key to a known value $this->customerData = $this->customerHelper->updateSampleCustomer( - $this->customerData[Customer::ID], + $this->customerData[CustomerInterface::ID], [ - 'id' => $this->customerData[Customer::ID], + 'id' => $this->customerData[CustomerInterface::ID], 'confirmation' => CustomerHelper::CONFIRMATION ] ); From 8334ad0daa529f5345c536112b9194c6d2f73683 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Fri, 2 Aug 2019 09:09:38 -0500 Subject: [PATCH 0261/1172] MC-17648: Registration email confirmation bugfix --- .../Magento/Customer/Api/AccountManagementMeTest.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php index 808906c64a5b..88bb3a8d59af 100644 --- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php @@ -215,15 +215,6 @@ public function testGetCustomerData() public function testGetCustomerActivateCustomer() { - // Update the customer's confirmation key to a known value - $this->customerData = $this->customerHelper->updateSampleCustomer( - $this->customerData[CustomerInterface::ID], - [ - 'id' => $this->customerData[CustomerInterface::ID], - 'confirmation' => CustomerHelper::CONFIRMATION - ] - ); - $serviceInfo = [ 'rest' => [ 'resourcePath' => self::RESOURCE_PATH . '/activate', From e62450604e7742381e2358400bb197f49035e4bb Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Fri, 2 Aug 2019 22:59:59 -0700 Subject: [PATCH 0262/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Updated composer, DisableAdminUsage, EnableAdminUsage --- .../Adminhtml/Config/DisableAdminUsage.php | 8 + .../Adminhtml/Config/EnableAdminUsage.php | 8 + app/code/Magento/AdminAnalytics/composer.json | 6 +- package-lock.json | 861 ++++++++++++++++++ 4 files changed, 880 insertions(+), 3 deletions(-) create mode 100644 package-lock.json diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 82d8ac6480b0..a5bf4640c650 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,4 +97,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 899d05d317e6..397176f37b9d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,4 +97,12 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/composer.json b/app/code/Magento/AdminAnalytics/composer.json index 0c930560425f..0b977a23ad3c 100644 --- a/app/code/Magento/AdminAnalytics/composer.json +++ b/app/code/Magento/AdminAnalytics/composer.json @@ -8,9 +8,9 @@ "php": "~7.1.3||~7.2.0||~7.3.0", "magento/framework": "*", "magento/module-backend": "*", - "magento/Config": "*", - "magento/Ui": "*", - "magento/ReleaseNotification": "*" + "magento/module-config": "*", + "magento/module-ui": "*", + "magento/module-release-notification": "*" }, "type": "magento2-module", "license": [ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000000..b3e14ddab5aa --- /dev/null +++ b/package-lock.json @@ -0,0 +1,861 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "acorn": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", + "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^6.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", + "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + }, + "espree": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", + "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz", + "integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + } + } + } +} From a70b6c9bb88109300d8f89cd3b93661a8500a238 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Sat, 3 Aug 2019 15:16:12 -0700 Subject: [PATCH 0263/1172] MC-15298: Allow admin to opt out of admin analytics tracking - edited DisableAdmin, EnableAdmin, admin_usage_notification --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 2 ++ .../Controller/Adminhtml/Config/EnableAdminUsage.php | 2 ++ ...nDataProvider.php => AdminUsageNotificationDataProvider.php} | 2 +- .../view/adminhtml/ui_component/admin_usage_notification.xml | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) rename app/code/Magento/AdminAnalytics/Ui/DataProvider/{NotificationDataProvider.php => AdminUsageNotificationDataProvider.php} (98%) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index a5bf4640c650..16667737f59a 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -99,6 +99,8 @@ public function execute() } /** + * Determines if its allowed + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 397176f37b9d..9d68121c147a 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -99,6 +99,8 @@ public function execute() } /** + * Determines if its allowed + * * @return bool */ protected function _isAllowed() diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php similarity index 98% rename from app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php rename to app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 8b3e25e2a6d2..9ab7c8b2c501 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/NotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -15,7 +15,7 @@ /** * Data Provider for the Admin usage UI component. */ -class NotificationDataProvider implements DataProviderInterface +class AdminUsageNotificationDataProvider implements DataProviderInterface { /** * @var PoolInterface diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 090259af427b..5547946eb66c 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -37,7 +37,7 @@ <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item> </item> </argument> - <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\NotificationDataProvider" name="admin_usage_notification_data_source"> + <dataProvider class="Magento\AdminAnalytics\Ui\DataProvider\AdminUsageNotificationDataProvider" name="admin_usage_notification_data_source"> <settings> <requestFieldName>id</requestFieldName> <primaryFieldName>entity_id</primaryFieldName> From 1a4a5066c3f3f8b0ad12b17e68ea617ccac9c119 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Mon, 5 Aug 2019 11:56:24 +0300 Subject: [PATCH 0264/1172] MC-15577: Fix url output --- lib/internal/Magento/Framework/Escaper.php | 25 ++++++++++++++++++- .../Framework/Test/Unit/EscaperTest.php | 23 +++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Escaper.php b/lib/internal/Magento/Framework/Escaper.php index cb4636471cd7..5fac9633bb37 100644 --- a/lib/internal/Magento/Framework/Escaper.php +++ b/lib/internal/Magento/Framework/Escaper.php @@ -28,6 +28,11 @@ class Escaper */ private $logger; + /** + * @var \Magento\Framework\Translate\InlineInterface + */ + private $translateInline; + /** * @var string[] */ @@ -335,8 +340,11 @@ public function escapeJsQuote($data, $quote = '\'') */ public function escapeXssInUrl($data) { + $data = (string)$data; + $this->getTranslateInline()->processResponseBody($data); + return htmlspecialchars( - $this->escapeScriptIdentifiers((string)$data), + $this->escapeScriptIdentifiers($data), $this->htmlSpecialCharsFlag | ENT_HTML5 | ENT_HTML401, 'UTF-8', false @@ -430,4 +438,19 @@ private function filterProhibitedTags(array $allowedTags): array return $allowedTags; } + + /** + * Resolve inline translator. + * + * @return \Magento\Framework\Translate\InlineInterface + */ + private function getTranslateInline() + { + if ($this->translateInline === null) { + $this->translateInline = \Magento\Framework\App\ObjectManager::getInstance() + ->get(\Magento\Framework\Translate\InlineInterface::class); + } + + return $this->translateInline; + } } diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index bc12b0bd1227..802477c0ee7b 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -7,6 +7,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\Escaper; +use Magento\Framework\Translate\Inline; /** * \Magento\Framework\Escaper test case @@ -16,26 +17,40 @@ class EscaperTest extends \PHPUnit\Framework\TestCase /** * @var \Magento\Framework\Escaper */ - protected $escaper = null; + protected $escaper; /** * @var \Magento\Framework\ZendEscaper */ private $zendEscaper; + /** + * @var Inline + */ + private $translateInline; + /** * @var \Psr\Log\LoggerInterface */ private $loggerMock; + /** + * @inheritdoc + */ protected function setUp() { + $objectManagerHelper = new ObjectManager($this); $this->escaper = new Escaper(); $this->zendEscaper = new \Magento\Framework\ZendEscaper(); + $this->translateInline = $objectManagerHelper->getObject(Inline::class); $this->loggerMock = $this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class); - $objectManagerHelper = new ObjectManager($this); $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'escaper', $this->zendEscaper); $objectManagerHelper->setBackwardCompatibleProperty($this->escaper, 'logger', $this->loggerMock); + $objectManagerHelper->setBackwardCompatibleProperty( + $this->escaper, + 'translateInline', + $this->translateInline + ); } /** @@ -390,6 +405,10 @@ public function escapeDataProvider() 'http://test.com/?redirect=\x64\x61\x74\x61\x3a\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', 'http://test.com/?redirect=:\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', ], + [ + 'http://test.com/?redirect={{{j}}{{j}}{{j}}{{j}}}avascript:alert(1)', + 'http://test.com/?redirect=:alert(1)', + ], ]; } } From 29051483b487beabda580f8a6e012e08402d48a9 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Mon, 5 Aug 2019 13:56:12 +0300 Subject: [PATCH 0265/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-6308 --- .../Magento/Catalog/Model/ProductTest.php | 111 ++++++++++++++++-- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php index c34120404a95..d7da47ef7872 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php @@ -8,7 +8,12 @@ namespace Magento\Catalog\Model; +use Magento\Catalog\Model\Product; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; /** * Tests product model: @@ -26,31 +31,32 @@ class ProductTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Catalog\Api\ProductRepositoryInterface + * @var ProductRepositoryInterface */ protected $productRepository; /** - * @var \Magento\Catalog\Model\Product + * @var Product */ protected $_model; + /** + * @var ObjectManagerInterface + */ + private $objectManager; + /** * @inheritdoc */ protected function setUp() { - $this->productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); - - $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Catalog\Model\Product::class - ); + $this->objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $this->_model = $this->objectManager->create(Product::class); } /** - * @throws \Magento\Framework\Exception\FileSystemException - * @return void + * @inheritdoc */ public static function tearDownAfterClass() { @@ -74,6 +80,8 @@ public static function tearDownAfterClass() } /** + * Test can affect options + * * @return void */ public function testCanAffectOptions() @@ -84,6 +92,8 @@ public function testCanAffectOptions() } /** + * Test CRUD + * * @magentoDbIsolation enabled * @magentoAppIsolation enabled * @magentoAppArea adminhtml @@ -116,6 +126,8 @@ public function testCRUD() } /** + * Test clean cache + * * @return void */ public function testCleanCache() @@ -139,6 +151,8 @@ public function testCleanCache() } /** + * Test add image to media gallery + * * @return void */ public function testAddImageToMediaGallery() @@ -183,6 +197,8 @@ protected function _copyFileToBaseTmpMediaPath($sourceFile) } /** + * Test duplicate method + * * @magentoAppIsolation enabled * @magentoAppArea adminhtml */ @@ -213,6 +229,8 @@ public function testDuplicate() } /** + * Test duplicate sku generation + * * @magentoAppArea adminhtml */ public function testDuplicateSkuGeneration() @@ -244,6 +262,8 @@ protected function _undo($duplicate) } /** + * Test visibility api + * * @covers \Magento\Catalog\Model\Product::getVisibleInCatalogStatuses * @covers \Magento\Catalog\Model\Product::getVisibleStatuses * @covers \Magento\Catalog\Model\Product::isVisibleInCatalog @@ -286,6 +306,8 @@ public function testVisibilityApi() } /** + * Test isDuplicable and setIsDuplicable methods + * * @covers \Magento\Catalog\Model\Product::isDuplicable * @covers \Magento\Catalog\Model\Product::setIsDuplicable */ @@ -297,6 +319,8 @@ public function testIsDuplicable() } /** + * Test isSalable, isSaleable, isAvailable and isInStock methods + * * @covers \Magento\Catalog\Model\Product::isSalable * @covers \Magento\Catalog\Model\Product::isSaleable * @covers \Magento\Catalog\Model\Product::isAvailable @@ -314,6 +338,8 @@ public function testIsSalable() } /** + * Test isSalable method when Status is disabled + * * @covers \Magento\Catalog\Model\Product::isSalable * @covers \Magento\Catalog\Model\Product::isSaleable * @covers \Magento\Catalog\Model\Product::isAvailable @@ -331,6 +357,8 @@ public function testIsNotSalableWhenStatusDisabled() } /** + * Test isVirtual and getIsVirtual methods + * * @covers \Magento\Catalog\Model\Product::isVirtual * @covers \Magento\Catalog\Model\Product::getIsVirtual */ @@ -349,6 +377,8 @@ public function testIsVirtual() } /** + * Test toArray method + * * @return void */ public function testToArray() @@ -359,6 +389,8 @@ public function testToArray() } /** + * Test fromArray method + * * @return void */ public function testFromArray() @@ -368,6 +400,8 @@ public function testFromArray() } /** + * Test set original data backend + * * @magentoAppArea adminhtml */ public function testSetOrigDataBackend() @@ -378,6 +412,8 @@ public function testSetOrigDataBackend() } /** + * Test reset method + * * @magentoAppArea frontend */ public function testReset() @@ -418,6 +454,8 @@ protected function _assertEmpty($model) } /** + * Test is products has sku + * * @magentoDataFixture Magento/Catalog/_files/multiple_products.php */ public function testIsProductsHasSku() @@ -433,6 +471,8 @@ public function testIsProductsHasSku() } /** + * Test process by request + * * @return void */ public function testProcessBuyRequest() @@ -444,6 +484,8 @@ public function testProcessBuyRequest() } /** + * Test validate method + * * @return void */ public function testValidate() @@ -480,6 +522,8 @@ public function testValidate() } /** + * Test validate unique input attribute value + * * @magentoDbIsolation enabled * @magentoDataFixture Magento/Catalog/_files/products_with_unique_input_attribute.php */ @@ -523,6 +567,8 @@ public function testValidateUniqueInputAttributeValue() } /** + * Test validate unique input attribute value on the same product + * * @magentoDbIsolation enabled * @magentoDataFixture Magento/Catalog/_files/products_with_unique_input_attribute.php */ @@ -618,8 +664,53 @@ public function testSaveWithBackordersEnabled(int $qty, int $stockStatus, bool $ $this->assertEquals($expectedStockStatus, $stockItem->getIsInStock()); } + /** + * Checking enable/disable product when Catalog Flat Product is enabled + * + * @magentoAppArea frontend + * @magentoDbIsolation disabled + * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1 + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * + * @return void + * @throws \Magento\Framework\Exception\CouldNotSaveException + * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @throws \Magento\Framework\Exception\StateException + */ + public function testProductStatusWhenCatalogFlatProductIsEnabled() + { + // check if product flat table is enabled + $productFlatState = $this->objectManager->get(\Magento\Catalog\Model\Indexer\Product\Flat\State::class); + $this->assertTrue($productFlatState->isFlatEnabled()); + // run reindex to create product flat table + $productFlatProcessor = $this->objectManager->get(\Magento\Catalog\Model\Indexer\Product\Flat\Processor::class); + $productFlatProcessor->reindexAll(); + // get created simple product + $product = $this->productRepository->get('simple'); + // get db connection and the product flat table name + $resource = $this->objectManager->get(\Magento\Framework\App\ResourceConnection::class); + /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ + $connection = $resource->getConnection(); + $productFlatTableName = $productFlatState->getFlatIndexerHelper()->getFlatTableName(1); + // generate sql query to find created simple product in the flat table + $sql = $connection->select()->from($productFlatTableName)->where('sku =?', $product->getSku()); + // check if the product exists in the product flat table + $products = $connection->fetchAll($sql); + $this->assertEquals(Status::STATUS_ENABLED, $product->getStatus()); + $this->assertNotEmpty($products); + // disable product + $product->setStatus(Status::STATUS_DISABLED); + $product = $this->productRepository->save($product); + // check if the product exists in the product flat table + $products = $connection->fetchAll($sql); + $this->assertEquals(Status::STATUS_DISABLED, $product->getStatus()); + $this->assertEmpty($products); + } + /** * DataProvider for the testSaveWithBackordersEnabled() + * * @return array */ public function productWithBackordersDataProvider(): array From 004db8edd825a3fd8798c89ed52885d66fcf579d Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 08:37:25 -0500 Subject: [PATCH 0266/1172] MC-15298: Allow admin to opt out of admin analytics tracking - edited DisableAdmin, EnableAdmin --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 ---------- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 16667737f59a..82d8ac6480b0 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,14 +97,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Determines if its allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9d68121c147a..899d05d317e6 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,14 +97,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Determines if its allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } From 3d1721e6a948727c96009544bb58685f30388b86 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 08:51:39 -0500 Subject: [PATCH 0267/1172] MC-15298: Allow admin to opt out of admin analytics tracking - edited CanViewNotificationTest's namespace --- .../Test/Unit/Condition/CanViewNotificationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php index 75306ddcd85e..00309f952701 100644 --- a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\AdminAnalytics\Test\Unit\Model\Condition; +namespace Magento\AdminAnalytics\Test\Unit\Condition; use Magento\AdminAnalytics\Model\Condition\CanViewNotification; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; From 7d3f1c72994b8e7509aaa8a19a8cdcde6a300f43 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 09:53:30 -0500 Subject: [PATCH 0268/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Edited composer.json, DisableAdminUsage, and EnableAdminUsage --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 ++++++++++ .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ++++++++++ composer.lock | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 82d8ac6480b0..7165a705233a 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -97,4 +97,14 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if DisableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 899d05d317e6..b6414b2a5996 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -97,4 +97,14 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if EnableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + return parent::_isAllowed(); + } } diff --git a/composer.lock b/composer.lock index 8c9f79cac256..e376df91e863 100644 --- a/composer.lock +++ b/composer.lock @@ -2402,7 +2402,7 @@ }, { "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "email": "backendtea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", From fd2b4ed135d9cd0420bb92790e0522f331879fe4 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 11:27:15 -0500 Subject: [PATCH 0269/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Implemented HttpPostActionInterface to EnableAdminUsage, DisableAdminUsage --- .../Adminhtml/Config/DisableAdminUsage.php | 13 ++----------- .../Adminhtml/Config/EnableAdminUsage.php | 13 ++----------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 7165a705233a..356f27498fa6 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -7,6 +7,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -17,7 +18,7 @@ /** * Controller to record Admin analytics usage log */ -class DisableAdminUsage extends Action +class DisableAdminUsage extends Action implements HttpPostActionInterface { private $configFactory; @@ -97,14 +98,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if DisableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index b6414b2a5996..28f22533a42b 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -7,6 +7,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; +use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -17,7 +18,7 @@ /** * Controller to record that the current admin user has responded to Admin Analytics notice */ -class EnableAdminUsage extends Action +class EnableAdminUsage extends Action implements HttpPostActionInterface { private $configFactory; @@ -97,14 +98,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if EnableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - return parent::_isAllowed(); - } } From 65d4444aeb618555c5b3609f0d7e2f240636b089 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 14:10:39 -0500 Subject: [PATCH 0270/1172] MC-17593: add mftw test case - updated LoginUser, AdminAuthLogin --- .../Backend/Test/Handler/Ui/LoginUser.php | 1 + .../Backend/Test/Page/AdminAuthLogin.php | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php index 01d8401b22fe..39f5866a3c2a 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Ui/LoginUser.php @@ -47,6 +47,7 @@ public function persist(FixtureInterface $fixture = null) $loginForm->fill($fixture); $loginForm->submit(); $loginPage->waitForHeaderBlock(); + $loginPage->dismissAdminUsageNotification(); } } } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index c836c4db81ef..1501a21163b5 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -40,6 +40,11 @@ class AdminAuthLogin extends Page */ protected $messagesBlock = '.messages'; + /** + * Admin Analytics selector + */ + protected $adminUsageSelector ='.modal-inner-wrap'; + /** * Constructor. */ @@ -98,4 +103,23 @@ function () use ($browser, $selector) { } ); } -} + + public function dismissAdminUsageNotification() + { + $browser = $this->browser; + $selector = $this->adminUsageSelector; + $browser->waitUntil( + function () use ($browser, $selector) { + $item = $browser->find($selector); + if ($item->isVisible()) { + return true; + } + usleep(200000); + return true; + } + ); + if ($this->browser->find($selector)->isVisible()) { + $this->browser->find($selector)->click(); + } + } +} \ No newline at end of file From e6bceb3d653d29e1d2215b17fcce80afe6765873 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 14:36:22 -0500 Subject: [PATCH 0271/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Edited DisableAdminUsage, EnableAdminUsage, AdminUsasgeNotificationDataProvider, admin_usage_notification, component, component-mixin, componser --- .../Adminhtml/Config/DisableAdminUsage.php | 11 +++++++++ .../Adminhtml/Config/EnableAdminUsage.php | 11 +++++++++ .../AdminUsageNotificationDataProvider.php | 9 -------- .../ui_component/admin_usage_notification.xml | 2 +- .../view/adminhtml/web/js/modal/component.js | 23 +++++++++++++++++++ .../modal/component-mixin.js | 10 ++++++-- composer.json | 1 + composer.lock | 2 +- 8 files changed, 56 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 356f27498fa6..170067bcc5db 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -98,4 +98,15 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if DisableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + $isAllowed = parent::_isAllowed(); + return $isAllowed; + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 28f22533a42b..cdb00f12e1d3 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -98,4 +98,15 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * Checks if EnableAdminUsage is allowed + * + * @return bool + */ + protected function _isAllowed() + { + $isAllowed = parent::_isAllowed(); + return $isAllowed; + } } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 9ab7c8b2c501..5e8bc2d9160d 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -86,11 +86,6 @@ public function __construct( */ public function getData() { - /** @var ModifierInterface $modifier */ - foreach ($this->pool->getModifiersInstances() as $modifier) { - $this->data = $modifier->modifyData($this->data); - } - return $this->data; } @@ -99,10 +94,6 @@ public function getData() */ public function getMeta() { - /** @var ModifierInterface $modifier */ - foreach ($this->pool->getModifiersInstances() as $modifier) { - $this->meta = $modifier->modifyMeta($this->meta); - } return $this->meta; } diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml index 5547946eb66c..3c35f1937783 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/ui_component/admin_usage_notification.xml @@ -85,7 +85,7 @@ <item name="text" xsi:type="string" translate="true"><![CDATA[ <p>Help us improve Magento Admin by allowing us to collect usage data.</p> <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a></p> + <p>You can learn more and opt out at any time by following the instructions in <a href="https://docs.magento.com/m2/ce/user_guide/stores/admin.html" target="_blank">merchant documentation</a>.</p> ]]></item> </item> </argument> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 091098a059a9..1725cf3dce33 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -22,6 +22,9 @@ define([ }, options: { keyEventHandlers: { + /** + * Prevents escape key from exiting out of modal + */ escapeKey: function () { return; } @@ -29,13 +32,25 @@ define([ }, notificationWindow: null, }, + + /** + * Initializes modal on opened function + */ initModal: function () { this.options.opened = this.onOpened.bind(this); this._super(); }, + + /** + * Once the modal is opened it hides the X + */ onOpened: function () { $('.modal-header button.action-close').hide(); }, + + /** + * Changes admin usage setting to yes + */ enableAdminUsage: function () { var data = { 'form_key': window.FORM_KEY @@ -58,6 +73,10 @@ define([ this.openReleasePopup(); this.closeModal(); }, + + /** + * Changes admin usage setting to no + */ disableAdminUsage: function () { var data = { 'form_key': window.FORM_KEY @@ -80,6 +99,10 @@ define([ this.openReleasePopup(); this.closeModal(); }, + + /** + * Allows admin usage popup to be shown first and then new release notification + */ openReleasePopup: function () { var notifiModal = registry.get('release_notification.release_notification.notification_modal_1'); diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index fdfb85dd1181..0cab32739a3b 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -6,8 +6,10 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { 'use strict'; - var deferred = $.Deferred(); - var mixin = { + var deferred = $.Deferred(), mixin = { + /** + * Initializes content only if its visible + */ initializeContent: function () { var initializeContent = this._super.bind(this); @@ -19,6 +21,10 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { }); } }, + + /** + * Initializes release notification content after admin analytics + */ initializeContentAfterAnalytics: function () { deferred.resolve(); } diff --git a/composer.json b/composer.json index 7235e75f2326..a2d5624ea6fd 100644 --- a/composer.json +++ b/composer.json @@ -99,6 +99,7 @@ }, "replace": { "magento/module-marketplace": "*", + "magento/module-admin-analytics": "*", "magento/module-admin-notification": "*", "magento/module-advanced-pricing-import-export": "*", "magento/module-amqp": "*", diff --git a/composer.lock b/composer.lock index e376df91e863..52a40e589fd9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0cf49b3b5a47076608e87c7ddb566073", + "content-hash": "630adf0f19937bd3303fd1e72a68efad", "packages": [ { "name": "braintree/braintree_php", From 439830da50d2e54e112cd5583cae5bbd4752dfa4 Mon Sep 17 00:00:00 2001 From: Sergey Dovbenko <sdovbenko@magecom.us> Date: Mon, 5 Aug 2019 20:49:19 +0000 Subject: [PATCH 0272/1172] Set GraphQlInputException when not formatted --- .../CatalogGraphQl/Model/Product/Option/DateType.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php index e1106a3f696e..40d77e36659a 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php +++ b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php @@ -10,6 +10,7 @@ use Magento\Catalog\Model\Product\Option\Type\Date as ProductDateOptionType; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Stdlib\DateTime; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** * @inheritdoc @@ -43,6 +44,13 @@ private function formatValues($values) if (isset($values[$this->getOption()->getId()])) { $value = $values[$this->getOption()->getId()]; $dateTime = \DateTime::createFromFormat(DateTime::DATETIME_PHP_FORMAT, $value); + + if (!$dateTime) { + throw new GraphQlInputException( + __('Invalid format provided. Please use \'Y-m-d H:i:s\' format.') + ); + } + $values[$this->getOption()->getId()] = [ 'date' => $value, 'year' => $dateTime->format('Y'), From 2503817fa0302820ac7c1a7f59d4160b221d2c01 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 15:55:55 -0500 Subject: [PATCH 0273/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Edited component, component-mixin, AdminAuthLogin static failures --- .../AdminAnalytics/view/adminhtml/web/js/modal/component.js | 2 +- .../web/js/release-notification/modal/component-mixin.js | 5 ++++- .../tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index 1725cf3dce33..bfe9ec3d97e9 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -30,7 +30,7 @@ define([ } } }, - notificationWindow: null, + notificationWindow: null }, /** diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js index 0cab32739a3b..ffecd031cbb4 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/release-notification/modal/component-mixin.js @@ -6,7 +6,9 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { 'use strict'; - var deferred = $.Deferred(), mixin = { + var deferred = $.Deferred(), + + mixin = { /** * Initializes content only if its visible */ @@ -34,3 +36,4 @@ define(['jquery', 'analyticsPopupConfig'], function ($, analyticsPopupConfig) { return target.extend(mixin); }; }); + diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 1501a21163b5..7201054121dc 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -122,4 +122,4 @@ function () use ($browser, $selector) { $this->browser->find($selector)->click(); } } -} \ No newline at end of file +} From 8b60dd092c86b0ba7457a8e2dcd9d266b4662d7c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 16:39:43 -0500 Subject: [PATCH 0274/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Edited component static failure --- .../AdminAnalytics/view/adminhtml/web/js/modal/component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js index bfe9ec3d97e9..bc09890d0d0b 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/web/js/modal/component.js @@ -109,7 +109,7 @@ define([ if (analyticsPopupConfig.releaseVisible) { notifiModal.initializeContentAfterAnalytics(); } - }, + } } ); } From 35a278548c483ff1e5d0161ff5e2980446820267 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Mon, 5 Aug 2019 20:13:43 -0500 Subject: [PATCH 0275/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Edited CreateTest, IndexTest, default.xml, adminhtml_dashboard_index --- .../layout/adminhtml_dashboard_index.xml | 22 +++++++++++++++++++ .../view/adminhtml/layout/default.xml | 10 --------- .../Adminhtml/Dashboard/IndexTest.php | 4 ++-- .../Controller/Adminhtml/Order/CreateTest.php | 2 +- 4 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml new file mode 100644 index 000000000000..3069db1ecc2b --- /dev/null +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceContainer name="content"> + <uiComponent name="admin_usage_notification"> + <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> + </uiComponent> + <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> + <arguments> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + </arguments> + </block> + </referenceContainer> + </body> +</page> \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 688bbc1e4188..05f7df828416 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -14,16 +14,6 @@ </arguments> </block> </referenceContainer> - <referenceContainer name="content"> - <uiComponent name="admin_usage_notification"> - <visibilityCondition name="can_view_admin_usage_notification" className="Magento\AdminAnalytics\Model\Condition\CanViewNotification"/> - </uiComponent> - <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> - <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> - </arguments> - </block> - </referenceContainer> </body> </page> diff --git a/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php b/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php index 2f89f70a6c87..ffe3ccf49eba 100644 --- a/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php +++ b/dev/tests/integration/testsuite/Magento/ReleaseNotification/Controller/Adminhtml/Dashboard/IndexTest.php @@ -72,7 +72,7 @@ public function testExecuteEmptyContent() $this->assertEquals(200, $this->getResponse()->getHttpResponseCode()); $actual = $this->getResponse()->getBody(); - $this->assertNotContains('"autoOpen":true', $actual); + $this->assertContains('"autoOpen":false', $actual); } public function testExecuteFalseContent() @@ -87,6 +87,6 @@ public function testExecuteFalseContent() $this->assertEquals(200, $this->getResponse()->getHttpResponseCode()); $actual = $this->getResponse()->getBody(); - $this->assertNotContains('"autoOpen":true', $actual); + $this->assertContains('"autoOpen":false', $actual); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php index a07616474a41..3d0eb2d4d75e 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php @@ -55,7 +55,7 @@ public function testLoadBlockAction() $this->getRequest()->setParam('block', ','); $this->getRequest()->setParam('json', 1); $this->dispatch('backend/sales/order_create/loadBlock'); - $this->assertEquals('{"message":""}', $this->getResponse()->getBody()); + $this->assertContains('"message":""}', $this->getResponse()->getBody()); } /** From 45e708cacfecd84181ff437c08733d93540b9086 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Tue, 6 Aug 2019 11:02:50 +0300 Subject: [PATCH 0276/1172] MC-15577: Fix url output --- lib/internal/Magento/Framework/Test/Unit/EscaperTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php index 802477c0ee7b..426081e71fde 100644 --- a/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php +++ b/lib/internal/Magento/Framework/Test/Unit/EscaperTest.php @@ -406,8 +406,8 @@ public function escapeDataProvider() 'http://test.com/?redirect=:\x74\x65\x78\x74x2cCPHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg', ], [ - 'http://test.com/?redirect={{{j}}{{j}}{{j}}{{j}}}avascript:alert(1)', - 'http://test.com/?redirect=:alert(1)', + 'http://test.com/?{{{test}}{{test_translated}}{{tes_origin}}{{theme}}}', + 'http://test.com/?test', ], ]; } From c75e923887f687ae88c859ddce6d82dfee402860 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 6 Aug 2019 11:51:56 +0300 Subject: [PATCH 0277/1172] MC-15930: [FT] [MFTF] AddOutOfStockProductToCompareListTest or functionality is wrong --- .../Controller/Product/Compare/Add.php | 61 ++++++++++++++++++- .../Controller/Product/Compare/Remove.php | 6 +- .../AddOutOfStockProductToCompareListTest.xml | 14 ++--- .../Checker/AddToCompareAvailability.php | 9 ++- ...refrontOnePageCheckoutJsValidationTest.xml | 1 + 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php index 2b989dde9809..8b854361fd4e 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php @@ -6,15 +6,72 @@ */ namespace Magento\Catalog\Controller\Product\Compare; -use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\ViewModel\Product\Checker\AddToCompareAvailability; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\Data\Form\FormKey\Validator; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Result\PageFactory; /** * Add item to compare list action. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Add extends \Magento\Catalog\Controller\Product\Compare implements HttpPostActionInterface { + /** + * @var AddToCompareAvailability + */ + private $compareAvailability; + + /** + * @param \Magento\Framework\App\Action\Context $context + * @param \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory + * @param \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory + * @param \Magento\Customer\Model\Session $customerSession + * @param \Magento\Customer\Model\Visitor $customerVisitor + * @param \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList + * @param \Magento\Catalog\Model\Session $catalogSession + * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param Validator $formKeyValidator + * @param PageFactory $resultPageFactory + * @param ProductRepositoryInterface $productRepository + * @param AddToCompareAvailability|null $compareAvailability + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + \Magento\Framework\App\Action\Context $context, + \Magento\Catalog\Model\Product\Compare\ItemFactory $compareItemFactory, + \Magento\Catalog\Model\ResourceModel\Product\Compare\Item\CollectionFactory $itemCollectionFactory, + \Magento\Customer\Model\Session $customerSession, + \Magento\Customer\Model\Visitor $customerVisitor, + \Magento\Catalog\Model\Product\Compare\ListCompare $catalogProductCompareList, + \Magento\Catalog\Model\Session $catalogSession, + \Magento\Store\Model\StoreManagerInterface $storeManager, + Validator $formKeyValidator, + PageFactory $resultPageFactory, + ProductRepositoryInterface $productRepository, + AddToCompareAvailability $compareAvailability = null + ) { + parent::__construct( + $context, + $compareItemFactory, + $itemCollectionFactory, + $customerSession, + $customerVisitor, + $catalogProductCompareList, + $catalogSession, + $storeManager, + $formKeyValidator, + $resultPageFactory, + $productRepository + ); + + $this->compareAvailability = $compareAvailability + ?: $this->_objectManager->get(AddToCompareAvailability::class); + } + /** * Add item to compare list. * @@ -37,7 +94,7 @@ public function execute() $product = null; } - if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { + if ($product && $this->compareAvailability->isAvailableForCompare($product)) { $this->_catalogProductCompareList->addProduct($product); $productName = $this->_objectManager->get( \Magento\Framework\Escaper::class diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php index acf0f1b754c1..f5d56dc9e6b0 100644 --- a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php +++ b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php @@ -6,6 +6,7 @@ */ namespace Magento\Catalog\Controller\Product\Compare; +use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; @@ -17,12 +18,13 @@ class Remove extends \Magento\Catalog\Controller\Product\Compare implements Http /** * Remove item from compare list. * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { $productId = (int)$this->getRequest()->getParam('product'); - if ($productId) { + if ($this->_formKeyValidator->validate($this->getRequest()) && $productId) { $storeId = $this->_storeManager->getStore()->getId(); try { /** @var \Magento\Catalog\Model\Product $product */ @@ -31,7 +33,7 @@ public function execute() $product = null; } - if ($product && $product->isSalable()) { + if ($product && (int)$product->getStatus() !== Status::STATUS_DISABLED) { /** @var $item \Magento\Catalog\Model\Product\Compare\Item */ $item = $this->_compareItemFactory->create(); if ($this->_customerSession->isLoggedIn()) { diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml index 31204c7b4b0b..9a0f5ad00272 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AddOutOfStockProductToCompareListTest.xml @@ -18,13 +18,10 @@ <testCaseId value="MAGETWO-98644"/> <useCaseId value="MAGETWO-98522"/> <group value="Catalog"/> - <skip> - <issueId value="MC-15930"/> - </skip> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 0" stepKey="displayOutOfStockNo"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <createData entity="SimpleSubCategory" stepKey="category"/> <createData entity="SimpleProduct4" stepKey="product"> @@ -32,7 +29,7 @@ </createData> </before> <after> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 0" stepKey="displayOutOfStockNo2"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <deleteData createDataKey="product" stepKey="deleteProduct"/> <deleteData createDataKey="category" stepKey="deleteCategory"/> @@ -40,23 +37,24 @@ </after> <!--Open product page--> <comment userInput="Open product page" stepKey="openProdPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.name$$)}}" stepKey="goToSimpleProductPage"/> + <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage"/> <waitForPageLoad stepKey="waitForSimpleProductPage"/> <!--'Add to compare' link is not available--> <comment userInput="'Add to compare' link is not available" stepKey="addToCompareLinkAvailability"/> <dontSeeElement selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="dontSeeAddToCompareLink"/> <!--Turn on 'out on stock' config--> <comment userInput="Turn on 'out of stock' config" stepKey="onOutOfStockConfig"/> - <magentoCLI command="config:set cataloginventory/options/show_out_of_stock 1" stepKey="displayOutOfStockYes"/> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> <!--Clear cache and reindex--> <comment userInput="Clear cache and reindex" stepKey="cleanCache"/> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> <!--Open product page--> <comment userInput="Open product page" stepKey="openProductPage"/> - <amOnPage url="{{StorefrontProductPage.url($$product.name$$)}}" stepKey="goToSimpleProductPage2"/> + <amOnPage url="{{StorefrontProductPage.url($$product.custom_attributes[url_key]$$)}}" stepKey="goToSimpleProductPage2"/> <waitForPageLoad stepKey="waitForSimpleProductPage2"/> <!--Click on 'Add to Compare' link--> + <waitForElementVisible selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="seeAddToCompareLink"/> <comment userInput="Click on 'Add to Compare' link" stepKey="clickOnAddToCompareLink"/> <click selector="{{StorefrontProductInfoMainSection.productAddToCompare}}" stepKey="clickOnAddToCompare"/> <waitForPageLoad stepKey="waitForProdAddToCmpList"/> diff --git a/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php b/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php index 27829155af29..00bac7e61b5b 100644 --- a/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php +++ b/app/code/Magento/Catalog/ViewModel/Product/Checker/AddToCompareAvailability.php @@ -10,6 +10,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Catalog\Api\Data\ProductInterface; use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\Catalog\Model\Product\Attribute\Source\Status; /** * Check is available add to compare. @@ -37,7 +38,11 @@ public function __construct(StockConfigurationInterface $stockConfiguration) */ public function isAvailableForCompare(ProductInterface $product): bool { - return $this->isInStock($product) || $this->stockConfiguration->isShowOutOfStock(); + if ((int)$product->getStatus() !== Status::STATUS_DISABLED) { + return $this->isInStock($product) || $this->stockConfiguration->isShowOutOfStock(); + } + + return false; } /** @@ -53,6 +58,6 @@ private function isInStock(ProductInterface $product): bool return $product->isSalable(); } - return isset($quantityAndStockStatus['is_in_stock']) && $quantityAndStockStatus['is_in_stock']; + return $quantityAndStockStatus['is_in_stock'] ?? false; } } diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml index 63751ad697ed..8ed8e590eb22 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontOnePageCheckoutJsValidationTest.xml @@ -11,6 +11,7 @@ <test name="StorefrontOnePageCheckoutJsValidationTest"> <annotations> <features value="Checkout"/> + <stories value="Checkout"/> <title value="Js validation error messages must be absent for required fields after checkout start."/> <description value="Js validation error messages must be absent for required fields after checkout start."/> <severity value="MAJOR" /> From a079c9139a1ae30f28f85b1f693a28e787e0f0b2 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 6 Aug 2019 17:06:42 +0300 Subject: [PATCH 0278/1172] MC-18967: [IT] Magento.SendFriend.Controller.SendmailTest fail on 2.3.3-develop --- .../testsuite/Magento/SendFriend/Controller/SendmailTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php index 8dbe9468923f..1d6adf52466d 100644 --- a/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php +++ b/dev/tests/integration/testsuite/Magento/SendFriend/Controller/SendmailTest.php @@ -24,10 +24,11 @@ class SendmailTest extends AbstractController /** * Share the product to friend as logged in customer * + * @magentoAppArea frontend * @magentoDbIsolation enabled * @magentoAppIsolation enabled - * @magentoConfigFixture default/sendfriend/email/allow_guest 0 - * @magentoConfigFixture default/sendfriend/email/enabled 1 + * @magentoConfigFixture default_store sendfriend/email/allow_guest 0 + * @magentoConfigFixture default_store sendfriend/email/enabled 1 * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Catalog/_files/products.php */ From 52abb64c9491bf5a33dc6f77e5f4c04a0c8cfe3a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 09:55:21 -0500 Subject: [PATCH 0279/1172] MC-15298: Allow admin to opt out of admin analytics tracking - admin analytics css --- .../web/css/source/_module.less | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less diff --git a/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less new file mode 100644 index 000000000000..05c0653a9bac --- /dev/null +++ b/app/design/adminhtml/Magento/backend/Magento_AdminAnalytics/web/css/source/_module.less @@ -0,0 +1,43 @@ +// /** +// * Copyright © Magento, Inc. All rights reserved. +// * See COPYING.txt for license details. +// */ + +// +// Magento_AdminAnalytics Modal on dashboard +// --------------------------------------------- + +.admin-usage-notification { + -webkit-transition: visibility 0s .5s, opacity .5s ease; + transition: visibility 0s .5s, opacity .5s ease; + + &._show { + -webkit-transition: opacity .5s ease; + opacity: 1; + transition: opacity .5s ease; + visibility: visible; + } + + .modal-inner-wrap { + .modal-content, + .modal-header { + padding-left: 4rem; + padding-right: 4rem; + + .action-close { + display: none; + } + } + + -webkit-transform: translateX(0); + -webkit-transition: -webkit-transform 0s; + transition: transform 0s; + transform: translateX(0); + margin-top: 13rem; + max-width: 75rem; + } + + .admin__fieldset { + padding: 0; + } +} From 3ce548211bb881c7eee2a8121d303d98efdcb9b8 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 11:00:51 -0500 Subject: [PATCH 0280/1172] MC-15298: Allow admin to opt out of admin analytics tracking - edited AdminAuthLogin --- .../tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 7201054121dc..8154f4bf1f20 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -43,7 +43,7 @@ class AdminAuthLogin extends Page /** * Admin Analytics selector */ - protected $adminUsageSelector ='.modal-inner-wrap'; + protected $adminUsageSelector ='.action-secondary'; /** * Constructor. From f681416e6975126c310dc68f8795db02b397054a Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:06:05 -0500 Subject: [PATCH 0281/1172] MC-15298: Allow admin to opt out of admin analytics tracking - changes based on review --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 9 ++++++--- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 ++++++---- .../Model/Condition/CanViewNotification.php | 4 +--- .../Model/ResourceModel/Viewer/Logger.php | 8 +++----- app/code/Magento/AdminAnalytics/Model/Viewer/Log.php | 4 ++-- .../Test/Unit/Condition/CanViewNotificationTest.php | 3 +++ app/code/Magento/AdminAnalytics/etc/module.xml | 1 - 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 170067bcc5db..d0e5cff85d9a 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -20,6 +20,9 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { + /** + * @var Factory + */ private $configFactory; /** @@ -63,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function disableAdminUsage() + private function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -75,7 +78,7 @@ public function disableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -104,7 +107,7 @@ public function execute() * * @return bool */ - protected function _isAllowed() + public function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index cdb00f12e1d3..be2a8ce1d3ca 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -20,7 +20,9 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { - + /** + * @var Factory + */ private $configFactory; /** * @var ProductMetadataInterface @@ -63,7 +65,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function enableAdminUsage() + private function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -75,7 +77,7 @@ public function enableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -104,7 +106,7 @@ public function execute() * * @return bool */ - protected function _isAllowed() + public function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 1af8702e5510..76591ffe5cc1 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -11,9 +11,7 @@ use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** - * Dynamic validator for UI release notification, manage UI component visibility. - * - * Return true if the logged in user has not seen the notification. + * Dynamic validator for UI admin analytics notification, manage UI component visibility. */ class CanViewNotification implements VisibilityConditionInterface { diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 505257f05147..38fdd2afed7a 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -34,7 +34,6 @@ class Logger private $logFactory; /** - * Logger constructor. * @param ResourceConnection $resource * @param LogFactory $logFactory */ @@ -71,16 +70,15 @@ public function log(string $lastViewVersion) : bool /** * Get log by the last view version. * - * @param string $lastViewVersion * @return Log */ - public function get(string $lastViewVersion) : Log + public function get() : Log { - return $this->logFactory->create(['data' => $this->loadLogData($lastViewVersion)]); + return $this->logFactory->create(['data' => $this->loadLogData()]); } /** - * Get log by the last view version. + * Checks is log already exists. * * @return boolean */ diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index 3ba1d15d716d..e97b8f94e12b 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -17,7 +17,7 @@ class Log extends DataObject * * @return int */ - public function getId() + public function getId() : int { return $this->getData('id'); } @@ -27,7 +27,7 @@ public function getId() * * @return string */ - public function getLastViewVersion() + public function getLastViewVersion() : ?string { return $this->getData('last_viewed_in_version'); } diff --git a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php index 00309f952701..7819f2f017a0 100644 --- a/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php +++ b/app/code/Magento/AdminAnalytics/Test/Unit/Condition/CanViewNotificationTest.php @@ -12,6 +12,9 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\App\CacheInterface; +/** + * Class CanViewNotificationTest + */ class CanViewNotificationTest extends \PHPUnit\Framework\TestCase { /** @var CanViewNotification */ diff --git a/app/code/Magento/AdminAnalytics/etc/module.xml b/app/code/Magento/AdminAnalytics/etc/module.xml index e27c90db11e2..f0990b114e25 100644 --- a/app/code/Magento/AdminAnalytics/etc/module.xml +++ b/app/code/Magento/AdminAnalytics/etc/module.xml @@ -8,4 +8,3 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Magento_AdminAnalytics"/> </config> - From 86c936941e5c4614fa7400e14f4f5b1ea61d2dcb Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:22:27 -0500 Subject: [PATCH 0282/1172] MC-17593: handle mtf and mftf failures - edited CanViewNotification,HttpContentProvider,Urlbuilder, config --- .../Backend/Test/Page/AdminAuthLogin.php | 23 ++++++------------ .../Magento/Ui/Test/Block/Adminhtml/Modal.php | 24 +++++++++++++++++++ .../UpdateAdminUserRoleEntityTest.php | 2 ++ .../Test/TestStep/LoginUserOnBackendStep.php | 2 ++ 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index 8154f4bf1f20..b9c614097140 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -43,7 +43,7 @@ class AdminAuthLogin extends Page /** * Admin Analytics selector */ - protected $adminUsageSelector ='.action-secondary'; + protected $adminUsageSelector ='.modal-inner-wrap'; /** * Constructor. @@ -87,6 +87,11 @@ public function getMessagesBlock() return Factory::getBlockFactory()->getMagentoBackendMessages($this->browser->find($this->messagesBlock)); } + public function getModalBlock() + { + return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find('.modal-inner-wrap')); + } + /** * Wait for Header block is visible in the page. * @@ -106,20 +111,6 @@ function () use ($browser, $selector) { public function dismissAdminUsageNotification() { - $browser = $this->browser; - $selector = $this->adminUsageSelector; - $browser->waitUntil( - function () use ($browser, $selector) { - $item = $browser->find($selector); - if ($item->isVisible()) { - return true; - } - usleep(200000); - return true; - } - ); - if ($this->browser->find($selector)->isVisible()) { - $this->browser->find($selector)->click(); - } + $this->getModalBlock()->dismissIfModalAppears(); } } diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php index 5c27776c0962..eb949dccb7ff 100644 --- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php +++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/Modal.php @@ -163,6 +163,30 @@ function () { ); } + /** + * Dismiss the modal if it appears + * + * @return void + */ + public function dismissIfModalAppears() + { + $browser = $this->browser; + $selector = $this->dismissWarningSelector; + $browser->waitUntil( + function () use ($browser, $selector) { + $item = $browser->find($selector); + if ($item->isVisible()) { + return true; + } + $this->waitModalAnimationFinished(); + return true; + } + ); + if ($this->browser->find($selector)->isVisible()) { + $this->browser->find($selector)->click(); + } + } + /** * Waiting until CSS animation is done. * Transition-duration is set at this file: "<magento_root>/lib/web/css/source/components/_modals.less" diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php index 58450abc7163..c7031e9fccbe 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php @@ -102,6 +102,8 @@ public function testUpdateAdminUserRolesEntity( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($user); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); $this->rolePage->open(); $this->rolePage->getRoleGrid()->searchAndOpen($filter); $this->userRoleEditRole->getRoleFormTabs()->fill($role); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php index c244e27d4289..93e5002a34d1 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php @@ -119,6 +119,8 @@ private function login() { $this->adminAuth->getLoginBlock()->fill($this->user); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); $this->adminAuth->getLoginBlock()->waitFormNotVisible(); } } From c191c7efe133bc5e616e7fdeafb21de8780b519b Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 14:26:33 -0500 Subject: [PATCH 0283/1172] MC-15298: Allow admin to opt out of admin analytics tracking - made disableAdminUsage, enableAdminUsage, markUserNotified public functions --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 4 ++-- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index d0e5cff85d9a..d5205f27f6ac 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -66,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - private function disableAdminUsage() + public function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -78,7 +78,7 @@ private function disableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + public function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index be2a8ce1d3ca..963954d917b4 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -65,7 +65,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - private function enableAdminUsage() + public function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -77,7 +77,7 @@ private function enableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + public function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( From 80b848a36567deb2540f4cfd6c3d005dfa0bf25e Mon Sep 17 00:00:00 2001 From: Sergey Dovbenko <sdovbenko@magecom.us> Date: Tue, 6 Aug 2019 20:32:44 +0000 Subject: [PATCH 0284/1172] Added SuppressWarnings to the class --- .../Magento/CatalogGraphQl/Model/Product/Option/DateType.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php index 40d77e36659a..5205115b772e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php +++ b/app/code/Magento/CatalogGraphQl/Model/Product/Option/DateType.php @@ -13,7 +13,10 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; /** - * @inheritdoc + * CatalogGraphQl product option date type. + * + * @author Magento Core Team <core@magentocommerce.com> + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class DateType extends ProductDateOptionType { From 7d36b8b02fbdf648d97c9fa1ba8ba332ea715785 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 16:35:22 -0500 Subject: [PATCH 0285/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added declare(strict_types=1) --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 1 + .../Controller/Adminhtml/Config/EnableAdminUsage.php | 1 + .../AdminAnalytics/Model/Condition/CanViewNotification.php | 2 ++ app/code/Magento/AdminAnalytics/Model/Viewer/Log.php | 2 ++ 4 files changed, 6 insertions(+) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index d5205f27f6ac..3bd5fe8afbeb 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 963954d917b4..ed55f8556df3 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 76591ffe5cc1..03b99f404e01 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\AdminAnalytics\Model\Condition; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index e97b8f94e12b..cd29783113d0 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\AdminAnalytics\Model\Viewer; use Magento\Framework\DataObject; From 28eeac6307821addd475798aa73a2383554b367d Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Tue, 6 Aug 2019 17:04:40 -0500 Subject: [PATCH 0286/1172] MC-17593: handle mtf and mftf failures - changed test files --- .../Magento/Backend/Test/Page/AdminAuthLogin.php | 15 +++++++++++++-- .../Test/TestCase/DeleteAdminUserEntityTest.php | 2 ++ .../Test/TestCase/DeleteUserRoleEntityTest.php | 2 ++ .../User/Test/TestCase/UnlockAdminUserTest.php | 2 ++ .../Test/TestCase/UpdateAdminUserEntityTest.php | 2 ++ .../User/Test/TestStep/LoginUserOnBackendStep.php | 4 ++-- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php index b9c614097140..4b72bb836523 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php @@ -80,16 +80,22 @@ public function getHeaderBlock() /** * Get global messages block. * - * @return \Magento\Backend\Test\Block\Messages + * @return \Magento\Ui\Test\Block\Adminhtml\Modal + */ public function getMessagesBlock() { return Factory::getBlockFactory()->getMagentoBackendMessages($this->browser->find($this->messagesBlock)); } + /** + * Get modal block + * + * @return void + */ public function getModalBlock() { - return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find('.modal-inner-wrap')); + return Factory::getBlockFactory()->getMagentoUiAdminhtmlModal($this->browser->find($this->adminUsageSelector)); } /** @@ -109,6 +115,11 @@ function () use ($browser, $selector) { ); } + /** + * Dismiss admin usage notification + * + * @return void + */ public function dismissAdminUsageNotification() { $this->getModalBlock()->dismissIfModalAppears(); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php index 42914cd697bf..81d9fe8393ae 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php @@ -117,6 +117,8 @@ public function testDeleteAdminUserEntity( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($user); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); } $this->userIndex->open(); $this->userIndex->getUserGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php index 47c5a4095830..2a1c9feb440b 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php @@ -117,6 +117,8 @@ public function testDeleteAdminUserRole( $this->adminAuthLogin->open(); $this->adminAuthLogin->getLoginBlock()->fill($adminUser); $this->adminAuthLogin->getLoginBlock()->submit(); + $this->adminAuthLogin->waitForHeaderBlock(); + $this->adminAuthLogin->dismissAdminUsageNotification(); } $this->userRoleIndex->open(); $this->userRoleIndex->getRoleGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php index 6a43be4afd42..8db927ccda29 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php @@ -124,6 +124,8 @@ public function test( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($incorrectUser); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); } // Test steps diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php index e8869de13462..dab4cec22c86 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php @@ -147,6 +147,8 @@ public function testUpdateAdminUser( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($initialUser); $this->adminAuth->getLoginBlock()->submit(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); } $this->userIndex->open(); $this->userIndex->getUserGrid()->searchAndOpen($filter); diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php index 93e5002a34d1..3e2a3a3d59fc 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php @@ -119,8 +119,8 @@ private function login() { $this->adminAuth->getLoginBlock()->fill($this->user); $this->adminAuth->getLoginBlock()->submit(); - $this->adminAuthLogin->waitForHeaderBlock(); - $this->adminAuthLogin->dismissAdminUsageNotification(); + $this->adminAuth->waitForHeaderBlock(); + $this->adminAuth->dismissAdminUsageNotification(); $this->adminAuth->getLoginBlock()->waitFormNotVisible(); } } From 94a8f6d69c448f50aacdfb5e08ed89dd2f3e5663 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 6 Aug 2019 23:02:10 -0500 Subject: [PATCH 0287/1172] MC-15298: Allow admin to opt out of admin analytics tracking - MTf fix --- .../app/Magento/User/Test/TestCase/UnlockAdminUserTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php index 8db927ccda29..6a43be4afd42 100644 --- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php +++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UnlockAdminUserTest.php @@ -124,8 +124,6 @@ public function test( $this->adminAuth->open(); $this->adminAuth->getLoginBlock()->fill($incorrectUser); $this->adminAuth->getLoginBlock()->submit(); - $this->adminAuth->waitForHeaderBlock(); - $this->adminAuth->dismissAdminUsageNotification(); } // Test steps From 6cde8c528f93f8a1a1f32f60641a5c6baef9a57e Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 6 Aug 2019 15:42:33 +0300 Subject: [PATCH 0288/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-11151 --- .../Adminhtml/Product/Set/SaveTest.php | 188 +++++++++++++++++- .../_files/attribute_set_based_on_default.php | 22 ++ ...ttribute_set_based_on_default_rollback.php | 21 ++ 3 files changed, 220 insertions(+), 11 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php index 8ccd426424a2..a3f9c542809a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Controller\Adminhtml\Product\Set; use Magento\Eav\Api\AttributeSetRepositoryInterface; @@ -10,9 +12,86 @@ use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Eav\Api\AttributeManagementInterface; +use Magento\Catalog\Api\Data\ProductInterfaceFactory; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Developer\Model\Logger\Handler\Syslog; +use Magento\Framework\Logger\Monolog; +use Magento\Catalog\Model\Product\Attribute\Repository; +/** + * Test save attribute set + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class SaveTest extends \Magento\TestFramework\TestCase\AbstractBackendController { + /** + * @var string + */ + private $systemLogPath = ''; + + /** + * @var Monolog + */ + private $logger; + + /** + * @var Syslog + */ + private $syslogHandler; + + /** + * @var AttributeManagementInterface + */ + private $attributeManagement; + + /** + * @var DataObjectHelper + */ + private $dataObjectHelper; + + /** + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * @var Repository + */ + private $attributeRepository; + + /** + * @inheritDoc + */ + public function setUp() + { + parent::setUp(); + $this->logger = $this->_objectManager->get(Monolog::class); + $this->syslogHandler = $this->_objectManager->create( + Syslog::class, + [ + 'filePath' => Bootstrap::getInstance()->getAppTempDir(), + ] + ); + $this->attributeManagement = $this->_objectManager->get(AttributeManagementInterface::class); + $this->productRepository = $this->_objectManager->get(ProductRepositoryInterface::class); + $this->attributeRepository = $this->_objectManager->get(Repository::class); + $this->dataObjectHelper = $this->_objectManager->get(DataObjectHelper::class); + } + + /** + * @inheritdoc + * @throws \Magento\Framework\Exception\FileSystemException + */ + public function tearDown() + { + $this->attributeRepository->get('country_of_manufacture')->setIsUserDefined(false); + parent::tearDown(); + } + /** * @magentoDataFixture Magento/Catalog/_files/attribute_set_with_renamed_group.php */ @@ -22,17 +101,22 @@ public function testAlreadyExistsExceptionProcessingWhenGroupCodeIsDuplicated() $this->assertNotEmpty($attributeSet, 'Attribute set with name "attribute_set_test" is missed'); $this->getRequest()->setMethod(HttpRequest::METHOD_POST); - $this->getRequest()->setPostValue('data', json_encode([ - 'attribute_set_name' => 'attribute_set_test', - 'groups' => [ - ['ynode-418', 'attribute-group-name', 1], - ], - 'attributes' => [ - ['9999', 'ynode-418', 1, null] - ], - 'not_attributes' => [], - 'removeGroups' => [], - ])); + $this->getRequest()->setPostValue( + 'data', + json_encode( + [ + 'attribute_set_name' => 'attribute_set_test', + 'groups' => [ + ['ynode-418', 'attribute-group-name', 1], + ], + 'attributes' => [ + ['9999', 'ynode-418', 1, null] + ], + 'not_attributes' => [], + 'removeGroups' => [], + ] + ) + ); $this->dispatch('backend/catalog/product_set/save/id/' . $attributeSet->getAttributeSetId()); $jsonResponse = json_decode($this->getResponse()->getBody()); @@ -63,4 +147,86 @@ protected function getAttributeSetByName($attributeSetName) $items = $result->getItems(); return $result->getTotalCount() ? array_pop($items) : null; } + + /** + * Test behavior when attribute set was changed to a new set + * with deleted attribute from the previous set + * + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + * @magentoDataFixture Magento/Catalog/_files/attribute_set_based_on_default.php + * @magentoDbIsolation disabled + */ + public function testRemoveAttributeFromAttributeSet() + { + $message = 'Attempt to load value of nonexistent EAV attribute'; + $this->removeSyslog(); + $attributeSet = $this->getAttributeSetByName('new_attribute_set'); + $product = $this->productRepository->get('simple'); + $this->attributeRepository->get('country_of_manufacture')->setIsUserDefined(true); + $this->attributeManagement->unassign($attributeSet->getId(), 'country_of_manufacture'); + $productData = [ + 'country_of_manufacture' => 'Angola' + ]; + $this->dataObjectHelper->populateWithArray($product, $productData, ProductInterface::class); + $this->productRepository->save($product); + $product->setAttributeSetId($attributeSet->getId()); + $product = $this->productRepository->save($product); + $this->dispatch('backend/catalog/product/edit/id/' . $product->getEntityId()); + $this->assertNotContains($message, $this->getSyslogContent()); + } + + /** + * Retrieve system.log file path + * + * @return string + */ + private function getSyslogPath() + { + if (!$this->systemLogPath) { + foreach ($this->logger->getHandlers() as $handler) { + if ($handler instanceof \Magento\Framework\Logger\Handler\System) { + $this->systemLogPath = $handler->getUrl(); + } + } + } + + return $this->systemLogPath; + } + + /** + * Remove system.log file + * + * @return void + */ + private function removeSyslog() + { + $this->detachLogger(); + if (file_exists($this->getSyslogPath())) { + unlink($this->getSyslogPath()); + } + } + + /** + * Detach system log handler. + * + * @return void + */ + private function detachLogger() + { + $this->syslogHandler->close(); + } + + /** + * Retrieve content of system.log file + * + * @return bool|string + */ + private function getSyslogContent() + { + if (!file_exists($this->getSyslogPath())) { + return ''; + } + + return file_get_contents($this->getSyslogPath()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default.php new file mode 100644 index 000000000000..d48578aa7346 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default.php @@ -0,0 +1,22 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class); +$entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product'); +$defaultSetId = $objectManager->create(\Magento\Catalog\Model\Product::class)->getDefaultAttributeSetid(); +$data = [ + 'attribute_set_name' => 'new_attribute_set', + 'entity_type_id' => $entityType->getId(), + 'sort_order' => 300, +]; + +$attributeSet->setData($data); +$attributeSet->validate(); +$attributeSet->save(); +$attributeSet->initFromSkeleton($defaultSetId); +$attributeSet->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php new file mode 100644 index 000000000000..981aed5d0ca2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php @@ -0,0 +1,21 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product'); + +$attributeSetCollection = $objectManager->create( + \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class +); +$attributeSetCollection->addFilter('attribute_set_name', 'new_attribute_set'); +$attributeSetCollection->addFilter('entity_type_id', $entityType->getId()); +$attributeSetCollection->setOrder('attribute_set_id'); +$attributeSetCollection->setPageSize(1); +$attributeSetCollection->load(); + +$attributeSet = $attributeSetCollection->fetchItem(); +$attributeSet->delete(); From bda4eb198e5bb0c392c3d6cbe8fb20d14b197f29 Mon Sep 17 00:00:00 2001 From: Dzmitry Tabusheu <dzmitry_tabusheu@epam.com> Date: Wed, 7 Aug 2019 16:43:36 +0300 Subject: [PATCH 0289/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Integration test for MC-6399 --- .../Magento/Catalog/Model/Product/UrlTest.php | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php index 4cf059d4bf69..afe052d9d853 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/UrlTest.php @@ -5,11 +5,15 @@ */ namespace Magento\Catalog\Model\Product; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; + /** * Test class for \Magento\Catalog\Model\Product\Url. * * @magentoDataFixture Magento/Catalog/_files/url_rewrites.php * @magentoAppArea frontend + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class UrlTest extends \PHPUnit\Framework\TestCase { @@ -132,4 +136,48 @@ public function testGetUrl() $product->setId(100); $this->assertContains('catalog/product/view/id/100/', $this->_model->getUrl($product)); } + + /** + * Check that rearranging product url rewrites do not influence on whether to use category in product links + * + * @magentoConfigFixture current_store catalog/seo/product_use_categories 0 + */ + public function testGetProductUrlWithRearrangedUrlRewrites() + { + $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ProductRepository::class + ); + $categoryRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\CategoryRepository::class + ); + $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\Registry::class + ); + $urlFinder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\UrlRewrite\Model\UrlFinderInterface::class + ); + $urlPersist = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\UrlRewrite\Model\UrlPersistInterface::class + ); + + $product = $productRepository->get('simple'); + $category = $categoryRepository->get($product->getCategoryIds()[0]); + $registry->register('current_category', $category); + $this->assertNotContains($category->getUrlPath(), $this->_model->getProductUrl($product)); + + $rewrites = $urlFinder->findAllByData( + [ + UrlRewrite::ENTITY_ID => $product->getId(), + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE + ] + ); + $this->assertGreaterThan(1, count($rewrites)); + foreach ($rewrites as $rewrite) { + if ($rewrite->getRequestPath() === 'simple-product.html') { + $rewrite->setUrlRewriteId($rewrite->getUrlRewriteId() + 1000); + } + } + $urlPersist->replace($rewrites); + $this->assertNotContains($category->getUrlPath(), $this->_model->getProductUrl($product)); + } } From b9855cb6675d9841fb2221510f7c3a83a92147ef Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 10:07:47 -0500 Subject: [PATCH 0290/1172] MC-15298: Allow admin to opt out of admin analytics tracking - deleted unused files --- .../Model/ContentProviderInterface.php | 24 ------ .../adminhtml/templates/confirm_popup.phtml | 81 ------------------- 2 files changed, 105 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php delete mode 100644 app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml diff --git a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php b/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php deleted file mode 100644 index ea67be7019e1..000000000000 --- a/app/code/Magento/AdminAnalytics/Model/ContentProviderInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\AdminAnalytics\Model; - -/** - * Requests the release notification content data from a defined service - */ -interface ContentProviderInterface -{ - /** - * Retrieves the release notification content data. - * - * @param string $version - * @param string $edition - * @param string $locale - * - * @return string|false - */ - public function getContent($version, $edition, $locale); -} diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml deleted file mode 100644 index ddd9b7acf03d..000000000000 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/confirm_popup.phtml +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -?> - -<div class="confirmation-modal-content"> - <p>Help us improve Magento Admin by allowing us to collect usage data.</p> - <p>All usage data that we collect for this purpose cannot be used to individually identify you and is used only to improve the Magento Admin and related products and services.</p> - <p>You can learn more and opt out at any time by following the instructions in <a href="https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html" target="_blank">merchant documentation</a></p> -</div> - -<script> - require([ - 'jquery', - 'Magento_Ui/js/modal/modal' - ], function ($) { - 'use strict'; - - $('.confirmation-modal-content').modal({ - imports: { - logAction: '${ $.provider }:data.logAction' - }, - title: 'Allow admin usage data collection', - autoOpen: true, - type: 'popup', - clickableOverlay: false, - responsive: true, - keyEventHandlers: { - escapeKey: function(){} - }, - opened: function($Event){ - $('.modal-header button.action-close', $Event.srcElement).hide(); - }, - buttons: [ - { - text: $.mage.__(`Don't Allow`), - class: 'action', - click: function(){ - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax({ - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/disableAdminUsage', - data: data, - showLoader: true - }).done(function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - }).fail(this.onError); - this.closeModal(); - }, - }, - { - text: $.mage.__('Ok'), - class: 'action', - click: function(){ - var data = { - 'form_key': window.FORM_KEY - }; - $.ajax({ - type: 'POST', - url: '/magento2ce/admin_michell/adminAnalytics/config/enableAdminUsage', - data: data, - showLoader: true - }).done(function (xhr) { - if (xhr.error) { - self.onError(xhr); - } - }).fail(this.onError); - - this.closeModal(); - }, - } - ], - }); - }); -</script> From 7b0b55a021c30d2af52b784b4022f689081e8d0c Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 12:28:43 -0500 Subject: [PATCH 0291/1172] MC-15298: Allow admin to opt out of admin analytics tracking - edited files based on review --- .../{ViewModel => Block}/Notification.php | 21 +- .../Adminhtml/Config/DisableAdminUsage.php | 8 +- .../Adminhtml/Config/EnableAdminUsage.php | 8 +- .../Model/Condition/CanViewNotification.php | 9 +- .../Model/ResourceModel/Viewer/Logger.php | 9 +- .../AdminAnalytics/Model/Viewer/Log.php | 2 +- .../AdminUsageNotificationDataProvider.php | 184 +----------------- .../Magento/AdminAnalytics/etc/db_schema.xml | 2 +- .../layout/adminhtml_dashboard_index.xml | 2 +- 9 files changed, 36 insertions(+), 209 deletions(-) rename app/code/Magento/AdminAnalytics/{ViewModel => Block}/Notification.php (57%) diff --git a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php b/app/code/Magento/AdminAnalytics/Block/Notification.php similarity index 57% rename from app/code/Magento/AdminAnalytics/ViewModel/Notification.php rename to app/code/Magento/AdminAnalytics/Block/Notification.php index 5b4a51c5b653..7988e2139a3d 100644 --- a/app/code/Magento/AdminAnalytics/ViewModel/Notification.php +++ b/app/code/Magento/AdminAnalytics/Block/Notification.php @@ -3,32 +3,37 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); -namespace Magento\AdminAnalytics\ViewModel; +namespace Magento\AdminAnalytics\Block; + +use Magento\Framework\View\Element\Block\ArgumentInterface; +use Magento\AdminAnalytics\Model\Condition\CanViewNotification as AdminAnalyticsNotification; +use Magento\ReleaseNotification\Model\Condition\CanViewNotification as ReleaseNotification; /** * Class Notification */ -class Notification implements \Magento\Framework\View\Element\Block\ArgumentInterface +class Notification implements ArgumentInterface { /** - * @var \Magento\AdminAnalytics\Model\Condition\CanViewNotification + * @var AdminAnalyticsNotification */ private $canViewNotificationAnalytics; /** - * @var \Magento\ReleaseNotification\Model\Condition\CanViewNotification + * @var ReleaseNotification */ private $canViewNotificationRelease; /** * Notification constructor. - * @param \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics - * @param \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + * @param AdminAnalyticsNotification $canViewNotificationAnalytics + * @param ReleaseNotification $canViewNotificationRelease */ public function __construct( - \Magento\AdminAnalytics\Model\Condition\CanViewNotification $canViewNotificationAnalytics, - \Magento\ReleaseNotification\Model\Condition\CanViewNotification $canViewNotificationRelease + AdminAnalyticsNotification $canViewNotificationAnalytics, + ReleaseNotification $canViewNotificationRelease ) { $this->canViewNotificationAnalytics = $canViewNotificationAnalytics; $this->canViewNotificationRelease = $canViewNotificationRelease; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 3bd5fe8afbeb..29a9479d72a9 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -8,7 +8,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -67,7 +67,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function disableAdminUsage() + private function disableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 0); @@ -79,7 +79,7 @@ public function disableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() : ResultInterface + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -108,7 +108,7 @@ public function execute() * * @return bool */ - public function _isAllowed() + protected function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index ed55f8556df3..35113d4a6b73 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -8,7 +8,7 @@ namespace Magento\AdminAnalytics\Controller\Adminhtml\Config; use Magento\Backend\App\Action; -use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Controller\ResultFactory; use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; @@ -66,7 +66,7 @@ public function __construct( /** * Changes the value of config/admin/usage/enabled */ - public function enableAdminUsage() + private function enableAdminUsage() { $configModel = $this->configFactory->create(); $configModel->setDataByPath('admin/usage/enabled', 1); @@ -78,7 +78,7 @@ public function enableAdminUsage() * * @return ResultInterface */ - public function markUserNotified() : ResultInterface + private function markUserNotified() : ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( @@ -107,7 +107,7 @@ public function execute() * * @return bool */ - public function _isAllowed() + protected function _isAllowed() { $isAllowed = parent::_isAllowed(); return $isAllowed; diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 03b99f404e01..1012f205d6bf 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -10,7 +10,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger; use Magento\Framework\View\Layout\Condition\VisibilityConditionInterface; use Magento\Framework\App\CacheInterface; -use function Magento\PAT\Reports\Utils\readResponseTimeReport; /** * Dynamic validator for UI admin analytics notification, manage UI component visibility. @@ -42,8 +41,6 @@ class CanViewNotification implements VisibilityConditionInterface private $cacheStorage; /** - * CanViewNotification constructor. - * * @param Logger $viewerLogger * @param CacheInterface $cacheStorage */ @@ -58,10 +55,10 @@ public function __construct( /** * Validate if notification popup can be shown and set the notification flag * - * @param array $arguments Attributes from element node. + * @param array $arguments Attributes from element node. * @inheritdoc */ - public function isVisible(array $arguments) + public function isVisible(array $arguments): bool { $cacheKey = self::$cachePrefix; $value = $this->cacheStorage->load($cacheKey); @@ -80,7 +77,7 @@ public function isVisible(array $arguments) * * @return string */ - public function getName() + public function getName(): string { return self::$conditionName; } diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index 38fdd2afed7a..b185e263f480 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -74,7 +74,7 @@ public function log(string $lastViewVersion) : bool */ public function get() : Log { - return $this->logFactory->create(['data' => $this->loadLogData()]); + return $this->logFactory->create(['data' => $this->loadLatestLogData()]); } /** @@ -84,7 +84,7 @@ public function get() : Log */ public function checkLogExists() : bool { - $data = $this->logFactory->create(['data' => $this->loadLogData()]); + $data = $this->logFactory->create(['data' => $this->loadLatestLogData()]); $lastViewedVersion = $data->getLastViewVersion(); return isset($lastViewedVersion); } @@ -94,11 +94,12 @@ public function checkLogExists() : bool * * @return array */ - private function loadLogData() : array + private function loadLatestLogData() : array { $connection = $this->resource->getConnection(); $select = $connection->select() - ->from($this->resource->getTableName(self::LOG_TABLE_NAME)) + ->from(['log_table' => $this->resource->getTableName(self::LOG_TABLE_NAME)]) + ->order('log_table.id desc') ->limit(['count' => 1]); $data = $connection->fetchRow($select); diff --git a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php index cd29783113d0..0c3b6b81ec81 100644 --- a/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php +++ b/app/code/Magento/AdminAnalytics/Model/Viewer/Log.php @@ -19,7 +19,7 @@ class Log extends DataObject * * @return int */ - public function getId() : int + public function getId() : ?int { return $this->getData('id'); } diff --git a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php index 5e8bc2d9160d..961a5663730a 100644 --- a/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php +++ b/app/code/Magento/AdminAnalytics/Ui/DataProvider/AdminUsageNotificationDataProvider.php @@ -6,81 +6,14 @@ namespace Magento\AdminAnalytics\Ui\DataProvider; -use Magento\Framework\Api\Search\SearchCriteriaInterface; -use Magento\Framework\Api\Search\SearchResultInterface; -use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; -use Magento\Ui\DataProvider\Modifier\ModifierInterface; -use Magento\Ui\DataProvider\Modifier\PoolInterface; +use Magento\Ui\DataProvider\AbstractDataProvider; +use Magento\Framework\Api\Filter; /** * Data Provider for the Admin usage UI component. */ -class AdminUsageNotificationDataProvider implements DataProviderInterface +class AdminUsageNotificationDataProvider extends AbstractDataProvider { - /** - * @var PoolInterface - */ - private $pool; - - /** - * Search result object. - * - * @var SearchResultInterface - */ - private $searchResult; - - /** - * Search criteria object. - * - * @var SearchCriteriaInterface - */ - private $searchCriteria; - - /** - * Own name of this provider. - * - * @var string - */ - private $name; - - /** - * Provider configuration data. - * - * @var array - */ - private $data; - - /** - * Provider configuration meta. - * - * @var array - */ - private $meta; - - /** - * @param string $name - * @param SearchResultInterface $searchResult - * @param SearchCriteriaInterface $searchCriteria - * @param PoolInterface $pool - * @param array $meta - * @param array $data - */ - public function __construct( - $name, - SearchResultInterface $searchResult, - SearchCriteriaInterface $searchCriteria, - PoolInterface $pool, - array $meta = [], - array $data = [] - ) { - $this->name = $name; - $this->searchResult = $searchResult; - $this->searchCriteria = $searchCriteria; - $this->pool = $pool; - $this->meta = $meta; - $this->data = $data; - } - /** * @inheritdoc */ @@ -92,117 +25,8 @@ public function getData() /** * @inheritdoc */ - public function getMeta() - { - return $this->meta; - } - - /** - * @inheritdoc - */ - public function getName() - { - return $this->name; - } - - /** - * @inheritdoc - */ - public function getConfigData() - { - return $this->data['config'] ?? []; - } - - /** - * @inheritdoc - */ - public function setConfigData($config) - { - $this->data['config'] = $config; - - return true; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldMetaInfo($fieldSetName, $fieldName) - { - return []; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldSetMetaInfo($fieldSetName) - { - return []; - } - - /** - * @inheritdoc - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function getFieldsMetaInfo($fieldSetName) - { - return []; - } - - /** - * @inheritdoc - */ - public function getPrimaryFieldName() - { - return 'admin_analytics'; - } - - /** - * @inheritdoc - */ - public function getRequestFieldName() - { - return 'admin_analytics'; - } - - /** - * @inheritdoc - */ - public function addFilter(\Magento\Framework\Api\Filter $filter) + public function addFilter(Filter $filter) { return null; } - - /** - * @inheritdoc - */ - public function addOrder($field, $direction) - { - return null; - } - - /** - * @inheritdoc - */ - public function setLimit($offset, $size) - { - return null; - } - - /** - * @inheritdoc - */ - public function getSearchCriteria() - { - return $this->searchCriteria; - } - - /** - * @inheritdoc - */ - public function getSearchResult() - { - return $this->searchResult; - } } diff --git a/app/code/Magento/AdminAnalytics/etc/db_schema.xml b/app/code/Magento/AdminAnalytics/etc/db_schema.xml index b9607ce77d15..ef1a657dc824 100644 --- a/app/code/Magento/AdminAnalytics/etc/db_schema.xml +++ b/app/code/Magento/AdminAnalytics/etc/db_schema.xml @@ -20,4 +20,4 @@ <column name="last_viewed_in_version"/> </constraint> </table> -</schema> \ No newline at end of file +</schema> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml index 3069db1ecc2b..829c5ed3f810 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -14,7 +14,7 @@ </uiComponent> <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\Block\Notification</argument> </arguments> </block> </referenceContainer> From 6b5c503e5e1795dde824707f951dd3ea1c7fddb4 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 7 Aug 2019 13:32:53 -0500 Subject: [PATCH 0292/1172] MC-15298: Allow admin to opt out of admin analytics tracking - static and health fix --- .../Adminhtml/Config/DisableAdminUsage.php | 16 ++++--------- .../Adminhtml/Config/EnableAdminUsage.php | 16 ++++--------- composer.lock | 23 +++++++++---------- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 29a9479d72a9..01790b4a417d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -41,6 +41,11 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * DisableAdminUsage constructor. * @@ -102,15 +107,4 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if DisableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - $isAllowed = parent::_isAllowed(); - return $isAllowed; - } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 35113d4a6b73..d61f69e484fd 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -40,6 +40,11 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * MarkUserNotified constructor. * @@ -101,15 +106,4 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } - - /** - * Checks if EnableAdminUsage is allowed - * - * @return bool - */ - protected function _isAllowed() - { - $isAllowed = parent::_isAllowed(); - return $isAllowed; - } } diff --git a/composer.lock b/composer.lock index 768b9fec82f2..675848c49591 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - - "content-hash": "a4299e3f4f0d4dd4915f37a5dde8e2ed", + "content-hash": "b5c5eeedfc8a724202af911b637f7b16", "packages": [ { "name": "braintree/braintree_php", @@ -1553,28 +1552,28 @@ "authors": [ { "name": "Jim Wigginton", - "role": "Lead Developer", - "email": "terrafrost@php.net" + "email": "terrafrost@php.net", + "role": "Lead Developer" }, { "name": "Patrick Monnerat", - "role": "Developer", - "email": "pm@datasphere.ch" + "email": "pm@datasphere.ch", + "role": "Developer" }, { "name": "Andreas Fischer", - "role": "Developer", - "email": "bantu@phpbb.com" + "email": "bantu@phpbb.com", + "role": "Developer" }, { "name": "Hans-Jürgen Petrich", - "role": "Developer", - "email": "petrich@tronic-media.com" + "email": "petrich@tronic-media.com", + "role": "Developer" }, { "name": "Graham Campbell", - "role": "Developer", - "email": "graham@alt-three.com" + "email": "graham@alt-three.com", + "role": "Developer" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", From 7ebf19be1f1bf6c9814c42df09cbb1c83ceff25f Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 7 Aug 2019 13:35:34 -0500 Subject: [PATCH 0293/1172] MC-15298: Allow admin to opt out of admin analytics tracking - static and health fix --- .../Controller/Adminhtml/Config/DisableAdminUsage.php | 10 +++++----- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 01790b4a417d..48937c3019ca 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -21,6 +21,11 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * @var Factory */ @@ -41,11 +46,6 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * DisableAdminUsage constructor. * diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index d61f69e484fd..9d16a789a2aa 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -21,6 +21,11 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { + /** + * Authorization level of a basic admin session + */ + const ADMIN_RESOURCE = 'Magento_Backend::admin'; + /** * @var Factory */ @@ -40,11 +45,6 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $logger; - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * MarkUserNotified constructor. * From 83369f7c2c6c1818c2231589014117ecbb89dfa1 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Wed, 7 Aug 2019 14:18:41 -0500 Subject: [PATCH 0294/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage --- .../VerifyCheckoutSuccessActionGroup.xml | 17 ++ .../OpenCartOnPayPalActionGroup.xml | 20 +++ ...xpressCheckoutConfigurationActionGroup.xml | 21 +-- .../PayPalExpressCheckoutConfigSection.xml | 2 +- .../Test/CheckCreditButtonConfiguration.xml | 79 +++++++++ ...efaultValueOfPayPalCustomizeButtonTest.xml | 44 +++++ .../Test/PayPalSmartButtonInCheckoutPage.xml | 158 ++++-------------- 7 files changed, 201 insertions(+), 140 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml create mode 100644 app/code/Magento/Paypal/Test/Mftf/ActionGroup/OpenCartOnPayPalActionGroup.xml create mode 100644 app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml create mode 100644 app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml new file mode 100644 index 000000000000..c633bb078b06 --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="VerifyCheckoutSuccessActionGroup"> + <waitForElement selector="{{CheckoutSuccessMainSection.successTitle}}" stepKey="waitForLoadSuccessPageTitle"/> + <waitForElement selector="{{CheckoutSuccessMainSection.success}}" time="30" stepKey="waitForLoadSuccessPage"/> + <seeElement selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="seeOrderLink"/> + </actionGroup> +</actionGroups> + diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/OpenCartOnPayPalActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/OpenCartOnPayPalActionGroup.xml new file mode 100644 index 000000000000..38cde73b5b7b --- /dev/null +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/OpenCartOnPayPalActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <!-- Action group to delete an item given that items name --> + <!-- Must already be on the admin page containing the grid --> + <actionGroup name="OpenCartOnPayPalActionGroup"> + <click selector="{{PayPalPaymentSection.cartIcon}}" stepKey="openCart"/> + <seeElement selector="{{PayPalPaymentSection.itemName($$createProduct.name$$)}}" stepKey="seeProductname"/> + <click selector="{{PayPalPaymentSection.PayPalSubmitBtn}}" stepKey="clickPayPalSubmitBtn"/> + <switchToPreviousTab stepKey="switchToPreviousTab"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml index bae517ffe2f3..c5c9aff86d37 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml @@ -16,39 +16,40 @@ <waitForPageLoad stepKey="waitForPageLoad1"/> <click selector="{{PayPalExpressCheckoutConfigSection.configureBtn(countryCode)}}" stepKey="clickPayPalConfigureBtn"/> <waitForElementVisible selector="{{PayPalAdvancedSettingConfigSection.advancedSettingTab(countryCode)}}" stepKey="waitForAdvancedSettingTab"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.email(countryCode)}}" userInput="{{credentials.paypal_express_email}}" stepKey="inputEmailAssociatedWithPayPalMerchantAccount"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.email(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_business_account}}" stepKey="inputEmailAssociatedWithPayPalMerchantAccount"/> <selectOption selector ="{{PayPalExpressCheckoutConfigSection.apiMethod(countryCode)}}" userInput="API Signature" stepKey="inputAPIAuthenticationMethods"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.username(countryCode)}}" userInput="{{credentials.paypal_express_api_username}}" stepKey="inputAPIUsername"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.password(countryCode)}}" userInput="{{credentials.paypal_express_api_password}}" stepKey="inputAPIPassword"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.signature(countryCode)}}" userInput="{{credentials.paypal_express_api_signature}}" stepKey="inputAPISignature"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.username(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_username}}" stepKey="inputAPIUsername"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.password(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_password}}" stepKey="inputAPIPassword"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.signature(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_signature}}" stepKey="inputAPISignature"/> <selectOption selector ="{{PayPalExpressCheckoutConfigSection.sandboxMode(countryCode)}}" userInput="Yes" stepKey="enableSandboxMode"/> <selectOption selector="{{PayPalExpressCheckoutConfigSection.enableSolution(countryCode)}}" userInput="Yes" stepKey="enableSolution"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.merchantID(countryCode)}}" userInput="{{credentials.paypal_express_merchantID}}" stepKey="inputMerchantID"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.merchantID(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_merchant_id}}" stepKey="inputMerchantID"/> <!--Save configuration--> <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> </actionGroup> <actionGroup name="CreatePayPalOrderWithSelectedPaymentMethodActionGroup" extends="CreateOrderToPrintPageActionGroup"> + <arguments> + <argument name="payerName" defaultValue="MPI" type="string"/> + </arguments> <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.PayPalPaymentRadio}}" stepKey="clickPlaceOrder"/> <!--set ID for iframe of PayPal group button--> <executeJS function="jQuery('.zoid-component-frame.zoid-visible').attr('id', 'myIframe')" stepKey="clickOrderLink"/> <!--switch to iframe of PayPal group button--> - <comment userInput="switch to iframe of PayPal group button" stepKey="commentSwitchToIframe"/> <switchToIFrame userInput="myIframe" stepKey="clickPrintOrderLink"/> <waitForElementVisible selector="{{CheckoutPaymentSection.PayPalBtn}}" stepKey="waitForPayPalBtn"/> <click selector="{{CheckoutPaymentSection.PayPalBtn}}" stepKey="clickPayPalBtn"/> <switchToIFrame stepKey="switchBack1"/> <!--Check in-context--> - <comment userInput="Check in-context" stepKey="commentVerifyInContext"/> <switchToNextTab stepKey="switchToInContentTab"/> <waitForPageLoad stepKey="waitForPageLoad"/> <seeCurrentUrlMatches regex="~\//www.sandbox.paypal.com/~" stepKey="seeCurrentUrlMatchesConfigPath1"/> <waitForElement selector="{{PayPalPaymentSection.email}}" stepKey="waitForLoginForm" /> - <fillField selector="{{PayPalPaymentSection.email}}" userInput="{{Payer.buyerEmail}}" stepKey="fillEmail"/> - <fillField selector="{{PayPalPaymentSection.password}}" userInput="{{Payer.buyerPassword}}" stepKey="fillPassword"/> + <fillField selector="{{PayPalPaymentSection.email}}" userInput="{{_CREDS.magento/paypal_sandbox_login_email}}" stepKey="fillEmail"/> + <fillField selector="{{PayPalPaymentSection.password}}" userInput="{{_CREDS.magento/paypal_sandbox_login_password}}" stepKey="fillPassword"/> <click selector="{{PayPalPaymentSection.loginBtn}}" stepKey="login"/> <waitForPageLoad stepKey="wait"/> - <seeElement selector="{{PayPalPaymentSection.reviewUserInfo}}" stepKey="seePayerName"/> + <see userInput="{{payerName}}" selector="{{PayPalPaymentSection.reviewUserInfo}}" stepKey="seePayerName"/> </actionGroup> <actionGroup name="addProductToCheckoutPage"> <arguments> diff --git a/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml b/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml index 85f94cd8691a..0be7a7873825 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml @@ -54,7 +54,7 @@ <element name="email" type="input" selector="//input[contains(@name, 'email') and not(contains(@style, 'display:none'))]"/> <element name="password" type="input" selector="//input[contains(@name, 'password') and not(contains(@style, 'display:none'))]"/> <element name="loginBtn" type="input" selector="button#btnLogin"/> - <element name="reviewUserInfo" type="text" selector="//p[@id='reviewUserInfo' and contains(text(),'Hi, MPI!')]"/> + <element name="reviewUserInfo" type="text" selector="//p[@id='reviewUserInfo']"/> <element name="cartIcon" type="text" selector="#transactionCart"/> <element name="itemName" type="text" selector="//span[@title='{{productName}}']" parameterized="true"/> <element name="PayPalSubmitBtn" type="text" selector="//input[@type='submit']"/> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml b/app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml new file mode 100644 index 000000000000..a0f13e8ae661 --- /dev/null +++ b/app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CheckCreditButtonConfiguration"> + <annotations> + <features value="PayPal"/> + <stories value="Button Configuration"/> + <title value="Check Credit Button Configuration"/> + <description value="Admin is able to customize Credit button"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-10900"/> + <skip> + <issueId value="DEVOPS-3311"/> + </skip> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> + <createData entity="_defaultProduct" stepKey="createPreReqProduct"> + <requiredEntity createDataKey="createPreReqCategory"/> + </createData> + <!-- Create Customer --> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + <!--Config PayPal Express Checkout--> + <comment userInput="config PayPal Express Checkout" stepKey="commemtConfigPayPalExpressCheckout"/> + <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpressCheckout"/> + </before> + <after> + <deleteData stepKey="deleteCategory" createDataKey="createPreReqCategory"/> + <deleteData stepKey="deleteProduct" createDataKey="createPreReqProduct"/> + <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + </after> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <!--Navigate to button configuration setting--> + <comment userInput="Navigate to button configuration setting in Admin site" stepKey="commentNavigateToButtonConfigurationInAdmin"/> + <actionGroup ref="OpenPayPalButtonCheckoutPage" stepKey="openPayPalButtonCheckoutPage"/> + <waitForElement selector="{{ButtonCustomization.customizeDrpDown}}" stepKey="seeCustomizeDropDown"/> + <selectOption selector="{{ButtonCustomization.customizeDrpDown}}" userInput="Yes" stepKey="enableButtonCustomization"/> + <!--Verify Credit Button value--> + <comment userInput="Verify Credit Button value" stepKey="commentVerifyDefaultValue2"/> + <selectOption selector="{{ButtonCustomization.label}}" userInput="{{PayPalLabel.credit}}" stepKey="selectCreditAsLabel"/> + <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize2"/> + <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape2"/> + <dontSeeElement selector="{{ButtonCustomization.layout}}" stepKey="dontSeeLayout"/> + <dontSeeElement selector="{{ButtonCustomization.color}}" stepKey="dontSeeColor"/> + <!--Customize Credit Button--> + <selectOption selector="{{ButtonCustomization.size}}" userInput="{{PayPalSize.medium}}" stepKey="selectSize"/> + <selectOption selector="{{ButtonCustomization.shape}}" userInput="{{PayPalShape.pill}}" stepKey="selectShape"/> + <!--Save configuration--> + <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> + <waitForPageLoad stepKey="waitForConfigSave"/> + <openNewTab stepKey="openNewTab"/> + <amOnPage url="/" stepKey="openStorefront"/> + <!--Login to storefront as previously created customer--> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <actionGroup ref="addProductToCheckoutPage" stepKey="addProductToCheckoutPage"> + <argument name="Category" value="$$createPreReqCategory$$"/> + </actionGroup> + <!--set ID for iframe of PayPal group button--> + <executeJS function="jQuery('.zoid-component-frame.zoid-visible').attr('id', 'myIframe')" stepKey="clickOrderLink"/> + <!--switch to iframe of PayPal group button--> + <comment userInput="switch to iframe of PayPal group button" stepKey="commentSwitchToIframe"/> + <switchToIFrame userInput="myIframe" stepKey="clickPrintOrderLink"/> + <waitForElementVisible selector="{{CheckoutPaymentSection.PayPalBtn}}" stepKey="waitForPayPalBtn"/> + <seeElement selector="{{PayPalButtonOnStorefront.label(PayPalLabel.credit)}}{{PayPalButtonOnStorefront.size(PayPalSize.medium)}}" stepKey="seeButtonInMediumSize"/> + <seeElement selector="{{PayPalButtonOnStorefront.label(PayPalLabel.credit)}}{{PayPalButtonOnStorefront.shape(PayPalShape.pill)}}" stepKey="seeButtonInPillShape"/> + </test> +</tests> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml new file mode 100644 index 000000000000..0a90295c5528 --- /dev/null +++ b/app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="CheckDefaultValueOfPayPalCustomizeButtonTest"> + <annotations> + <features value="PayPal"/> + <stories value="Button Configuration"/> + <title value="Check Default Value Of PayPal Customize Button"/> + <description value="Default value of PayPal Customize Button should be NO"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-10904"/> + <skip> + <issueId value="DEVOPS-3311"/> + </skip> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpressCheckout"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + </after> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <actionGroup ref="OpenPayPalButtonCheckoutPage" stepKey= "openPayPalButtonCheckoutPage"/> + <seeElement selector="{{ButtonCustomization.customizeDrpDown}}" stepKey="seeCustomizeDropDown"/> + <seeOptionIsSelected selector="{{ButtonCustomization.customizeDrpDown}}" userInput="No" stepKey="seeNoIsDefaultValue"/> + <selectOption selector="{{ButtonCustomization.customizeDrpDown}}" userInput="Yes" stepKey="enableButtonCustomization"/> + <!--Verify default value--> + <comment userInput="Verify default value" stepKey="commentVerifyDefaultValue1"/> + <seeElement selector="{{ButtonCustomization.label}}" stepKey="seeLabel"/> + <seeElement selector="{{ButtonCustomization.layout}}" stepKey="seeLayout"/> + <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize1"/> + <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape1"/> + <seeElement selector="{{ButtonCustomization.color}}" stepKey="seeColor"/> + </test> +</tests> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml index 079b46dc1b0c..426838596fad 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml @@ -8,107 +8,6 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="CheckDefaultValueOfPayPalCustomizeButtonTest"> - <annotations> - <features value="PayPal"/> - <stories value="Button Configuration"/> - <title value="Check Default Value Of PayPal Customize Button"/> - <description value="Default value of PayPal Customize Button should be NO"/> - <severity value="AVERAGE"/> - <testCaseId value="MC-10904"/> - <skip> - <issueId value="DEVOPS-3311"/> - </skip> - </annotations> - <before> - <actionGroup ref="LoginActionGroup" stepKey="login"/> - <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpressCheckout"/> - </before> - <after> - <actionGroup ref="logout" stepKey="logoutFromAdmin"/> - </after> - <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - <actionGroup ref="OpenPayPalButtonCheckoutPage" stepKey="openPayPalButtonCheckoutPage"/> - <seeElement selector="{{ButtonCustomization.customizeDrpDown}}" stepKey="seeCustomizeDropDown"/> - <seeOptionIsSelected selector="{{ButtonCustomization.customizeDrpDown}}" userInput="No" stepKey="seeNoIsDefaultValue"/> - <selectOption selector="{{ButtonCustomization.customizeDrpDown}}" userInput="Yes" stepKey="enableButtonCustomization"/> - <!--Verify default value--> - <comment userInput="Verify default value" stepKey="commentVerifyDefaultValue1"/> - <seeElement selector="{{ButtonCustomization.label}}" stepKey="seeLabel"/> - <seeElement selector="{{ButtonCustomization.layout}}" stepKey="seeLayout"/> - <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize1"/> - <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape1"/> - <seeElement selector="{{ButtonCustomization.color}}" stepKey="seeColor"/> - </test> - <test name="CheckCreditButtonConfiguration"> - <annotations> - <features value="PayPal"/> - <stories value="Button Configuration"/> - <title value="Check Credit Button Configuration"/> - <description value="Admin is able to customize Credit button"/> - <severity value="AVERAGE"/> - <testCaseId value="MC-10900"/> - <skip> - <issueId value="DEVOPS-3311"/> - </skip> - </annotations> - <before> - <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> - <createData entity="_defaultProduct" stepKey="createPreReqProduct"> - <requiredEntity createDataKey="createPreReqCategory"/> - </createData> - <!-- Create Customer --> - <createData entity="Simple_US_Customer" stepKey="createCustomer"/> - <actionGroup ref="LoginActionGroup" stepKey="login"/> - <!--Config PayPal Express Checkout--> - <comment userInput="config PayPal Express Checkout" stepKey="commemtConfigPayPalExpressCheckout"/> - <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpressCheckout"/> - </before> - <after> - <deleteData stepKey="deleteCategory" createDataKey="createPreReqCategory"/> - <deleteData stepKey="deleteProduct" createDataKey="createPreReqProduct"/> - <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> - <actionGroup ref="logout" stepKey="logoutFromAdmin"/> - </after> - <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> - <!--Navigate to button configuration setting--> - <comment userInput="Navigate to button configuration setting in Admin site" stepKey="commentNavigateToButtonConfigurationInAdmin"/> - <actionGroup ref="OpenPayPalButtonCheckoutPage" stepKey="openPayPalButtonCheckoutPage"/> - <waitForElement selector="{{ButtonCustomization.customizeDrpDown}}" stepKey="seeCustomizeDropDown"/> - <selectOption selector="{{ButtonCustomization.customizeDrpDown}}" userInput="Yes" stepKey="enableButtonCustomization"/> - <!--Verify Credit Button value--> - <comment userInput="Verify Credit Button value" stepKey="commentVerifyDefaultValue2"/> - <selectOption selector="{{ButtonCustomization.label}}" userInput="{{PayPalLabel.credit}}" stepKey="selectCreditAsLabel"/> - <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize2"/> - <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape2"/> - <dontSeeElement selector="{{ButtonCustomization.layout}}" stepKey="dontSeeLayout"/> - <dontSeeElement selector="{{ButtonCustomization.color}}" stepKey="dontSeeColor"/> - <!--Customize Credit Button--> - <selectOption selector="{{ButtonCustomization.size}}" userInput="{{PayPalSize.medium}}" stepKey="selectSize"/> - <selectOption selector="{{ButtonCustomization.shape}}" userInput="{{PayPalShape.pill}}" stepKey="selectShape"/> - <!--Save configuration--> - <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> - <waitForPageLoad stepKey="waitForConfigSave"/> - <openNewTab stepKey="openNewTab"/> - <amOnPage url="/" stepKey="openStorefront"/> - <!--Login to storefront as previously created customer--> - <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> - <argument name="Customer" value="$$createCustomer$$"/> - </actionGroup> - <actionGroup ref="addProductToCheckoutPage" stepKey="addProductToCheckoutPage"> - <argument name="Category" value="$$createPreReqCategory$$"/> - </actionGroup> - <!--set ID for iframe of PayPal group button--> - <executeJS function="jQuery('.zoid-component-frame.zoid-visible').attr('id', 'myIframe')" stepKey="clickOrderLink"/> - <!--switch to iframe of PayPal group button--> - <comment userInput="switch to iframe of PayPal group button" stepKey="commentSwitchToIframe"/> - <switchToIFrame userInput="myIframe" stepKey="clickPrintOrderLink"/> - <waitForElementVisible selector="{{CheckoutPaymentSection.PayPalBtn}}" stepKey="waitForPayPalBtn"/> - <seeElement selector="{{PayPalButtonOnStorefront.label(PayPalLabel.credit)}}{{PayPalButtonOnStorefront.size(PayPalSize.medium)}}" stepKey="seeButtonInMediumSize"/> - <seeElement selector="{{PayPalButtonOnStorefront.label(PayPalLabel.credit)}}{{PayPalButtonOnStorefront.shape(PayPalShape.pill)}}" stepKey="seeButtonInPillShape"/> - </test> <test name="PayPalSmartButtonInCheckoutPage"> <annotations> <features value="PayPal"/> @@ -122,49 +21,50 @@ </skip> </annotations> <before> - <createData entity="_defaultCategory" stepKey="createPreReqCategory"/> - <createData entity="_defaultProduct" stepKey="createPreReqProduct"> - <requiredEntity createDataKey="createPreReqCategory"/> + + <!-- Create Product --> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> </createData> + <!-- Create Customer --> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + + <!-- Login --> <actionGroup ref="LoginActionGroup" stepKey="login"/> - <!--Config PayPal Express Checkout--> - <comment userInput="config PayPal Express Checkout" stepKey="commemtConfigPayPalExpressCheckout"/> - <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpressCheckout"/> - <magentoCLI command="config:set payment/paypal_express/in_context 1" stepKey="disableInContextPayPal"/> </before> <after> - <deleteData stepKey="deleteCategory" createDataKey="createPreReqCategory"/> - <deleteData stepKey="deleteProduct" createDataKey="createPreReqProduct"/> + <!-- Cleanup environment --> + <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> + <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> - <magentoCLI command="config:set payment/paypal_express/in_context 0" stepKey="enableInContextPayPal"/> + + <!-- Logout --> <actionGroup ref="logout" stepKey="logoutFromAdmin"/> </after> - <magentoCLI command="config:set payment/paypal_express/payment_action Authorization" stepKey="inputPaymentAction"/> - <magentoCLI command="config:set payment/paypal_express/solution_type Sole" stepKey="enablePayPalGuestCheckout"/> - <magentoCLI command="config:set payment/paypal_express/line_items_enabled 1" stepKey="enableTransferCartLine"/> + + <!-- Configure PayPal sandbox --> + <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="configPayPalExpressCheckout"/> + + <!-- Set skip order review --> <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 1" stepKey="enableSkipOrderReview"/> + <!--Login to storefront as previously created customer--> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> <argument name="Customer" value="$$createCustomer$$"/> </actionGroup> - <!--Place an order using PayPal method--> - <comment userInput="Place an order using PayPal method" stepKey="commentPayPalPlaceOrder"/> + + <!-- Place an order using PayPal payment method --> <actionGroup ref="CreatePayPalOrderWithSelectedPaymentMethodActionGroup" stepKey="createPayPalOrder"> - <argument name="Category" value="$$createPreReqCategory$$"/> + <argument name="Category" value="$$createCategory$$"/> + <argument name="payerName" value="Alex"/> </actionGroup> - <!--Open Cart on PayPal--> - <comment userInput="Open Cart on PayPal" stepKey="commentOpenCart"/> - <click selector="{{PayPalPaymentSection.cartIcon}}" stepKey="openCart"/> - <seeElement selector="{{PayPalPaymentSection.itemName($$createPreReqProduct.name$$)}}" stepKey="seeProductname"/> - <click selector="{{PayPalPaymentSection.PayPalSubmitBtn}}" stepKey="clickPayPalSubmitBtn"/> - <switchToPreviousTab stepKey="switchToPreviousTab"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <!--I see order successful Page instead of Order Review Page--> - <comment userInput="I see order successful Page instead of Order Review Page" stepKey="commentVerifyOrderReviewPage"/> - <waitForElement selector="{{CheckoutSuccessMainSection.successTitle}}" stepKey="waitForLoadSuccessPageTitle"/> - <waitForElement selector="{{CheckoutSuccessMainSection.success}}" time="30" stepKey="waitForLoadSuccessPage"/> - <seeElement selector="{{CheckoutSuccessMainSection.orderLink}}" stepKey="seeOrderLink"/> + + <!-- Open Cart on PayPal--> + <actionGroup ref="OpenCartOnPayPalActionGroup" stepKey="openCartOnPayPal"/> + + <!-- I see order successful Page instead of Order Review Page --> + <actionGroup ref="VerifyCheckoutSuccessActionGroup" stepKey="verifyCheckoutSuccessActionGroup"/> </test> </tests> \ No newline at end of file From 70c27d391c1aa9b5aa031f2309bf1ad919aceb5f Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Wed, 7 Aug 2019 14:46:13 -0500 Subject: [PATCH 0295/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added protected isAllowed --- .../Adminhtml/Config/DisableAdminUsage.php | 24 +++++++----------- .../Adminhtml/Config/EnableAdminUsage.php | 25 ++++++++----------- 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 48937c3019ca..13a13e8d2403 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -13,7 +13,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Controller\ResultInterface; -use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** @@ -21,11 +20,6 @@ */ class DisableAdminUsage extends Action implements HttpPostActionInterface { - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * @var Factory */ @@ -41,11 +35,6 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface */ private $notificationLogger; - /** - * @var LoggerInterface - */ - private $logger; - /** * DisableAdminUsage constructor. * @@ -53,20 +42,17 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger * @param Factory $configFactory - * @param LoggerInterface $logger */ public function __construct( Action\Context $context, ProductMetadataInterface $productMetadata, NotificationLogger $notificationLogger, - Factory $configFactory, - LoggerInterface $logger + Factory $configFactory ) { parent::__construct($context); $this->configFactory = $configFactory; $this->productMetadata = $productMetadata; $this->notificationLogger = $notificationLogger; - $this->logger = $logger; } /** @@ -107,4 +93,12 @@ public function execute() $this->disableAdminUsage(); $this->markUserNotified(); } + + /** + * @inheritDoc + */ + protected function _isAllowed() + { + return $this->_authorization->isAllowed(static::ADMIN_RESOURCE); + } } diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index 9d16a789a2aa..aee300c2f6e8 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -13,7 +13,6 @@ use Magento\AdminAnalytics\Model\ResourceModel\Viewer\Logger as NotificationLogger; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Controller\ResultInterface; -use Psr\Log\LoggerInterface; use Magento\Config\Model\Config\Factory; /** @@ -21,15 +20,11 @@ */ class EnableAdminUsage extends Action implements HttpPostActionInterface { - /** - * Authorization level of a basic admin session - */ - const ADMIN_RESOURCE = 'Magento_Backend::admin'; - /** * @var Factory */ private $configFactory; + /** * @var ProductMetadataInterface */ @@ -40,11 +35,6 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface */ private $notificationLogger; - /** - * @var LoggerInterface - */ - private $logger; - /** * MarkUserNotified constructor. * @@ -52,20 +42,17 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface * @param ProductMetadataInterface $productMetadata * @param NotificationLogger $notificationLogger * @param Factory $configFactory - * @param LoggerInterface $logger */ public function __construct( Action\Context $context, ProductMetadataInterface $productMetadata, NotificationLogger $notificationLogger, - Factory $configFactory, - LoggerInterface $logger + Factory $configFactory ) { parent::__construct($context); $this->configFactory = $configFactory; $this->productMetadata = $productMetadata; $this->notificationLogger = $notificationLogger; - $this->logger = $logger; } /** @@ -106,4 +93,12 @@ public function execute() $this->enableAdminUsage(); $this->markUserNotified(); } + + /** + * @inheritDoc + */ + protected function _isAllowed() + { + return $this->_authorization->isAllowed(static::ADMIN_RESOURCE); + } } From 2f279661a6fe2f9a2de9e63a50b63e88d9622b74 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Wed, 7 Aug 2019 15:11:36 -0500 Subject: [PATCH 0296/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage fixed formatting issues --- .../PayPalExpressCheckoutConfigurationActionGroup.xml | 1 + .../Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml index af0969615be5..4de7337cf2cc 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml @@ -5,6 +5,7 @@ * See COPYING.txt for license details. */ --> + <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="ConfigPayPalExpressCheckout"> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml index ba68e394087d..85e1ce347d50 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml @@ -52,7 +52,6 @@ <!-- TODO: Below step will be replaced with createData once MQE-1561 is completed --> <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="configPayPalExpressCheckout"/> - <!-- Set skip order review --> <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 1" stepKey="enableSkipOrderReview"/> @@ -73,4 +72,4 @@ <!-- I see order successful Page instead of Order Review Page --> <actionGroup ref="VerifyCheckoutSuccessActionGroup" stepKey="verifyCheckoutSuccess"/> </test> -</tests> \ No newline at end of file +</tests> From 673cec3bf2b2d1da2c37dfdf0de1e36e198c6bfc Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Thu, 8 Aug 2019 12:22:03 +0400 Subject: [PATCH 0297/1172] MC-18821: Increase test coverage for Account functional area - Automation test for MC-11531 --- .../StorefrontCategorySidebarSection.xml | 2 + .../AdminConfigurableProductActionGroup.xml | 4 + .../AddSwatchToProductActionGroup.xml | 8 ++ .../Section/AdminNewAttributePanelSection.xml | 1 + ...tImageColorWhenFilterByColorFilterTest.xml | 93 +++++++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml index 1b7bbd58eea9..2c73941a92b4 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml @@ -12,6 +12,8 @@ <element name="filterOptions" type="text" selector=".filter-options-content .items"/> <element name="filterOption" type="text" selector=".filter-options-content .item"/> <element name="optionQty" type="text" selector=".filter-options-content .item .count"/> + <element name="filterOptionByLabel" type="button" selector="//div[contains(@class, 'filter-options-item')]//div[contains(@class, 'swatch-option') and @option-label='{{optionLabel}}']" parameterized="true"/> + <element name="removeFilter" type="button" selector="//div[contains(@class, 'filter-current')]//a[contains(@class, 'remove')]"/> </section> <section name="StorefrontCategorySidebarMobileSection"> <element name="shopByButton" type="button" selector="//div[contains(@class, 'filter-title')]/strong[contains(text(), 'Shop By')]"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml index a0a3a551c3d9..1561fa5e2702 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml @@ -220,6 +220,10 @@ <click selector="{{AdminCreateProductConfigurationsPanel.next}}" before="clickOnSaveButton2" stepKey="clickOnNextButton"/> <click selector="{{AdminCreateProductConfigurationsPanel.next}}" after="clickOnNextButton" stepKey="clickOnGenerateProductsButton"/> </actionGroup> + <actionGroup name="GenerateConfiguredProductAfterSettingOptions"> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton"/> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnGenerateProductsButton"/> + </actionGroup> <actionGroup name="addNewProductConfigurationAttribute"> <annotations> diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AddSwatchToProductActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AddSwatchToProductActionGroup.xml index cd8470fe47fd..1cb3e630ae08 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AddSwatchToProductActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AddSwatchToProductActionGroup.xml @@ -84,4 +84,12 @@ <selectOption selector="{{AdminNewAttributePanel.visibleOnCatalogPagesOnStorefront}}" stepKey="switchOnVisibleOnCatalogPagesOnStorefront" userInput="Yes" after="selectUseInLayer"/> <selectOption selector="{{AdminNewAttributePanel.useInProductListing}}" stepKey="switchOnUsedInProductListing" userInput="Yes" after="switchOnVisibleOnCatalogPagesOnStorefront"/> </actionGroup> + <actionGroup name="AddVisualSwatchWithProductWithStorefrontPreviewImageConfigActionGroup" extends="AddVisualSwatchToProductActionGroup"> + <selectOption selector="{{AdminNewAttributePanel.updateProductPreviewImage}}" userInput="Yes" stepKey="selectUpdatePreviewImage" after="selectInputType"/> + <click selector="{{AdminNewAttributePanel.storefrontPropertiesTab}}" stepKey="goToStorefrontPropertiesTab" after="fillDefaultStoreLabel2"/> + <waitForElementVisible selector="{{AdminNewAttributePanel.storefrontPropertiesTitle}}" after="goToStorefrontPropertiesTab" stepKey="waitTabLoad"/> + <selectOption selector="{{AdminNewAttributePanel.useInLayeredNavigation}}" userInput="Filterable (with results)" stepKey="selectUseInLayer" after="waitTabLoad"/> + <selectOption selector="{{AdminNewAttributePanel.useInProductListing}}" userInput="Yes" stepKey="switchOnUsedInProductListing" after="selectUseInLayer"/> + <selectOption selector="{{AdminNewAttributePanel.usedForStoringInProductListing}}" userInput="Yes" stepKey="switchOnUsedForStoringInProductListing" after="switchOnUsedInProductListing"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml index 0c2dea5f4123..5149fa3a1e51 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminNewAttributePanelSection.xml @@ -9,6 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminNewAttributePanel"> + <element name="updateProductPreviewImage" type="select" selector="#update_product_preview_image"/> <element name="addVisualSwatchOption" type="button" selector="button#add_new_swatch_visual_option_button"/> <element name="addTextSwatchOption" type="button" selector="button#add_new_swatch_text_option_button"/> <element name="visualSwatchOptionAdminValue" type="input" selector="[data-role='swatch-visual-options-container'] input[name='optionvisual[value][option_{{row}}][0]']" parameterized="true"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml new file mode 100644 index 000000000000..428915ab8ae6 --- /dev/null +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontImageColorWhenFilterByColorFilterTest"> + <annotations> + <features value="Swatches"/> + <stories value="Color image when filtering by color filter"/> + <title value="Image color when filtering by color filter on the Storefront"/> + <description value="Image color when filtering by color filter on the Storefront"/> + <severity value="MAJOR"/> + <useCaseId value="MC-18821"/> + <testCaseId value="MC-11531"/> + <group value="Swatches"/> + </annotations> + <before> + <!--Create category and configurable product with two options--> + <comment userInput="Create category and configurable product" stepKey="commentCreateData"/> + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <actionGroup ref="deleteProductAttributeByLabel" stepKey="deleteAttribute"> + <argument name="ProductAttribute" value="visualSwatchAttribute"/> + </actionGroup> + <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="openProductIndexPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> + <actionGroup ref="adminDataGridSelectPerPage" stepKey="selectNumberOfProductsPerPage"> + <argument name="perPage" value="100"/> + </actionGroup> + <actionGroup ref="deleteProductsIfTheyExist" stepKey="deleteAllProducts"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <amOnPage url="{{AdminProductEditPage.url($$createConfigProduct.id$$)}}" stepKey="navigateToConfigProductPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <!--Create visual swatch attribute--> + <comment userInput="Create visual swatch attribute" stepKey="commentCreateAttribute"/> + <actionGroup ref="AddVisualSwatchWithProductWithStorefrontPreviewImageConfigActionGroup" stepKey="addSwatchToProduct"> + <argument name="attribute" value="visualSwatchAttribute"/> + <argument name="option1" value="visualSwatchOption1"/> + <argument name="option2" value="visualSwatchOption2"/> + </actionGroup> + <click selector="{{AdminProductFormConfigurationsSection.createConfigurations}}" stepKey="clickEditConfigurations"/> + <see userInput="Select Attributes" selector="{{AdminProductFormConfigurationsSection.stepsWizardTitle}}" stepKey="seeStepTitle"/> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton1"/> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton2"/> + <!--Add images to product attribute options--> + <comment userInput="Add images to product attribute options" stepKey="commentAddImageToOptions"/> + <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionOne"> + <argument name="image" value="MagentoLogo"/> + <argument name="frontend_label" value="{{visualSwatchAttribute.default_label}}"/> + <argument name="label" value="{{visualSwatchOption1.default_label}}"/> + </actionGroup> + <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionTwo"> + <argument name="image" value="TestImageNew"/> + <argument name="frontend_label" value="{{visualSwatchAttribute.default_label}}"/> + <argument name="label" value="{{visualSwatchOption2.default_label}}"/> + </actionGroup> + <actionGroup ref="GenerateConfiguredProductAfterSettingOptions" stepKey="generateConfigs"/> + <actionGroup ref="saveProductForm" stepKey="saveProductForm"/> + <!--Select any option in the Layered navigation and verify product image--> + <comment userInput="Select any option in the Layered navigation and verify product image" stepKey="commentVerifyImage"/> + <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="navigateToCategoryPage"/> + <actionGroup ref="SelectStorefrontSideBarAttributeOption" stepKey="selectStorefrontProductAttributeOption"> + <argument name="categoryName" value="$$createCategory.name$$"/> + <argument name="attributeDefaultLabel" value="{{visualSwatchAttribute.default_label}}"/> + </actionGroup> + <waitForElementVisible selector="{{StorefrontCategorySidebarSection.filterOptionByLabel(visualSwatchOption1.default_label)}}" stepKey="waitForOption"/> + <click selector="{{StorefrontCategorySidebarSection.filterOptionByLabel(visualSwatchOption1.default_label)}}" stepKey="clickFirstOption"/> + <grabAttributeFrom selector="{{StorefrontCategoryMainSection.productImage}}" userInput="src" stepKey="grabFirstOptionImg"/> + <assertContains expectedType="string" expected="{{MagentoLogo.filename}}" actualType="variable" actual="$grabFirstOptionImg" stepKey="assertProductFirstOptionImage"/> + <click selector="{{StorefrontCategorySidebarSection.removeFilter}}" stepKey="removeSideBarFilter"/> + <actionGroup ref="SelectStorefrontSideBarAttributeOption" stepKey="selectStorefrontProductAttributeForSecondOption"> + <argument name="categoryName" value="$$createCategory.name$$"/> + <argument name="attributeDefaultLabel" value="{{visualSwatchAttribute.default_label}}"/> + </actionGroup> + <waitForElementVisible selector="{{StorefrontCategorySidebarSection.filterOptionByLabel(visualSwatchOption2.default_label)}}" stepKey="waitForSecondOption"/> + <click selector="{{StorefrontCategorySidebarSection.filterOptionByLabel(visualSwatchOption2.default_label)}}" stepKey="clickSecondOption"/> + <grabAttributeFrom selector="{{StorefrontCategoryMainSection.productImage}}" userInput="src" stepKey="grabSecondOptionImg"/> + <assertContains expectedType="string" expected="{{TestImageNew.filename}}" actualType="variable" actual="$grabSecondOptionImg" stepKey="assertProductSecondOptionImage"/> + </test> +</tests> From ba2390fe8b468a757fb9e4c8465d0f8577d4deda Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 09:06:35 -0500 Subject: [PATCH 0298/1172] MC-15298: Allow admin to opt out of admin analytics tracking - added config, rm packaged-lock --- .../LoginAdminWithCredentialsActionGroup.xml | 14 + .../ActionGroup/LoginAsAdminActionGroup.xml | 14 + .../Magento/AdminAnalytics/etc/config.xml | 18 + .../LoginAdminWithCredentialsActionGroup.xml | 1 - .../ActionGroup/LoginAsAdminActionGroup.xml | 1 - package-lock.json | 861 ------------------ 6 files changed, 46 insertions(+), 863 deletions(-) create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml delete mode 100644 package-lock.json diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml new file mode 100644 index 000000000000..d9f5e5dbcb10 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LoginAdminWithCredentialsActionGroup"> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible" before="closeAdminNotification"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml new file mode 100644 index 000000000000..5cf7be8a6fe1 --- /dev/null +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="LoginAsAdmin"> + <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible" before="closeAdminNotification"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 000000000000..ba683f13c11e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 1 + </enabled> + </usage> + </admin> + </default> +</config> \ No newline at end of file diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml index e423c68dd938..6aaa612b249b 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAdminWithCredentialsActionGroup.xml @@ -17,7 +17,6 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminPassword}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml index 9c1963119d38..b2fbadcbe38e 100644 --- a/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml +++ b/app/code/Magento/Backend/Test/Mftf/ActionGroup/LoginAsAdminActionGroup.xml @@ -16,7 +16,6 @@ <fillField selector="{{AdminLoginFormSection.username}}" userInput="{{adminUser.username}}" stepKey="fillUsername"/> <fillField selector="{{AdminLoginFormSection.password}}" userInput="{{adminUser.password}}" stepKey="fillPassword"/> <click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/> - <conditionalClick selector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" dependentSelector="{{AdminUsageNotificationSection.adminUsageDontAllowButton}}" visible="true" stepKey="clickDontAllowButtonIfVisible"/> <closeAdminNotification stepKey="closeAdminNotification"/> </actionGroup> </actionGroups> diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index b3e14ddab5aa..000000000000 --- a/package-lock.json +++ /dev/null @@ -1,861 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==" - }, - "acorn-jsx": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", - "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==" - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - } - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz", - "integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^6.0.0", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.4.1", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz", - "integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==", - "requires": { - "eslint-visitor-keys": "^1.0.0" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" - }, - "espree": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", - "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "requires": { - "flat-cache": "^2.0.1" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" - }, - "import-fresh": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", - "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "inquirer": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", - "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "requires": { - "glob": "^7.1.3" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", - "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - } - } - }, - "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz", - "integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==", - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "requires": { - "mkdirp": "^0.5.1" - } - } - } -} From 753b922262b307aefdfc54abb4fa9f69261141e6 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Thu, 8 Aug 2019 17:23:21 +0300 Subject: [PATCH 0299/1172] MC-18821: Increase test coverage for Catalog functional area - Jasmine test for MC-6354 --- .../frontend/web/js/swatch-renderer.test.js | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js new file mode 100644 index 000000000000..b3172beec770 --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js @@ -0,0 +1,76 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'jquery', + 'Magento_Swatches/js/swatch-renderer' +], function ($, SwatchRenderer) { + 'use strict'; + + describe('Testing SwatchRenderer Widget', function () { + var widget, + attribute, + optionId = 2, + swathImageHeight = '60', + swathImageWidth = '70', + swathThumbImageHeight = '40', + swathThumbImageWidth = '50'; + + beforeEach(function () { + widget = new SwatchRenderer(); + attribute = { + id: 1, + options: [{id: optionId}] + }; + widget.options = { + classes: {optionClass: "swatch-option"}, + jsonSwatchConfig: {1: {2: {type: 2}}}, + jsonSwatchImageSizeConfig: { + swatchImage: { + width: swathImageWidth, + height: swathImageHeight + }, + swatchThumb: { + width: swathThumbImageWidth, + height: swathThumbImageHeight + } + } + }; + }); + + describe('"_RenderSwatchOptions" method', function () { + var html, + optionConfig; + + beforeEach(function () { + optionConfig = widget.options.jsonSwatchConfig[attribute.id]; + html = $(widget._RenderSwatchOptions(attribute, 'option-label-control-id-1'))[0]; + }); + + it('check first conditional statement', function () { + expect(widget.options.jsonSwatchConfig.hasOwnProperty(attribute.id)).toEqual(true); + }); + + it('check second conditional statement', function () { + expect(optionConfig.hasOwnProperty(optionId)).toEqual(true); + }); + + it('check swatch thumbnail image height attribute', function () { + expect(html.hasAttribute('thumb-height')).toBe(true); + expect(html.getAttribute('thumb-height')).toEqual(swathThumbImageHeight); + }); + + it('check swatch thumbnail image width attribute', function () { + expect(html.hasAttribute('thumb-width')).toBe(true); + expect(html.getAttribute('thumb-width')).toEqual(swathThumbImageWidth); + }); + + it('check swatch image styles', function () { + expect(html.style.height).toEqual(swathImageHeight + 'px'); + expect(html.style.width).toEqual(swathImageWidth + 'px'); + }); + }); + }); +}); From 3b0d7b7ef25e854fba0f437b5ce18b84fb51aa5f Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 10:46:39 -0500 Subject: [PATCH 0300/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Updated files based on review --- app/code/Magento/AdminAnalytics/Block/Metadata.php | 4 ++-- .../Magento/AdminAnalytics/Block/Notification.php | 1 - .../Adminhtml/Config/DisableAdminUsage.php | 10 +++++----- .../Controller/Adminhtml/Config/EnableAdminUsage.php | 12 +++++------- .../Model/Condition/CanViewNotification.php | 4 ++-- .../Model/ResourceModel/Viewer/Logger.php | 8 ++++---- app/code/Magento/AdminAnalytics/README.md | 2 +- .../Test/Mftf/Section/AdminUsageConfigSection.xml | 1 - 8 files changed, 19 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/Block/Metadata.php index 2a669829a821..30a911d996f5 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/Block/Metadata.php @@ -5,8 +5,8 @@ */ namespace Magento\AdminAnalytics\Block; -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context; +use Magento\Backend\Block\Template; +use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ProductMetadataInterface; use Magento\Backend\Model\Auth\Session; use Magento\Framework\App\State; diff --git a/app/code/Magento/AdminAnalytics/Block/Notification.php b/app/code/Magento/AdminAnalytics/Block/Notification.php index 7988e2139a3d..1b4314e585b7 100644 --- a/app/code/Magento/AdminAnalytics/Block/Notification.php +++ b/app/code/Magento/AdminAnalytics/Block/Notification.php @@ -27,7 +27,6 @@ class Notification implements ArgumentInterface private $canViewNotificationRelease; /** - * Notification constructor. * @param AdminAnalyticsNotification $canViewNotificationAnalytics * @param ReleaseNotification $canViewNotificationRelease */ diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php index 13a13e8d2403..34a9ef4f75b9 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/DisableAdminUsage.php @@ -38,10 +38,10 @@ class DisableAdminUsage extends Action implements HttpPostActionInterface /** * DisableAdminUsage constructor. * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory */ public function __construct( Action\Context $context, @@ -56,7 +56,7 @@ public function __construct( } /** - * Changes the value of config/admin/usage/enabled + * Change the value of config/admin/usage/enabled */ private function disableAdminUsage() { @@ -70,7 +70,7 @@ private function disableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + private function markUserNotified(): ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php index aee300c2f6e8..f70dd57aa59d 100644 --- a/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php +++ b/app/code/Magento/AdminAnalytics/Controller/Adminhtml/Config/EnableAdminUsage.php @@ -36,12 +36,10 @@ class EnableAdminUsage extends Action implements HttpPostActionInterface private $notificationLogger; /** - * MarkUserNotified constructor. - * - * @param Action\Context $context + * @param Action\Context $context * @param ProductMetadataInterface $productMetadata - * @param NotificationLogger $notificationLogger - * @param Factory $configFactory + * @param NotificationLogger $notificationLogger + * @param Factory $configFactory */ public function __construct( Action\Context $context, @@ -56,7 +54,7 @@ public function __construct( } /** - * Changes the value of config/admin/usage/enabled + * Change the value of config/admin/usage/enabled */ private function enableAdminUsage() { @@ -70,7 +68,7 @@ private function enableAdminUsage() * * @return ResultInterface */ - private function markUserNotified() : ResultInterface + private function markUserNotified(): ResultInterface { $responseContent = [ 'success' => $this->notificationLogger->log( diff --git a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php index 1012f205d6bf..222261d4abfb 100644 --- a/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php +++ b/app/code/Magento/AdminAnalytics/Model/Condition/CanViewNotification.php @@ -12,7 +12,7 @@ use Magento\Framework\App\CacheInterface; /** - * Dynamic validator for UI admin analytics notification, manage UI component visibility. + * Dynamic validator for UI admin analytics notification, control UI component visibility. */ class CanViewNotification implements VisibilityConditionInterface { @@ -41,7 +41,7 @@ class CanViewNotification implements VisibilityConditionInterface private $cacheStorage; /** - * @param Logger $viewerLogger + * @param Logger $viewerLogger * @param CacheInterface $cacheStorage */ public function __construct( diff --git a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php index b185e263f480..5c225ebfeceb 100644 --- a/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php +++ b/app/code/Magento/AdminAnalytics/Model/ResourceModel/Viewer/Logger.php @@ -51,7 +51,7 @@ public function __construct( * @param string $lastViewVersion * @return bool */ - public function log(string $lastViewVersion) : bool + public function log(string $lastViewVersion): bool { /** @var \Magento\Framework\DB\Adapter\AdapterInterface $connection */ $connection = $this->resource->getConnection(ResourceConnection::DEFAULT_CONNECTION); @@ -72,7 +72,7 @@ public function log(string $lastViewVersion) : bool * * @return Log */ - public function get() : Log + public function get(): Log { return $this->logFactory->create(['data' => $this->loadLatestLogData()]); } @@ -82,7 +82,7 @@ public function get() : Log * * @return boolean */ - public function checkLogExists() : bool + public function checkLogExists(): bool { $data = $this->logFactory->create(['data' => $this->loadLatestLogData()]); $lastViewedVersion = $data->getLastViewVersion(); @@ -94,7 +94,7 @@ public function checkLogExists() : bool * * @return array */ - private function loadLatestLogData() : array + private function loadLatestLogData(): array { $connection = $this->resource->getConnection(); $select = $connection->select() diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md index 1280e0fcef10..1aaf204ba04b 100644 --- a/app/code/Magento/AdminAnalytics/README.md +++ b/app/code/Magento/AdminAnalytics/README.md @@ -1 +1 @@ -The purpose of Magento\AdminAnalytics module is gather information on which features the users uses and sends it to adobe analytics \ No newline at end of file +The purpose of Magento\AdminAnalytics module is to gather information on which features the admins use, to help improve Magento admin experience. \ No newline at end of file diff --git a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml index ddb89f0bfb72..634ebf855d94 100644 --- a/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml +++ b/app/code/Magento/AdminAnalytics/Test/Mftf/Section/AdminUsageConfigSection.xml @@ -9,7 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminUsageConfigSection"> - <element name="adminUsageHeader" type="text" selector="#admin_usage-head"/> <element name="adminUsageOptions" type="select" selector="#admin_usage_enabled"/> </section> From f96b7aed68d649bdd03293620d4ef0f2948e62cc Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 11:00:49 -0500 Subject: [PATCH 0301/1172] MC-15298: Allow admin to opt out of admin analytics tracking - Updated README --- app/code/Magento/AdminAnalytics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/AdminAnalytics/README.md b/app/code/Magento/AdminAnalytics/README.md index 1aaf204ba04b..e905344031ad 100644 --- a/app/code/Magento/AdminAnalytics/README.md +++ b/app/code/Magento/AdminAnalytics/README.md @@ -1 +1 @@ -The purpose of Magento\AdminAnalytics module is to gather information on which features the admins use, to help improve Magento admin experience. \ No newline at end of file +The Magento\AdminAnalytics module gathers information about the features Magento administrators use. This information will be used to help improve the user experience on the Magento Admin. \ No newline at end of file From e70e30484b746b316575014d0727fbe092a9bec3 Mon Sep 17 00:00:00 2001 From: michellbrito <michellbp@msn.com> Date: Thu, 8 Aug 2019 14:37:42 -0500 Subject: [PATCH 0302/1172] MC-15298: Allow admin to opt out of admin analytics tracking - removed config --- app/code/Magento/AdminAnalytics/etc/config.xml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml deleted file mode 100644 index ba683f13c11e..000000000000 --- a/app/code/Magento/AdminAnalytics/etc/config.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> - <default> - <admin> - <usage> - <enabled> - 1 - </enabled> - </usage> - </admin> - </default> -</config> \ No newline at end of file From 912f8c5a963383655584a074c7d7c0cf1a9057bc Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 8 Aug 2019 16:24:59 -0500 Subject: [PATCH 0303/1172] MC-15298: Allow admin to opt out of admin analytics tracking --- .../{Block => ViewModel}/Metadata.php | 16 ++++------------ .../{Block => ViewModel}/Notification.php | 4 ++-- .../layout/adminhtml_dashboard_index.xml | 2 +- .../view/adminhtml/layout/default.xml | 3 ++- .../view/adminhtml/templates/tracking.phtml | 6 +++--- 5 files changed, 12 insertions(+), 19 deletions(-) rename app/code/Magento/AdminAnalytics/{Block => ViewModel}/Metadata.php (81%) rename app/code/Magento/AdminAnalytics/{Block => ViewModel}/Notification.php (93%) diff --git a/app/code/Magento/AdminAnalytics/Block/Metadata.php b/app/code/Magento/AdminAnalytics/ViewModel/Metadata.php similarity index 81% rename from app/code/Magento/AdminAnalytics/Block/Metadata.php rename to app/code/Magento/AdminAnalytics/ViewModel/Metadata.php index 30a911d996f5..9b1accbe0c82 100644 --- a/app/code/Magento/AdminAnalytics/Block/Metadata.php +++ b/app/code/Magento/AdminAnalytics/ViewModel/Metadata.php @@ -3,20 +3,17 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\AdminAnalytics\Block; +namespace Magento\AdminAnalytics\ViewModel; -use Magento\Backend\Block\Template; -use Magento\Backend\Block\Template\Context; use Magento\Framework\App\ProductMetadataInterface; use Magento\Backend\Model\Auth\Session; use Magento\Framework\App\State; +use Magento\Framework\View\Element\Block\ArgumentInterface; /** * Gets user version and mode - * - * @api */ -class Metadata extends Template +class Metadata implements ArgumentInterface { /** * @var State @@ -34,23 +31,18 @@ class Metadata extends Template private $productMetadata; /** - * @param Context $context * @param ProductMetadataInterface $productMetadata * @param Session $authSession * @param State $appState - * @param array $data */ public function __construct( - Context $context, ProductMetadataInterface $productMetadata, Session $authSession, - State $appState, - array $data = [] + State $appState ) { $this->productMetadata = $productMetadata; $this->authSession = $authSession; $this->appState = $appState; - parent::__construct($context, $data); } /** diff --git a/app/code/Magento/AdminAnalytics/Block/Notification.php b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php similarity index 93% rename from app/code/Magento/AdminAnalytics/Block/Notification.php rename to app/code/Magento/AdminAnalytics/ViewModel/Notification.php index 1b4314e585b7..030e027b83fc 100644 --- a/app/code/Magento/AdminAnalytics/Block/Notification.php +++ b/app/code/Magento/AdminAnalytics/ViewModel/Notification.php @@ -5,14 +5,14 @@ */ declare(strict_types=1); -namespace Magento\AdminAnalytics\Block; +namespace Magento\AdminAnalytics\ViewModel; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\AdminAnalytics\Model\Condition\CanViewNotification as AdminAnalyticsNotification; use Magento\ReleaseNotification\Model\Condition\CanViewNotification as ReleaseNotification; /** - * Class Notification + * Control display of admin analytics and release notification modals */ class Notification implements ArgumentInterface { diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml index 829c5ed3f810..3069db1ecc2b 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/adminhtml_dashboard_index.xml @@ -14,7 +14,7 @@ </uiComponent> <block name="tracking_notification" as="tracking_notification" template="Magento_AdminAnalytics::notification.phtml"> <arguments> - <argument name="notification" xsi:type="object">Magento\AdminAnalytics\Block\Notification</argument> + <argument name="notification" xsi:type="object">Magento\AdminAnalytics\ViewModel\Notification</argument> </arguments> </block> </referenceContainer> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml index 05f7df828416..7e379a17c78d 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/layout/default.xml @@ -8,9 +8,10 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" > <body> <referenceContainer name="header"> - <block class="Magento\AdminAnalytics\Block\Metadata" name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> + <block name="tracking" as="tracking" template="Magento_AdminAnalytics::tracking.phtml" ifconfig="admin/usage/enabled"> <arguments> <argument name="tracking_url" xsi:type="string">//assets.adobedtm.com/launch-EN30eb7ffa064444f1b8b0368ef38fd3a9.min.js</argument> + <argument name="metadata" xsi:type="object">Magento\AdminAnalytics\ViewModel\Metadata</argument> </arguments> </block> </referenceContainer> diff --git a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml index 03c4c848aa44..0ea5c753c933 100644 --- a/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml +++ b/app/code/Magento/AdminAnalytics/view/adminhtml/templates/tracking.phtml @@ -8,8 +8,8 @@ <script src="<?= $block->escapeUrl($block->getTrackingUrl()) ?>" async></script> <script> var adminAnalyticsMetadata = { - "version": "<?= $block->escapeJs($block->getMagentoVersion()) ?>", - "user": "<?= $block->escapeJs($block->getCurrentUser()) ?>", - "mode": "<?= $block->escapeJs($block->getMode()) ?>" + "version": "<?= $block->escapeJs($block->getMetadata()->getMagentoVersion()) ?>", + "user": "<?= $block->escapeJs($block->getMetadata()->getCurrentUser()) ?>", + "mode": "<?= $block->escapeJs($block->getMetadata()->getMode()) ?>" }; </script> From fa4957fea80bdd3b675d5c0816fc33ece100cba9 Mon Sep 17 00:00:00 2001 From: Evgeny Petrov <evgeny_petrov@epam.com> Date: Tue, 6 Aug 2019 18:21:46 +0300 Subject: [PATCH 0304/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Unit tests for MC-6387 --- .../Test/Unit/Model/DirectpostTest.php | 590 ++++++++++-------- 1 file changed, 340 insertions(+), 250 deletions(-) diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php index 95c67f67852d..50cf7e86e8fc 100644 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php +++ b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php @@ -3,8 +3,18 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Authorizenet\Test\Unit\Model; +use Magento\Authorizenet\Helper\Backend\Data; +use Magento\Authorizenet\Helper\Data as HelperData; +use Magento\Authorizenet\Model\Directpost\Response; +use Magento\Authorizenet\Model\Directpost\Response\Factory as ResponseFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\HTTP\ZendClient; +use Magento\Framework\HTTP\ZendClientFactory; +use Magento\Payment\Model\InfoInterface; +use Magento\Payment\Model\Method\ConfigInterface; use Magento\Sales\Api\PaymentFailuresInterface; use Magento\Framework\Simplexml\Element; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; @@ -13,118 +23,118 @@ use Magento\Authorizenet\Model\Request; use Magento\Authorizenet\Model\Directpost\Request\Factory; use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Payment; +use Magento\Sales\Model\Order\Payment\Transaction; use Magento\Sales\Model\Order\Payment\Transaction\Repository as TransactionRepository; +use PHPUnit\Framework\MockObject_MockBuilder; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; +use ReflectionClass; /** * Class DirectpostTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class DirectpostTest extends \PHPUnit\Framework\TestCase +class DirectpostTest extends TestCase { const TOTAL_AMOUNT = 100.02; const INVOICE_NUM = '00000001'; const TRANSACTION_ID = '41a23x34fd124'; /** - * @var \Magento\Authorizenet\Model\Directpost + * @var Directpost */ protected $directpost; /** - * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ScopeConfigInterface|PHPUnit_Framework_MockObject_MockObject */ protected $scopeConfigMock; /** - * @var \Magento\Payment\Model\InfoInterface|\PHPUnit_Framework_MockObject_MockObject + * @var InfoInterface|PHPUnit_Framework_MockObject_MockObject */ protected $paymentMock; /** - * @var \Magento\Authorizenet\Helper\Data|\PHPUnit_Framework_MockObject_MockObject + * @var HelperData|PHPUnit_Framework_MockObject_MockObject */ protected $dataHelperMock; /** - * @var \Magento\Authorizenet\Model\Directpost\Response\Factory|\PHPUnit_Framework_MockObject_MockObject + * @var ResponseFactory|PHPUnit_Framework_MockObject_MockObject */ protected $responseFactoryMock; /** - * @var TransactionRepository|\PHPUnit_Framework_MockObject_MockObject + * @var TransactionRepository|PHPUnit_Framework_MockObject_MockObject */ protected $transactionRepositoryMock; /** - * @var \Magento\Authorizenet\Model\Directpost\Response|\PHPUnit_Framework_MockObject_MockObject + * @var Response|PHPUnit_Framework_MockObject_MockObject */ protected $responseMock; /** - * @var TransactionService|\PHPUnit_Framework_MockObject_MockObject + * @var TransactionService|PHPUnit_Framework_MockObject_MockObject */ protected $transactionServiceMock; /** - * @var \Magento\Framework\HTTP\ZendClient|\PHPUnit_Framework_MockObject_MockObject + * @var ZendClient|PHPUnit_Framework_MockObject_MockObject */ protected $httpClientMock; /** - * @var \Magento\Authorizenet\Model\Directpost\Request\Factory|\PHPUnit_Framework_MockObject_MockObject + * @var Factory|PHPUnit_Framework_MockObject_MockObject */ protected $requestFactory; /** - * @var PaymentFailuresInterface|\PHPUnit_Framework_MockObject_MockObject + * @var PaymentFailuresInterface|PHPUnit_Framework_MockObject_MockObject */ private $paymentFailures; + /** + * @var ZendClientFactory|PHPUnit_Framework_MockObject_MockObject + */ + private $httpClientFactoryMock; + /** * @inheritdoc */ protected function setUp() { - $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) - ->getMock(); - $this->paymentMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment::class) - ->disableOriginalConstructor() - ->setMethods([ - 'getOrder', 'getId', 'setAdditionalInformation', 'getAdditionalInformation', - 'setIsTransactionDenied', 'setIsTransactionClosed', 'decrypt', 'getCcLast4', - 'getParentTransactionId', 'getPoNumber' - ]) - ->getMock(); - $this->dataHelperMock = $this->getMockBuilder(\Magento\Authorizenet\Helper\Data::class) - ->disableOriginalConstructor() - ->getMock(); - + $this->initPaymentMock(); $this->initResponseFactoryMock(); + $this->initHttpClientMock(); - $this->transactionRepositoryMock = $this->getMockBuilder( - \Magento\Sales\Model\Order\Payment\Transaction\Repository::class - ) + $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)->getMock(); + $this->dataHelperMock = $this->getMockBuilder(HelperData::class)->disableOriginalConstructor()->getMock(); + $this->transactionRepositoryMock = $this->getMockBuilder(TransactionRepository::class) ->disableOriginalConstructor() ->setMethods(['getByTransactionId']) ->getMock(); - - $this->transactionServiceMock = $this->getMockBuilder(\Magento\Authorizenet\Model\TransactionService::class) + $this->transactionServiceMock = $this->getMockBuilder(TransactionService::class) ->disableOriginalConstructor() ->setMethods(['getTransactionDetails']) ->getMock(); - - $this->paymentFailures = $this->getMockBuilder( - PaymentFailuresInterface::class - ) + $this->paymentFailures = $this->getMockBuilder(PaymentFailuresInterface::class) ->disableOriginalConstructor() ->getMock(); - - $this->requestFactory = $this->getRequestFactoryMock(); - $httpClientFactoryMock = $this->getHttpClientFactoryMock(); + $this->requestFactory = $this->getMockBuilder(Factory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->httpClientFactoryMock = $this->getMockBuilder(ZendClientFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); $helper = new ObjectManagerHelper($this); $this->directpost = $helper->getObject( - \Magento\Authorizenet\Model\Directpost::class, + Directpost::class, [ 'scopeConfig' => $this->scopeConfigMock, 'dataHelper' => $this->dataHelperMock, @@ -132,18 +142,97 @@ protected function setUp() 'responseFactory' => $this->responseFactoryMock, 'transactionRepository' => $this->transactionRepositoryMock, 'transactionService' => $this->transactionServiceMock, - 'httpClientFactory' => $httpClientFactoryMock, + 'httpClientFactory' => $this->httpClientFactoryMock, 'paymentFailures' => $this->paymentFailures, ] ); } + /** + * Create mock for response factory + * + * @return void + */ + private function initResponseFactoryMock() + { + $this->responseFactoryMock = $this->getMockBuilder(ResponseFactory::class) + ->disableOriginalConstructor() + ->getMock(); + $this->responseMock = $this->getMockBuilder(Response::class) + ->setMethods( + [ + 'isValidHash', + 'getXTransId', + 'getXResponseCode', + 'getXResponseReasonCode', + 'getXResponseReasonText', + 'getXAmount', + 'setXResponseCode', + 'setXResponseReasonCode', + 'setXAvsCode', + 'setXResponseReasonText', + 'setXTransId', + 'setXInvoiceNum', + 'setXAmount', + 'setXMethod', + 'setXType', + 'setData', + 'getData', + 'setXAccountNumber', + '__wakeup' + ] + ) + ->disableOriginalConstructor() + ->getMock(); + + $this->responseFactoryMock->expects($this->any())->method('create')->willReturn($this->responseMock); + } + + /** + * Create mock for payment + * + * @return void + */ + private function initPaymentMock() + { + $this->paymentMock = $this->getMockBuilder(Payment::class) + ->disableOriginalConstructor() + ->setMethods( + [ + 'getOrder', + 'setAmount', + 'setAnetTransType', + 'setXTransId', + 'getId', + 'setAdditionalInformation', + 'getAdditionalInformation', + 'setIsTransactionDenied', + 'setIsTransactionClosed', + 'decrypt', + 'getCcLast4', + 'getParentTransactionId', + 'getPoNumber' + ] + ) + ->getMock(); + } + + /** + * Create a mock for http client + * + * @return void + */ + private function initHttpClientMock() + { + $this->httpClientMock = $this->getMockBuilder(ZendClient::class) + ->disableOriginalConstructor() + ->setMethods(['request', 'getBody', '__wakeup']) + ->getMock(); + } + public function testGetConfigInterface() { - $this->assertInstanceOf( - \Magento\Payment\Model\Method\ConfigInterface::class, - $this->directpost->getConfigInterface() - ); + $this->assertInstanceOf(ConfigInterface::class, $this->directpost->getConfigInterface()); } public function testGetConfigValue() @@ -162,7 +251,7 @@ public function testSetDataHelper() $storeId = 'store-id'; $expectedResult = 'relay-url'; - $helperDataMock = $this->getMockBuilder(\Magento\Authorizenet\Helper\Backend\Data::class) + $helperDataMock = $this->getMockBuilder(Data::class) ->disableOriginalConstructor() ->getMock(); @@ -179,7 +268,7 @@ public function testAuthorize() { $paymentAction = 'some_action'; - $this->scopeConfigMock->expects($this->any()) + $this->scopeConfigMock->expects($this->once()) ->method('getValue') ->with('payment/authorizenet_directpost/payment_action', 'store', null) ->willReturn($paymentAction); @@ -190,11 +279,141 @@ public function testAuthorize() $this->directpost->authorize($this->paymentMock, 10); } + /** + * @dataProvider dataProviderCaptureWithInvalidAmount + * @expectedExceptionMessage Invalid amount for capture. + * @expectedException \Magento\Framework\Exception\LocalizedException + * + * @param int $invalidAmount + */ + public function testCaptureWithInvalidAmount($invalidAmount) + { + $this->directpost->capture($this->paymentMock, $invalidAmount); + } + + /** + * @return array + */ + public function dataProviderCaptureWithInvalidAmount() + { + return [ + [0], + [0.000], + [-1.000], + [-1], + [null], + ]; + } + + /** + * @@expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testCaptureHasParentTransactionId() + { + $amount = 10; + + $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); + $this->paymentMock->expects($this->exactly(2))->method('getParentTransactionId')->willReturn(1); + $this->paymentMock->expects($this->once())->method('setAnetTransType')->willReturn('PRIOR_AUTH_CAPTURE'); + + $this->paymentMock->expects($this->once())->method('getId')->willReturn(1); + $orderMock = $this->getOrderMock(); + $orderMock->expects($this->once())->method('getId')->willReturn(1); + $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); + + $transactionMock = $this->getMockBuilder(Transaction::class)->disableOriginalConstructor()->getMock(); + $this->transactionRepositoryMock->expects($this->once()) + ->method('getByTransactionId') + ->with(1, 1, 1) + ->willReturn($transactionMock); + + $this->paymentMock->expects($this->once())->method('setXTransId'); + $this->responseMock->expects($this->once())->method('getData')->willReturn([1]); + + $this->directpost->capture($this->paymentMock, 10); + } + + /** + * @@expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testCaptureWithoutParentTransactionId() + { + $amount = 10; + + $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); + $this->paymentMock->expects($this->once())->method('getParentTransactionId')->willReturn(null); + $this->responseMock->expects($this->once())->method('getData')->willReturn([1]); + + $this->directpost->capture($this->paymentMock, 10); + } + + public function testCaptureWithoutParentTransactionIdWithoutData() + { + $amount = 10; + + $this->paymentMock->expects($this->once())->method('setAmount')->with($amount); + $this->paymentMock->expects($this->exactly(2))->method('getParentTransactionId')->willReturn(null); + $this->responseMock->expects($this->once())->method('getData')->willReturn([]); + + $this->paymentMock->expects($this->once()) + ->method('setIsTransactionClosed') + ->with(0) + ->willReturnSelf(); + + $this->httpClientFactoryMock->expects($this->once())->method('create')->willReturn($this->httpClientMock); + $this->httpClientMock->expects($this->once())->method('request')->willReturnSelf(); + + $this->buildRequestTest(); + $this->postRequestTest(); + + $this->directpost->capture($this->paymentMock, 10); + } + + private function buildRequestTest() + { + $orderMock = $this->getOrderMock(); + $orderMock->expects($this->once())->method('getStoreId')->willReturn(1); + $orderMock->expects($this->exactly(2))->method('getIncrementId')->willReturn(self::INVOICE_NUM); + $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); + + $this->addRequestMockToRequestFactoryMock(); + } + + private function postRequestTest() + { + $this->httpClientFactoryMock->expects($this->once())->method('create')->willReturn($this->httpClientMock); + $this->httpClientMock->expects($this->once())->method('request')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXResponseCode')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXResponseReasonCode')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXResponseReasonText')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXAvsCode')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXTransId')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXInvoiceNum')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXAmount')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXMethod')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setXType')->willReturnSelf(); + $this->responseMock->expects($this->once())->method('setData')->willReturnSelf(); + + $response = $this->getRefundResponseBody( + Directpost::RESPONSE_CODE_APPROVED, + Directpost::RESPONSE_REASON_CODE_APPROVED, + 'Successful' + ); + $this->httpClientMock->expects($this->once())->method('getBody')->willReturn($response); + $this->responseMock->expects($this->once()) + ->method('getXResponseCode') + ->willReturn(Directpost::RESPONSE_CODE_APPROVED); + $this->responseMock->expects($this->once()) + ->method('getXResponseReasonCode') + ->willReturn(Directpost::RESPONSE_REASON_CODE_APPROVED); + $this->dataHelperMock->expects($this->never())->method('wrapGatewayError'); + } + public function testGetCgiUrl() { $url = 'cgi/url'; - $this->scopeConfigMock->expects($this->any()) + $this->scopeConfigMock->expects($this->once()) ->method('getValue') ->with('payment/authorizenet_directpost/cgi_url', 'store', null) ->willReturn($url); @@ -204,7 +423,7 @@ public function testGetCgiUrl() public function testGetCgiUrlWithEmptyConfigValue() { - $this->scopeConfigMock->expects($this->any()) + $this->scopeConfigMock->expects($this->once()) ->method('getValue') ->with('payment/authorizenet_directpost/cgi_url', 'store', null) ->willReturn(null); @@ -218,7 +437,7 @@ public function testGetRelayUrl() $url = 'relay/url'; $this->directpost->setData('store', $storeId); - $this->dataHelperMock->expects($this->any()) + $this->dataHelperMock->expects($this->exactly(2)) ->method('getRelayUrl') ->with($storeId) ->willReturn($url); @@ -268,7 +487,7 @@ public function testValidateResponseFailure() */ protected function prepareTestValidateResponse($transMd5, $login, $isValidHash) { - $this->scopeConfigMock->expects($this->any()) + $this->scopeConfigMock->expects($this->exactly(2)) ->method('getValue') ->willReturnMap( [ @@ -276,7 +495,7 @@ protected function prepareTestValidateResponse($transMd5, $login, $isValidHash) ['payment/authorizenet_directpost/login', 'store', null, $login] ] ); - $this->responseMock->expects($this->any()) + $this->responseMock->expects($this->exactly(1)) ->method('isValidHash') ->with($transMd5, $login) ->willReturn($isValidHash); @@ -328,6 +547,23 @@ public function checkResponseCodeSuccessDataProvider() ]; } + /** + * Checks response failures behaviour. + * + * @param int $responseCode + * @param int $failuresHandlerCalls + * @return void + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testCheckResponseCodeFailureDefault(): void + { + $responseCode = 999999; + $this->responseMock->expects($this->once())->method('getXResponseCode')->willReturn($responseCode); + + $this->directpost->checkResponseCode(); + } + /** * Checks response failures behaviour. * @@ -338,34 +574,24 @@ public function checkResponseCodeSuccessDataProvider() * @expectedException \Magento\Framework\Exception\LocalizedException * @dataProvider checkResponseCodeFailureDataProvider */ - public function testCheckResponseCodeFailure(int $responseCode, int $failuresHandlerCalls): void + public function testCheckResponseCodeFailureDeclinedOrError(int $responseCode, int $failuresHandlerCalls): void { $reasonText = 'reason text'; $this->responseMock->expects($this->once()) ->method('getXResponseCode') ->willReturn($responseCode); - $this->responseMock->expects($this->any()) - ->method('getXResponseReasonText') - ->willReturn($reasonText); - $this->dataHelperMock->expects($this->any()) + $this->responseMock->expects($this->once())->method('getXResponseReasonText')->willReturn($reasonText); + $this->dataHelperMock->expects($this->once()) ->method('wrapGatewayError') ->with($reasonText) ->willReturn(__('Gateway error: %1', $reasonText)); - $orderMock = $this->getMockBuilder(Order::class) - ->disableOriginalConstructor() - ->getMock(); - - $orderMock->expects($this->exactly($failuresHandlerCalls)) - ->method('getQuoteId') - ->willReturn(1); - - $this->paymentFailures->expects($this->exactly($failuresHandlerCalls)) - ->method('handle') - ->with(1); + $this->paymentFailures->expects($this->exactly($failuresHandlerCalls))->method('handle')->with(1); + $orderMock = $this->getOrderMock($failuresHandlerCalls); - $reflection = new \ReflectionClass($this->directpost); + $orderMock->expects($this->exactly($failuresHandlerCalls))->method('getQuoteId')->willReturn(1); + $reflection = new ReflectionClass($this->directpost); $order = $reflection->getProperty('order'); $order->setAccessible(true); $order->setValue($this->directpost, $orderMock); @@ -381,7 +607,6 @@ public function checkResponseCodeFailureDataProvider(): array return [ ['responseCode' => Directpost::RESPONSE_CODE_DECLINED, 1], ['responseCode' => Directpost::RESPONSE_CODE_ERROR, 1], - ['responseCode' => 999999, 0], ]; } @@ -417,7 +642,7 @@ public function testCanCapture($isGatewayActionsLocked, $canCapture) { $this->directpost->setData('info_instance', $this->paymentMock); - $this->paymentMock->expects($this->any()) + $this->paymentMock->expects($this->once()) ->method('getAdditionalInformation') ->with(Directpost::GATEWAY_ACTIONS_LOCKED_STATE_KEY) ->willReturn($isGatewayActionsLocked); @@ -452,30 +677,16 @@ public function testFetchVoidedTransactionInfo($transactionId, $resultStatus, $r $paymentId = 36; $orderId = 36; - $this->paymentMock->expects(static::once()) - ->method('getId') - ->willReturn($paymentId); - - $orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class) - ->disableOriginalConstructor() - ->setMethods(['getId', '__wakeup']) - ->getMock(); - $orderMock->expects(static::once()) - ->method('getId') - ->willReturn($orderId); + $this->paymentMock->expects($this->once())->method('getId')->willReturn($paymentId); - $this->paymentMock->expects(static::once()) - ->method('getOrder') - ->willReturn($orderMock); - - $transactionMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Payment\Transaction::class) - ->disableOriginalConstructor() - ->getMock(); - $this->transactionRepositoryMock->expects(static::once()) + $orderMock = $this->getOrderMock(); + $orderMock->expects($this->once())->method('getId')->willReturn($orderId); + $this->paymentMock->expects($this->once())->method('getOrder')->willReturn($orderMock); + $transactionMock = $this->getMockBuilder(Transaction::class)->disableOriginalConstructor()->getMock(); + $this->transactionRepositoryMock->expects($this->once()) ->method('getByTransactionId') ->with($transactionId, $paymentId, $orderId) ->willReturn($transactionMock); - $document = $this->getTransactionXmlDocument( $transactionId, TransactionService::PAYMENT_UPDATE_STATUS_CODE_SUCCESS, @@ -483,20 +694,15 @@ public function testFetchVoidedTransactionInfo($transactionId, $resultStatus, $r $responseStatus, $responseCode ); - $this->transactionServiceMock->expects(static::once()) + $this->transactionServiceMock->expects($this->once()) ->method('getTransactionDetails') ->with($this->directpost, $transactionId) ->willReturn($document); // transaction should be closed - $this->paymentMock->expects(static::once()) - ->method('setIsTransactionDenied') - ->with(true); - $this->paymentMock->expects(static::once()) - ->method('setIsTransactionClosed') - ->with(true); - $transactionMock->expects(static::once()) - ->method('close'); + $this->paymentMock->expects($this->once())->method('setIsTransactionDenied')->with(true); + $this->paymentMock->expects($this->once())->method('setIsTransactionClosed')->with(true); + $transactionMock->expects($this->once())->method('close'); $this->directpost->fetchTransactionInfo($this->paymentMock, $transactionId); } @@ -509,60 +715,41 @@ public function testSuccessRefund() { $card = 1111; - $this->paymentMock->expects(static::exactly(2)) - ->method('getCcLast4') - ->willReturn($card); - $this->paymentMock->expects(static::once()) - ->method('decrypt') - ->willReturn($card); - $this->paymentMock->expects(static::exactly(3)) + $this->paymentMock->expects($this->exactly(1))->method('getCcLast4')->willReturn($card); + $this->paymentMock->expects($this->once())->method('decrypt')->willReturn($card); + $this->paymentMock->expects($this->exactly(3)) ->method('getParentTransactionId') ->willReturn(self::TRANSACTION_ID . '-capture'); - $this->paymentMock->expects(static::once()) - ->method('getPoNumber') - ->willReturn(self::INVOICE_NUM); - $this->paymentMock->expects(static::once()) + $this->paymentMock->expects($this->once())->method('getPoNumber')->willReturn(self::INVOICE_NUM); + $this->paymentMock->expects($this->once()) ->method('setIsTransactionClosed') ->with(true) ->willReturnSelf(); + $this->addRequestMockToRequestFactoryMock(); + $orderMock = $this->getOrderMock(); - $this->paymentMock->expects(static::exactly(2)) - ->method('getOrder') - ->willReturn($orderMock); + $orderMock->expects($this->once())->method('getId')->willReturn(1); + $orderMock->expects($this->exactly(2))->method('getIncrementId')->willReturn(self::INVOICE_NUM); + $orderMock->expects($this->once())->method('getStoreId')->willReturn(1); + + $this->paymentMock->expects($this->exactly(2))->method('getOrder')->willReturn($orderMock); - $transactionMock = $this->getMockBuilder(Order\Payment\Transaction::class) + $transactionMock = $this->getMockBuilder(Transaction::class) ->disableOriginalConstructor() ->setMethods(['getAdditionalInformation']) ->getMock(); - $transactionMock->expects(static::once()) + $transactionMock->expects($this->once()) ->method('getAdditionalInformation') ->with(Directpost::REAL_TRANSACTION_ID_KEY) ->willReturn(self::TRANSACTION_ID); - $this->transactionRepositoryMock->expects(static::once()) + $this->transactionRepositoryMock->expects($this->once()) ->method('getByTransactionId') ->willReturn($transactionMock); - $response = $this->getRefundResponseBody( - Directpost::RESPONSE_CODE_APPROVED, - Directpost::RESPONSE_REASON_CODE_APPROVED, - 'Successful' - ); - $this->httpClientMock->expects(static::once()) - ->method('getBody') - ->willReturn($response); - - $this->responseMock->expects(static::once()) - ->method('getXResponseCode') - ->willReturn(Directpost::RESPONSE_CODE_APPROVED); - $this->responseMock->expects(static::once()) - ->method('getXResponseReasonCode') - ->willReturn(Directpost::RESPONSE_REASON_CODE_APPROVED); - - $this->dataHelperMock->expects(static::never()) - ->method('wrapGatewayError'); + $this->postRequestTest(); $this->directpost->refund($this->paymentMock, self::TOTAL_AMOUNT); } @@ -583,65 +770,6 @@ public function dataProviderTransaction() ]; } - /** - * Create mock for response factory - * @return void - */ - private function initResponseFactoryMock() - { - $this->responseFactoryMock = $this->getMockBuilder( - \Magento\Authorizenet\Model\Directpost\Response\Factory::class - )->disableOriginalConstructor()->getMock(); - $this->responseMock = $this->getMockBuilder(\Magento\Authorizenet\Model\Directpost\Response::class) - ->setMethods( - [ - 'isValidHash', - 'getXTransId', 'getXResponseCode', 'getXResponseReasonCode', 'getXResponseReasonText', 'getXAmount', - 'setXResponseCode', 'setXResponseReasonCode', 'setXAvsCode', 'setXResponseReasonText', - 'setXTransId', 'setXInvoiceNum', 'setXAmount', 'setXMethod', 'setXType', 'setData', - 'setXAccountNumber', - '__wakeup' - ] - ) - ->disableOriginalConstructor() - ->getMock(); - - $this->responseMock->expects(static::any()) - ->method('setXResponseCode') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXResponseReasonCode') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXResponseReasonText') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXAvsCode') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXTransId') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXInvoiceNum') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXAmount') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXMethod') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setXType') - ->willReturnSelf(); - $this->responseMock->expects(static::any()) - ->method('setData') - ->willReturnSelf(); - - $this->responseFactoryMock->expects($this->any()) - ->method('create') - ->willReturn($this->responseMock); - } - /** * Get transaction data * @param $transactionId @@ -694,80 +822,40 @@ private function getTransactionXmlDocument( /** * Get mock for authorize.net request factory - * @return \PHPUnit\Framework\MockObject_MockBuilder */ - private function getRequestFactoryMock() + private function addRequestMockToRequestFactoryMock() { - $requestFactory = $this->getMockBuilder(Factory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); $request = $this->getMockBuilder(Request::class) ->disableOriginalConstructor() ->setMethods(['__wakeup']) ->getMock(); - $requestFactory->expects(static::any()) + $this->requestFactory->expects($this->once()) ->method('create') ->willReturn($request); - return $requestFactory; } /** * Get mock for order - * @return \PHPUnit_Framework_MockObject_MockObject + * @return PHPUnit_Framework_MockObject_MockObject */ private function getOrderMock() { - $orderMock = $this->getMockBuilder(Order::class) - ->disableOriginalConstructor() - ->setMethods([ - 'getId', 'getIncrementId', 'getStoreId', 'getBillingAddress', 'getShippingAddress', - 'getBaseCurrencyCode', 'getBaseTaxAmount', '__wakeup' - ]) - ->getMock(); - - $orderMock->expects(static::once()) - ->method('getId') - ->willReturn(1); - - $orderMock->expects(static::exactly(2)) - ->method('getIncrementId') - ->willReturn(self::INVOICE_NUM); - - $orderMock->expects(static::once()) - ->method('getStoreId') - ->willReturn(1); - - $orderMock->expects(static::once()) - ->method('getBaseCurrencyCode') - ->willReturn('USD'); - return $orderMock; - } - - /** - * Create and return mock for http client factory - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function getHttpClientFactoryMock() - { - $this->httpClientMock = $this->getMockBuilder(\Magento\Framework\HTTP\ZendClient::class) + return $this->getMockBuilder(Order::class) ->disableOriginalConstructor() - ->setMethods(['request', 'getBody', '__wakeup']) - ->getMock(); - - $this->httpClientMock->expects(static::any()) - ->method('request') - ->willReturnSelf(); - - $httpClientFactoryMock = $this->getMockBuilder(\Magento\Framework\HTTP\ZendClientFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) + ->setMethods( + [ + 'getId', + 'getQuoteId', + 'getIncrementId', + 'getStoreId', + 'getBillingAddress', + 'getShippingAddress', + 'getBaseCurrencyCode', + 'getBaseTaxAmount', + '__wakeup' + ] + ) ->getMock(); - - $httpClientFactoryMock->expects(static::any()) - ->method('create') - ->willReturn($this->httpClientMock); - return $httpClientFactoryMock; } /** @@ -788,7 +876,9 @@ private function getRefundResponseBody($code, $reasonCode, $reasonText) $result[9] = self::TOTAL_AMOUNT; // XAmount $result[10] = Directpost::REQUEST_METHOD_CC; // XMethod $result[11] = Directpost::REQUEST_TYPE_CREDIT; // XType + // @codingStandardsIgnoreStart $result[37] = md5(self::TRANSACTION_ID); // x_MD5_Hash + // @codingStandardsIgnoreEnd $result[50] = '48329483921'; // setXAccountNumber return implode(Directpost::RESPONSE_DELIM_CHAR, $result); } From 2e2d9dbd3be307a4f21330d1c4ba488039f3f274 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 9 Aug 2019 16:02:12 +0400 Subject: [PATCH 0305/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11701 --- .../AdminForgotPasswordFormSection.xml | 2 + ...gRefreshCaptchaImageProductionModeTest.xml | 63 +++++++++++++++++++ .../Test/Mftf/Data/DeveloperJsConfigs.xml | 22 +++++++ .../Metadata/developer_js_config-meta.xml | 23 +++++++ 4 files changed, 110 insertions(+) create mode 100644 app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml create mode 100644 app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml create mode 100644 app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml index efaca2212335..fae3b768d445 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml @@ -11,5 +11,7 @@ <section name="AdminForgotPasswordFormSection"> <element name="email" type="input" selector="#login-form input[name='email']"/> <element name="retrievePasswordButton" type="button" selector="#login-form button[type='submit']" timeout="30"/> + <element name="captchaImage" type="file" selector="#backend_forgotpassword"/> + <element name="captchaReload" type="button" selector="#captcha-reload"/> </section> </sections> diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml new file mode 100644 index 000000000000..08bc3dbd0241 --- /dev/null +++ b/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckingRefreshCaptchaImageProductionModeTest"> + <annotations> + <features value="Captcha"/> + <stories value="Cannot refresh Captcha image in production mode"/> + <title value="Checking refresh Captcha image in production mode"/> + <description value="Checking refresh Captcha image in production mode"/> + <severity value="MAJOR"/> + <testCaseId value="MC-11701"/> + <useCaseId value="MAGETWO-96404"/> + <group value="captcha"/> + </annotations> + <before> + <!--Switch to developer mode--> + <comment userInput="Switch to developer mode" stepKey="commentSwitchDevMode"/> + <magentoCLI command="deploy:mode:set developer" stepKey="switchToDeveloperMode"/> + <!--Enable JavaScript setting--> + <comment userInput="Enable JavaScript setting" stepKey="commentEnableJSSettings"/> + <magentoCLI command="config:set dev/js/enable_js_bundling 1" stepKey="enableJSBundling"/> + <magentoCLI command="config:set dev/js/minify_files 1" stepKey="enableMinifyJSFiles"/> + <!--Enable admin captcha--> + <comment userInput="Enable admin captcha" stepKey="commentEnableAdminCaptcha"/> + <magentoCLI command="config:set admin/captcha/enable 1" stepKey="enableAdminCaptcha"/> + <!--Clean cache--> + <comment userInput="Clean cache" stepKey="commentCleanCache"/> + <!--<magentoCLI command="cache:clean" stepKey="cleanCaches"/>--> + </before> + <after> + <!--Set default settings--> + <comment userInput="Set default settings" stepKey="commentSetDafault"/> + <createData entity="SetDefaultJavaScriptBundling" stepKey="setDefaultJavaScriptBundling"/> + <createData entity="SetDefaultMinifyJavaScriptFiles" stepKey="setDefaultMinifyJavaScriptFiles"/> + </after> + <!--Go to forgot password--> + <comment userInput="Go to forgot password" stepKey="commentGoToForgotPassword"/> + <amOnPage url="{{AdminForgotPasswordPage.url}}" stepKey="navigateToForgotPasswordPagePage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageBeforeRefresh"/> + <click selector="{{AdminForgotPasswordFormSection.captchaReload}}" stepKey="reloadCaptcha"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageAfterRefresh"/> + <assertNotEquals expected="$grabCaptchaImageBeforeRefresh" expectedType="variable" actual="$grabCaptchaImageAfterRefresh" actualType="variable" stepKey="assertCaptchaImagesNotEquals"/> + <!--Switch to production mode--> + <comment userInput="Switch to production mode" stepKey="commentSwitchProdMode"/> + <magentoCLI command="deploy:mode:set production" stepKey="switchToProductionMode"/> + <amOnPage url="{{AdminForgotPasswordPage.url}}" stepKey="navigateToForgotPasswordPagePageProdMode"/> + <waitForPageLoad stepKey="waitForPageLoadProdMode"/> + <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageBeforeRefreshProdMode"/> + <click selector="{{AdminForgotPasswordFormSection.captchaReload}}" stepKey="reloadCaptchaProdMode"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskProdMode"/> + <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageAfterRefreshProdMode"/> + <assertNotEquals expected="$grabCaptchaImageBeforeRefreshProdMode" expectedType="variable" actual="$grabCaptchaImageAfterRefreshProdMode" actualType="variable" stepKey="assertCaptchaImagesNotEqualsProdMode"/> + </test> +</tests> diff --git a/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml b/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml new file mode 100644 index 000000000000..e490ef62bbed --- /dev/null +++ b/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SetDefaultJavaScriptBundling" type="dev_js_settings"> + <requiredEntity type="default_bundling">DefaultJSBundling</requiredEntity> + </entity> + <entity name="DefaultJSBundling" type="default_bundling"> + <data key="inherit">1</data> + </entity> + <entity name="SetDefaultMinifyJavaScriptFiles" type="dev_js_settings"> + <requiredEntity type="default_bundling">DefaultJSBundling</requiredEntity> + </entity> + <entity name="DefaultMinifyJSFiles" type="default_minify_files"> + <data key="inherit">1</data> + </entity> +</entities> diff --git a/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml b/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml new file mode 100644 index 000000000000..b56c88a22dd1 --- /dev/null +++ b/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> + <operation name="DeveloperJSConfig" dataType="developer_js_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/dev/" method="POST"> + <object key="groups" dataType="dev_js_settings"> + <object key="js" dataType="dev_js_settings"> + <object key="fields" dataType="dev_js_settings"> + <object key="minify_files" dataType="default_minify_files"> + <field key="inherit">string</field> + </object> + <object key="enable_js_bundling" dataType="default_bundling"> + <field key="inherit">string</field> + </object> + </object> + </object> + </object> + </operation> +</operations> From 6af74d9925c94280f8a7e773dc7d07b49abaf197 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Fri, 9 Aug 2019 15:48:03 +0300 Subject: [PATCH 0306/1172] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../frontend/web/js/action/set-payment-information-extended.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js index 4085da82f415..263d5747f284 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js @@ -21,6 +21,8 @@ define([ var serviceUrl, payload; + delete paymentData.__disableTmpl; + skipBilling = skipBilling || false; payload = { cartId: quote.getQuoteId(), From 8cc4f7663af090ff76a8fe4fd104c0a8576bf593 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Fri, 9 Aug 2019 13:12:07 -0500 Subject: [PATCH 0307/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage fixed review comments --- .../VerifyCheckoutSuccessActionGroup.xml | 2 +- .../PayOrderOnPayPalCheckoutActionGroup.xml | 7 +++++-- ...lExpressCheckoutConfigurationActionGroup.xml | 17 ++++++++++------- .../Test/PayPalSmartButtonInCheckoutPage.xml | 4 +++- .../CreateOrderToPrintPageActionGroup.xml | 2 +- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml index 2cbe97e16322..5048bcf37b32 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml @@ -10,7 +10,7 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="VerifyCheckoutSuccessActionGroup"> <annotations> - <description>Goes to the checkout one page success page and verifies if theorder is placed successfully.</description> + <description>Verifies if the order is placed successfully on the 'one page checkout' page.</description> </annotations> <waitForElement selector="{{CheckoutSuccessMainSection.successTitle}}" stepKey="waitForLoadSuccessPageTitle"/> <waitForElement selector="{{CheckoutSuccessMainSection.success}}" time="30" stepKey="waitForLoadSuccessPage"/> diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml index 02d6743e085e..13409b16b56b 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml @@ -10,10 +10,13 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="PayOrderOnPayPalCheckoutActionGroup"> <annotations> - <description>Goes to PayPal payment checkout page, confirms product name and clicks 'Pay Now'.</description> + <description>Verifies product name on Paypal cart and clicks 'Pay Now' on PayPal payment checkout page.</description> </annotations> + <arguments> + <argument name="productName" type="string"/> + </arguments> <click selector="{{PayPalPaymentSection.cartIcon}}" stepKey="openCart"/> - <seeElement selector="{{PayPalPaymentSection.itemName($$createProduct.name$$)}}" stepKey="seeProductname"/> + <seeElement selector="{{PayPalPaymentSection.itemName(productName)}}" stepKey="seeProductName"/> <click selector="{{PayPalPaymentSection.PayPalSubmitBtn}}" stepKey="clickPayPalSubmitBtn"/> <switchToPreviousTab stepKey="switchToPreviousTab"/> <waitForPageLoad stepKey="waitForPageLoad"/> diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml index 4de7337cf2cc..1ed519a8a3db 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml @@ -21,14 +21,14 @@ <waitForPageLoad stepKey="waitForPageLoad1"/> <click selector="{{PayPalExpressCheckoutConfigSection.configureBtn(countryCode)}}" stepKey="clickPayPalConfigureBtn"/> <waitForElementVisible selector="{{PayPalAdvancedSettingConfigSection.advancedSettingTab(countryCode)}}" stepKey="waitForAdvancedSettingTab"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.email(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_business_account}}" stepKey="inputEmailAssociatedWithPayPalMerchantAccount"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.email(countryCode)}}" userInput="{{credentials.magento/paypal_express_checkout_us_business_account}}" stepKey="inputEmailAssociatedWithPayPalMerchantAccount"/> <selectOption selector ="{{PayPalExpressCheckoutConfigSection.apiMethod(countryCode)}}" userInput="API Signature" stepKey="inputAPIAuthenticationMethods"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.username(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_username}}" stepKey="inputAPIUsername"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.password(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_password}}" stepKey="inputAPIPassword"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.signature(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_api_signature}}" stepKey="inputAPISignature"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.username(countryCode)}}" userInput="{{credentials.magento/paypal_express_checkout_us_api_username}}" stepKey="inputAPIUsername"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.password(countryCode)}}" userInput="{{credentials.magento/paypal_express_checkout_us_api_password}}" stepKey="inputAPIPassword"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.signature(countryCode)}}" userInput="{{credentials.magento/paypal_express_checkout_us_api_signature}}" stepKey="inputAPISignature"/> <selectOption selector ="{{PayPalExpressCheckoutConfigSection.sandboxMode(countryCode)}}" userInput="Yes" stepKey="enableSandboxMode"/> <selectOption selector="{{PayPalExpressCheckoutConfigSection.enableSolution(countryCode)}}" userInput="Yes" stepKey="enableSolution"/> - <fillField selector ="{{PayPalExpressCheckoutConfigSection.merchantID(countryCode)}}" userInput="{{_CREDS.magento/paypal_express_checkout_us_merchant_id}}" stepKey="inputMerchantID"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.merchantID(countryCode)}}" userInput="{{credentials.magento/paypal_express_checkout_us_merchant_id}}" stepKey="inputMerchantID"/> <!--Save configuration--> <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> </actionGroup> @@ -39,7 +39,10 @@ </annotations> <arguments> <argument name="payerName" defaultValue="MPI" type="string"/> + <argument name="credentials" defaultValue="_CREDS"/> </arguments> + + <!-- click on PayPal payment radio button --> <waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" stepKey="waitForPlaceOrderButton"/> <click selector="{{CheckoutPaymentSection.PayPalPaymentRadio}}" stepKey="clickPlaceOrder"/> @@ -57,8 +60,8 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <seeCurrentUrlMatches regex="~\//www.sandbox.paypal.com/~" stepKey="seeCurrentUrlMatchesConfigPath1"/> <waitForElement selector="{{PayPalPaymentSection.email}}" stepKey="waitForLoginForm" /> - <fillField selector="{{PayPalPaymentSection.email}}" userInput="{{_CREDS.magento/paypal_sandbox_login_email}}" stepKey="fillEmail"/> - <fillField selector="{{PayPalPaymentSection.password}}" userInput="{{_CREDS.magento/paypal_sandbox_login_password}}" stepKey="fillPassword"/> + <fillField selector="{{PayPalPaymentSection.email}}" userInput="{{credentials.magento/paypal_sandbox_login_email}}" stepKey="fillEmail"/> + <fillField selector="{{PayPalPaymentSection.password}}" userInput="{{credentials.magento/paypal_sandbox_login_password}}" stepKey="fillPassword"/> <click selector="{{PayPalPaymentSection.loginBtn}}" stepKey="login"/> <waitForPageLoad stepKey="wait"/> <see userInput="{{payerName}}" selector="{{PayPalPaymentSection.reviewUserInfo}}" stepKey="seePayerName"/> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml index 85e1ce347d50..dcf00e49a5b9 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml @@ -67,7 +67,9 @@ </actionGroup> <!-- PayPal checkout --> - <actionGroup ref="PayOrderOnPayPalCheckoutActionGroup" stepKey="payOrderOnPayPalCheckout"/> + <actionGroup ref="PayOrderOnPayPalCheckoutActionGroup" stepKey="payOrderOnPayPalCheckout"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> <!-- I see order successful Page instead of Order Review Page --> <actionGroup ref="VerifyCheckoutSuccessActionGroup" stepKey="verifyCheckoutSuccess"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml index aaeb9ffb30bd..7388eaa96f21 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/CreateOrderToPrintPageActionGroup.xml @@ -15,7 +15,7 @@ <arguments> <argument name="Category"/> </arguments> - + <amOnPage url="{{StorefrontCategoryPage.url(Category.name)}}" stepKey="onCategoryPage"/> <waitForPageLoad stepKey="waitForPageLoad1"/> <moveMouseOver selector="{{StorefrontCategoryMainSection.ProductItemInfo}}" stepKey="hoverProduct"/> From faddcf9e32093dbbf94e684144d5e6272533294b Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Fri, 9 Aug 2019 15:19:30 -0500 Subject: [PATCH 0308/1172] MC-19115: Admin Analytics tracking should be enabled by default - Enabling tracking by Default --- app/code/Magento/AdminAnalytics/etc/config.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 app/code/Magento/AdminAnalytics/etc/config.xml diff --git a/app/code/Magento/AdminAnalytics/etc/config.xml b/app/code/Magento/AdminAnalytics/etc/config.xml new file mode 100644 index 000000000000..ba683f13c11e --- /dev/null +++ b/app/code/Magento/AdminAnalytics/etc/config.xml @@ -0,0 +1,18 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + <default> + <admin> + <usage> + <enabled> + 1 + </enabled> + </usage> + </admin> + </default> +</config> \ No newline at end of file From 16aa234c85476ffa7f68b91ff72c412b6fdb1cc5 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 9 Aug 2019 15:20:24 -0500 Subject: [PATCH 0309/1172] MC-18977: Revert change of ENGCOM-3260 --- .../Model/ReportXml/ModuleIterator.php | 2 +- .../Model/ReportXml/ModuleIteratorTest.php | 2 +- .../Backend/Block/Dashboard/Orders/Grid.php | 6 +-- .../Magento/Backend/Block/Dashboard/Sales.php | 6 +-- .../Block/Dashboard/Tab/Products/Ordered.php | 6 +-- .../Backend/Block/Dashboard/Totals.php | 6 +-- app/code/Magento/Backend/Model/Menu/Item.php | 6 +-- .../Block/Checkout/Cart/Item/Renderer.php | 4 +- .../Model/ResourceModel/Indexer/Price.php | 40 +++++++++---------- .../ResourceModel/Selection/Collection.php | 4 +- .../Block/Adminhtml/Helper/Form/Wysiwyg.php | 6 +-- .../Product/Edit/Tab/Alerts/Price.php | 6 +-- .../Product/Edit/Tab/Alerts/Stock.php | 6 +-- .../Adminhtml/Product/Edit/Tab/Inventory.php | 6 +-- .../Edit/Tab/Price/Group/AbstractGroup.php | 6 +-- .../Block/Adminhtml/Product/Edit/Tabs.php | 8 ++-- .../Catalog/Block/Adminhtml/Product/Grid.php | 6 +-- .../Block/Product/ProductList/Related.php | 6 +-- .../Block/Product/ProductList/Upsell.php | 6 +-- app/code/Magento/Catalog/Model/Product.php | 6 +-- .../ResourceModel/Product/Collection.php | 6 +-- .../Product/Compare/Item/Collection.php | 5 ++- .../Product/Indexer/Price/DefaultPrice.php | 6 +-- .../Indexer/Price/Query/BaseFinalPrice.php | 6 +-- .../Product/Edit/Tab/InventoryTest.php | 2 +- .../Catalog/Test/Unit/Model/ProductTest.php | 4 +- .../ResourceModel/Product/CollectionTest.php | 2 +- .../Form/Modifier/AdvancedPricingTest.php | 2 +- .../Product/Form/Modifier/AdvancedPricing.php | 2 +- .../ResourceModel/Advanced/Collection.php | 4 +- .../ResourceModel/Fulltext/Collection.php | 4 +- .../Model/ResourceModel/Search/Collection.php | 4 +- .../Checkout/Block/Cart/Item/Renderer.php | 6 +-- app/code/Magento/Checkout/Block/Cart/Link.php | 6 +-- app/code/Magento/Checkout/Block/Link.php | 6 +-- .../Model/Layout/DepersonalizePluginTest.php | 2 +- .../Config/Structure/AbstractElement.php | 12 ++---- .../Structure/Element/AbstractComposite.php | 4 +- .../Model/Config/Structure/Element/Field.php | 4 +- .../Model/Config/Structure/Element/Group.php | 4 +- .../Config/Structure/Element/Section.php | 4 +- .../Element/AbstractCompositeTest.php | 4 +- .../Model/Product/Type/Plugin.php | 8 ++-- .../Magento/Customer/Block/Form/Register.php | 6 +-- .../Helper/Session/CurrentCustomer.php | 4 +- .../Customer/Model/Customer/Source/Group.php | 2 +- .../Test/Unit/Block/Form/RegisterTest.php | 2 +- .../Helper/Session/CurrentCustomerTest.php | 4 +- .../Unit/Model/Customer/Source/GroupTest.php | 6 +-- .../Magento/Deploy/Collector/Collector.php | 12 +++--- .../Block/Checkout/Cart/Item/Renderer.php | 4 +- .../Model/Product/Type/Plugin.php | 8 ++-- .../Grouped/AssociatedProductsCollection.php | 4 +- .../Test/Unit/Model/ProductTest.php | 11 ++--- .../Model/Export/Config/Converter.php | 6 +-- .../Model/Import/Config/Converter.php | 8 ++-- .../Model/Export/Config/ConverterTest.php | 2 +- .../Model/Import/Config/ConverterTest.php | 2 +- ...ductAttributeFormBuildFrontTabObserver.php | 8 ++-- .../ProductAttributeGridBuildObserver.php | 8 ++-- .../Model/Module/Collect.php | 8 ++-- .../Test/Unit/Model/Module/CollectTest.php | 1 + .../PageCache/Model/DepersonalizeChecker.php | 6 +-- .../Unit/Model/DepersonalizeCheckerTest.php | 4 +- .../Model/Layout/DepersonalizePluginTest.php | 14 ++----- .../ResourceModel/Product/Collection.php | 4 +- .../Index/Collection/AbstractCollection.php | 4 +- .../Product/Lowstock/Collection.php | 4 +- .../ResourceModel/Product/CollectionTest.php | 2 +- .../Review/Block/Adminhtml/Product/Grid.php | 4 +- .../Review/Model/ResourceModel/Rating.php | 6 +-- .../Review/Product/Collection.php | 4 +- .../Product/Form/Modifier/ReviewTest.php | 2 +- .../Product/Form/Modifier/Review.php | 2 +- .../Search/Block/Adminhtml/Dashboard/Last.php | 6 +-- .../Search/Block/Adminhtml/Dashboard/Top.php | 6 +-- .../Observer/AddFieldsToAttributeObserver.php | 8 ++-- .../AddSwatchAttributeTypeObserver.php | 8 ++-- .../AddFieldsToAttributeObserverTest.php | 2 +- .../AddSwatchAttributeTypeObserverTest.php | 2 +- .../Tax/Model/App/Action/ContextPlugin.php | 6 +-- .../Tax/Observer/AfterAddressSaveObserver.php | 8 ++-- .../Tax/Observer/CustomerLoggedInObserver.php | 8 ++-- .../Unit/App/Action/ContextPluginTest.php | 4 +- .../Observer/AfterAddressSaveObserverTest.php | 8 ++-- .../Observer/CustomerLoggedInObserverTest.php | 4 +- .../layout/sales_email_item_price.xml | 12 +----- .../Weee/Model/App/Action/ContextPlugin.php | 6 +-- .../Weee/Observer/AfterAddressSave.php | 8 ++-- .../Weee/Observer/CustomerLoggedIn.php | 6 +-- .../Unit/App/Action/ContextPluginTest.php | 4 +- .../Unit/Observer/AfterAddressSaveTest.php | 10 ++--- .../Unit/Observer/CustomerLoggedInTest.php | 4 +- .../Wishlist/Test/Unit/Helper/RssTest.php | 4 +- app/etc/di.xml | 1 - .../Block/Account/Dashboard/AddressTest.php | 2 +- .../Test/Legacy/_files/obsolete_methods.php | 4 +- .../Framework/App/Helper/AbstractHelper.php | 4 +- .../Magento/Framework/App/Helper/Context.php | 8 ++-- .../Magento/Framework/Module/Manager.php | 16 ++++++-- .../Module/ModuleManagerInterface.php | 26 ------------ .../Module/Test/Unit/ManagerTest.php | 3 +- .../Unit/Plugin/DbStatusValidatorTest.php | 2 +- .../File/Collector/Decorator/ModuleOutput.php | 6 +-- 104 files changed, 283 insertions(+), 326 deletions(-) delete mode 100644 lib/internal/Magento/Framework/Module/ModuleManagerInterface.php diff --git a/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php b/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php index 4d6234419740..fecbf2033c1b 100644 --- a/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php +++ b/app/code/Magento/Analytics/Model/ReportXml/ModuleIterator.php @@ -5,7 +5,7 @@ */ namespace Magento\Analytics\Model\ReportXml; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; /** * Iterator for ReportXml modules diff --git a/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php b/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php index b08d41ac829b..5288bcd306af 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/ReportXml/ModuleIteratorTest.php @@ -7,7 +7,7 @@ namespace Magento\Analytics\Test\Unit\Model\ReportXml; use Magento\Analytics\Model\ReportXml\ModuleIterator; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; /** diff --git a/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php b/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php index bca7f13b0cee..0a73430aad0f 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php +++ b/app/code/Magento/Backend/Block/Dashboard/Orders/Grid.php @@ -19,21 +19,21 @@ class Grid extends \Magento\Backend\Block\Dashboard\Grid protected $_collectionFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, array $data = [] ) { diff --git a/app/code/Magento/Backend/Block/Dashboard/Sales.php b/app/code/Magento/Backend/Block/Dashboard/Sales.php index 3455ff087a79..b38833946010 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Sales.php +++ b/app/code/Magento/Backend/Block/Dashboard/Sales.php @@ -18,20 +18,20 @@ class Sales extends \Magento\Backend\Block\Dashboard\Bar protected $_template = 'Magento_Backend::dashboard/salebar.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_moduleManager = $moduleManager; diff --git a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php index 7dc897a62a32..a0b1571bd17b 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php +++ b/app/code/Magento/Backend/Block/Dashboard/Tab/Products/Ordered.php @@ -19,21 +19,21 @@ class Ordered extends \Magento\Backend\Block\Dashboard\Grid protected $_collectionFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory $collectionFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory $collectionFactory, array $data = [] ) { diff --git a/app/code/Magento/Backend/Block/Dashboard/Totals.php b/app/code/Magento/Backend/Block/Dashboard/Totals.php index e57a6249af47..20bcfebe31a8 100644 --- a/app/code/Magento/Backend/Block/Dashboard/Totals.php +++ b/app/code/Magento/Backend/Block/Dashboard/Totals.php @@ -22,20 +22,20 @@ class Totals extends \Magento\Backend\Block\Dashboard\Bar protected $_template = 'Magento_Backend::dashboard/totalbar.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Reports\Model\ResourceModel\Order\CollectionFactory $collectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_moduleManager = $moduleManager; diff --git a/app/code/Magento/Backend/Model/Menu/Item.php b/app/code/Magento/Backend/Model/Menu/Item.php index d535e9c84df2..67c6216cbbc0 100644 --- a/app/code/Magento/Backend/Model/Menu/Item.php +++ b/app/code/Magento/Backend/Model/Menu/Item.php @@ -145,7 +145,7 @@ class Item protected $_moduleList; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $_moduleManager; @@ -163,7 +163,7 @@ class Item * @param \Magento\Backend\Model\MenuFactory $menuFactory * @param \Magento\Backend\Model\UrlInterface $urlModel * @param \Magento\Framework\Module\ModuleListInterface $moduleList - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -173,7 +173,7 @@ public function __construct( \Magento\Backend\Model\MenuFactory $menuFactory, \Magento\Backend\Model\UrlInterface $urlModel, \Magento\Framework\Module\ModuleListInterface $moduleList, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_validator = $validator; diff --git a/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php b/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php index c0a2d9d43034..863f27322569 100644 --- a/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php +++ b/app/code/Magento/Bundle/Block/Checkout/Cart/Item/Renderer.php @@ -32,7 +32,7 @@ class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param Configuration $bundleProductConfiguration * @param array $data @@ -46,7 +46,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, Configuration $bundleProductConfiguration, array $data = [] diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php index b71853cde41a..077ebd4422aa 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Price.php @@ -85,7 +85,7 @@ class Price implements DimensionalIndexerInterface private $eventManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -97,7 +97,7 @@ class Price implements DimensionalIndexerInterface * @param BasePriceModifier $basePriceModifier * @param JoinAttributeProcessor $joinAttributeProcessor * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param bool $fullReindexAction * @param string $connectionName * @@ -111,7 +111,7 @@ public function __construct( BasePriceModifier $basePriceModifier, JoinAttributeProcessor $joinAttributeProcessor, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, $fullReindexAction = false, $connectionName = 'indexer' ) { @@ -139,16 +139,16 @@ public function executeByDimensions(array $dimensions, \Traversable $entityIds) $temporaryPriceTable = $this->indexTableStructureFactory->create( [ - 'tableName' => $this->tableMaintainer->getMainTmpTable($dimensions), - 'entityField' => 'entity_id', - 'customerGroupField' => 'customer_group_id', - 'websiteField' => 'website_id', - 'taxClassField' => 'tax_class_id', - 'originalPriceField' => 'price', - 'finalPriceField' => 'final_price', - 'minPriceField' => 'min_price', - 'maxPriceField' => 'max_price', - 'tierPriceField' => 'tier_price', + 'tableName' => $this->tableMaintainer->getMainTmpTable($dimensions), + 'entityField' => 'entity_id', + 'customerGroupField' => 'customer_group_id', + 'websiteField' => 'website_id', + 'taxClassField' => 'tax_class_id', + 'originalPriceField' => 'price', + 'finalPriceField' => 'final_price', + 'minPriceField' => 'min_price', + 'maxPriceField' => 'max_price', + 'tierPriceField' => 'tier_price', ] ); @@ -335,9 +335,9 @@ private function prepareBundlePriceByType($priceType, array $dimensions, $entity ); $finalPrice = $connection->getLeastSql( [ - $price, - $connection->getIfNullSql($specialPriceExpr, $price), - $connection->getIfNullSql($tierPrice, $price), + $price, + $connection->getIfNullSql($specialPriceExpr, $price), + $connection->getIfNullSql($tierPrice, $price), ] ); } else { @@ -477,8 +477,8 @@ private function calculateBundleSelectionPrice($dimensions, $priceType) $priceExpr = $connection->getLeastSql( [ - $priceExpr, - $connection->getIfNullSql($tierExpr, $priceExpr), + $priceExpr, + $connection->getIfNullSql($tierExpr, $priceExpr), ] ); } else { @@ -495,8 +495,8 @@ private function calculateBundleSelectionPrice($dimensions, $priceType) ); $priceExpr = $connection->getLeastSql( [ - $specialExpr, - $connection->getIfNullSql($tierExpr, $price), + $specialExpr, + $connection->getIfNullSql($tierExpr, $price), ] ); } diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php index 21ba1f75ba90..7b3f6dd8bbef 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Selection/Collection.php @@ -61,7 +61,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -88,7 +88,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php index a829c058d89b..c58ed58370e3 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Helper/Form/Wysiwyg.php @@ -26,7 +26,7 @@ class Wysiwyg extends \Magento\Framework\Data\Form\Element\Textarea /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager = null; @@ -46,7 +46,7 @@ class Wysiwyg extends \Magento\Framework\Data\Form\Element\Textarea * @param \Magento\Framework\Escaper $escaper * @param \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig * @param \Magento\Framework\View\LayoutInterface $layout - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Backend\Helper\Data $backendData * @param array $data */ @@ -56,7 +56,7 @@ public function __construct( \Magento\Framework\Escaper $escaper, \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig, \Magento\Framework\View\LayoutInterface $layout, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Backend\Helper\Data $backendData, array $data = [] ) { diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php index e754ab970051..386fe1333a7e 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Price.php @@ -19,7 +19,7 @@ class Price extends Extended /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -32,14 +32,14 @@ class Price extends Extended * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\ProductAlert\Model\PriceFactory $priceFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\ProductAlert\Model\PriceFactory $priceFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_priceFactory = $priceFactory; diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php index 2c6647fd57be..ede478cabe78 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Alerts/Stock.php @@ -19,7 +19,7 @@ class Stock extends Extended /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -32,14 +32,14 @@ class Stock extends Extended * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper * @param \Magento\ProductAlert\Model\StockFactory $stockFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\ProductAlert\Model\StockFactory $stockFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_stockFactory = $stockFactory; diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php index 9278b84362e7..782147e1e8ef 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Inventory.php @@ -18,7 +18,7 @@ class Inventory extends \Magento\Backend\Block\Widget protected $_template = 'Magento_Catalog::catalog/product/tab/inventory.phtml'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -53,7 +53,7 @@ class Inventory extends \Magento\Backend\Block\Widget * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\CatalogInventory\Model\Source\Backorders $backorders * @param \Magento\CatalogInventory\Model\Source\Stock $stock - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Registry $coreRegistry * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration @@ -63,7 +63,7 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\CatalogInventory\Model\Source\Backorders $backorders, \Magento\CatalogInventory\Model\Source\Stock $stock, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Registry $coreRegistry, \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry, \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php index 42990116e933..5ffd3d1dda38 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Price/Group/AbstractGroup.php @@ -41,7 +41,7 @@ abstract class AbstractGroup extends Widget implements RendererInterface /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -81,7 +81,7 @@ abstract class AbstractGroup extends Widget implements RendererInterface * @param \Magento\Backend\Block\Template\Context $context * @param GroupRepositoryInterface $groupRepository * @param \Magento\Directory\Helper\Data $directoryHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Registry $registry * @param GroupManagementInterface $groupManagement * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder @@ -92,7 +92,7 @@ public function __construct( \Magento\Backend\Block\Template\Context $context, GroupRepositoryInterface $groupRepository, \Magento\Directory\Helper\Data $directoryHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Registry $registry, GroupManagementInterface $groupManagement, \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php index 51c326763b09..37ad3f4bea20 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tabs.php @@ -14,7 +14,7 @@ use Magento\Catalog\Helper\Data; use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory; use Magento\Framework\Json\EncoderInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Registry; use Magento\Framework\Translate\InlineInterface; @@ -65,7 +65,7 @@ class Tabs extends WidgetTabs protected $_collectionFactory; /** - * @var ModuleManagerInterface + * @var Manager */ protected $_moduleManager; @@ -78,7 +78,7 @@ class Tabs extends WidgetTabs * @param Context $context * @param EncoderInterface $jsonEncoder * @param Session $authSession - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param CollectionFactory $collectionFactory * @param Catalog $helperCatalog * @param Data $catalogData @@ -91,7 +91,7 @@ public function __construct( Context $context, EncoderInterface $jsonEncoder, Session $authSession, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, CollectionFactory $collectionFactory, Catalog $helperCatalog, Data $catalogData, diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php index 7e43f2fc064a..01408ade5643 100644 --- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php +++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Grid.php @@ -16,7 +16,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -59,7 +59,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended * @param \Magento\Catalog\Model\Product\Type $type * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $status * @param \Magento\Catalog\Model\Product\Visibility $visibility - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data * * @SuppressWarnings(PHPMD.ExcessiveParameterList) @@ -73,7 +73,7 @@ public function __construct( \Magento\Catalog\Model\Product\Type $type, \Magento\Catalog\Model\Product\Attribute\Source\Status $status, \Magento\Catalog\Model\Product\Visibility $visibility, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_websiteFactory = $websiteFactory; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 088619511545..6de70bb97136 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -46,7 +46,7 @@ class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements protected $_checkoutCart; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -55,7 +55,7 @@ class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements * @param \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart * @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -63,7 +63,7 @@ public function __construct( \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart, \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_checkoutCart = $checkoutCart; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index d888f44a6fbf..24822447ae91 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -60,7 +60,7 @@ class Upsell extends \Magento\Catalog\Block\Product\AbstractProduct implements protected $_checkoutCart; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -69,7 +69,7 @@ class Upsell extends \Magento\Catalog\Block\Product\AbstractProduct implements * @param \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart * @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param array $data */ public function __construct( @@ -77,7 +77,7 @@ public function __construct( \Magento\Checkout\Model\ResourceModel\Cart $checkoutCart, \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, array $data = [] ) { $this->_checkoutCart = $checkoutCart; diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index fc9fffb2a7e9..fc3cc11cade5 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -177,7 +177,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements protected $_catalogProduct = null; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -381,7 +381,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements * @param Product\Attribute\Source\Status $catalogProductStatus * @param Product\Media\Config $catalogProductMediaConfig * @param Product\Type $catalogProductType - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Helper\Product $catalogProduct * @param ResourceModel\Product $resource * @param ResourceModel\Product\Collection $resourceCollection @@ -422,7 +422,7 @@ public function __construct( \Magento\Catalog\Model\Product\Attribute\Source\Status $catalogProductStatus, \Magento\Catalog\Model\Product\Media\Config $catalogProductMediaConfig, Product\Type $catalogProductType, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Helper\Product $catalogProduct, \Magento\Catalog\Model\ResourceModel\Product $resource, \Magento\Catalog\Model\ResourceModel\Product\Collection $resourceCollection, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index dbd6a7a2e109..384b6ddcefc3 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -191,7 +191,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac /** * Catalog data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager = null; @@ -315,7 +315,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -344,7 +344,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php index dc3411743a06..92741cf9ba88 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php @@ -64,7 +64,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -76,6 +76,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Product\Compare\Item $catalogProductCompareItem * @param \Magento\Catalog\Helper\Product\Compare $catalogProductCompare * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection + * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -89,7 +90,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php index 9643f4c3a718..b64cca4ff1b2 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/DefaultPrice.php @@ -40,7 +40,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface /** * Core data * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -73,7 +73,7 @@ class DefaultPrice extends AbstractIndexer implements PriceInterface * @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy * @param \Magento\Eav\Model\Config $eavConfig * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param string|null $connectionName * @param IndexTableStructureFactory $indexTableStructureFactory * @param PriceModifierInterface[] $priceModifiers @@ -83,7 +83,7 @@ public function __construct( \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy, \Magento\Eav\Model\Config $eavConfig, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, $connectionName = null, IndexTableStructureFactory $indexTableStructureFactory = null, array $priceModifiers = [] diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php index a3f463d53e7a..77407ed699fb 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/Query/BaseFinalPrice.php @@ -37,7 +37,7 @@ class BaseFinalPrice private $joinAttributeProcessor; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -69,7 +69,7 @@ class BaseFinalPrice /** * @param \Magento\Framework\App\ResourceConnection $resource * @param JoinAttributeProcessor $joinAttributeProcessor - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Framework\EntityManager\MetadataPool $metadataPool * @param string $connectionName @@ -77,7 +77,7 @@ class BaseFinalPrice public function __construct( \Magento\Framework\App\ResourceConnection $resource, JoinAttributeProcessor $joinAttributeProcessor, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Framework\EntityManager\MetadataPool $metadataPool, $connectionName = 'indexer' diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php index 2008d0b9414c..19c578e976cd 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Edit/Tab/InventoryTest.php @@ -85,7 +85,7 @@ protected function setUp() $this->backordersMock = $this->createMock(\Magento\CatalogInventory\Model\Source\Backorders::class); $this->stockMock = $this->createMock(\Magento\CatalogInventory\Model\Source\Stock::class); $this->coreRegistryMock = $this->createMock(\Magento\Framework\Registry::class); - $this->moduleManager = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManager = $this->createMock(\Magento\Framework\Module\Manager::class); $this->storeManagerMock = $this->getMockForAbstractClass( \Magento\Store\Model\StoreManagerInterface::class, [], diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php index 8bf8473080c5..2ef848ca5aad 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php @@ -40,7 +40,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; @@ -215,7 +215,7 @@ protected function setUp() $this->categoryIndexerMock = $this->getMockForAbstractClass(\Magento\Framework\Indexer\IndexerInterface::class); $this->moduleManager = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, + \Magento\Framework\Module\Manager::class, ['isEnabled'] ); $this->extensionAttributes = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php index 6370a4a7a27e..0316b2e374d2 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -98,7 +98,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['getStore', 'getId', 'getWebsiteId']) ->getMockForAbstractClass(); - $moduleManager = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $moduleManager = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); $catalogProductFlatState = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Flat\State::class) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php index e9f9349100f1..e455ad47ee62 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AdvancedPricingTest.php @@ -11,7 +11,7 @@ use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Directory\Helper\Data as DirectoryHelper; use Magento\Catalog\Model\ResourceModel\Product as ProductResource; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php index 9ad75b5fda92..00132c6ad89e 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php @@ -14,7 +14,7 @@ use Magento\Customer\Api\GroupManagementInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Ui\Component\Container; use Magento\Ui\Component\Form\Element\DataType\Number; use Magento\Ui\Component\Form\Element\DataType\Price; diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 1946dd35b8d3..a37cd80056b0 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -125,7 +125,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param Product\OptionFactory $productOptionFactory @@ -160,7 +160,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 4f84f3868c6a..a596354a0c8c 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -146,7 +146,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -185,7 +185,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index 6cdcc7c55a26..e625ccbe51fe 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -50,7 +50,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -74,7 +74,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php index 4941bf8451bf..c99c9041941b 100644 --- a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php +++ b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php @@ -85,7 +85,7 @@ class Renderer extends \Magento\Framework\View\Element\Template implements protected $priceCurrency; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ public $moduleManager; @@ -105,7 +105,7 @@ class Renderer extends \Magento\Framework\View\Element\Template implements * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param array $data * @param ItemResolverInterface|null $itemResolver @@ -120,7 +120,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, array $data = [], ItemResolverInterface $itemResolver = null diff --git a/app/code/Magento/Checkout/Block/Cart/Link.php b/app/code/Magento/Checkout/Block/Cart/Link.php index 6ea513752110..9e6db1754d9e 100644 --- a/app/code/Magento/Checkout/Block/Cart/Link.php +++ b/app/code/Magento/Checkout/Block/Cart/Link.php @@ -13,7 +13,7 @@ class Link extends \Magento\Framework\View\Element\Html\Link { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -24,14 +24,14 @@ class Link extends \Magento\Framework\View\Element\Html\Link /** * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Checkout\Helper\Cart $cartHelper * @param array $data * @codeCoverageIgnore */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Checkout\Helper\Cart $cartHelper, array $data = [] ) { diff --git a/app/code/Magento/Checkout/Block/Link.php b/app/code/Magento/Checkout/Block/Link.php index 3d0740181f4a..4ab2981e9185 100644 --- a/app/code/Magento/Checkout/Block/Link.php +++ b/app/code/Magento/Checkout/Block/Link.php @@ -13,7 +13,7 @@ class Link extends \Magento\Framework\View\Element\Html\Link { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -24,14 +24,14 @@ class Link extends \Magento\Framework\View\Element\Html\Link /** * @param \Magento\Framework\View\Element\Template\Context $context - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Checkout\Helper\Data $checkoutHelper * @param array $data * @codeCoverageIgnore */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Checkout\Helper\Data $checkoutHelper, array $data = [] ) { diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 3cc80e14fd02..350f9954208f 100644 --- a/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -43,7 +43,7 @@ protected function setUp() ); $this->checkoutSessionMock = $this->createPartialMock(\Magento\Checkout\Model\Session::class, ['clearStorage']); $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->cacheConfigMock = $this->createMock(\Magento\PageCache\Model\Config::class); $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); diff --git a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php index db815ec87ed7..23a3dea1a702 100644 --- a/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php +++ b/app/code/Magento/Config/Model/Config/Structure/AbstractElement.php @@ -40,7 +40,7 @@ abstract class AbstractElement implements StructureElementInterface protected $_storeManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -50,15 +50,11 @@ abstract class AbstractElement implements StructureElementInterface private $elementVisibility; /** - * Construct. - * * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager */ - public function __construct( - StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager - ) { + public function __construct(StoreManagerInterface $storeManager, \Magento\Framework\Module\Manager $moduleManager) + { $this->_storeManager = $storeManager; $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php b/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php index efb918226aa3..a14114a116e7 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/AbstractComposite.php @@ -23,12 +23,12 @@ abstract class AbstractComposite extends \Magento\Config\Model\Config\Structure\ /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator $childrenIterator */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Iterator $childrenIterator ) { parent::__construct($storeManager, $moduleManager); diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Field.php b/app/code/Magento/Config/Model/Config/Structure/Element/Field.php index 6a8cc6e76746..834b2a9e17e3 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Field.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Field.php @@ -56,7 +56,7 @@ class Field extends \Magento\Config\Model\Config\Structure\AbstractElement /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Config\Model\Config\BackendFactory $backendFactory * @param \Magento\Config\Model\Config\SourceFactory $sourceFactory * @param \Magento\Config\Model\Config\CommentFactory $commentFactory @@ -65,7 +65,7 @@ class Field extends \Magento\Config\Model\Config\Structure\AbstractElement */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Config\Model\Config\BackendFactory $backendFactory, \Magento\Config\Model\Config\SourceFactory $sourceFactory, \Magento\Config\Model\Config\CommentFactory $commentFactory, diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Group.php b/app/code/Magento/Config/Model/Config/Structure/Element/Group.php index db479e8b795a..1ca0afa942f8 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Group.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Group.php @@ -29,14 +29,14 @@ class Group extends AbstractComposite /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator\Field $childrenIterator * @param \Magento\Config\Model\Config\BackendClone\Factory $cloneModelFactory * @param Dependency\Mapper $dependencyMapper */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Config\Model\Config\Structure\Element\Iterator\Field $childrenIterator, \Magento\Config\Model\Config\BackendClone\Factory $cloneModelFactory, \Magento\Config\Model\Config\Structure\Element\Dependency\Mapper $dependencyMapper diff --git a/app/code/Magento/Config/Model/Config/Structure/Element/Section.php b/app/code/Magento/Config/Model/Config/Structure/Element/Section.php index 134411fbd87c..80c029dfea2d 100644 --- a/app/code/Magento/Config/Model/Config/Structure/Element/Section.php +++ b/app/code/Magento/Config/Model/Config/Structure/Element/Section.php @@ -22,13 +22,13 @@ class Section extends AbstractComposite /** * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Iterator $childrenIterator * @param \Magento\Framework\AuthorizationInterface $authorization */ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Iterator $childrenIterator, \Magento\Framework\AuthorizationInterface $authorization ) { diff --git a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php index e448b628ef02..8c54a02a491c 100644 --- a/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php +++ b/app/code/Magento/Config/Test/Unit/Model/Config/Structure/Element/AbstractCompositeTest.php @@ -29,7 +29,7 @@ class AbstractCompositeTest extends \PHPUnit\Framework\TestCase protected $_iteratorMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface | \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager | \PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -56,7 +56,7 @@ protected function setUp() ->getMockForAbstractClass(); $this->_iteratorMock = $this->createMock(\Magento\Config\Model\Config\Structure\Element\Iterator::class); $this->_storeManagerMock = $this->createMock(\Magento\Store\Model\StoreManager::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->_model = $this->getMockForAbstractClass( \Magento\Config\Model\Config\Structure\Element\AbstractComposite::class, [$this->_storeManagerMock, $this->moduleManagerMock, $this->_iteratorMock] diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php index e8b7299a03db..cb4ac975cd58 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Plugin.php @@ -6,7 +6,7 @@ */ namespace Magento\ConfigurableProduct\Model\Product\Type; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; /** * Type plugin. @@ -14,14 +14,14 @@ class Plugin { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Customer/Block/Form/Register.php b/app/code/Magento/Customer/Block/Form/Register.php index a190ccde50b5..59966768a2ed 100644 --- a/app/code/Magento/Customer/Block/Form/Register.php +++ b/app/code/Magento/Customer/Block/Form/Register.php @@ -23,7 +23,7 @@ class Register extends \Magento\Directory\Block\Data protected $_customerSession; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -41,7 +41,7 @@ class Register extends \Magento\Directory\Block\Data * @param \Magento\Framework\App\Cache\Type\Config $configCacheType * @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory * @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Model\Url $customerUrl * @param array $data @@ -55,7 +55,7 @@ public function __construct( \Magento\Framework\App\Cache\Type\Config $configCacheType, \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory, \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Model\Url $customerUrl, array $data = [] diff --git a/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php b/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php index 5cd09aca9f87..d48ff5918c3f 100644 --- a/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php +++ b/app/code/Magento/Customer/Helper/Session/CurrentCustomer.php @@ -10,7 +10,7 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ViewInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\View\LayoutInterface; /** @@ -45,7 +45,7 @@ class CurrentCustomer protected $request; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; diff --git a/app/code/Magento/Customer/Model/Customer/Source/Group.php b/app/code/Magento/Customer/Model/Customer/Source/Group.php index efcc7d0fe93a..1064152b20fd 100644 --- a/app/code/Magento/Customer/Model/Customer/Source/Group.php +++ b/app/code/Magento/Customer/Model/Customer/Source/Group.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Model\Customer\Source; use Magento\Customer\Api\Data\GroupSearchResultsInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Customer\Api\Data\GroupInterface; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; diff --git a/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php b/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php index b93b9f40d75b..d234ebfb334d 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Form/RegisterTest.php @@ -40,7 +40,7 @@ class RegisterTest extends \PHPUnit\Framework\TestCase /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Model\Session */ private $_customerSession; - /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Module\ModuleManagerInterface */ + /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Module\Manager */ private $_moduleManager; /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Model\Url */ diff --git a/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php b/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php index 03158d05db8e..15ced1ce66d0 100644 --- a/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php +++ b/app/code/Magento/Customer/Test/Unit/Helper/Session/CurrentCustomerTest.php @@ -47,7 +47,7 @@ class CurrentCustomerTest extends \PHPUnit\Framework\TestCase protected $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -80,7 +80,7 @@ protected function setUp() $this->customerDataMock = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); $this->customerRepositoryMock = $this->createMock(\Magento\Customer\Api\CustomerRepositoryInterface::class); $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->viewMock = $this->createMock(\Magento\Framework\App\View::class); $this->currentCustomer = new \Magento\Customer\Helper\Session\CurrentCustomer( diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php index 9128d7c67526..bc4c19bc23ac 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/Source/GroupTest.php @@ -6,7 +6,7 @@ namespace Magento\Customer\Test\Unit\Model\Customer\Source; use Magento\Customer\Model\Customer\Source\Group; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Customer\Api\GroupRepositoryInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Api\SearchCriteria; @@ -23,7 +23,7 @@ class GroupTest extends \PHPUnit\Framework\TestCase private $model; /** - * @var ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -49,7 +49,7 @@ class GroupTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->moduleManagerMock = $this->getMockBuilder(ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(Manager::class) ->disableOriginalConstructor() ->getMock(); $this->groupRepositoryMock = $this->getMockBuilder(GroupRepositoryInterface::class) diff --git a/app/code/Magento/Deploy/Collector/Collector.php b/app/code/Magento/Deploy/Collector/Collector.php index 7742f2971a2f..b09001a7ac04 100644 --- a/app/code/Magento/Deploy/Collector/Collector.php +++ b/app/code/Magento/Deploy/Collector/Collector.php @@ -9,7 +9,7 @@ use Magento\Deploy\Package\Package; use Magento\Deploy\Package\PackageFactory; use Magento\Deploy\Package\PackageFile; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\View\Asset\PreProcessor\FileNameResolver; /** @@ -45,8 +45,8 @@ class Collector implements CollectorInterface * @var PackageFactory */ private $packageFactory; - - /** @var \Magento\Framework\Module\ModuleManagerInterface */ + + /** @var \Magento\Framework\Module\Manager */ private $moduleManager; /** @@ -66,19 +66,19 @@ class Collector implements CollectorInterface * @param SourcePool $sourcePool * @param FileNameResolver $fileNameResolver * @param PackageFactory $packageFactory - * @param ModuleManagerInterface|null $moduleManager + * @param Manager|null $moduleManager */ public function __construct( SourcePool $sourcePool, FileNameResolver $fileNameResolver, PackageFactory $packageFactory, - ModuleManagerInterface $moduleManager = null + Manager $moduleManager = null ) { $this->sourcePool = $sourcePool; $this->fileNameResolver = $fileNameResolver; $this->packageFactory = $packageFactory; $this->moduleManager = $moduleManager ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Framework\Module\ModuleManagerInterface::class); + ->get(\Magento\Framework\Module\Manager::class); } /** diff --git a/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php b/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php index 51efc7473804..8b8a9b6bf289 100644 --- a/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php +++ b/app/code/Magento/Downloadable/Block/Checkout/Cart/Item/Renderer.php @@ -37,7 +37,7 @@ class Renderer extends \Magento\Checkout\Block\Cart\Item\Renderer * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param PriceCurrencyInterface $priceCurrency - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param InterpretationStrategyInterface $messageInterpretationStrategy * @param \Magento\Downloadable\Helper\Catalog\Product\Configuration $downloadableProductConfiguration * @param array $data @@ -51,7 +51,7 @@ public function __construct( \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Framework\Message\ManagerInterface $messageManager, PriceCurrencyInterface $priceCurrency, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, InterpretationStrategyInterface $messageInterpretationStrategy, \Magento\Downloadable\Helper\Catalog\Product\Configuration $downloadableProductConfiguration, array $data = [] diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php index 4777b2bae07a..350edb5b8495 100644 --- a/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php +++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Plugin.php @@ -6,7 +6,7 @@ */ namespace Magento\GroupedProduct\Model\Product\Type; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; /** * Plugin. @@ -14,14 +14,14 @@ class Plugin { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php index 519da2051081..c492939232b1 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Product/Type/Grouped/AssociatedProductsCollection.php @@ -41,7 +41,7 @@ class AssociatedProductsCollection extends \Magento\Catalog\Model\ResourceModel\ * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -67,7 +67,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php index cec7931c1c61..78fa2445ff58 100644 --- a/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php +++ b/app/code/Magento/GroupedProduct/Test/Unit/Model/ProductTest.php @@ -30,7 +30,7 @@ class ProductTest extends \PHPUnit\Framework\TestCase protected $model; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; @@ -159,14 +159,9 @@ class ProductTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->categoryIndexerMock = $this->getMockForAbstractClass( - \Magento\Framework\Indexer\IndexerInterface::class - ); + $this->categoryIndexerMock = $this->getMockForAbstractClass(\Magento\Framework\Indexer\IndexerInterface::class); - $this->moduleManager = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, - ['isEnabled'] - ); + $this->moduleManager = $this->createPartialMock(\Magento\Framework\Module\Manager::class, ['isEnabled']); $this->stockItemFactoryMock = $this->createPartialMock( \Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory::class, ['create'] diff --git a/app/code/Magento/ImportExport/Model/Export/Config/Converter.php b/app/code/Magento/ImportExport/Model/Export/Config/Converter.php index 20ab81ec1cd5..298f63d18f88 100644 --- a/app/code/Magento/ImportExport/Model/Export/Config/Converter.php +++ b/app/code/Magento/ImportExport/Model/Export/Config/Converter.php @@ -5,7 +5,7 @@ */ namespace Magento\ImportExport\Model\Export\Config; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\App\Utility\Classes; /** @@ -14,14 +14,14 @@ class Converter implements \Magento\Framework\Config\ConverterInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/ImportExport/Model/Import/Config/Converter.php b/app/code/Magento/ImportExport/Model/Import/Config/Converter.php index f2d1596ec3d9..a1eb8470b4dd 100644 --- a/app/code/Magento/ImportExport/Model/Import/Config/Converter.php +++ b/app/code/Magento/ImportExport/Model/Import/Config/Converter.php @@ -5,7 +5,7 @@ */ namespace Magento\ImportExport\Model\Import\Config; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\App\Utility\Classes; /** @@ -14,14 +14,14 @@ class Converter implements \Magento\Framework\Config\ConverterInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php index c888c6b44734..e08f382d9400 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Export/Config/ConverterTest.php @@ -21,7 +21,7 @@ class ConverterTest extends \PHPUnit\Framework\TestCase protected $filePath; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php index b29a04322ce4..69118d2e2a31 100644 --- a/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php +++ b/app/code/Magento/ImportExport/Test/Unit/Model/Import/Config/ConverterTest.php @@ -21,7 +21,7 @@ class ConverterTest extends \PHPUnit\Framework\TestCase protected $filePath; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManager; diff --git a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php index 0b9cb377d1d0..ce618f97883b 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Edit/Tab/Front/ProductAttributeFormBuildFrontTabObserver.php @@ -8,7 +8,7 @@ namespace Magento\LayeredNavigation\Observer\Edit\Tab\Front; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\ObserverInterface; /** @@ -22,15 +22,15 @@ class ProductAttributeFormBuildFrontTabObserver implements ObserverInterface protected $optionList; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Source\Yesno $optionList */ - public function __construct(ModuleManagerInterface $moduleManager, Source\Yesno $optionList) + public function __construct(Manager $moduleManager, Source\Yesno $optionList) { $this->optionList = $optionList; $this->moduleManager = $moduleManager; diff --git a/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php b/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php index b98230c1ebe3..57a20cf17371 100644 --- a/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php +++ b/app/code/Magento/LayeredNavigation/Observer/Grid/ProductAttributeGridBuildObserver.php @@ -7,7 +7,7 @@ */ namespace Magento\LayeredNavigation\Observer\Grid; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\ObserverInterface; /** @@ -16,16 +16,16 @@ class ProductAttributeGridBuildObserver implements ObserverInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** * Construct. * - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/NewRelicReporting/Model/Module/Collect.php b/app/code/Magento/NewRelicReporting/Model/Module/Collect.php index 0d8a94fbed94..fe5389e258aa 100644 --- a/app/code/Magento/NewRelicReporting/Model/Module/Collect.php +++ b/app/code/Magento/NewRelicReporting/Model/Module/Collect.php @@ -6,7 +6,7 @@ namespace Magento\NewRelicReporting\Model\Module; use Magento\Framework\Module\FullModuleList; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Module\ModuleListInterface; use Magento\NewRelicReporting\Model\Config; use Magento\NewRelicReporting\Model\Module; @@ -22,7 +22,7 @@ class Collect protected $moduleList; /** - * @var ModuleManagerInterface + * @var Manager */ protected $moduleManager; @@ -46,14 +46,14 @@ class Collect * * @param ModuleListInterface $moduleList * @param FullModuleList $fullModuleList - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param \Magento\NewRelicReporting\Model\ModuleFactory $moduleFactory * @param \Magento\NewRelicReporting\Model\ResourceModel\Module\CollectionFactory $moduleCollectionFactory */ public function __construct( ModuleListInterface $moduleList, FullModuleList $fullModuleList, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, \Magento\NewRelicReporting\Model\ModuleFactory $moduleFactory, \Magento\NewRelicReporting\Model\ResourceModel\Module\CollectionFactory $moduleCollectionFactory ) { diff --git a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php index 3c30d95b77de..4286406d6e9a 100644 --- a/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php +++ b/app/code/Magento/NewRelicReporting/Test/Unit/Model/Module/CollectTest.php @@ -8,6 +8,7 @@ use Magento\NewRelicReporting\Model\Module\Collect; use Magento\Framework\Module\FullModuleList; use Magento\Framework\Module\ModuleListInterface; +use Magento\Framework\Module\Manager; use Magento\NewRelicReporting\Model\Module; /** diff --git a/app/code/Magento/PageCache/Model/DepersonalizeChecker.php b/app/code/Magento/PageCache/Model/DepersonalizeChecker.php index 4012499d5da5..3023efb7a71a 100644 --- a/app/code/Magento/PageCache/Model/DepersonalizeChecker.php +++ b/app/code/Magento/PageCache/Model/DepersonalizeChecker.php @@ -20,7 +20,7 @@ class DepersonalizeChecker /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -33,12 +33,12 @@ class DepersonalizeChecker /** * @param \Magento\Framework\App\RequestInterface $request - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param Config $cacheConfig */ public function __construct( \Magento\Framework\App\RequestInterface $request, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, Config $cacheConfig ) { $this->request = $request; diff --git a/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php b/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php index 6857c637bab8..8cc933853a49 100644 --- a/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php +++ b/app/code/Magento/PageCache/Test/Unit/Model/DepersonalizeCheckerTest.php @@ -18,7 +18,7 @@ class DepersonalizeCheckerTest extends \PHPUnit\Framework\TestCase private $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -30,7 +30,7 @@ class DepersonalizeCheckerTest extends \PHPUnit\Framework\TestCase public function setup() { $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\ModuleManagerInterface::class); + $this->moduleManagerMock = $this->createMock(\Magento\Framework\Module\Manager::class); $this->cacheConfigMock = $this->createMock(\Magento\PageCache\Model\Config::class); } diff --git a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php index 5ba0182ecc57..9731811ea8a9 100644 --- a/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Model/Layout/DepersonalizePluginTest.php @@ -46,17 +46,9 @@ protected function setUp() $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class); - $this->moduleManagerMock = $this->createPartialMock( - \Magento\Framework\Module\ModuleManagerInterface::class, - ['isEnabled'] - ); - $this->cacheConfigMock = $this->createPartialMock( - \Magento\PageCache\Model\Config::class, - ['isEnabled'] - ); - $this->depersonalizeCheckerMock = $this->createMock( - \Magento\PageCache\Model\DepersonalizeChecker::class - ); + $this->moduleManagerMock = $this->createPartialMock(\Magento\Framework\Module\Manager::class, ['isEnabled']); + $this->cacheConfigMock = $this->createPartialMock(\Magento\PageCache\Model\Config::class, ['isEnabled']); + $this->depersonalizeCheckerMock = $this->createMock(\Magento\PageCache\Model\DepersonalizeChecker::class); $this->plugin = $this->objectManager->getObject( \Magento\Persistent\Model\Layout\DepersonalizePlugin::class, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php index 8c985238efe4..ab76cad8da5c 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php @@ -77,7 +77,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -111,7 +111,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php index ec514f45ff65..5b4cf39d65de 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php @@ -44,7 +44,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\ResourceModel\P * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -69,7 +69,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php index c02de01117a7..39d673911111 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php @@ -63,7 +63,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -94,7 +94,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php index 3f1857b352db..23067457081a 100644 --- a/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php +++ b/app/code/Magento/Reports/Test/Unit/Model/ResourceModel/Product/CollectionTest.php @@ -29,7 +29,7 @@ use Magento\Framework\DB\Adapter\AdapterInterface; use Magento\Framework\DB\Select; use Magento\Framework\Event\ManagerInterface; -use Magento\Framework\Module\ModuleManagerInterface as Manager; +use Magento\Framework\Module\Manager as Manager; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Stdlib\DateTime\TimezoneInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; diff --git a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php index 509e826e6f7d..d3bbdf9a7eb4 100644 --- a/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php +++ b/app/code/Magento/Review/Block/Adminhtml/Product/Grid.php @@ -29,7 +29,7 @@ class Grid extends \Magento\Catalog\Block\Adminhtml\Product\Grid * @param \Magento\Catalog\Model\Product\Type $type * @param \Magento\Catalog\Model\Product\Attribute\Source\Status $status * @param \Magento\Catalog\Model\Product\Visibility $visibility - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\ResourceModel\Website\CollectionFactory $websitesFactory * @param array $data * @@ -44,7 +44,7 @@ public function __construct( \Magento\Catalog\Model\Product\Type $type, \Magento\Catalog\Model\Product\Attribute\Source\Status $status, \Magento\Catalog\Model\Product\Visibility $visibility, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\ResourceModel\Website\CollectionFactory $websitesFactory, array $data = [] ) { diff --git a/app/code/Magento/Review/Model/ResourceModel/Rating.php b/app/code/Magento/Review/Model/ResourceModel/Rating.php index 42c14e16a50e..37a93d40b110 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Rating.php +++ b/app/code/Magento/Review/Model/ResourceModel/Rating.php @@ -29,7 +29,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb protected $_storeManager; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -46,7 +46,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param Review\Summary $reviewSummary * @param string $connectionName @@ -55,7 +55,7 @@ class Rating extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Review\Model\ResourceModel\Review\Summary $reviewSummary, $connectionName = null, diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index 7175baa92a2f..ab264ef1b617 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -75,7 +75,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper * @param \Magento\Framework\Validator\UniversalFactory $universalFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory @@ -103,7 +103,7 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, \Magento\Framework\Validator\UniversalFactory $universalFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory, diff --git a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php index e1e5503ad475..1000821dd189 100644 --- a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php +++ b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php @@ -8,7 +8,7 @@ use Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier\AbstractModifierTest; use Magento\Framework\UrlInterface; use Magento\Review\Ui\DataProvider\Product\Form\Modifier\Review; -use \Magento\Framework\Module\Manager as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Ui\DataProvider\Modifier\ModifierInterface; /** diff --git a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php index 433be1c86098..5f1401a201e3 100644 --- a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php +++ b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php @@ -12,7 +12,7 @@ use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; use Magento\Ui\Component\Form; use Magento\Framework\UrlInterface; -use \Magento\Framework\Module\ModuleManagerInterface as ModuleManager; +use Magento\Framework\Module\Manager as ModuleManager; use Magento\Framework\App\ObjectManager; /** diff --git a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php index ad8d247b2a6f..ff49f4a15b06 100644 --- a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php +++ b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Last.php @@ -24,7 +24,7 @@ class Last extends \Magento\Backend\Block\Dashboard\Grid protected $_queriesFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -36,14 +36,14 @@ class Last extends \Magento\Backend\Block\Dashboard\Grid /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory, array $data = [] ) { diff --git a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php index 63893f788673..3e10e1137d6b 100644 --- a/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php +++ b/app/code/Magento/Search/Block/Adminhtml/Dashboard/Top.php @@ -24,7 +24,7 @@ class Top extends \Magento\Backend\Block\Dashboard\Grid protected $_queriesFactory; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -36,14 +36,14 @@ class Top extends \Magento\Backend\Block\Dashboard\Grid /** * @param \Magento\Backend\Block\Template\Context $context * @param \Magento\Backend\Helper\Data $backendHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory * @param array $data */ public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Search\Model\ResourceModel\Query\CollectionFactory $queriesFactory, array $data = [] ) { diff --git a/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php b/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php index 3ef202af95a1..303f1eda2e40 100644 --- a/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php +++ b/app/code/Magento/Swatches/Observer/AddFieldsToAttributeObserver.php @@ -6,7 +6,7 @@ namespace Magento\Swatches\Observer; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; @@ -21,15 +21,15 @@ class AddFieldsToAttributeObserver implements ObserverInterface protected $yesNo; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Source\Yesno $yesNo */ - public function __construct(ModuleManagerInterface $moduleManager, Source\Yesno $yesNo) + public function __construct(Manager $moduleManager, Source\Yesno $yesNo) { $this->moduleManager = $moduleManager; $this->yesNo = $yesNo; diff --git a/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php b/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php index ca75da332169..fb8c185cc545 100644 --- a/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php +++ b/app/code/Magento/Swatches/Observer/AddSwatchAttributeTypeObserver.php @@ -6,7 +6,7 @@ namespace Magento\Swatches\Observer; use Magento\Config\Model\Config\Source; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\Event\Observer as EventObserver; use Magento\Framework\Event\ObserverInterface; @@ -16,14 +16,14 @@ class AddSwatchAttributeTypeObserver implements ObserverInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; /** - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager */ - public function __construct(ModuleManagerInterface $moduleManager) + public function __construct(Manager $moduleManager) { $this->moduleManager = $moduleManager; } diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php index f8ba5c20250a..45c680366264 100644 --- a/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddFieldsToAttributeObserverTest.php @@ -10,7 +10,7 @@ */ class AddFieldsToAttributeObserverTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; /** @var \Magento\Config\Model\Config\Source\Yesno|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php index 24afa1045e5c..f78797d93cb0 100644 --- a/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Observer/AddSwatchAttributeTypeObserverTest.php @@ -10,7 +10,7 @@ */ class AddSwatchAttributeTypeObserverTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; /** @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject */ diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index bba9bc3f3ebe..4eb399544870 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -34,7 +34,7 @@ class ContextPlugin /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -50,7 +50,7 @@ class ContextPlugin * @param \Magento\Framework\App\Http\Context $httpContext * @param \Magento\Tax\Model\Calculation\Proxy $calculation * @param \Magento\Tax\Helper\Data $taxHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig */ public function __construct( @@ -58,7 +58,7 @@ public function __construct( \Magento\Framework\App\Http\Context $httpContext, \Magento\Tax\Model\Calculation\Proxy $calculation, \Magento\Tax\Helper\Data $taxHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig ) { $this->customerSession = $customerSession; diff --git a/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php b/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php index ef84eac32e95..cf5d939b35c0 100644 --- a/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php +++ b/app/code/Magento/Tax/Observer/AfterAddressSaveObserver.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Address; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Tax\Helper\Data; @@ -26,7 +26,7 @@ class AfterAddressSaveObserver implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -46,13 +46,13 @@ class AfterAddressSaveObserver implements ObserverInterface /** * @param Data $taxHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $taxHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php b/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php index 00b3a9f9e09a..c1e4ad66d75d 100644 --- a/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php +++ b/app/code/Magento/Tax/Observer/CustomerLoggedInObserver.php @@ -9,7 +9,7 @@ use Magento\Customer\Model\Session; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Tax\Helper\Data; @@ -33,7 +33,7 @@ class CustomerLoggedInObserver implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -60,7 +60,7 @@ class CustomerLoggedInObserver implements ObserverInterface * @param GroupRepositoryInterface $groupRepository * @param Session $customerSession * @param Data $taxHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ @@ -68,7 +68,7 @@ public function __construct( GroupRepositoryInterface $groupRepository, Session $customerSession, Data $taxHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php index 020baa0c30ec..a6c7e9bb8685 100644 --- a/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Tax/Test/Unit/App/Action/ContextPluginTest.php @@ -38,7 +38,7 @@ class ContextPluginTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -89,7 +89,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 2e957e528e29..571cc7173bc9 100644 --- a/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Tax/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -6,7 +6,7 @@ namespace Magento\Tax\Test\Unit\Observer; use Magento\Framework\Event\Observer; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; @@ -31,7 +31,7 @@ class AfterAddressSaveObserverTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -65,7 +65,7 @@ protected function setUp() ->setMethods(['getCustomerAddress']) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); @@ -77,7 +77,7 @@ protected function setUp() ->setMethods(['isCatalogPriceDisplayAffectedByTax']) ->disableOriginalConstructor() ->getMock(); - + $this->addressManagerMock = $this->getMockBuilder(TaxAddressManagerInterface::class) ->setMethods(['setDefaultAddressAfterSave', 'setDefaultAddressAfterLogIn']) ->disableOriginalConstructor() diff --git a/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php b/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php index facbb6733b5c..c577f1727552 100644 --- a/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php +++ b/app/code/Magento/Tax/Test/Unit/Observer/CustomerLoggedInObserverTest.php @@ -31,7 +31,7 @@ class CustomerLoggedInObserverTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -82,7 +82,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml b/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml index 5dc1e5c72313..35bcfc265eaf 100644 --- a/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml +++ b/app/code/Magento/Tax/view/frontend/layout/sales_email_item_price.xml @@ -5,8 +5,7 @@ * See COPYING.txt for license details. */ --> -<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="items"> <block class="Magento\Tax\Block\Item\Price\Renderer" name="item_price" template="Magento_Tax::email/items/price/row.phtml"> @@ -16,11 +15,4 @@ </block> </referenceBlock> </body> -</page> - - - - - - - +</page> \ No newline at end of file diff --git a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php index 5d5426660d8f..aae6f769eb50 100644 --- a/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Weee/Model/App/Action/ContextPlugin.php @@ -33,7 +33,7 @@ class ContextPlugin protected $weeeHelper; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManager; @@ -63,7 +63,7 @@ class ContextPlugin * @param \Magento\Weee\Model\Tax $weeeTax * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Weee\Helper\Data $weeeHelper - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig @@ -74,7 +74,7 @@ public function __construct( \Magento\Weee\Model\Tax $weeeTax, \Magento\Tax\Helper\Data $taxHelper, \Magento\Weee\Helper\Data $weeeHelper, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig diff --git a/app/code/Magento/Weee/Observer/AfterAddressSave.php b/app/code/Magento/Weee/Observer/AfterAddressSave.php index 9acea506adf6..ba15854b2dff 100644 --- a/app/code/Magento/Weee/Observer/AfterAddressSave.php +++ b/app/code/Magento/Weee/Observer/AfterAddressSave.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Address; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Weee\Helper\Data; @@ -26,7 +26,7 @@ class AfterAddressSave implements ObserverInterface /** * Module manager * - * @var ModuleManagerInterface + * @var Manager */ private $moduleManager; @@ -46,13 +46,13 @@ class AfterAddressSave implements ObserverInterface /** * @param Data $weeeHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $weeeHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Weee/Observer/CustomerLoggedIn.php b/app/code/Magento/Weee/Observer/CustomerLoggedIn.php index 95299d96cabd..0b22c24d7fa2 100644 --- a/app/code/Magento/Weee/Observer/CustomerLoggedIn.php +++ b/app/code/Magento/Weee/Observer/CustomerLoggedIn.php @@ -8,7 +8,7 @@ use Magento\Customer\Model\Session; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\PageCache\Model\Config; use Magento\Tax\Api\TaxAddressManagerInterface; use Magento\Weee\Helper\Data; @@ -52,13 +52,13 @@ class CustomerLoggedIn implements ObserverInterface /** * @param Data $weeeHelper - * @param ModuleManagerInterface $moduleManager + * @param Manager $moduleManager * @param Config $cacheConfig * @param TaxAddressManagerInterface $addressManager */ public function __construct( Data $weeeHelper, - ModuleManagerInterface $moduleManager, + Manager $moduleManager, Config $cacheConfig, TaxAddressManagerInterface $addressManager ) { diff --git a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php index b720f42378fa..c829b524527a 100644 --- a/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php +++ b/app/code/Magento/Weee/Test/Unit/App/Action/ContextPluginTest.php @@ -39,7 +39,7 @@ class ContextPluginTest extends \PHPUnit\Framework\TestCase protected $taxCalculationMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $moduleManagerMock; @@ -93,7 +93,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php b/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php index a7b88f572712..868d603f34b8 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/AfterAddressSaveTest.php @@ -18,7 +18,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase * @var ObjectManager */ private $objectManager; - + /** * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject */ @@ -27,7 +27,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManagerMock; @@ -42,7 +42,7 @@ class AfterAddressSaveTest extends \PHPUnit\Framework\TestCase * @var \Magento\Weee\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ private $weeeHelperMock; - + /** * @var TaxAddressManagerInterface|MockObject */ @@ -61,7 +61,7 @@ protected function setUp() ->setMethods(['getCustomerAddress']) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); @@ -129,7 +129,7 @@ public function testExecute( $this->addressManagerMock->expects($isNeedSetAddress ? $this->once() : $this->never()) ->method('setDefaultAddressAfterSave') ->with($address); - + $this->session->execute($this->observerMock); } diff --git a/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php b/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php index 06d1dbedcfd8..af8c2e70a8ff 100644 --- a/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php +++ b/app/code/Magento/Weee/Test/Unit/Observer/CustomerLoggedInTest.php @@ -21,7 +21,7 @@ class CustomerLoggedInTest extends \PHPUnit\Framework\TestCase /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManagerMock; @@ -59,7 +59,7 @@ protected function setUp() ) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php b/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php index b55766d77fee..d0397be83fac 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Helper/RssTest.php @@ -46,7 +46,7 @@ class RssTest extends \PHPUnit\Framework\TestCase protected $customerRepositoryMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ protected $moduleManagerMock; @@ -80,7 +80,7 @@ protected function setUp() $this->customerRepositoryMock = $this->getMockBuilder(\Magento\Customer\Api\CustomerRepositoryInterface::class) ->getMock(); - $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\ModuleManagerInterface::class) + $this->moduleManagerMock = $this->getMockBuilder(\Magento\Framework\Module\Manager::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/etc/di.xml b/app/etc/di.xml index edb206a83c00..2863c5d4708d 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -65,7 +65,6 @@ <preference for="Magento\Framework\Config\CacheInterface" type="Magento\Framework\App\Cache\Type\Config" /> <preference for="Magento\Framework\Config\ValidationStateInterface" type="Magento\Framework\App\Arguments\ValidationState" /> <preference for="Magento\Framework\Module\ModuleListInterface" type="Magento\Framework\Module\ModuleList" /> - <preference for="Magento\Framework\Module\ModuleManagerInterface" type="Magento\Framework\Module\Manager" /> <preference for="Magento\Framework\Component\ComponentRegistrarInterface" type="Magento\Framework\Component\ComponentRegistrar"/> <preference for="Magento\Framework\Event\ConfigInterface" type="Magento\Framework\Event\Config" /> <preference for="Magento\Framework\Event\InvokerInterface" type="Magento\Framework\Event\Invoker\InvokerDefault" /> diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php index b159dceadfb7..c5b76807f1ff 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Account/Dashboard/AddressTest.php @@ -69,7 +69,7 @@ public function testGetCustomer() public function testGetCustomerMissingCustomer() { - $moduleManager = $this->objectManager->get(\Magento\Framework\Module\ModuleManagerInterface::class); + $moduleManager = $this->objectManager->get(\Magento\Framework\Module\Manager::class); if ($moduleManager->isEnabled('Magento_PageCache')) { $customerDataFactory = $this->objectManager->create( \Magento\Customer\Api\Data\CustomerInterfaceFactory::class diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php index 9417baea67ba..ff8e7db0f426 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php @@ -1982,8 +1982,8 @@ ['_escapeDefaultValue', 'Magento\Framework\Code\Generator\EntityAbstract'], ['urlEncode', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Url\EncoderInterface::encode'], ['urlDecode', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Url\DecoderInterface::decode'], - ['isModuleEnabled', 'Magento\Framework\App\Helper\AbstractHelper', '\Magento\Framework\Module\ModuleManagerInterface::isEnabled()'], - ['isModuleOutputEnabled', 'Magento\Framework\App\Helper\AbstractHelper', '\Magento\Framework\Module\ModuleManagerInterface::isOutputEnabled()'], + ['isModuleEnabled', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Module\Manager::isEnabled()'], + ['isModuleOutputEnabled', 'Magento\Framework\App\Helper\AbstractHelper', 'Magento\Framework\Module\Manager::isOutputEnabled()'], ['_packToTar', 'Magento\Framework\Archive\Tar'], ['_parseHeader', 'Magento\Framework\Archive\Tar'], ['getIdentities', 'Magento\Wishlist\Block\Link'], diff --git a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php index 7875e0c8885f..1a76610bc081 100644 --- a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php +++ b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php @@ -27,7 +27,7 @@ abstract class AbstractHelper protected $_request; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -125,7 +125,7 @@ protected function _getModuleName() * * @param string $moduleName Full module name * @return boolean - * use \Magento\Framework\Module\ModuleManagerInterface::isOutputEnabled() + * use \Magento\Framework\Module\Manager::isOutputEnabled() */ public function isModuleOutputEnabled($moduleName = null) { diff --git a/lib/internal/Magento/Framework/App/Helper/Context.php b/lib/internal/Magento/Framework/App/Helper/Context.php index cc57f109cc8e..5b90df8c5520 100644 --- a/lib/internal/Magento/Framework/App/Helper/Context.php +++ b/lib/internal/Magento/Framework/App/Helper/Context.php @@ -21,7 +21,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface { /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ protected $_moduleManager; @@ -79,7 +79,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface * @param \Magento\Framework\Url\EncoderInterface $urlEncoder * @param \Magento\Framework\Url\DecoderInterface $urlDecoder * @param \Psr\Log\LoggerInterface $logger - * @param \Magento\Framework\Module\ModuleManagerInterface $moduleManager + * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\Framework\App\RequestInterface $httpRequest * @param \Magento\Framework\Cache\ConfigInterface $cacheConfig * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -94,7 +94,7 @@ public function __construct( \Magento\Framework\Url\EncoderInterface $urlEncoder, \Magento\Framework\Url\DecoderInterface $urlDecoder, \Psr\Log\LoggerInterface $logger, - \Magento\Framework\Module\ModuleManagerInterface $moduleManager, + \Magento\Framework\Module\Manager $moduleManager, \Magento\Framework\App\RequestInterface $httpRequest, \Magento\Framework\Cache\ConfigInterface $cacheConfig, \Magento\Framework\Event\ManagerInterface $eventManager, @@ -119,7 +119,7 @@ public function __construct( /** * Get module manager. * - * @return \Magento\Framework\Module\ModuleManagerInterface + * @return \Magento\Framework\Module\Manager */ public function getModuleManager() { diff --git a/lib/internal/Magento/Framework/Module/Manager.php b/lib/internal/Magento/Framework/Module/Manager.php index 659ada3c20ac..b47349631a03 100644 --- a/lib/internal/Magento/Framework/Module/Manager.php +++ b/lib/internal/Magento/Framework/Module/Manager.php @@ -12,9 +12,14 @@ namespace Magento\Framework\Module; /** - * @inheritdoc + * Module status manager + * + * Usage: + * ```php + * $manager->isEnabled('Vendor_Module'); + * ``` */ -class Manager implements ModuleManagerInterface +class Manager { /** * @var Output\ConfigInterface @@ -49,9 +54,12 @@ public function __construct( } /** - * @inheritdoc + * Whether a module is enabled in the configuration or not + * + * @param string $moduleName Fully-qualified module name + * @return boolean */ - public function isEnabled(string $moduleName): bool + public function isEnabled($moduleName) { return $this->moduleList->has($moduleName); } diff --git a/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php b/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php deleted file mode 100644 index decc91200354..000000000000 --- a/lib/internal/Magento/Framework/Module/ModuleManagerInterface.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Framework\Module; - -/** - * Module status manager - * - * Usage: - * ```php - * $manager->isEnabled('Vendor_Module'); - * ``` - */ -interface ModuleManagerInterface -{ - /** - * Retrieve whether or not a module is enabled by configuration - * - * @param string $moduleName Fully-qualified module name, e.g. Magento_Config - * @return boolean Whether or not the module is enabled in the configuration - */ - public function isEnabled(string $moduleName): bool; -} diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php index e4cf4c41599e..748474943a43 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php @@ -16,7 +16,7 @@ class ManagerTest extends \PHPUnit\Framework\TestCase const XML_PATH_OUTPUT_ENABLED = 'custom/is_module_output_enabled'; /** - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $_model; @@ -73,7 +73,6 @@ public function testIsEnabled() public function testIsOutputEnabledReturnsFalseForDisabledModule() { - $this->_moduleList->expects($this->once())->method('has')->with('Disabled_Module')->willReturn(false); $this->_outputConfig->expects($this->any())->method('isSetFlag')->will($this->returnValue(true)); $this->assertFalse($this->_model->isOutputEnabled('Disabled_Module')); } diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php index 7a631eed1adb..bfd916dbfba5 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/Plugin/DbStatusValidatorTest.php @@ -35,7 +35,7 @@ class DbStatusValidatorTest extends \PHPUnit\Framework\TestCase protected $requestMock; /** - * @var \Magento\Framework\Module\ModuleManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject */ private $moduleManager; diff --git a/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php b/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php index 71fa8d2c0ae6..34f32b2f6b7b 100644 --- a/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php +++ b/lib/internal/Magento/Framework/View/File/Collector/Decorator/ModuleOutput.php @@ -6,7 +6,7 @@ namespace Magento\Framework\View\File\Collector\Decorator; -use Magento\Framework\Module\ModuleManagerInterface; +use Magento\Framework\Module\Manager; use Magento\Framework\View\Design\ThemeInterface; use Magento\Framework\View\File; use Magento\Framework\View\File\CollectorInterface; @@ -26,7 +26,7 @@ class ModuleOutput implements CollectorInterface /** * Module manager * - * @var \Magento\Framework\Module\ModuleManagerInterface + * @var \Magento\Framework\Module\Manager */ private $moduleManager; @@ -38,7 +38,7 @@ class ModuleOutput implements CollectorInterface */ public function __construct( CollectorInterface $subject, - ModuleManagerInterface $moduleManager + Manager $moduleManager ) { $this->subject = $subject; $this->moduleManager = $moduleManager; From 9687ccf68d7d6c8b6059e3bc018e28ac60915962 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Fri, 9 Aug 2019 15:37:29 -0500 Subject: [PATCH 0310/1172] MSI-2471: Fix Elasticsearch support for MSI --- .../Indexer/Fulltext/Action/DataProvider.php | 81 ------------ .../Plugin/StockedProductsFilterPlugin.php | 91 +++++++++++++ .../StockedProductsFilterPluginTest.php | 125 ++++++++++++++++++ app/code/Magento/CatalogSearch/etc/di.xml | 3 + 4 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php create mode 100644 app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php index 09d4f0068459..cd2529a8fd72 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/DataProvider.php @@ -7,14 +7,9 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; -use Magento\CatalogInventory\Api\Data\StockStatusInterface; -use Magento\CatalogInventory\Api\StockConfigurationInterface; -use Magento\CatalogInventory\Api\StockStatusCriteriaInterface; -use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Select; use Magento\Store\Model\Store; -use Magento\Framework\App\ObjectManager; /** * Catalog search full test search data provider. @@ -129,16 +124,6 @@ class DataProvider */ private $antiGapMultiplier; - /** - * @var StockConfigurationInterface - */ - private $stockConfiguration; - - /** - * @var StockStatusRepositoryInterface - */ - private $stockStatusRepository; - /** * @param ResourceConnection $resource * @param \Magento\Catalog\Model\Product\Type $catalogProductType @@ -563,8 +548,6 @@ public function prepareProductIndex($indexData, $productData, $storeId) { $index = []; - $indexData = $this->filterOutOfStockProducts($indexData, $storeId); - foreach ($this->getSearchableAttributes('static') as $attribute) { $attributeCode = $attribute->getAttributeCode(); @@ -689,68 +672,4 @@ private function filterAttributeValue($value) { return preg_replace('/\s+/iu', ' ', trim(strip_tags($value))); } - - /** - * Filter out of stock products for products. - * - * @param array $indexData - * @param int $storeId - * @return array - */ - private function filterOutOfStockProducts($indexData, $storeId): array - { - if (!$this->getStockConfiguration()->isShowOutOfStock($storeId)) { - $productIds = array_keys($indexData); - $stockStatusCriteria = $this->createStockStatusCriteria(); - $stockStatusCriteria->setProductsFilter($productIds); - $stockStatusCollection = $this->getStockStatusRepository()->getList($stockStatusCriteria); - $stockStatuses = $stockStatusCollection->getItems(); - $stockStatuses = array_filter( - $stockStatuses, - function (StockStatusInterface $stockStatus) { - return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus(); - } - ); - $indexData = array_intersect_key($indexData, $stockStatuses); - } - return $indexData; - } - - /** - * Get stock configuration. - * - * @return StockConfigurationInterface - */ - private function getStockConfiguration() - { - if (null === $this->stockConfiguration) { - $this->stockConfiguration = ObjectManager::getInstance()->get(StockConfigurationInterface::class); - } - return $this->stockConfiguration; - } - - /** - * Create stock status criteria. - * - * Substitution of autogenerated factory in backward compatibility reasons. - * - * @return StockStatusCriteriaInterface - */ - private function createStockStatusCriteria() - { - return ObjectManager::getInstance()->create(StockStatusCriteriaInterface::class); - } - - /** - * Get stock status repository. - * - * @return StockStatusRepositoryInterface - */ - private function getStockStatusRepository() - { - if (null === $this->stockStatusRepository) { - $this->stockStatusRepository = ObjectManager::getInstance()->get(StockStatusRepositoryInterface::class); - } - return $this->stockStatusRepository; - } } diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php b/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php new file mode 100644 index 000000000000..02e48c5d8a1c --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Plugin/StockedProductsFilterPlugin.php @@ -0,0 +1,91 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogSearch\Model\Indexer\Plugin; + +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory; +use Magento\CatalogInventory\Api\Data\StockStatusInterface; +use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; + +/** + * Plugin for filtering child products that are out of stock for preventing their saving to catalog search index. + * + * This plugin reverts changes introduced in commit 9ab466d8569ea556cb01393989579c3aac53d9a3 which break extensions + * relying on stocks. Plugin location is changed for consistency purposes. + */ +class StockedProductsFilterPlugin +{ + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + + /** + * @var StockStatusRepositoryInterface + */ + private $stockStatusRepository; + + /** + * @var StockStatusCriteriaInterfaceFactory + */ + private $stockStatusCriteriaFactory; + + /** + * @param StockConfigurationInterface $stockConfiguration + * @param StockStatusRepositoryInterface $stockStatusRepository + * @param StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory + */ + public function __construct( + StockConfigurationInterface $stockConfiguration, + StockStatusRepositoryInterface $stockStatusRepository, + StockStatusCriteriaInterfaceFactory $stockStatusCriteriaFactory + ) { + $this->stockConfiguration = $stockConfiguration; + $this->stockStatusRepository = $stockStatusRepository; + $this->stockStatusCriteriaFactory = $stockStatusCriteriaFactory; + } + + /** + * Filter out of stock options for configurable product. + * + * @param DataProvider $dataProvider + * @param array $indexData + * @param array $productData + * @param int $storeId + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforePrepareProductIndex( + DataProvider $dataProvider, + array $indexData, + array $productData, + int $storeId + ): array { + if (!$this->stockConfiguration->isShowOutOfStock($storeId)) { + $productIds = array_keys($indexData); + $stockStatusCriteria = $this->stockStatusCriteriaFactory->create(); + $stockStatusCriteria->setProductsFilter($productIds); + $stockStatusCollection = $this->stockStatusRepository->getList($stockStatusCriteria); + $stockStatuses = $stockStatusCollection->getItems(); + $stockStatuses = array_filter( + $stockStatuses, + function (StockStatusInterface $stockStatus) { + return StockStatusInterface::STATUS_IN_STOCK == $stockStatus->getStockStatus(); + } + ); + $indexData = array_intersect_key($indexData, $stockStatuses); + } + + return [ + $indexData, + $productData, + $storeId, + ]; + } +} diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php new file mode 100644 index 000000000000..eb3060c16a14 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogSearch\Test\Unit\Model\Indexer\Plugin; + +use Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin; +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Api\StockStatusRepositoryInterface; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterfaceFactory; +use Magento\CatalogInventory\Api\StockStatusCriteriaInterface; +use Magento\CatalogInventory\Api\Data\StockStatusCollectionInterface; +use Magento\CatalogInventory\Api\Data\StockStatusInterface; +use Magento\CatalogInventory\Model\Stock; +use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider; + +/** + * Test for Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin class. + * + * This plugin reverts changes introduced in commit 9ab466d8569ea556cb01393989579c3aac53d9a3 which break extensions + * relying on stocks. Plugin location is changed for consistency purposes. + */ +class StockedProductsFilterPluginTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockConfigurationMock; + + /** + * @var StockStatusRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockStatusRepositoryMock; + + /** + * @var StockStatusCriteriaInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $stockStatusCriteriaFactoryMock; + + /** + * @var StockedProductsFilterPlugin + */ + private $plugin; + + /** + * {@inheritdoc} + */ + protected function setUp() + { + $this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusRepositoryMock = $this->getMockBuilder(StockStatusRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $this->stockStatusCriteriaFactoryMock = $this->getMockBuilder(StockStatusCriteriaInterfaceFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new StockedProductsFilterPlugin( + $this->stockConfigurationMock, + $this->stockStatusRepositoryMock, + $this->stockStatusCriteriaFactoryMock + ); + } + + /** + * @return void + */ + public function testBeforePrepareProductIndex(): void + { + /** @var DataProvider|\PHPUnit_Framework_MockObject_MockObject $dataProviderMock */ + $dataProviderMock = $this->getMockBuilder(DataProvider::class)->disableOriginalConstructor()->getMock(); + $indexData = [ + 1 => [], + 2 => [], + ]; + $productData = []; + $storeId = 1; + + $this->stockConfigurationMock + ->expects($this->once()) + ->method('isShowOutOfStock') + ->willReturn(false); + + $stockStatusCriteriaMock = $this->getMockBuilder(StockStatusCriteriaInterface::class)->getMock(); + $stockStatusCriteriaMock + ->expects($this->once()) + ->method('setProductsFilter') + ->willReturn(true); + $this->stockStatusCriteriaFactoryMock + ->expects($this->once()) + ->method('create') + ->willReturn($stockStatusCriteriaMock); + + $stockStatusMock = $this->getMockBuilder(StockStatusInterface::class)->getMock(); + $stockStatusMock->expects($this->atLeastOnce()) + ->method('getStockStatus') + ->willReturnOnConsecutiveCalls(Stock::STOCK_IN_STOCK, Stock::STOCK_OUT_OF_STOCK); + $stockStatusCollectionMock = $this->getMockBuilder(StockStatusCollectionInterface::class)->getMock(); + $stockStatusCollectionMock + ->expects($this->once()) + ->method('getItems') + ->willReturn([ + 1 => $stockStatusMock, + 2 => $stockStatusMock, + ]); + $this->stockStatusRepositoryMock + ->expects($this->once()) + ->method('getList') + ->willReturn($stockStatusCollectionMock); + + list ($indexData, $productData, $storeId) = $this->plugin->beforePrepareProductIndex( + $dataProviderMock, + $indexData, + $productData, + $storeId + ); + + $this->assertEquals([1], array_keys($indexData)); + } +} diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml index 28d5035308de..63de2dc00926 100644 --- a/app/code/Magento/CatalogSearch/etc/di.xml +++ b/app/code/Magento/CatalogSearch/etc/di.xml @@ -373,4 +373,7 @@ </argument> </arguments> </type> + <type name="Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider"> + <plugin name="stockedProductsFilterPlugin" type="Magento\CatalogSearch\Model\Indexer\Plugin\StockedProductsFilterPlugin"/> + </type> </config> From fa628ed3f3134dcd319a0e57a961ff6323f6ef30 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov <ishakhsuvarov@magento.com> Date: Fri, 9 Aug 2019 16:59:37 -0500 Subject: [PATCH 0311/1172] MSI-2471: Fixed static test failure --- .../Model/Indexer/Plugin/StockedProductsFilterPluginTest.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php index eb3060c16a14..b9909ec2c74b 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Plugin/StockedProductsFilterPluginTest.php @@ -104,10 +104,7 @@ public function testBeforePrepareProductIndex(): void $stockStatusCollectionMock ->expects($this->once()) ->method('getItems') - ->willReturn([ - 1 => $stockStatusMock, - 2 => $stockStatusMock, - ]); + ->willReturn([1 => $stockStatusMock, 2 => $stockStatusMock]); $this->stockStatusRepositoryMock ->expects($this->once()) ->method('getList') From fd73c392026c990721600e5e49f4b096973d99c7 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Mon, 12 Aug 2019 15:35:51 +0300 Subject: [PATCH 0312/1172] MC-19075: Html text are visible on frontend --- .../Checkout/view/frontend/templates/onepage/review/item.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml index 2a7ccc38e9d8..8e83526b4cea 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml @@ -30,7 +30,7 @@ $taxDataHelper = $this->helper(Magento\Tax\Helper\Data::class); <?php if (isset($_formatedOptionValue['full_view'])) :?> <?= $block->escapeHtml($_formatedOptionValue['full_view']) ?> <?php else :?> - <?= $block->escapeHtml($_formatedOptionValue['value']) ?> + <?= /* @noEscape */ $_formatedOptionValue['value'] ?> <?php endif; ?> </dd> <?php endforeach; ?> From ee853472c01c0d7e02da6f8659d0f13657a47854 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Mon, 12 Aug 2019 18:18:55 +0300 Subject: [PATCH 0313/1172] MC-19140: [DHL] You are still on New Shipment page after creating the shipment --- .../view/adminhtml/templates/order/packaging/popup.phtml | 2 +- .../Magento/Shipping/view/adminhtml/templates/view/form.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml index cd25cb919adb..28322d953492 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml @@ -31,7 +31,7 @@ $girthEnabled = $block->isDisplayGirthValue() && $block->isGirthAllowed() ? 1 : packaging.sendCreateLabelRequest(); }); packaging.setLabelCreatedCallback(function(response){ - setLocation("<?php $block->escapeJs($block->escapeUrl($block->getUrl( + setLocation("<?= $block->escapeJs($block->escapeUrl($block->getUrl( 'sales/order/view', ['order_id' => $block->getShipment()->getOrderId()] ))); ?>"); diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml index f10556215108..44fe4b9ccd35 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/view/form.phtml @@ -85,7 +85,7 @@ $order = $block->getShipment()->getOrder(); window.packaging.sendCreateLabelRequest(); }); window.packaging.setLabelCreatedCallback(function () { - setLocation("<?php $block->escapeUrl($block->getUrl('adminhtml/order_shipment/view', ['shipment_id' => $block->getShipment()->getId()])); ?>"); + setLocation("<?= $block->escapeUrl($block->getUrl('adminhtml/order_shipment/view', ['shipment_id' => $block->getShipment()->getId()])); ?>"); }); }; From f49f1f5592c9263e339bf42f2e842cc1fcfe63e6 Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Mon, 12 Aug 2019 11:48:59 -0500 Subject: [PATCH 0314/1172] MC-19061: Revert ticket MC-17003 --- .../Order/Creditmemo/Create/Adjustments.php | 16 ----- .../Order/Creditmemo/Create/Items.php | 17 +---- ...dminCheckingCreditMemoUpdateTotalsTest.xml | 3 + .../order/creditmemo/create/items.phtml | 3 - .../web/css/source/module/order/_total.less | 4 -- .../Adminhtml/Order/Creditmemo/Totals.php | 68 ------------------- .../Test/TestStep/CreateCreditMemoStep.php | 32 +-------- 7 files changed, 5 insertions(+), 138 deletions(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php index 1210391f70dd..50d29c195968 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Adjustments.php @@ -111,20 +111,4 @@ public function getShippingLabel() } return $label; } - - /** - * Get update totals url. - * - * @return string - */ - public function getUpdateTotalsUrl(): string - { - return $this->getUrl( - 'sales/*/updateQty', - [ - 'order_id' => $this->getSource()->getOrderId(), - 'invoice_id' => $this->getRequest()->getParam('invoice_id', null), - ] - ); - } } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php index 389c29bedf4c..65163f9ed5d8 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create/Items.php @@ -56,12 +56,7 @@ protected function _prepareLayout() $this->addChild( 'update_button', \Magento\Backend\Block\Widget\Button::class, - ['label' => __('Update Qty\'s'), 'class' => 'update-button secondary', 'onclick' => $onclick] - ); - $this->addChild( - 'update_totals_button', - \Magento\Backend\Block\Widget\Button::class, - ['label' => __('Update Totals'), 'class' => 'update-totals-button secondary', 'onclick' => $onclick] + ['label' => __('Update Qty\'s'), 'class' => 'update-button', 'onclick' => $onclick] ); if ($this->getCreditmemo()->canRefund()) { @@ -181,16 +176,6 @@ public function getUpdateButtonHtml() return $this->getChildHtml('update_button'); } - /** - * Get update totals button html - * - * @return string - */ - public function getUpdateTotalsButtonHtml(): string - { - return $this->getChildHtml('update_totals_button'); - } - /** * Get update url * diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml index 8cd2b8ee60ed..45ea09a06ed2 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCheckingCreditMemoUpdateTotalsTest.xml @@ -18,6 +18,9 @@ <testCaseId value="MC-18159"/> <useCaseId value="MC-17003"/> <group value="sales"/> + <skip> + <issueId value="MC-17003"/> + </skip> </annotations> <before> <!--Create product--> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index 31aefd8d2ca5..16ab1750efeb 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -100,7 +100,6 @@ <span class="title"><?= $block->escapeHtml(__('Refund Totals')) ?></span> </div> <?= $block->getChildHtml('creditmemo_totals') ?> - <div class="totals-actions"><?= $block->getUpdateTotalsButtonHtml() ?></div> <div class="order-totals-actions"> <div class="field choice admin__field admin__field-option field-append-comments"> <input id="notify_customer" @@ -140,8 +139,6 @@ require(['jquery'], function(jQuery){ //<![CDATA[ var submitButtons = jQuery('.submit-button'); -var updateButtons = jQuery('.update-button,.update-totals-button'); -var fields = jQuery('.qty-input,.order-subtotal-table input[type="text"]'); function enableButtons(buttons) { buttons.removeClass('disabled').prop('disabled', false); diff --git a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less index 6e663b15c89c..f2369ad8f35e 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less +++ b/app/design/adminhtml/Magento/backend/Magento_Sales/web/css/source/module/order/_total.less @@ -22,10 +22,6 @@ } } -.totals-actions { - text-align: right; -} - .order-totals-actions { margin-top: @indent__s; .actions { diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php index 28bb00757dac..d98c5696c81f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Creditmemo/Totals.php @@ -27,34 +27,6 @@ class Totals extends \Magento\Sales\Test\Block\Adminhtml\Order\Totals */ protected $capture = '[name="invoice[capture_case]"]'; - /** - * Refund Shipping css selector. - * - * @var string - */ - private $refundShippingSelector = '#shipping_amount'; - - /** - * Adjustment Refund css selector. - * - * @var string - */ - private $adjustmentRefundSelector = '#adjustment_positive'; - - /** - * Adjustment Fee css selector. - * - * @var string - */ - private $adjustmentFeeSelector = '#adjustment_negative'; - - /** - * Update Totals button css selector. - * - * @var string - */ - private $updateTotalsSelector = '.update-totals-button'; - /** * Submit invoice. * @@ -85,44 +57,4 @@ public function setCaptureOption($option) { $this->_rootElement->find($this->capture, Locator::SELECTOR_CSS, 'select')->setValue($option); } - - /** - * Get Refund Shipping input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getRefundShippingElement() - { - return $this->_rootElement->find($this->refundShippingSelector, Locator::SELECTOR_CSS); - } - - /** - * Get Adjustment Refund input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getAdjustmentRefundElement() - { - return $this->_rootElement->find($this->adjustmentRefundSelector, Locator::SELECTOR_CSS); - } - - /** - * Get Adjustment Fee input element. - * - * @return \Magento\Mtf\Client\ElementInterface - */ - public function getAdjustmentFeeElement() - { - return $this->_rootElement->find($this->adjustmentFeeSelector, Locator::SELECTOR_CSS); - } - - /** - * Click update totals button. - * - * @return void - */ - public function clickUpdateTotals() - { - $this->_rootElement->find($this->updateTotalsSelector)->click(); - } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php index 25b576a06dd3..45298c5898c2 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/CreateCreditMemoStep.php @@ -95,12 +95,8 @@ public function run() if ($this->compare($items, $refundData)) { $this->orderCreditMemoNew->getFormBlock()->updateQty(); } - $hasChangeTotals = $this->isTotalsDataChanged($refundData); - $this->orderCreditMemoNew->getFormBlock()->fillFormData($refundData); - if ($hasChangeTotals) { - $this->orderCreditMemoNew->getTotalsBlock()->clickUpdateTotals(); - } + $this->orderCreditMemoNew->getFormBlock()->fillFormData($refundData); $this->orderCreditMemoNew->getFormBlock()->submit(); } @@ -120,30 +116,4 @@ protected function getCreditMemoIds() $this->salesOrderView->getOrderForm()->openTab('creditmemos'); return $this->salesOrderView->getOrderForm()->getTab('creditmemos')->getGridBlock()->getIds(); } - - /** - * Is totals data changed. - * - * @param array $data - * @return bool - */ - private function isTotalsDataChanged(array $data): bool - { - $compareData = [ - 'shipping_amount' => - $this->orderCreditMemoNew->getTotalsBlock()->getRefundShippingElement()->getValue(), - 'adjustment_positive' => - $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentRefundElement()->getValue(), - 'adjustment_negative' => - $this->orderCreditMemoNew->getTotalsBlock()->getAdjustmentFeeElement()->getValue(), - ]; - - foreach ($compareData as $fieldName => $fieldValue) { - if (isset($data['form_data'][$fieldName]) && $fieldValue != $data['form_data'][$fieldName]) { - return true; - } - } - - return false; - } } From 09ec6714cc137b411d8facb3025164d94429e910 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Mon, 12 Aug 2019 14:08:56 -0500 Subject: [PATCH 0315/1172] MC-19115: Admin Analytics tracking should be enabled by default - Added caching in product metadata to improve performance --- .../Magento/Framework/App/ProductMetadata.php | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index c9fde94352a7..3683d7ecf61d 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -28,6 +28,11 @@ class ProductMetadata implements ProductMetadataInterface */ const PRODUCT_NAME = 'Magento'; + /** + * Magento version cache prefix + */ + const CACHE_PREFIX = 'mage-version'; + /** * Product version * @@ -47,11 +52,21 @@ class ProductMetadata implements ProductMetadataInterface private $composerInformation; /** + * @var CacheInterface + */ + private $cache; + + /** + * ProductMetadata constructor. * @param ComposerJsonFinder $composerJsonFinder + * @param \Magento\Framework\App\CacheInterface $cache */ - public function __construct(ComposerJsonFinder $composerJsonFinder) - { + public function __construct( + ComposerJsonFinder $composerJsonFinder, + CacheInterface $cache = null + ) { $this->composerJsonFinder = $composerJsonFinder; + $this->cache = $cache ?? ObjectManager::getInstance()->get(CacheInterface::class); } /** @@ -61,6 +76,8 @@ public function __construct(ComposerJsonFinder $composerJsonFinder) */ public function getVersion() { + $versionFromCache = $this->cache->load(self::CACHE_PREFIX); + $this->version = $this->version ?: $versionFromCache; if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { if ($this->getComposerInformation()->isMagentoRoot()) { @@ -68,6 +85,7 @@ public function getVersion() } else { $this->version = 'UNKNOWN'; } + $this->cache->save($this->version, self::CACHE_PREFIX, [Config::CACHE_TAG]); } } return $this->version; From f1b284b478356cb7b3a544049b35b8e3f5062eb5 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 12 Aug 2019 15:51:45 -0500 Subject: [PATCH 0316/1172] MC-18977: Revert change of ENGCOM-3260 - fix static failures --- app/code/Magento/Catalog/Block/Product/ProductList/Related.php | 1 + app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php | 1 + app/code/Magento/Catalog/Model/Product.php | 1 + app/code/Magento/Tax/Model/App/Action/ContextPlugin.php | 2 ++ 4 files changed, 5 insertions(+) diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php index 6de70bb97136..24811d61a771 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php @@ -141,6 +141,7 @@ public function getIdentities() { $identities = []; foreach ($this->getItems() as $item) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $identities = array_merge($identities, $item->getIdentities()); } return $identities; diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php index 24822447ae91..fa1beaf6e0ea 100644 --- a/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php +++ b/app/code/Magento/Catalog/Block/Product/ProductList/Upsell.php @@ -264,6 +264,7 @@ public function getIdentities() { $identities = []; foreach ($this->getItems() as $item) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $identities = array_merge($identities, $item->getIdentities()); } return $identities; diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php index fc3cc11cade5..2af54b8086a7 100644 --- a/app/code/Magento/Catalog/Model/Product.php +++ b/app/code/Magento/Catalog/Model/Product.php @@ -837,6 +837,7 @@ public function getStoreIds() } foreach ($websiteIds as $websiteId) { $websiteStores = $this->_storeManager->getWebsite($websiteId)->getStoreIds(); + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $storeIds = array_merge($storeIds, $websiteStores); } } diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index 4eb399544870..992f206279b2 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -52,6 +52,8 @@ class ContextPlugin * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig + * + * phpcs:ignore Magento2.Classes.DiscouragedDependencies */ public function __construct( \Magento\Customer\Model\Session $customerSession, From 1ab19302128366b99a6847af3133de23be2ad5c8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Mon, 12 Aug 2019 16:07:56 -0500 Subject: [PATCH 0317/1172] MC-19161: Revert ENGCOM-2983 --- .../Config/ConfigOptionsListConstants.php | 19 ---- .../Setup/Controller/DatabaseCheck.php | 36 +------- .../Magento/Setup/Model/ConfigGenerator.php | 14 +-- .../Magento/Setup/Model/ConfigOptionsList.php | 48 +--------- .../Model/ConfigOptionsList/DriverOptions.php | 72 --------------- setup/src/Magento/Setup/Model/Installer.php | 30 +------ .../Setup/Model/RequestDataConverter.php | 8 -- .../Test/Unit/Model/ConfigGeneratorTest.php | 12 --- .../Test/Unit/Model/ConfigOptionsListTest.php | 21 +---- .../Test/Unit/Module/ConfigGeneratorTest.php | 9 +- .../Validator/AdminCredentialsValidator.php | 15 +--- .../Magento/Setup/Validator/DbValidator.php | 22 ----- setup/view/magento/setup/add-database.phtml | 88 ------------------- 13 files changed, 11 insertions(+), 383 deletions(-) delete mode 100644 setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php diff --git a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php index ab32504baaa0..6bdb74ef7b89 100644 --- a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php +++ b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php @@ -21,7 +21,6 @@ class ConfigOptionsListConstants const CONFIG_PATH_CRYPT_KEY = 'crypt/key'; const CONFIG_PATH_SESSION_SAVE = 'session/save'; const CONFIG_PATH_RESOURCE_DEFAULT_SETUP = 'resource/default_setup/connection'; - const CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS = 'db/connection/default/driver_options'; const CONFIG_PATH_DB_CONNECTION_DEFAULT = 'db/connection/default'; const CONFIG_PATH_DB_CONNECTIONS = 'db/connection'; const CONFIG_PATH_DB_PREFIX = 'db/table_prefix'; @@ -65,10 +64,6 @@ class ConfigOptionsListConstants const INPUT_KEY_DB_MODEL = 'db-model'; const INPUT_KEY_DB_INIT_STATEMENTS = 'db-init-statements'; const INPUT_KEY_DB_ENGINE = 'db-engine'; - const INPUT_KEY_DB_SSL_KEY = 'db-ssl-key'; - const INPUT_KEY_DB_SSL_CERT = 'db-ssl-cert'; - const INPUT_KEY_DB_SSL_CA = 'db-ssl-ca'; - const INPUT_KEY_DB_SSL_VERIFY = 'db-ssl-verify'; const INPUT_KEY_RESOURCE = 'resource'; const INPUT_KEY_SKIP_DB_VALIDATION = 'skip-db-validation'; const INPUT_KEY_CACHE_HOSTS = 'http-cache-hosts'; @@ -109,20 +104,6 @@ class ConfigOptionsListConstants const KEY_MODEL = 'model'; const KEY_INIT_STATEMENTS = 'initStatements'; const KEY_ACTIVE = 'active'; - const KEY_DRIVER_OPTIONS = 'driver_options'; - /**#@-*/ - - /**#@+ - * Array keys for database driver options configurations - */ - const KEY_MYSQL_SSL_KEY = \PDO::MYSQL_ATTR_SSL_KEY; - const KEY_MYSQL_SSL_CERT = \PDO::MYSQL_ATTR_SSL_CERT; - const KEY_MYSQL_SSL_CA = \PDO::MYSQL_ATTR_SSL_CA; - /** - * Constant \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT cannot be used as it was introduced in PHP 7.1.4 - * and Magento 2 is currently supporting PHP 7.1.3. - */ - const KEY_MYSQL_SSL_VERIFY = 1014; /**#@-*/ /** diff --git a/setup/src/Magento/Setup/Controller/DatabaseCheck.php b/setup/src/Magento/Setup/Controller/DatabaseCheck.php index 4b88a8732d2c..4511abccaf09 100644 --- a/setup/src/Magento/Setup/Controller/DatabaseCheck.php +++ b/setup/src/Magento/Setup/Controller/DatabaseCheck.php @@ -5,7 +5,6 @@ */ namespace Magento\Setup\Controller; -use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Setup\Validator\DbValidator; use Zend\Json\Json; use Zend\Mvc\Controller\AbstractActionController; @@ -41,25 +40,7 @@ public function indexAction() try { $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY); $password = isset($params['password']) ? $params['password'] : ''; - $driverOptions = []; - if ($this->isDriverOptionsGiven($params)) { - if (empty($params['driverOptionsSslVerify'])) { - $params['driverOptionsSslVerify'] = 0; - } - $driverOptions = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => $params['driverOptionsSslKey'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => $params['driverOptionsSslCert'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => $params['driverOptionsSslCa'], - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => (int) $params['driverOptionsSslVerify'], - ]; - } - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( - $params['name'], - $params['host'], - $params['user'], - $password, - $driverOptions - ); + $this->dbValidator->checkDatabaseConnection($params['name'], $params['host'], $params['user'], $password); $tablePrefix = isset($params['tablePrefix']) ? $params['tablePrefix'] : ''; $this->dbValidator->checkDatabaseTablePrefix($tablePrefix); return new JsonModel(['success' => true]); @@ -67,19 +48,4 @@ public function indexAction() return new JsonModel(['success' => false, 'error' => $e->getMessage()]); } } - - /** - * Is Driver Options Given - * - * @param array $params - * @return bool - */ - private function isDriverOptionsGiven($params) - { - return !( - empty($params['driverOptionsSslKey']) || - empty($params['driverOptionsSslCert']) || - empty($params['driverOptionsSslCa']) - ); - } } diff --git a/setup/src/Magento/Setup/Model/ConfigGenerator.php b/setup/src/Magento/Setup/Model/ConfigGenerator.php index 88421797e59d..80a20ff2e80f 100644 --- a/setup/src/Magento/Setup/Model/ConfigGenerator.php +++ b/setup/src/Magento/Setup/Model/ConfigGenerator.php @@ -14,7 +14,6 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Framework\App\State; use Magento\Framework\Math\Random; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Creates deployment config data based on user input array @@ -63,11 +62,6 @@ class ConfigGenerator */ private $cryptKeyGenerator; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Constructor * @@ -75,20 +69,17 @@ class ConfigGenerator * @param DeploymentConfig $deploymentConfig * @param ConfigDataFactory|null $configDataFactory * @param CryptKeyGeneratorInterface|null $cryptKeyGenerator - * @param DriverOptions|null $driverOptions */ public function __construct( Random $random, DeploymentConfig $deploymentConfig, ConfigDataFactory $configDataFactory = null, - CryptKeyGeneratorInterface $cryptKeyGenerator = null, - DriverOptions $driverOptions = null + CryptKeyGeneratorInterface $cryptKeyGenerator = null ) { $this->random = $random; $this->deploymentConfig = $deploymentConfig; $this->configDataFactory = $configDataFactory ?? ObjectManager::getInstance()->get(ConfigDataFactory::class); $this->cryptKeyGenerator = $cryptKeyGenerator ?? ObjectManager::getInstance()->get(CryptKeyGenerator::class); - $this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class); } /** @@ -190,9 +181,6 @@ public function createDbConfig(array $data) $configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_ACTIVE, '1'); } - $driverOptions = $this->driverOptions->getDriverOptions($data); - $configData->set($dbConnectionPrefix . ConfigOptionsListConstants::KEY_DRIVER_OPTIONS, $driverOptions); - return $configData; } diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList.php b/setup/src/Magento/Setup/Model/ConfigOptionsList.php index 313e08d6c92c..4568c7040377 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList.php @@ -11,9 +11,7 @@ use Magento\Framework\Encryption\KeyValidator; use Magento\Framework\Setup\ConfigOptionsListInterface; use Magento\Framework\Setup\Option\FlagConfigOption; -use Magento\Framework\Setup\Option\SelectConfigOption; use Magento\Framework\Setup\Option\TextConfigOption; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; use Magento\Setup\Validator\DbValidator; /** @@ -55,24 +53,17 @@ class ConfigOptionsList implements ConfigOptionsListInterface \Magento\Setup\Model\ConfigOptionsList\Lock::class, ]; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Constructor * * @param ConfigGenerator $configGenerator * @param DbValidator $dbValidator * @param KeyValidator|null $encryptionKeyValidator - * @param DriverOptions|null $driverOptions */ public function __construct( ConfigGenerator $configGenerator, DbValidator $dbValidator, - KeyValidator $encryptionKeyValidator = null, - DriverOptions $driverOptions = null + KeyValidator $encryptionKeyValidator = null ) { $this->configGenerator = $configGenerator; $this->dbValidator = $dbValidator; @@ -81,7 +72,6 @@ public function __construct( $this->configOptionsCollection[] = $objectManager->get($className); } $this->encryptionKeyValidator = $encryptionKeyValidator ?: $objectManager->get(KeyValidator::class); - $this->driverOptions = $driverOptions ?? $objectManager->get(DriverOptions::class); } /** @@ -172,36 +162,6 @@ public function getOptions() ConfigOptionsListConstants::CONFIG_PATH_CACHE_HOSTS, 'http Cache hosts' ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY, - 'Full path of client key file in order to establish db connection through SSL', - null - ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT, - 'Full path of client certificate file in order to establish db connection through SSL', - null - ), - new TextConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA, - TextConfigOption::FRONTEND_WIZARD_TEXT, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_CA, - 'Full path of server certificate file in order to establish db connection through SSL', - null - ), - new FlagConfigOption( - ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY, - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . - '/' . ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY, - 'Verify server certification' - ), ]; foreach ($this->configOptionsCollection as $configOptionsList) { @@ -387,14 +347,12 @@ private function validateDbSettings(array $options, DeploymentConfig $deployment ) { try { $options = $this->getDbSettings($options, $deploymentConfig); - $driverOptions = $this->driverOptions->getDriverOptions($options); - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( + $this->dbValidator->checkDatabaseConnection( $options[ConfigOptionsListConstants::INPUT_KEY_DB_NAME], $options[ConfigOptionsListConstants::INPUT_KEY_DB_HOST], $options[ConfigOptionsListConstants::INPUT_KEY_DB_USER], - $options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD], - $driverOptions + $options[ConfigOptionsListConstants::INPUT_KEY_DB_PASSWORD] ); } catch (\Exception $exception) { $errors[] = $exception->getMessage(); diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php b/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php deleted file mode 100644 index 591089935491..000000000000 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList/DriverOptions.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Setup\Model\ConfigOptionsList; - -use Magento\Framework\Config\ConfigOptionsListConstants; - -/** - * MySql driver options - */ -class DriverOptions -{ - /** - * Get driver options. - * - * @param array $options - * @return array - */ - public function getDriverOptions(array $options): array - { - $driverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_KEY, - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CERT, - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_CA, - ]; - $booleanDriverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => ConfigOptionsListConstants::INPUT_KEY_DB_SSL_VERIFY, - ]; - $driverOptions = []; - foreach ($driverOptionKeys as $configKey => $driverOptionKey) { - if ($this->optionExists($options, $driverOptionKey)) { - $driverOptions[$configKey] = $options[$driverOptionKey]; - } - } - foreach ($booleanDriverOptionKeys as $configKey => $driverOptionKey) { - $driverOptions[$configKey] = $this->booleanValue($options, $driverOptionKey); - } - - return $driverOptions; - } - - /** - * Check if provided option exists. - * - * @param array $options - * @param string $driverOptionKey - * @return bool - */ - private function optionExists(array $options, string $driverOptionKey): bool - { - return isset($options[$driverOptionKey]) - && ($options[$driverOptionKey] === false || !empty($options[$driverOptionKey])); - } - - /** - * Transforms checkbox flag value into boolean. - * - * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#value - * - * @param array $options - * @param string $driverOptionKey - * @return bool - */ - private function booleanValue(array $options, string $driverOptionKey): bool - { - return isset($options[$driverOptionKey]) && (bool)$options[$driverOptionKey]; - } -} diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index f80a35937d5d..2510817c2e01 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -1371,32 +1371,7 @@ private function deleteDeploymentConfig() */ private function assertDbAccessible() { - $driverOptionKeys = [ - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_KEY, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_CERT, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_CA, - - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY => - ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT_DRIVER_OPTIONS . '/' . - ConfigOptionsListConstants::KEY_MYSQL_SSL_VERIFY - ]; - $driverOptions = []; - foreach ($driverOptionKeys as $driverOptionKey => $driverOptionConfig) { - $config = $this->deploymentConfig->get($driverOptionConfig); - if ($config !== null) { - $driverOptions[$driverOptionKey] = $config; - } - } - - $this->dbValidator->checkDatabaseConnectionWithDriverOptions( + $this->dbValidator->checkDatabaseConnection( $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_NAME @@ -1412,8 +1387,7 @@ private function assertDbAccessible() $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . '/' . ConfigOptionsListConstants::KEY_PASSWORD - ), - $driverOptions + ) ); $prefix = $this->deploymentConfig->get( ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTION_DEFAULT . diff --git a/setup/src/Magento/Setup/Model/RequestDataConverter.php b/setup/src/Magento/Setup/Model/RequestDataConverter.php index 4964dbe596d8..0ed5dc669c95 100644 --- a/setup/src/Magento/Setup/Model/RequestDataConverter.php +++ b/setup/src/Magento/Setup/Model/RequestDataConverter.php @@ -51,14 +51,6 @@ private function convertDeploymentConfigForm(array $source) isset($source['db']['tablePrefix']) ? $source['db']['tablePrefix'] : ''; $result[BackendConfigOptionsList::INPUT_KEY_BACKEND_FRONTNAME] = isset($source['config']['address']['admin']) ? $source['config']['address']['admin'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_KEY] = isset($source['db']['driverOptionsSslKey']) - ? $source['db']['driverOptionsSslKey'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CERT] = isset($source['db']['driverOptionsSslCert']) - ? $source['db']['driverOptionsSslCert'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_CA] = isset($source['db']['driverOptionsSslCa']) - ? $source['db']['driverOptionsSslCa'] : ''; - $result[SetupConfigOptionsList::INPUT_KEY_DB_SSL_VERIFY] = isset($source['db']['driverOptionsSslVerify']) - ? $source['db']['driverOptionsSslVerify'] : ''; $result[SetupConfigOptionsList::INPUT_KEY_ENCRYPTION_KEY] = isset($source['config']['encrypt']['key']) ? $source['config']['encrypt']['key'] : null; $result[SetupConfigOptionsList::INPUT_KEY_SESSION_SAVE] = isset($source['config']['sessionSave']['type']) diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php index 63a92bd4a198..a388c72fc834 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigGeneratorTest.php @@ -11,7 +11,6 @@ use Magento\Framework\Config\Data\ConfigData; use Magento\Framework\Config\Data\ConfigDataFactory; use Magento\Setup\Model\ConfigGenerator; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Test for Magento\Setup\Model\ConfigGenerator class. @@ -33,11 +32,6 @@ class ConfigGeneratorTest extends \PHPUnit\Framework\TestCase */ private $configDataMock; - /** - * @var DriverOptions - */ - private $driverOptionsMock; - public function setUp() { $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -59,17 +53,11 @@ public function setUp() $configDataFactoryMock->method('create') ->willReturn($this->configDataMock); - $this->driverOptionsMock = $this->getMockBuilder(DriverOptions::class) - ->disableOriginalConstructor() - ->setMethods(['getDriverOptions']) - ->getMock(); - $this->model = $objectManager->getObject( ConfigGenerator::class, [ 'deploymentConfig' => $this->deploymentConfigMock, 'configDataFactory' => $configDataFactoryMock, - 'driverOptions' => $this->driverOptionsMock, ] ); } diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php index 435f03f9de60..a3ade400fd36 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php @@ -37,29 +37,12 @@ class ConfigOptionsListTest extends \PHPUnit\Framework\TestCase */ private $dbValidator; - /** - * @var \Magento\Framework\Encryption\KeyValidator|\PHPUnit_Framework_MockObject_MockObject - */ - private $encryptionKeyValidator; - - /** - * @var ConfigOptionsList\DriverOptions - */ - private $driverOptionsMock; - protected function setUp() { $this->generator = $this->createMock(\Magento\Setup\Model\ConfigGenerator::class); $this->deploymentConfig = $this->createMock(\Magento\Framework\App\DeploymentConfig::class); $this->dbValidator = $this->createMock(\Magento\Setup\Validator\DbValidator::class); - $this->encryptionKeyValidator = $this->createMock(\Magento\Framework\Encryption\KeyValidator::class); - $this->driverOptionsMock = $this->createMock(ConfigOptionsList\DriverOptions::class); - $this->object = new ConfigOptionsList( - $this->generator, - $this->dbValidator, - $this->encryptionKeyValidator, - $this->driverOptionsMock - ); + $this->object = new ConfigOptionsList($this->generator, $this->dbValidator); } public function testGetOptions() @@ -181,7 +164,7 @@ private function prepareValidationMocks() $this->dbValidator->expects($this->once())->method('checkDatabaseTablePrefix')->willReturn($configDataMock); $this->dbValidator ->expects($this->once()) - ->method('checkDatabaseConnectionWithDriverOptions') + ->method('checkDatabaseConnection') ->willReturn($configDataMock); } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php index ea4261b27158..d4cdee4b84ba 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/ConfigGeneratorTest.php @@ -15,7 +15,6 @@ use Magento\Framework\Config\ConfigOptionsListConstants; use Magento\Setup\Model\CryptKeyGenerator; use PHPUnit\Framework\TestCase; -use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** * Test for Magento\Setup\Model\ConfigGenerator class. @@ -48,17 +47,11 @@ protected function setUp() $configDataFactoryMock = (new ObjectManager($this)) ->getObject(ConfigDataFactory::class, ['objectManager' => $objectManagerMock]); - $driverOptions = $this->getMockBuilder(DriverOptions::class) - ->disableOriginalConstructor() - ->setMethods(['getDriverOptions']) - ->getMock(); - $this->configGeneratorObject = new ConfigGenerator( $randomMock, $deployConfig, $configDataFactoryMock, - $cryptKeyGenerator, - $driverOptions + $cryptKeyGenerator ); } diff --git a/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php b/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php index 23e41df900d4..d8380bca54f7 100644 --- a/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php +++ b/setup/src/Magento/Setup/Validator/AdminCredentialsValidator.php @@ -5,10 +5,8 @@ */ namespace Magento\Setup\Validator; -use Magento\Framework\App\ObjectManager; use Magento\Framework\Config\ConfigOptionsListConstants as ConfigOption; use Magento\Setup\Model\AdminAccount; -use Magento\Setup\Model\Installer; use Magento\Setup\Model\ConfigOptionsList\DriverOptions; /** @@ -31,29 +29,21 @@ class AdminCredentialsValidator */ private $setupFactory; - /** - * @var DriverOptions - */ - private $driverOptions; - /** * Initialize dependencies. * * @param \Magento\Setup\Model\AdminAccountFactory $adminAccountFactory * @param \Magento\Setup\Module\ConnectionFactory $connectionFactory * @param \Magento\Setup\Module\SetupFactory $setupFactory - * @param DriverOptions|null $driverOptions */ public function __construct( \Magento\Setup\Model\AdminAccountFactory $adminAccountFactory, \Magento\Setup\Module\ConnectionFactory $connectionFactory, - \Magento\Setup\Module\SetupFactory $setupFactory, - DriverOptions $driverOptions = null + \Magento\Setup\Module\SetupFactory $setupFactory ) { $this->connectionFactory = $connectionFactory; $this->adminAccountFactory = $adminAccountFactory; $this->setupFactory = $setupFactory; - $this->driverOptions = $driverOptions ?? ObjectManager::getInstance()->get(DriverOptions::class); } /** @@ -65,8 +55,6 @@ public function __construct( */ public function validate(array $data) { - $driverOptions = $this->driverOptions->getDriverOptions($data); - $dbConnection = $this->connectionFactory->create( [ ConfigOption::KEY_NAME => $data[ConfigOption::INPUT_KEY_DB_NAME], @@ -74,7 +62,6 @@ public function validate(array $data) ConfigOption::KEY_USER => $data[ConfigOption::INPUT_KEY_DB_USER], ConfigOption::KEY_PASSWORD => $data[ConfigOption::INPUT_KEY_DB_PASSWORD], ConfigOption::KEY_PREFIX => $data[ConfigOption::INPUT_KEY_DB_PREFIX], - ConfigOption::KEY_DRIVER_OPTIONS => $driverOptions ] ); diff --git a/setup/src/Magento/Setup/Validator/DbValidator.php b/setup/src/Magento/Setup/Validator/DbValidator.php index 01ed537f887c..075e48140e15 100644 --- a/setup/src/Magento/Setup/Validator/DbValidator.php +++ b/setup/src/Magento/Setup/Validator/DbValidator.php @@ -78,27 +78,6 @@ public function checkDatabaseTablePrefix($prefix) */ public function checkDatabaseConnection($dbName, $dbHost, $dbUser, $dbPass = '') { - return $this->checkDatabaseConnectionWithDriverOptions($dbName, $dbHost, $dbUser, $dbPass, []); - } - - /** - * Checks Database Connection with Driver Options - * - * @param string $dbName - * @param string $dbHost - * @param string $dbUser - * @param string $dbPass - * @param array $driverOptions - * @return bool - * @throws \Magento\Setup\Exception - */ - public function checkDatabaseConnectionWithDriverOptions( - $dbName, - $dbHost, - $dbUser, - $dbPass = '', - $driverOptions = [] - ) { // establish connection to information_schema view to retrieve information about user and table privileges $connection = $this->connectionFactory->create( [ @@ -107,7 +86,6 @@ public function checkDatabaseConnectionWithDriverOptions( ConfigOptionsListConstants::KEY_USER => $dbUser, ConfigOptionsListConstants::KEY_PASSWORD => $dbPass, ConfigOptionsListConstants::KEY_ACTIVE => true, - ConfigOptionsListConstants::KEY_DRIVER_OPTIONS => $driverOptions, ] ); diff --git a/setup/view/magento/setup/add-database.phtml b/setup/view/magento/setup/add-database.phtml index c858d92cfef5..f36024c11282 100644 --- a/setup/view/magento/setup/add-database.phtml +++ b/setup/view/magento/setup/add-database.phtml @@ -475,94 +475,6 @@ */ ?> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslKey"> - Driver Options - SSL Key - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslKey" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains X509 key" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslKey" - ng-model="db.driverOptionsSslKey" - placeholder="/path/to/client-key.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslCert"> - Driver Options - SSL Certificate - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslCert" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains X509 certificate" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslCert" - ng-model="db.driverOptionsSslCert" - placeholder="/path/to/client-cert.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label" for="dbDriverOptionsSslCa"> - Driver Options - SSL Certificate Authorities - </label> - </div> - <div class="col-m-4"> - <input - id="dbDriverOptionsSslCa" - class="form-el-input" - tooltip-placement="right" - tooltip="File that contains list of trusted SSL Certificate Authorities" - tooltip-trigger="focus" - tooltip-append-to-body="true" - type="text" - name="dbDriverOptionsSslCa" - ng-model="db.driverOptionsSslCa" - placeholder="/path/to/ca.pem" - > - </div> -</div> - -<div class="row form-row"> - <div class="col-m-3"> - <label class="form-label"> - Driver Options - SSL Verification - </label> - </div> - <div class="col-m-4"> - <div class="form-row"> - <input - id="dbDriverOptionsSslVerify" - class="form-el-checkbox" - type="checkbox" - ng-model="db.driverOptionsSslVerify" - ng-checked="db.driverOptionsSslVerify" - > - <label class="form-label" for="dbDriverOptionsSslVerify"> - Perform verification against the server CA certificate and against the server host name in its certificate - </label> - </div> - </div> -</div> </fieldset> </form> From ee52bbe016d6afe072761ef18d5110c7513c26ce Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 09:50:11 +0300 Subject: [PATCH 0318/1172] MC-19084: Browser console error after applying gift card account during checkout --- .../Checkout/view/frontend/web/js/sidebar.js | 3 +- .../Ui/view/frontend/web/js/view/messages.js | 3 +- .../css/source/module/checkout/_checkout.less | 39 ++++++++++--------- lib/web/jquery/ui-modules/effect-fade.js | 3 -- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js index e67b04e6104c..472f7588d5b6 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js @@ -13,7 +13,8 @@ define([ 'jquery-ui-modules/widget', 'mage/decorate', 'mage/collapsible', - 'mage/cookies' + 'mage/cookies', + 'jquery-ui-modules/effect-fade' ], function ($, authenticationPopup, customerData, alert, confirm, _) { 'use strict'; diff --git a/app/code/Magento/Ui/view/frontend/web/js/view/messages.js b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js index 57a590c87179..b2fb3f216199 100644 --- a/app/code/Magento/Ui/view/frontend/web/js/view/messages.js +++ b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js @@ -10,7 +10,8 @@ define([ 'ko', 'jquery', 'uiComponent', - '../model/messageList' + '../model/messageList', + 'jquery-ui-modules/effect-blind' ], function (ko, $, Component, globalMessages) { 'use strict'; diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less index a2daf0da247d..ce3f45c990b9 100644 --- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less +++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less @@ -78,27 +78,28 @@ } .abs-discount-code { - .actions-toolbar { - display: table-cell; - vertical-align: top; - width: 1%; - - .primary { - float: left; - .action { - &:extend(.abs-revert-to-action-secondary all); - border-bottom-left-radius: 0; - border-top-left-radius: 0; - margin: 0 0 0 -2px; - white-space: nowrap; - width: auto; - } - } - } - .form-discount { + .form-discount { display: table; width: 100%; - + + .actions-toolbar { + display: table-cell; + vertical-align: top; + width: 1%; + + .primary { + float: left; + .action { + &:extend(.abs-revert-to-action-secondary all); + border-bottom-left-radius: 0; + border-top-left-radius: 0; + margin: 0 0 0 -2px; + white-space: nowrap; + width: auto; + } + } + } + > .field { > .label { display: none; diff --git a/lib/web/jquery/ui-modules/effect-fade.js b/lib/web/jquery/ui-modules/effect-fade.js index ba289cbeb018..46db40fc8a42 100644 --- a/lib/web/jquery/ui-modules/effect-fade.js +++ b/lib/web/jquery/ui-modules/effect-fade.js @@ -7,9 +7,6 @@ * http://jquery.org/license * * http://api.jqueryui.com/fade-effect/ - * - * Depends: - * jquery.ui.effect.js */ define([ From c5574b8eb9c7f30f59a5e58d85462deb71279e2a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 10:20:42 +0300 Subject: [PATCH 0319/1172] MC-19075: Html text are visible on frontend --- .../Checkout/view/frontend/templates/onepage/review/item.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml index 8e83526b4cea..b3b94cfae18d 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/review/item.phtml @@ -28,7 +28,7 @@ $taxDataHelper = $this->helper(Magento\Tax\Helper\Data::class); <dt><?= $block->escapeHtml($_option['label']) ?></dt> <dd> <?php if (isset($_formatedOptionValue['full_view'])) :?> - <?= $block->escapeHtml($_formatedOptionValue['full_view']) ?> + <?= /* @noEscape */ $_formatedOptionValue['full_view'] ?> <?php else :?> <?= /* @noEscape */ $_formatedOptionValue['value'] ?> <?php endif; ?> From 76b668bc8a5b0a83bb3414660eaa793d969cf8ff Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 13 Aug 2019 12:04:13 +0300 Subject: [PATCH 0320/1172] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../web/js/action/select-payment-method.js | 9 +- .../set-payment-information-extended.js | 25 +++++- .../set-payment-information-extended.test.js | 86 +++++++++++++++++++ 3 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js index 6bda10fceb7b..34f170074979 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js @@ -12,10 +12,11 @@ define([ 'use strict'; return function (paymentMethod) { - paymentMethod.__disableTmpl = { - title: true - }; - + if (paymentMethod) { + paymentMethod.__disableTmpl = { + title: true + }; + } quote.paymentMethod(paymentMethod); }; }); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js index 263d5747f284..9de8a93905c9 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information-extended.js @@ -13,16 +13,33 @@ define([ 'Magento_Checkout/js/model/error-processor', 'Magento_Customer/js/model/customer', 'Magento_Checkout/js/action/get-totals', - 'Magento_Checkout/js/model/full-screen-loader' -], function (quote, urlBuilder, storage, errorProcessor, customer, getTotalsAction, fullScreenLoader) { + 'Magento_Checkout/js/model/full-screen-loader', + 'underscore' +], function (quote, urlBuilder, storage, errorProcessor, customer, getTotalsAction, fullScreenLoader, _) { 'use strict'; + /** + * Filter template data. + * + * @param {Object|Array} data + */ + var filterTemplateData = function (data) { + return _.each(data, function (value, key, list) { + if (_.isArray(value) || _.isObject(value)) { + list[key] = filterTemplateData(value); + } + + if (key === '__disableTmpl') { + delete list[key]; + } + }); + }; + return function (messageContainer, paymentData, skipBilling) { var serviceUrl, payload; - delete paymentData.__disableTmpl; - + paymentData = filterTemplateData(paymentData); skipBilling = skipBilling || false; payload = { cartId: quote.getQuoteId(), diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js new file mode 100644 index 000000000000..d928ee9f995d --- /dev/null +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js @@ -0,0 +1,86 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'squire', + 'jquery' +], function (Squire, $) { + 'use strict'; + + var injector = new Squire(), + setPaymentInformation, + serviceUrl = 'http://url', + mocks = { + 'Magento_Checkout/js/model/quote': { + getQuoteId: jasmine.createSpy().and.returnValue(1), + billingAddress: jasmine.createSpy().and.returnValue(null) + }, + 'Magento_Checkout/js/model/url-builder': { + createUrl: jasmine.createSpy().and.returnValue(serviceUrl) + }, + 'mage/storage': { + post: function () {} // jscs:ignore jsDoc + }, + 'Magento_Customer/js/model/customer': { + isLoggedIn: jasmine.createSpy().and.returnValue(false) + }, + 'Magento_Checkout/js/model/full-screen-loader': { + startLoader: jasmine.createSpy(), + stopLoader: jasmine.createSpy() + }, + 'Magento_Checkout/js/action/get-totals': jasmine.createSpy('getTotalsAction'), + 'Magento_Checkout/js/model/error-processor': jasmine.createSpy('errorProcessor') + }; + + beforeEach(function (done) { + injector.mock(mocks); + injector.require( + ['Magento_Checkout/js/action/set-payment-information-extended'], + function (action) { + setPaymentInformation = action; + done(); + }); + }); + + afterEach(function () { + try { + injector.clean(); + injector.remove(); + } catch (e) { + } + }); + + describe('Magento/Checkout/js/action/set-payment-information-extended', function () { + it('Checks that paymentData consist correct data value.', function () { + var messageContainer = jasmine.createSpy('messageContainer'), + deferral = new $.Deferred(), + paymentData = { + method: 'checkmo', + additionalData: null, + __disableTmpl: { + title: true + } + }, + formattedData = { + method: 'checkmo', + additionalData: null + }, + payload = { + cartId: 1, + paymentMethod: formattedData, + billingAddress: null + }; + + spyOn(mocks['mage/storage'], 'post').and.callFake(function () { + return deferral.resolve({}); + }); + + setPaymentInformation(messageContainer, paymentData, false); + expect(mocks['Magento_Checkout/js/model/full-screen-loader'].startLoader).toHaveBeenCalled(); + expect(mocks['mage/storage'].post).toHaveBeenCalledWith(serviceUrl, JSON.stringify(payload)); + expect(mocks['Magento_Checkout/js/model/full-screen-loader'].stopLoader).toHaveBeenCalled(); + }); + }); +}); From 30c3db8364c85f4e39680a1f63717d8b28709a04 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 12:26:00 +0300 Subject: [PATCH 0321/1172] MC-19014: QueueManagementTest caused flakiness during nightly build Integration test runs --- .../Magento/MysqlMq/Model/ResourceModel/Queue.php | 2 +- .../Test/Unit/Model/ResourceModel/QueueTest.php | 2 +- .../Magento/MysqlMq/Model/QueueManagementTest.php | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php b/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php index d50ed851b64a..2a45eafc63f2 100644 --- a/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php +++ b/app/code/Magento/MysqlMq/Model/ResourceModel/Queue.php @@ -151,7 +151,7 @@ public function getMessages($queueName, $limit = null) 'queue_message_status.status IN (?)', [QueueManagement::MESSAGE_STATUS_NEW, QueueManagement::MESSAGE_STATUS_RETRY_REQUIRED] )->where('queue.name = ?', $queueName) - ->order('queue_message_status.updated_at ASC'); + ->order(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC']); if ($limit) { $select->limit($limit); diff --git a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php index d3fe09a71294..c8669809b3aa 100644 --- a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php +++ b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php @@ -206,7 +206,7 @@ public function testGetMessages() ] )->willReturnSelf(); $select->expects($this->once()) - ->method('order')->with('queue_message_status.updated_at ASC')->willReturnSelf(); + ->method('order')->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC'])->willReturnSelf(); $select->expects($this->once())->method('limit')->with($limit)->willReturnSelf(); $connection->expects($this->once())->method('fetchAll')->with($select)->willReturn($messages); $this->assertEquals($messages, $this->queue->getMessages($queueName, $limit)); diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index 56dd77d3da17..8fbbe800d673 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -91,13 +91,17 @@ public function testAllFlows() $messages = $this->queueManagement->readMessages('queue2', 1); $message = array_shift($messages); $messageRelationId = $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]; + $this->queueManagement->pushToQueueForRetry($messageRelationId); - for ($i = 0; $i < 2; $i++) { - $this->assertEquals($i, $message[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); - $this->queueManagement->pushToQueueForRetry($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); + $retryMessage = null; + for ($i = 1; $i <= 3; $i++) { $messages = $this->queueManagement->readMessages('queue2', 1); $message = array_shift($messages); - $this->assertEquals($messageRelationId, $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); + if ($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID] == $messageRelationId) { + $retryMessage = $message; + } } + $this->assertNotNull($retryMessage, 'Made retry message not found in queue'); + $this->assertEquals(1, $retryMessage[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); } } From 7c240d94881c76838141dcfb91fe2f6b2208928f Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 13 Aug 2019 13:58:07 +0300 Subject: [PATCH 0322/1172] MC-19023: PayPal Express Checkout Payflow Edition don't work (Internal Error) --- .../js/action/set-payment-information-extended.test.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js index d928ee9f995d..66f7731415c0 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Checkout/frontend/js/action/set-payment-information-extended.test.js @@ -63,13 +63,12 @@ define([ title: true } }, - formattedData = { - method: 'checkmo', - additionalData: null - }, payload = { cartId: 1, - paymentMethod: formattedData, + paymentMethod: { + method: 'checkmo', + additionalData: null + }, billingAddress: null }; From 9092e5e22c736aca6dff5e0943c214e293ec1c66 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Tue, 13 Aug 2019 14:14:38 +0300 Subject: [PATCH 0323/1172] MC-19014: QueueManagementTest caused flakiness during nightly build Integration test runs --- .../MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php index c8669809b3aa..e3c6e6d9aee2 100644 --- a/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php +++ b/app/code/Magento/MysqlMq/Test/Unit/Model/ResourceModel/QueueTest.php @@ -206,7 +206,9 @@ public function testGetMessages() ] )->willReturnSelf(); $select->expects($this->once()) - ->method('order')->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC'])->willReturnSelf(); + ->method('order') + ->with(['queue_message_status.updated_at ASC', 'queue_message_status.id ASC']) + ->willReturnSelf(); $select->expects($this->once())->method('limit')->with($limit)->willReturnSelf(); $connection->expects($this->once())->method('fetchAll')->with($select)->willReturn($messages); $this->assertEquals($messages, $this->queue->getMessages($queueName, $limit)); From 8e3edf17c1e352bbf6320e68c06c9a0a402e2e9e Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 15:31:19 +0300 Subject: [PATCH 0324/1172] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index d52e70ef56a1..5ef6b1802b0a 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -297,7 +297,7 @@ private function _fillBackgroundColor(&$imageResourceTo) return $transparentColor; } } catch (\Exception $e) { - throw new \DomainException('Failed to fill image.'); + // fallback to default background color } } list($r, $g, $b) = $this->_backgroundColor; From fe432468b13d1f85c301b60ea890abb4bead5c34 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Tue, 13 Aug 2019 08:13:58 -0500 Subject: [PATCH 0325/1172] MC-18977: Revert change of ENGCOM-3260 - fix static failures --- app/code/Magento/Tax/Model/App/Action/ContextPlugin.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php index 992f206279b2..913fa4c46f0a 100644 --- a/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php +++ b/app/code/Magento/Tax/Model/App/Action/ContextPlugin.php @@ -52,13 +52,11 @@ class ContextPlugin * @param \Magento\Tax\Helper\Data $taxHelper * @param \Magento\Framework\Module\Manager $moduleManager * @param \Magento\PageCache\Model\Config $cacheConfig - * - * phpcs:ignore Magento2.Classes.DiscouragedDependencies */ public function __construct( \Magento\Customer\Model\Session $customerSession, \Magento\Framework\App\Http\Context $httpContext, - \Magento\Tax\Model\Calculation\Proxy $calculation, + \Magento\Tax\Model\Calculation\Proxy $calculation, //phpcs:ignore Magento2.Classes.DiscouragedDependencies \Magento\Tax\Helper\Data $taxHelper, \Magento\Framework\Module\Manager $moduleManager, \Magento\PageCache\Model\Config $cacheConfig From 2c5fd23470c42e9c92e643bc9025cdc6de0e1a56 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 13 Aug 2019 17:00:43 +0300 Subject: [PATCH 0326/1172] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index 5ef6b1802b0a..f8cad0e8821e 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -296,6 +296,7 @@ private function _fillBackgroundColor(&$imageResourceTo) imagecolortransparent($imageResourceTo, $transparentColor); return $transparentColor; } + // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\Exception $e) { // fallback to default background color } From bc97aedd25622f040ccba347b5dfc3efdacc3827 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Tue, 13 Aug 2019 17:51:54 +0300 Subject: [PATCH 0327/1172] MC-19080: Incorrect behavior after shipping methods disabled --- app/code/Magento/Shipping/Model/Shipping.php | 26 +++-- .../Shipping/Test/Unit/Model/ShippingTest.php | 33 ++++++- .../Magento/Shipping/Model/ShippingTest.php | 99 ++++++++++++++----- 3 files changed, 125 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php index 5470f9a96775..77e6f3c5219f 100644 --- a/app/code/Magento/Shipping/Model/Shipping.php +++ b/app/code/Magento/Shipping/Model/Shipping.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Model; use Magento\Framework\App\ObjectManager; @@ -272,7 +273,9 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req */ private function prepareCarrier(string $carrierCode, RateRequest $request): AbstractCarrier { - $carrier = $this->_carrierFactory->create($carrierCode, $request->getStoreId()); + $carrier = $this->isActive($carrierCode) + ? $this->_carrierFactory->create($carrierCode, $request->getStoreId()) + : null; if (!$carrier) { throw new \RuntimeException('Failed to initialize carrier'); } @@ -425,13 +428,10 @@ public function composePackagesForCarrier($carrier, $request) if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems = array_merge( - $fullItems, - array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']) - ); + $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems = array_merge($fullItems, array_fill(0, $qty, $itemWeight)); + $fullItems[] = array_fill(0, $qty, $itemWeight); } } sort($fullItems); @@ -532,4 +532,18 @@ public function setCarrierAvailabilityConfigField($code = 'active') $this->_availabilityConfigField = $code; return $this; } + + /** + * Checks availability of carrier. + * + * @param string $carrierCode + * @return bool|null + */ + private function isActive(string $carrierCode) + { + return $this->_scopeConfig->isSetFlag( + 'carriers/' . $carrierCode . '/' . $this->_availabilityConfigField, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + } } diff --git a/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php b/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php index 1df41aeba076..e5723c38ac56 100644 --- a/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Model/ShippingTest.php @@ -3,12 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Test\Unit\Model; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Type as ProductType; use Magento\CatalogInventory\Model\Stock\Item as StockItem; use Magento\CatalogInventory\Model\StockRegistry; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Quote\Model\Quote\Item as QuoteItem; use Magento\Shipping\Model\Carrier\AbstractCarrierInterface; use Magento\Shipping\Model\CarrierFactory; @@ -19,12 +21,14 @@ use PHPUnit_Framework_MockObject_MockObject as MockObject; /** - * @see Shipping + * Unit tests for \Magento\Shipping\Model\Shipping class. + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ShippingTest extends \PHPUnit\Framework\TestCase { /** - * Test identification number of product + * Test identification number of product. * * @var int */ @@ -50,22 +54,34 @@ class ShippingTest extends \PHPUnit\Framework\TestCase */ private $carrier; + /** + * @var ScopeConfigInterface|MockObject + */ + private $scopeConfig; + + /** + * @inheritdoc + */ protected function setUp() { $this->stockRegistry = $this->createMock(StockRegistry::class); $this->stockItemData = $this->createMock(StockItem::class); + $this->scopeConfig = $this->createMock(ScopeConfigInterface::class); $this->shipping = (new ObjectManagerHelper($this))->getObject( Shipping::class, [ 'stockRegistry' => $this->stockRegistry, 'carrierFactory' => $this->getCarrierFactory(), + 'scopeConfig' => $this->scopeConfig, ] ); } /** + * Compose Packages For Carrier. * + * @return void */ public function testComposePackages() { @@ -125,14 +141,25 @@ function ($key) { /** * Active flag should be set before collecting carrier rates. + * + * @return void */ public function testCollectCarrierRatesSetActiveFlag() { + $carrierCode = 'carrier'; + $scopeStore = 'store'; + $this->scopeConfig->expects($this->once()) + ->method('isSetFlag') + ->with( + 'carriers/' . $carrierCode . '/active', + $scopeStore + ) + ->willReturn(true); $this->carrier->expects($this->atLeastOnce()) ->method('setActiveFlag') ->with('active'); - $this->shipping->collectCarrierRates('carrier', new RateRequest()); + $this->shipping->collectCarrierRates($carrierCode, new RateRequest()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php index 760b24db5ef3..8c5dfb0d0ff5 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php @@ -3,16 +3,19 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Shipping\Model; use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Quote\Model\Quote\Address\RateResult\Method; use Magento\Shipping\Model\Rate\Result; use Magento\TestFramework\Helper\Bootstrap; /** - * Contains list of tests for Shipping model + * Contains list of tests for Shipping model. + * @magentoAppIsolation enabled */ class ShippingTest extends \PHPUnit\Framework\TestCase { @@ -42,22 +45,8 @@ protected function setUp() */ public function testCollectRatesByAddress() { - $address = $this->objectManager->create(DataObject::class, [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1 - ] - ]); /** @var Shipping $result */ - $result = $this->model->collectRatesByAddress($address, 'flatrate'); + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); static::assertInstanceOf(Shipping::class, $result); return $result->getResult(); @@ -68,19 +57,81 @@ public function testCollectRatesByAddress() * @covers \Magento\Shipping\Model\Shipping::collectRatesByAddress * @param Result $result * @depends testCollectRatesByAddress - * @magentoConfigFixture carriers/flatrate/active 1 - * @magentoConfigFixture carriers/flatrate/price 5.00 */ public function testCollectRates(Result $result) { - $rates = $result->getAllRates(); - static::assertNotEmpty($rates); - - /** @var Method $rate */ - $rate = array_pop($rates); - + $rate = $this->getRate($result); static::assertInstanceOf(Method::class, $rate); static::assertEquals('flatrate', $rate->getData('carrier')); static::assertEquals(5, $rate->getData('price')); } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 1 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testShippingMethodIsActiveAndNotApplicable() + { + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $rate = $this->getRate($result->getResult()); + + static::assertEquals('flatrate', $rate->getData('carrier')); + static::assertEquals( + 'This shipping method is not available. To use this shipping method, please contact us.', + $rate->getData('error_message') + ); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 0 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testShippingMethodIsNotActiveAndNotApplicable() + { + $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } } From eb6d625269699de731b2be64098f83cab6a045ab Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Tue, 13 Aug 2019 09:58:25 -0500 Subject: [PATCH 0328/1172] MC-19061: Revert ticket MC-17003 --- .../adminhtml/templates/order/creditmemo/create/items.phtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml index 16ab1750efeb..22e648e2b5bd 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/creditmemo/create/items.phtml @@ -139,7 +139,8 @@ require(['jquery'], function(jQuery){ //<![CDATA[ var submitButtons = jQuery('.submit-button'); - +var updateButtons = jQuery('.update-button'); +var fields = jQuery('.qty-input'); function enableButtons(buttons) { buttons.removeClass('disabled').prop('disabled', false); } From a098f4fe398be310a46f4cc106efc951b64cc8e8 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 13 Aug 2019 11:13:06 -0500 Subject: [PATCH 0329/1172] MC-19115: Admin Analytics tracking should be enabled by default - static fix --- lib/internal/Magento/Framework/App/ProductMetadata.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/ProductMetadata.php b/lib/internal/Magento/Framework/App/ProductMetadata.php index 3683d7ecf61d..583638826e76 100644 --- a/lib/internal/Magento/Framework/App/ProductMetadata.php +++ b/lib/internal/Magento/Framework/App/ProductMetadata.php @@ -14,6 +14,7 @@ /** * Class ProductMetadata + * * @package Magento\Framework\App */ class ProductMetadata implements ProductMetadataInterface @@ -29,9 +30,9 @@ class ProductMetadata implements ProductMetadataInterface const PRODUCT_NAME = 'Magento'; /** - * Magento version cache prefix + * Magento version cache key */ - const CACHE_PREFIX = 'mage-version'; + const VERSION_CACHE_KEY = 'mage-version'; /** * Product version @@ -76,7 +77,7 @@ public function __construct( */ public function getVersion() { - $versionFromCache = $this->cache->load(self::CACHE_PREFIX); + $versionFromCache = $this->cache->load(self::VERSION_CACHE_KEY); $this->version = $this->version ?: $versionFromCache; if (!$this->version) { if (!($this->version = $this->getSystemPackageVersion())) { @@ -85,7 +86,7 @@ public function getVersion() } else { $this->version = 'UNKNOWN'; } - $this->cache->save($this->version, self::CACHE_PREFIX, [Config::CACHE_TAG]); + $this->cache->save($this->version, self::VERSION_CACHE_KEY, [Config::CACHE_TAG]); } } return $this->version; From 6d7e1f714c455764255f654a1b88707a0243e1d8 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Tue, 13 Aug 2019 11:51:58 -0500 Subject: [PATCH 0330/1172] MC-19161: Revert ENGCOM-2983 --- setup/src/Magento/Setup/Model/ConfigOptionsList.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup/src/Magento/Setup/Model/ConfigOptionsList.php b/setup/src/Magento/Setup/Model/ConfigOptionsList.php index 4568c7040377..c080b3c7fc6a 100644 --- a/setup/src/Magento/Setup/Model/ConfigOptionsList.php +++ b/setup/src/Magento/Setup/Model/ConfigOptionsList.php @@ -165,6 +165,7 @@ public function getOptions() ]; foreach ($this->configOptionsCollection as $configOptionsList) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $options = array_merge($options, $configOptionsList->getOptions()); } @@ -221,6 +222,7 @@ public function validate(array $options, DeploymentConfig $deploymentConfig) } foreach ($this->configOptionsCollection as $configOptionsList) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $errors = array_merge($errors, $configOptionsList->validate($options, $deploymentConfig)); } From 7d3042fae6bfa3b8f7eb2afa6cd23407b0e44353 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Tue, 13 Aug 2019 14:23:40 -0500 Subject: [PATCH 0331/1172] MC-19061: Revert ticket MC-17003 Skip MFTF test --- .../Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml index a667f40ad327..afe70243f602 100644 --- a/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml +++ b/app/code/Magento/Theme/Test/Mftf/Test/AdminWatermarkUploadTest.xml @@ -16,6 +16,9 @@ <description value="Watermark images should be able to be uploaded in the admin"/> <severity value="MAJOR"/> <testCaseId value="MC-5796"/> + <skip> + <issueId value="MC-18496"/> + </skip> <group value="Watermark"/> </annotations> <before> From e913ce88010bbee69909e2d3e9cdf28816971eb8 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 14 Aug 2019 15:03:02 +0300 Subject: [PATCH 0332/1172] MC-19218: Catalog Event created with incorrect start and end dates - revert #22463 --- .../Magento/Framework/Stdlib/DateTime/Timezone.php | 3 +-- .../Stdlib/Test/Unit/DateTime/TimezoneTest.php | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php index 45c31d367b34..5b028eda4c71 100644 --- a/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php +++ b/lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php @@ -196,8 +196,7 @@ public function date($date = null, $locale = null, $useTimezone = true, $include public function scopeDate($scope = null, $date = null, $includeTime = false) { $timezone = $this->_scopeConfig->getValue($this->getDefaultTimezonePath(), $this->_scopeType, $scope); - $date = new \DateTime(is_numeric($date) ? '@' . $date : $date); - $date->setTimezone(new \DateTimeZone($timezone)); + $date = new \DateTime(is_numeric($date) ? '@' . $date : $date, new \DateTimeZone($timezone)); if (!$includeTime) { $date->setTime(0, 0, 0); } diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php index 3d7d14a39462..d57525590b9e 100644 --- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php +++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/DateTime/TimezoneTest.php @@ -253,15 +253,4 @@ private function scopeConfigWillReturnConfiguredTimezone($configuredTimezone) { $this->scopeConfig->method('getValue')->with('', '', null)->willReturn($configuredTimezone); } - - public function testCheckIfScopeDateSetsTimeZone() - { - $scopeDate = new \DateTime('now', new \DateTimeZone('America/Vancouver')); - $this->scopeConfig->method('getValue')->willReturn('America/Vancouver'); - - $this->assertEquals( - $scopeDate->getTimezone(), - $this->getTimezone()->scopeDate(0, $scopeDate->getTimestamp())->getTimezone() - ); - } } From ccc5074fba3d60f132908d6bf7ad2fefad0280dc Mon Sep 17 00:00:00 2001 From: Stas Kozar <stas.kozar@transoftgroup.com> Date: Wed, 14 Aug 2019 15:07:06 +0300 Subject: [PATCH 0333/1172] MC-19078: Product is missing from shopping cart after payment cancellation --- .../CheckExpirePersistentQuoteObserver.php | 34 +++++++++++++++++-- ...CheckExpirePersistentQuoteObserverTest.php | 18 +++++++++- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php index 1261a90b5843..862ac561433e 100644 --- a/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php +++ b/app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php @@ -6,6 +6,9 @@ namespace Magento\Persistent\Observer; use Magento\Framework\Event\ObserverInterface; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote; /** @@ -74,6 +77,11 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface */ private $quote; + /** + * @var CartRepositoryInterface + */ + private $quoteRepository; + /** * @param \Magento\Persistent\Helper\Session $persistentSession * @param \Magento\Persistent\Helper\Data $persistentData @@ -82,6 +90,7 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Checkout\Model\Session $checkoutSession * @param \Magento\Framework\App\RequestInterface $request + * @param CartRepositoryInterface $quoteRepository */ public function __construct( \Magento\Persistent\Helper\Session $persistentSession, @@ -90,7 +99,8 @@ public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Customer\Model\Session $customerSession, \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Framework\App\RequestInterface $request + \Magento\Framework\App\RequestInterface $request, + CartRepositoryInterface $quoteRepository ) { $this->_persistentSession = $persistentSession; $this->quoteManager = $quoteManager; @@ -99,6 +109,7 @@ public function __construct( $this->_eventManager = $eventManager; $this->_persistentData = $persistentData; $this->request = $request; + $this->quoteRepository = $quoteRepository; } /** @@ -146,9 +157,11 @@ public function execute(\Magento\Framework\Event\Observer $observer) */ private function isPersistentQuoteOutdated(): bool { - if ((!$this->_persistentData->isEnabled() || !$this->_persistentData->isShoppingCartPersist()) + if (!($this->_persistentData->isEnabled() && $this->_persistentData->isShoppingCartPersist()) && !$this->_customerSession->isLoggedIn() - && $this->_checkoutSession->getQuoteId()) { + && $this->_checkoutSession->getQuoteId() + && $this->isActiveQuote() + ) { return (bool)$this->getQuote()->getIsPersistent(); } return false; @@ -181,6 +194,21 @@ private function getQuote(): Quote return $this->quote; } + /** + * Check if quote is active. + * + * @return bool + */ + private function isActiveQuote(): bool + { + try { + $this->quoteRepository->getActive($this->_checkoutSession->getQuoteId()); + return true; + } catch (NoSuchEntityException $e) { + return false; + } + } + /** * Check current request is coming from onepage checkout page. * diff --git a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php index 2c5b9dad48eb..31a6ba9f10e7 100644 --- a/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php @@ -6,6 +6,8 @@ namespace Magento\Persistent\Test\Unit\Observer; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; /** @@ -63,6 +65,11 @@ class CheckExpirePersistentQuoteObserverTest extends \PHPUnit\Framework\TestCase */ private $quoteMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|CartRepositoryInterface + */ + private $quoteRepositoryMock; + /** * @inheritdoc */ @@ -82,6 +89,7 @@ protected function setUp() ->disableOriginalConstructor() ->setMethods(['getRequestUri', 'getServer']) ->getMockForAbstractClass(); + $this->quoteRepositoryMock = $this->createMock(CartRepositoryInterface::class); $this->model = new \Magento\Persistent\Observer\CheckExpirePersistentQuoteObserver( $this->sessionMock, @@ -90,7 +98,8 @@ protected function setUp() $this->eventManagerMock, $this->customerSessionMock, $this->checkoutSessionMock, - $this->requestMock + $this->requestMock, + $this->quoteRepositoryMock ); $this->quoteMock = $this->getMockBuilder(Quote::class) ->setMethods(['getCustomerIsGuest', 'getIsPersistent']) @@ -111,12 +120,19 @@ public function testExecuteWhenCanNotApplyPersistentData() public function testExecuteWhenPersistentIsNotEnabled() { + $quoteId = 'quote_id_1'; + $this->persistentHelperMock ->expects($this->once()) ->method('canProcess') ->with($this->observerMock) ->willReturn(true); $this->persistentHelperMock->expects($this->exactly(2))->method('isEnabled')->willReturn(false); + $this->checkoutSessionMock->expects($this->exactly(2))->method('getQuoteId')->willReturn($quoteId); + $this->quoteRepositoryMock->expects($this->once()) + ->method('getActive') + ->with($quoteId) + ->willThrowException(new NoSuchEntityException()); $this->eventManagerMock->expects($this->never())->method('dispatch'); $this->model->execute($this->observerMock); } From 8a4e7c4ca5f3e75fd2f158afa5338c39b5132418 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Wed, 14 Aug 2019 17:22:09 +0300 Subject: [PATCH 0334/1172] MC-19132: Child product image of configurable product not displayed --- lib/internal/Magento/Framework/Image/Adapter/Gd2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php index f8cad0e8821e..7e92b336cfdc 100644 --- a/lib/internal/Magento/Framework/Image/Adapter/Gd2.php +++ b/lib/internal/Magento/Framework/Image/Adapter/Gd2.php @@ -296,7 +296,7 @@ private function _fillBackgroundColor(&$imageResourceTo) imagecolortransparent($imageResourceTo, $transparentColor); return $transparentColor; } - // phpcs:disable Magento2.CodeAnalysis.EmptyBlock.DetectedCatch + // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch } catch (\Exception $e) { // fallback to default background color } From eb3d1728566f992401bbfb648ab56cf39deecf9b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Wed, 14 Aug 2019 18:02:38 +0300 Subject: [PATCH 0335/1172] MC-19080: Incorrect behavior after shipping methods disabled --- app/code/Magento/Shipping/Model/Shipping.php | 12 +- .../Model/CollectRatesTest.php | 118 ++++++++++++++++++ .../Magento/Shipping/Model/ShippingTest.php | 99 ++++----------- .../Magento/Ups/Model/CollectRatesTest.php | 50 ++++++++ 4 files changed, 199 insertions(+), 80 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php index 77e6f3c5219f..48127469ea98 100644 --- a/app/code/Magento/Shipping/Model/Shipping.php +++ b/app/code/Magento/Shipping/Model/Shipping.php @@ -273,7 +273,7 @@ public function collectRates(\Magento\Quote\Model\Quote\Address\RateRequest $req */ private function prepareCarrier(string $carrierCode, RateRequest $request): AbstractCarrier { - $carrier = $this->isActive($carrierCode) + $carrier = $this->isShippingCarrierAvailable($carrierCode) ? $this->_carrierFactory->create($carrierCode, $request->getStoreId()) : null; if (!$carrier) { @@ -363,6 +363,7 @@ public function composePackagesForCarrier($carrier, $request) { $allItems = $request->getAllItems(); $fullItems = []; + $weightItems = []; $maxWeight = (double)$carrier->getConfigData('max_package_weight'); @@ -428,12 +429,13 @@ public function composePackagesForCarrier($carrier, $request) if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); + $weightItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems[] = array_fill(0, $qty, $itemWeight); + $weightItems[] = array_fill(0, $qty, $itemWeight); } } + $fullItems = array_merge($fullItems, ...$weightItems); sort($fullItems); return $this->_makePieces($fullItems, $maxWeight); @@ -537,9 +539,9 @@ public function setCarrierAvailabilityConfigField($code = 'active') * Checks availability of carrier. * * @param string $carrierCode - * @return bool|null + * @return bool */ - private function isActive(string $carrierCode) + private function isShippingCarrierAvailable(string $carrierCode): bool { return $this->_scopeConfig->isSetFlag( 'carriers/' . $carrierCode . '/' . $this->_availabilityConfigField, diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php new file mode 100644 index 000000000000..c5e3ab1935a2 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -0,0 +1,118 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\OfflineShipping\Model; + +use Magento\Framework\DataObject; +use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Quote\Model\Quote\Address\RateResult\Method; +use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Shipping; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Integration tests for offline shipping carriers. + * @magentoAppIsolation enabled + */ +class CollectRatesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Shipping + */ + protected $shipping; + + /** + * @var string + */ + protected $carrier = 'flatrate'; + + /** + * @var string + */ + protected $errorMessage = 'This shipping method is not available. To use this shipping method, please contact us.'; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->shipping = $this->objectManager->get(Shipping::class); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 1 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertEquals($this->carrier, $rate->getData('carrier')); + static::assertEquals($this->errorMessage, $rate->getData('error_message')); + } + + /** + * @magentoConfigFixture default_store carriers/flatrate/active 0 + * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 + * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK + * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php index 8c5dfb0d0ff5..760b24db5ef3 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/ShippingTest.php @@ -3,19 +3,16 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Shipping\Model; use Magento\Framework\DataObject; use Magento\Framework\ObjectManagerInterface; -use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Quote\Model\Quote\Address\RateResult\Method; use Magento\Shipping\Model\Rate\Result; use Magento\TestFramework\Helper\Bootstrap; /** - * Contains list of tests for Shipping model. - * @magentoAppIsolation enabled + * Contains list of tests for Shipping model */ class ShippingTest extends \PHPUnit\Framework\TestCase { @@ -45,8 +42,22 @@ protected function setUp() */ public function testCollectRatesByAddress() { + $address = $this->objectManager->create(DataObject::class, [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1 + ] + ]); /** @var Shipping $result */ - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); + $result = $this->model->collectRatesByAddress($address, 'flatrate'); static::assertInstanceOf(Shipping::class, $result); return $result->getResult(); @@ -57,81 +68,19 @@ public function testCollectRatesByAddress() * @covers \Magento\Shipping\Model\Shipping::collectRatesByAddress * @param Result $result * @depends testCollectRatesByAddress + * @magentoConfigFixture carriers/flatrate/active 1 + * @magentoConfigFixture carriers/flatrate/price 5.00 */ public function testCollectRates(Result $result) { - $rate = $this->getRate($result); - static::assertInstanceOf(Method::class, $rate); - static::assertEquals('flatrate', $rate->getData('carrier')); - static::assertEquals(5, $rate->getData('price')); - } + $rates = $result->getAllRates(); + static::assertNotEmpty($rates); - /** - * @magentoConfigFixture default_store carriers/flatrate/active 1 - * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 - * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK - * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 - */ - public function testShippingMethodIsActiveAndNotApplicable() - { - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); - $rate = $this->getRate($result->getResult()); + /** @var Method $rate */ + $rate = array_pop($rates); + static::assertInstanceOf(Method::class, $rate); static::assertEquals('flatrate', $rate->getData('carrier')); - static::assertEquals( - 'This shipping method is not available. To use this shipping method, please contact us.', - $rate->getData('error_message') - ); - } - - /** - * @magentoConfigFixture default_store carriers/flatrate/active 0 - * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 - * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK - * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 - */ - public function testShippingMethodIsNotActiveAndNotApplicable() - { - $result = $this->model->collectRatesByAddress($this->getAddress(), 'flatrate'); - $rate = $this->getRate($result->getResult()); - - static::assertNull($rate); - } - - /** - * @return DataObject - */ - private function getAddress(): DataObject - { - $address = $this->objectManager->create( - DataObject::class, - [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1, - ], - ] - ); - - return $address; - } - - /** - * @param Result $result - * @return Method|Error - */ - private function getRate(Result $result) - { - $rates = $result->getAllRates(); - - return array_pop($rates); + static::assertEquals(5, $rate->getData('price')); } } diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php new file mode 100644 index 000000000000..27323bf22f01 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Ups\Model; + +/** + * Integration tests for online shipping carriers. + * @magentoAppIsolation enabled + */ +class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest +{ + /** + * @var string + */ + protected $carrier = 'ups'; + + /** + * @var string + */ + protected $errorMessage = 'This shipping method is currently unavailable. ' . + 'If you would like to ship using this shipping method, please contact us.'; + + /** + * @magentoConfigFixture default_store carriers/ups/active 1 + * @magentoConfigFixture default_store carriers/ups/type UPS + * @magentoConfigFixture default_store carriers/ups/sallowspecific 1 + * @magentoConfigFixture default_store carriers/ups/specificcountry UK + * @magentoConfigFixture default_store carriers/ups/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); + } + + /** + * @magentoConfigFixture default_store carriers/ups/active 0 + * @magentoConfigFixture default_store carriers/ups/type UPS + * @magentoConfigFixture default_store carriers/ups/sallowspecific 1 + * @magentoConfigFixture default_store carriers/ups/specificcountry UK + * @magentoConfigFixture default_store carriers/ups/showmethod 1 + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); + } +} From 380e14f9bd108a99ca26328ba345adb241585a1a Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Wed, 14 Aug 2019 12:11:54 -0500 Subject: [PATCH 0336/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage replaced Paypal UI configurations with <magentoCLI> and <createData> --- .../Paypal/Test/Mftf/Data/PaypalData.xml | 30 +++++++++++++++++++ .../Test/PayPalSmartButtonInCheckoutPage.xml | 29 ++++++++++-------- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml index ae34476e9ac0..b8994f0e4bc0 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml @@ -99,4 +99,34 @@ <data key="paypal_express_api_signature">someApiSignature</data> <data key="paypal_express_merchantID">someMerchantId</data> </entity> + <entity name="PaypalConfig" type="paypal_config_state"> + <requiredEntity type="business_account">BusinessAccount</requiredEntity> + <requiredEntity type="api_username">ApiUsername</requiredEntity> + <requiredEntity type="api_password">ApiPassword</requiredEntity> + <requiredEntity type="api_signature">ApiSignature</requiredEntity> + <requiredEntity type="api_authentication">ApiAuthentication</requiredEntity> + <requiredEntity type="sandbox_flag">SandboxFlag</requiredEntity> + <requiredEntity type="use_proxy">UseProxy</requiredEntity> + </entity> + <entity name="BusinessAccount" type="business_account"> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_business_account}}</data> + </entity> + <entity name="ApiUsername" type="api_username"> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_username}}</data> + </entity> + <entity name="ApiPassword" type="api_password"> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_password}}</data> + </entity> + <entity name="ApiSignature" type="api_signature"> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_signature}}</data> + </entity> + <entity name="ApiAuthentication" type="api_authentication"> + <data key="value">0</data> + </entity> + <entity name="SandboxFlag" type="sandbox_flag"> + <data key="value">1</data> + </entity> + <entity name="UseProxy" type="use_proxy"> + <data key="value">0</data> + </entity> </entities> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml index dcf00e49a5b9..5fd81d408900 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml @@ -31,30 +31,35 @@ <!-- Create Customer --> <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <!-- Set Paypal express config --> + <magentoCLI command="config:set payment/paypal_express/active 1" stepKey="enablePaypal"/> + <magentoCLI command="config:set payment/paypal_express/in_context 1" stepKey="enableInContextPayPal"/> + <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 1" stepKey="enableSkipOrderReview"/> + <magentoCLI command="config:set payment/paypal_express/merchant_id {{_CREDS.magento/paypal_express_checkout_us_merchant_id}}" stepKey="setMerchantId"/> + <createData entity="PaypalConfig" stepKey="createPaypalExpressConfig"/> + <!-- Login --> <actionGroup ref="LoginActionGroup" stepKey="login"/> </before> <after> - <!-- Cleanup environment --> + <!-- Cleanup Paypal configurations --> + <magentoCLI command="config:set payment/paypal_express/merchant_id ''" stepKey="deleteMerchantId"/> + <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 0" stepKey="disableSkipOrderReview"/> + <magentoCLI command="config:set payment/paypal_express/in_context 0" stepKey="disableInContextPayPal"/> + <magentoCLI command="config:set payment/paypal_express/active 0" stepKey="disablePaypal"/> + <createData entity="SamplePaypalConfig" stepKey="setDefaultPaypalConfig"/> + + <!-- Delete product --> <deleteData stepKey="deleteCategory" createDataKey="createCategory"/> <deleteData stepKey="deleteProduct" createDataKey="createProduct"/> - <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> - <!-- TODO: Delete created paypal configuration --> - <!-- revert skip order settings --> - <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 0" stepKey="enableSkipOrderReview"/> + <!--Delete customer --> + <deleteData stepKey="deleteCustomer" createDataKey="createCustomer"/> <!-- Logout --> <actionGroup ref="logout" stepKey="logoutFromAdmin"/> </after> - <!-- Configure PayPal sandbox --> - <!-- TODO: Below step will be replaced with createData once MQE-1561 is completed --> - <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="configPayPalExpressCheckout"/> - - <!-- Set skip order review --> - <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 1" stepKey="enableSkipOrderReview"/> - <!--Login to storefront as previously created customer--> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> <argument name="Customer" value="$$createCustomer$$"/> From 9532e283542714364f2ce7b15508ea8c110e4165 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 14 Aug 2019 12:20:56 -0500 Subject: [PATCH 0337/1172] MC-19194: UpdateCartItems mutation does not update cart item quantity - Reverted back commit c7d9130289993310992cb3e4a0b5ec7c3dd196bd and modified functional test --- .../Model/Cart/UpdateCartItem.php | 1 + .../Quote/Guest/UpdateCartItemsTest.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php index 81a7779eb98b..b18c6ad66233 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php @@ -117,6 +117,7 @@ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) } $cartItem->setQty($quantity); $this->validateCartItem($cartItem); + $this->cartItemRepository->save($cartItem); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index 988ead7d86df..13d9bb011d9b 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -70,6 +70,16 @@ public function testUpdateCartItemQuantity() $this->assertEquals($itemId, $item['id']); $this->assertEquals($quantity, $item['quantity']); + + $cartQuery = $this->getCartQuery($maskedQuoteId); + $response = $this->graphQlQuery($cartQuery); + + $this->assertArrayHasKey('cart', $response); + + $responseCart = $response['cart']; + $item = current($responseCart['items']); + + $this->assertEquals($quantity, $item['quantity']); } /** @@ -268,6 +278,26 @@ private function getQuery(string $maskedQuoteId, int $itemId, float $quantity): } } } +QUERY; + } + + /** + * @param string $maskedQuoteId + * @return string + */ + private function getCartQuery(string $maskedQuoteId) + { + return <<<QUERY +query { + cart(cart_id: "{$maskedQuoteId}"){ + items{ + product{ + name + } + quantity + } + } +} QUERY; } } From 2fa2eb9d1314c7177a6a4bd8c9d19f90759fdf23 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 14 Aug 2019 14:59:56 -0500 Subject: [PATCH 0338/1172] MC-19161: Revert ENGCOM-2983 --- .../Magento/Mtf/TestSuite/InjectableTests/acceptance.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml index 6a8e2c615f84..d433f8c3fd06 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml @@ -21,6 +21,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> </config> From 59e76d9a78e513730ac920cc785c52b9691796aa Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 15 Aug 2019 09:22:02 +0300 Subject: [PATCH 0339/1172] MC-19080: Incorrect behavior after shipping methods disabled --- .../testsuite/Magento/Ups/Model/CollectRatesTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 27323bf22f01..3aab12df5f17 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -31,6 +31,7 @@ class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest * @magentoConfigFixture default_store carriers/ups/specificcountry UK * @magentoConfigFixture default_store carriers/ups/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() { parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); @@ -43,6 +44,7 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() * @magentoConfigFixture default_store carriers/ups/specificcountry UK * @magentoConfigFixture default_store carriers/ups/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() { parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); From 08bbdbf0246a09612f893c12587b3fae0d61efa7 Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Thu, 15 Aug 2019 14:24:11 +0300 Subject: [PATCH 0340/1172] MC-19080: Incorrect behavior after shipping methods disabled --- .../Model/CollectRatesTest.php | 79 +----------- .../Shipping/Model/CollectRatesTest.php | 114 ++++++++++++++++++ .../Magento/Ups/Model/CollectRatesTest.php | 2 +- 3 files changed, 120 insertions(+), 75 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php index c5e3ab1935a2..910b4f570c36 100644 --- a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -7,30 +7,12 @@ namespace Magento\OfflineShipping\Model; -use Magento\Framework\DataObject; -use Magento\Framework\ObjectManagerInterface; -use Magento\Quote\Model\Quote\Address\RateResult\Error; -use Magento\Quote\Model\Quote\Address\RateResult\Method; -use Magento\Shipping\Model\Rate\Result; -use Magento\Shipping\Model\Shipping; -use Magento\TestFramework\Helper\Bootstrap; - /** * Integration tests for offline shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \PHPUnit\Framework\TestCase +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest { - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var Shipping - */ - protected $shipping; - /** * @var string */ @@ -41,28 +23,16 @@ class CollectRatesTest extends \PHPUnit\Framework\TestCase */ protected $errorMessage = 'This shipping method is not available. To use this shipping method, please contact us.'; - /** - * @inheritdoc - */ - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - $this->shipping = $this->objectManager->get(Shipping::class); - } - /** * @magentoConfigFixture default_store carriers/flatrate/active 1 * @magentoConfigFixture default_store carriers/flatrate/sallowspecific 1 * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() { - $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); - $rate = $this->getRate($result->getResult()); - - static::assertEquals($this->carrier, $rate->getData('carrier')); - static::assertEquals($this->errorMessage, $rate->getData('error_message')); + parent::testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable(); } /** @@ -71,48 +41,9 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() * @magentoConfigFixture default_store carriers/flatrate/specificcountry UK * @magentoConfigFixture default_store carriers/flatrate/showmethod 1 */ + // phpcs:ignore Generic.CodeAnalysis.UselessOverridingMethod public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() { - $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); - $rate = $this->getRate($result->getResult()); - - static::assertNull($rate); - } - - /** - * @return DataObject - */ - private function getAddress(): DataObject - { - $address = $this->objectManager->create( - DataObject::class, - [ - 'data' => [ - 'region_id' => 'CA', - 'postcode' => '11111', - 'lastname' => 'John', - 'firstname' => 'Doe', - 'street' => 'Some street', - 'city' => 'Los Angeles', - 'email' => 'john.doe@example.com', - 'telephone' => '11111111', - 'country_id' => 'US', - 'item_qty' => 1, - ], - ] - ); - - return $address; - } - - /** - * @param Result $result - * @return Method|Error - */ - private function getRate(Result $result) - { - $rates = $result->getAllRates(); - - return array_pop($rates); + parent::testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable(); } } diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php new file mode 100644 index 000000000000..a5994cc604a6 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php @@ -0,0 +1,114 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Shipping\Model; + +use Magento\Framework\DataObject; +use Magento\Framework\ObjectManagerInterface; +use Magento\Quote\Model\Quote\Address\RateResult\Error; +use Magento\Quote\Model\Quote\Address\RateResult\Method; +use Magento\Shipping\Model\Rate\Result; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Integration tests for shipping carriers. + */ +class CollectRatesTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var Shipping + */ + protected $shipping; + + /** + * @var string + */ + protected $carrier = ''; + + /** + * @var string + */ + protected $errorMessage = ''; + + /** + * @inheritdoc + */ + protected function setUp() + { + if (empty($this->carrier) || empty($this->errorMessage)) { + $this->markTestSkipped('Required fields are empty'); + } + $this->objectManager = Bootstrap::getObjectManager(); + $this->shipping = $this->objectManager->get(Shipping::class); + } + + /** + * @return void + */ + public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertEquals($this->carrier, $rate->getData('carrier')); + static::assertEquals($this->errorMessage, $rate->getData('error_message')); + } + + /** + * @return void + */ + public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() + { + $result = $this->shipping->collectRatesByAddress($this->getAddress(), $this->carrier); + $rate = $this->getRate($result->getResult()); + + static::assertNull($rate); + } + + /** + * @return DataObject + */ + private function getAddress(): DataObject + { + $address = $this->objectManager->create( + DataObject::class, + [ + 'data' => [ + 'region_id' => 'CA', + 'postcode' => '11111', + 'lastname' => 'John', + 'firstname' => 'Doe', + 'street' => 'Some street', + 'city' => 'Los Angeles', + 'email' => 'john.doe@example.com', + 'telephone' => '11111111', + 'country_id' => 'US', + 'item_qty' => 1, + ], + ] + ); + + return $address; + } + + /** + * @param Result $result + * @return Method|Error + */ + private function getRate(Result $result) + { + $rates = $result->getAllRates(); + + return array_pop($rates); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 3aab12df5f17..58f31836a310 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for online shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\OfflineShipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest { /** * @var string From c6cc4b23b4b357adc925d6ae6ded2b43bf37d791 Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Thu, 15 Aug 2019 17:58:49 +0300 Subject: [PATCH 0341/1172] MC-19044: [FT] Magento\Downloadable\Test\TestCase\CreateDownloadableProductEntityTest fails on Jenkins --- .../CreateDownloadableProductEntityTest.php | 24 ++++++++++++++++++- .../TestSuite/InjectableTests/acceptance.xml | 2 ++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php index 496b7a280ca1..de71cdff7ae4 100644 --- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php @@ -11,6 +11,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew; use Magento\Downloadable\Test\Fixture\DownloadableProduct; use Magento\Mtf\TestCase\Injectable; +use Magento\Mtf\Util\Command\Cli\EnvWhitelist; /** * Steps: @@ -53,6 +54,13 @@ class CreateDownloadableProductEntityTest extends Injectable */ protected $catalogProductNew; + /** + * DomainWhitelist CLI + * + * @var EnvWhitelist + */ + private $envWhitelist; + /** * Persist category * @@ -73,16 +81,19 @@ public function __prepare(Category $category) * @param Category $category * @param CatalogProductIndex $catalogProductIndexNewPage * @param CatalogProductNew $catalogProductNewPage + * @param EnvWhitelist $envWhitelist * @return void */ public function __inject( Category $category, CatalogProductIndex $catalogProductIndexNewPage, - CatalogProductNew $catalogProductNewPage + CatalogProductNew $catalogProductNewPage, + EnvWhitelist $envWhitelist ) { $this->category = $category; $this->catalogProductIndex = $catalogProductIndexNewPage; $this->catalogProductNew = $catalogProductNewPage; + $this->envWhitelist = $envWhitelist; } /** @@ -95,10 +106,21 @@ public function __inject( public function test(DownloadableProduct $product, Category $category) { // Steps + $this->envWhitelist->addHost('example.com'); $this->catalogProductIndex->open(); $this->catalogProductIndex->getGridPageActionBlock()->addProduct('downloadable'); $productBlockForm = $this->catalogProductNew->getProductForm(); $productBlockForm->fill($product, null, $category); $this->catalogProductNew->getFormPageActions()->save(); } + + /** + * Clean data after running test. + * + * @return void + */ + protected function tearDown() + { + $this->envWhitelist->removeHost('example.com'); + } } diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml index 6a8e2c615f84..2eae769416c2 100644 --- a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/acceptance.xml @@ -13,6 +13,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> <rule scope="variation"> @@ -21,6 +22,7 @@ </allow> <deny> <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> </deny> </rule> </config> From 2dbf838540bf9bc0efbad683eb5b743632877bbe Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 15 Aug 2019 13:00:54 -0500 Subject: [PATCH 0342/1172] MC-19194: UpdateCartItems mutation does not update cart item quantity - fix performance issue --- .../QuoteGraphQl/Model/Cart/UpdateCartItem.php | 5 +---- .../QuoteGraphQl/Model/Resolver/UpdateCartItems.php | 12 +++++++++++- .../GraphQl/Quote/Guest/UpdateCartItemsTest.php | 10 ++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php index b18c6ad66233..7b5c9a57a7be 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/UpdateCartItem.php @@ -93,8 +93,6 @@ public function execute(Quote $cart, int $cartItemId, float $quantity, array $cu ) ); } - - $this->quoteRepository->save($cart); } /** @@ -105,7 +103,7 @@ public function execute(Quote $cart, int $cartItemId, float $quantity, array $cu * @param float $quantity * @throws GraphQlNoSuchEntityException * @throws NoSuchEntityException - * @throws GraphQlNoSuchEntityException + * @throws GraphQlInputException */ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) { @@ -117,7 +115,6 @@ private function updateItemQuantity(int $itemId, Quote $cart, float $quantity) } $cartItem->setQty($quantity); $this->validateCartItem($cartItem); - $this->cartItemRepository->save($cartItem); } /** diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php index 8066c28e9e48..241237613b94 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/UpdateCartItems.php @@ -15,6 +15,7 @@ use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Quote\Api\CartItemRepositoryInterface; +use Magento\Quote\Api\CartRepositoryInterface; use Magento\Quote\Model\Quote; use Magento\QuoteGraphQl\Model\Cart\GetCartForUser; use Magento\QuoteGraphQl\Model\Cart\UpdateCartItem; @@ -39,19 +40,27 @@ class UpdateCartItems implements ResolverInterface */ private $cartItemRepository; + /** + * @var CartRepositoryInterface + */ + private $cartRepository; + /** * @param GetCartForUser $getCartForUser * @param CartItemRepositoryInterface $cartItemRepository * @param UpdateCartItem $updateCartItem + * @param CartRepositoryInterface $cartRepository */ public function __construct( GetCartForUser $getCartForUser, CartItemRepositoryInterface $cartItemRepository, - UpdateCartItem $updateCartItem + UpdateCartItem $updateCartItem, + CartRepositoryInterface $cartRepository ) { $this->getCartForUser = $getCartForUser; $this->cartItemRepository = $cartItemRepository; $this->updateCartItem = $updateCartItem; + $this->cartRepository = $cartRepository; } /** @@ -76,6 +85,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value try { $this->processCartItems($cart, $cartItems); + $this->cartRepository->save($cart); } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } catch (LocalizedException $e) { diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php index 13d9bb011d9b..6ac683ef77ad 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/UpdateCartItemsTest.php @@ -71,6 +71,7 @@ public function testUpdateCartItemQuantity() $this->assertEquals($itemId, $item['id']); $this->assertEquals($quantity, $item['quantity']); + //Check that update is correctly reflected in cart $cartQuery = $this->getCartQuery($maskedQuoteId); $response = $this->graphQlQuery($cartQuery); @@ -101,6 +102,15 @@ public function testRemoveCartItemIfQuantityIsZero() $responseCart = $response['updateCartItems']['cart']; $this->assertCount(0, $responseCart['items']); + + //Check that update is correctly reflected in cart + $cartQuery = $this->getCartQuery($maskedQuoteId); + $response = $this->graphQlQuery($cartQuery); + + $this->assertArrayHasKey('cart', $response); + + $responseCart = $response['cart']; + $this->assertCount(0, $responseCart['items']); } /** From 98efddb24cc787d94113b9c5a83dae4a5771a9f2 Mon Sep 17 00:00:00 2001 From: Kevin Kozan <kkozan@magento.com> Date: Thu, 15 Aug 2019 13:50:28 -0500 Subject: [PATCH 0343/1172] MQE-1702: Bump MFTF version in Magento - MFTF Version Bump --- composer.json | 2 +- composer.lock | 74 +++++++++++++++++++++++++-------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/composer.json b/composer.json index 60f52e8ebc0b..8b2cb0b53972 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,7 @@ "friendsofphp/php-cs-fixer": "~2.14.0", "lusitanian/oauth": "~0.8.10", "magento/magento-coding-standard": "~3.0.0", - "magento/magento2-functional-testing-framework": "2.4.3", + "magento/magento2-functional-testing-framework": "2.4.4", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 675848c49591..8af9ead67d9c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b5c5eeedfc8a724202af911b637f7b16", + "content-hash": "8819d140d0951fefd8e14b052ff0f61a", "packages": [ { "name": "braintree/braintree_php", @@ -1440,13 +1440,13 @@ }, { "name": "John Kelly", - "email": "johnmkelly86@gmail.com", - "role": "Maintainer" + "role": "Maintainer", + "email": "johnmkelly86@gmail.com" }, { "name": "Raúl Araya", - "email": "nubeiro@gmail.com", - "role": "Maintainer" + "role": "Maintainer", + "email": "nubeiro@gmail.com" } ], "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", @@ -1552,28 +1552,28 @@ "authors": [ { "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" + "role": "Lead Developer", + "email": "terrafrost@php.net" }, { "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" + "role": "Developer", + "email": "pm@datasphere.ch" }, { "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" + "role": "Developer", + "email": "bantu@phpbb.com" }, { "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "role": "Developer", + "email": "petrich@tronic-media.com" }, { "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" + "role": "Developer", + "email": "graham@alt-three.com" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", @@ -2402,7 +2402,7 @@ }, { "name": "Gert de Pagter", - "email": "backendtea@gmail.com" + "email": "BackEndTea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -4912,8 +4912,8 @@ "authors": [ { "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" + "role": "Developer", + "email": "vania-pooh@yandex-team.ru" } ], "description": "A Codeception adapter for Allure report.", @@ -4967,8 +4967,8 @@ "authors": [ { "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" + "role": "Developer", + "email": "vania-pooh@yandex-team.ru" } ], "description": "PHP API for Allure adapter", @@ -6697,9 +6697,9 @@ "authors": [ { "name": "Phil Bennett", + "role": "Developer", "email": "philipobenito@gmail.com", - "homepage": "http://www.philipobenito.com", - "role": "Developer" + "homepage": "http://www.philipobenito.com" } ], "description": "A fast and intuitive dependency injection container.", @@ -6814,16 +6814,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.4.3", + "version": "2.4.4", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "9e9a20fd4c77833ef41ac07eb076a7f2434ce61c" + "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/9e9a20fd4c77833ef41ac07eb076a7f2434ce61c", - "reference": "9e9a20fd4c77833ef41ac07eb076a7f2434ce61c", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/ab347cf23d01f6bb9d158ab37d2dc56594999beb", + "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb", "shasum": "" }, "require": { @@ -6885,7 +6885,7 @@ "magento", "testing" ], - "time": "2019-08-02T14:26:18+00:00" + "time": "2019-08-15T14:46:36+00:00" }, { "name": "mikey179/vfsstream", @@ -6925,8 +6925,8 @@ "authors": [ { "name": "Frank Kleine", - "homepage": "http://frankkleine.de/", - "role": "Developer" + "role": "Developer", + "homepage": "http://frankkleine.de/" } ], "description": "Virtual file system to mock the real file system in unit tests.", @@ -7700,8 +7700,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", @@ -7970,8 +7970,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "The PHP Unit Testing framework.", @@ -8545,8 +8545,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Copy/Paste Detector (CPD) for PHP code.", @@ -9542,8 +9542,8 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" + "role": "lead", + "email": "arne@blankerts.de" } ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", From b9d468ceb37a9ef32b6ca60e88feac6711e3bb32 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 15 Aug 2019 14:03:32 -0500 Subject: [PATCH 0344/1172] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 56 ++++++++++--------- app/code/Magento/Ups/Model/Carrier.php | 46 +++++++-------- app/code/Magento/Usps/Model/Carrier.php | 46 +++++++-------- .../Async/ProxyDeferredFactoryTest.php | 31 +++++----- 4 files changed, 95 insertions(+), 84 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 5959294fe6dc..5d96d4bcbf43 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -10,7 +10,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ProductMetadataInterface; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\HTTP\AsyncClient\HttpResponseDeferredInterface; use Magento\Framework\HTTP\AsyncClient\Request; use Magento\Framework\HTTP\AsyncClientInterface; @@ -21,6 +20,7 @@ use Magento\Quote\Model\Quote\Address\RateResult\Error; use Magento\Shipping\Model\Carrier\AbstractCarrier; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Framework\Xml\Security; use Magento\Dhl\Model\Validator\XmlValidator; @@ -389,16 +389,17 @@ public function collectRates(RateRequest $request) //Saving $result to use proper result with the callback $this->_result = $result = $this->_getQuotes(); //After quotes are loaded parsing the response. - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); - - return $this->_result; - } - ) + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); + + return $this->_result; + } + ) + ] ); } @@ -1057,23 +1058,24 @@ protected function _getQuotes() } } - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($deferredResponses, $responseBodies) { - //Loading rates not found in cache - foreach ($deferredResponses as $deferredResponseData) { - $responseBodies[] = [ - 'body' => $deferredResponseData['deferred']->get()->getBody(), - 'date' => $deferredResponseData['date'], - 'request' => $deferredResponseData['request'], - 'from_cache' => false - ]; - } + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($deferredResponses, $responseBodies) { + //Loading rates not found in cache + foreach ($deferredResponses as $deferredResponseData) { + $responseBodies[] = [ + 'body' => $deferredResponseData['deferred']->get()->getBody(), + 'date' => $deferredResponseData['date'], + 'request' => $deferredResponseData['request'], + 'from_cache' => false + ]; + } - return $this->processQuotesResponses($responseBodies); - } - ) + return $this->processQuotesResponses($responseBodies); + } + ) + ] ); } diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php index 5320aeb5bcc8..72b68c476d88 100644 --- a/app/code/Magento/Ups/Model/Carrier.php +++ b/app/code/Magento/Ups/Model/Carrier.php @@ -9,7 +9,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\DataObject; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\HTTP\AsyncClient\HttpResponseDeferredInterface; @@ -22,6 +21,7 @@ use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; use Magento\Shipping\Model\Carrier\CarrierInterface; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Shipping\Model\Simplexml\Element; use Magento\Ups\Helper\Config; use Magento\Shipping\Model\Shipment\Request as Shipment; @@ -239,15 +239,16 @@ public function collectRates(RateRequest $request) //To use the correct result in the callback. $this->_result = $result = $this->_getQuotes(); - return $this->deferredProxyFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); - return $this->getResult(); - } - ) + return $this->deferredProxyFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); + return $this->getResult(); + } + ) + ] ); } @@ -782,19 +783,20 @@ protected function _getXmlQuotes() new Request($url, Request::METHOD_POST, ['Content-Type' => 'application/xml'], $xmlRequest) ); - return $this->deferredProxyFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($httpResponse) { - if ($httpResponse->get()->getStatusCode() >= 400) { - $xmlResponse = ''; - } else { - $xmlResponse = $httpResponse->get()->getBody(); - } + return $this->deferredProxyFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($httpResponse) { + if ($httpResponse->get()->getStatusCode() >= 400) { + $xmlResponse = ''; + } else { + $xmlResponse = $httpResponse->get()->getBody(); + } - return $this->_parseXmlResponse($xmlResponse); - } - ) + return $this->_parseXmlResponse($xmlResponse); + } + ) + ] ); } diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php index 7136a403003d..1c8ff0ce9efa 100644 --- a/app/code/Magento/Usps/Model/Carrier.php +++ b/app/code/Magento/Usps/Model/Carrier.php @@ -8,7 +8,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Async\CallbackDeferred; -use Magento\Framework\Async\ProxyDeferredFactory; use Magento\Framework\HTTP\AsyncClient\Request; use Magento\Framework\HTTP\AsyncClientInterface; use Magento\Framework\Xml\Security; @@ -16,6 +15,7 @@ use Magento\Shipping\Helper\Carrier as CarrierHelper; use Magento\Shipping\Model\Carrier\AbstractCarrierOnline; use Magento\Shipping\Model\Rate\Result; +use Magento\Shipping\Model\Rate\Result\ProxyDeferredFactory; use Magento\Usps\Helper\Data as DataHelper; /** @@ -239,16 +239,17 @@ public function collectRates(RateRequest $request) //Saving current result to use the right one in the callback. $this->_result = $result = $this->_getQuotes(); - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($request, $result) { - $this->_result = $result; - $this->_updateFreeMethodQuote($request); + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($request, $result) { + $this->_result = $result; + $this->_updateFreeMethodQuote($request); - return $this->getResult(); - } - ) + return $this->getResult(); + } + ) + ] ); } @@ -555,18 +556,19 @@ protected function _getXmlQuotes() ) ); - return $this->proxyDeferredFactory->createFor( - Result::class, - new CallbackDeferred( - function () use ($deferredResponse, $request, $debugData) { - $responseBody = $deferredResponse->get()->getBody(); - $debugData['result'] = $responseBody; - $this->_setCachedQuotes($request, $responseBody); - $this->_debug($debugData); - - return $this->_parseXmlResponse($responseBody); - } - ) + return $this->proxyDeferredFactory->create( + [ + 'deferred' => new CallbackDeferred( + function () use ($deferredResponse, $request, $debugData) { + $responseBody = $deferredResponse->get()->getBody(); + $debugData['result'] = $responseBody; + $this->_setCachedQuotes($request, $responseBody); + $this->_debug($debugData); + + return $this->_parseXmlResponse($responseBody); + } + ) + ] ); } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php index e4385b598c60..21392e5f7b12 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Async/ProxyDeferredFactoryTest.php @@ -18,7 +18,7 @@ class ProxyDeferredFactoryTest extends TestCase { /** - * @var ProxyDeferredFactory + * @var \TestDeferred\TestClass\ProxyDeferredFactory */ private $factory; @@ -43,6 +43,7 @@ protected function setUp() //phpcs:ignore include_once __DIR__ .'/_files/test_class.php'; \TestDeferred\TestClass::$created = 0; + $this->factory = Bootstrap::getObjectManager()->get(\TestDeferred\TestClass\ProxyDeferredFactory::class); } /* @@ -57,9 +58,10 @@ public function testCreate(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertInstanceOf(\TestDeferred\TestClass::class, $proxy); $this->assertEmpty(\TestDeferred\TestClass::$created); @@ -80,9 +82,10 @@ public function testSerialize(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); //phpcs:disable /** @var \TestDeferred\TestClass $unserialized */ @@ -106,9 +109,10 @@ public function testClone(): void return new \TestDeferred\TestClass($value); }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertEquals(0, \TestDeferred\TestClass::$created); $this->assertEquals(0, $called); @@ -137,9 +141,10 @@ public function getValue() }; }; /** @var \TestDeferred\TestClass $proxy */ - $proxy = $this->factory->createFor( - \TestDeferred\TestClass::class, - $this->callbackDeferredFactory->create(['callback' => $callback]) + $proxy = $this->factory->create( + [ + 'deferred' => $this->callbackDeferredFactory->create(['callback' => $callback]) + ] ); $this->assertInstanceOf(\TestDeferred\TestClass::class, $proxy); $this->assertEmpty(\TestDeferred\TestClass::$created); From 905804a24c934a166afe2e6fdb3434714dd35fd7 Mon Sep 17 00:00:00 2001 From: Mila Lesechko <l.lesechko@gmail.com> Date: Thu, 15 Aug 2019 22:40:41 -0500 Subject: [PATCH 0345/1172] Convert AdvancedSearchEntityTest to MFTF --- .../Test/Mftf/Data/CustomAttributeData.xml | 8 ++++ .../Catalog/Test/Mftf/Data/ProductData.xml | 27 +++++++++++ ...frontFillFormAdvancedSearchActionGroup.xml | 29 ++++++++++++ ...frontAdvancedSearchByAllParametersTest.xml | 30 ++++++++++++ ...refrontAdvancedSearchByDescriptionTest.xml | 28 +++++++++++ ...cedSearchByNameSkuDescriptionPriceTest.xml | 30 ++++++++++++ .../StorefrontAdvancedSearchByNameTest.xml | 28 +++++++++++ ...refrontAdvancedSearchByPartialNameTest.xml | 25 ++++++++++ ...cedSearchByPartialShortDescriptionTest.xml | 25 ++++++++++ ...edSearchByPartialSkuAndDescriptionTest.xml | 26 ++++++++++ ...orefrontAdvancedSearchByPartialSkuTest.xml | 25 ++++++++++ ...dvancedSearchByPriceFromAndPriceToTest.xml | 26 ++++++++++ .../StorefrontAdvancedSearchByPriceToTest.xml | 33 +++++++++++++ ...ntAdvancedSearchByShortDescriptionTest.xml | 29 ++++++++++++ .../StorefrontAdvancedSearchBySkuTest.xml | 25 ++++++++++ ...tAdvancedSearchEntitySimpleProductTest.xml | 47 +++++++++++++++++++ ...dvancedSearchNegativeProductSearchTest.xml | 29 ++++++++++++ ...tAdvancedSearchWithoutEnteringDataTest.xml | 33 +++++++++++++ .../TestCase/AdvancedSearchEntityTest.xml | 16 ++++++- 19 files changed, 518 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontFillFormAdvancedSearchActionGroup.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByDescriptionTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuAndDescriptionTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceFromAndPriceToTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceToTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByShortDescriptionTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchBySkuTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchNegativeProductSearchTest.xml create mode 100644 app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchWithoutEnteringDataTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml index 1684bd0c8a2c..95e256c856fb 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml @@ -51,4 +51,12 @@ <data key="attribute_code">short_description</data> <data key="value">Short Fixedtest 555</data> </entity> + <entity name="ProductShortDescriptionAdvancedSearch" type="custom_attribute"> + <data key="attribute_code">short_description</data> + <data key="value"><p>abc_short</p></data> + </entity> + <entity name="ProductDescriptionAdvancedSearchADC123" type="custom_attribute"> + <data key="attribute_code">description</data> + <data key="value"><p>dfj_full</p></data> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 517ab253b823..70d58be4b0df 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -1210,4 +1210,31 @@ <requiredEntity type="product_extension_attribute">EavStock1</requiredEntity> <requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity> </entity> + <entity name="ABC_dfj_SimpleProduct" type="product"> + <data key="name" unique="suffix">abc_dfj_</data> + <data key="sku" unique="suffix">abc_dfj</data> + <data key="price">50.00</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ProductDescriptionAdvancedSearchABC</requiredEntity> + <requiredEntity type="custom_attribute_array">ProductShortDescriptionAdvancedSearch</requiredEntity> + </entity> + <entity name="ABC_123_SimpleProduct" type="product"> + <data key="name" unique="suffix">adc_123_</data> + <data key="sku" unique="suffix">adc_123</data> + <data key="price">100.00</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="status">1</data> + <data key="quantity">100</data> + <data key="weight">1</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ProductDescriptionAdvancedSearchADC123</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontFillFormAdvancedSearchActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontFillFormAdvancedSearchActionGroup.xml new file mode 100644 index 000000000000..1afdb6e5e46f --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontFillFormAdvancedSearchActionGroup.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontFillFormAdvancedSearchActionGroup"> + <arguments> + <argument name="productName" type="string" defaultValue=""/> + <argument name="sku" type="string" defaultValue=""/> + <argument name="description" type="string" defaultValue=""/> + <argument name="short_description" type="string" defaultValue=""/> + <argument name="price_from" type="string" defaultValue=""/> + <argument name="price_to" type="string" defaultValue=""/> + </arguments> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.ProductName}}" userInput="{{productName}}" stepKey="fillName"/> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.SKU}}" userInput="{{sku}}" stepKey="fillSku"/> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.Description}}" userInput="{{description}}" stepKey="fillDescription"/> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.ShortDescription}}" userInput="{{short_description}}" stepKey="fillShortDescription"/> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.PriceFrom}}" userInput="{{price_from}}" stepKey="fillPriceFrom"/> + <fillField selector="{{StorefrontCatalogSearchAdvancedFormSection.PriceTo}}" userInput="{{price_to}}" stepKey="fillPriceTo"/> + <click selector="{{StorefrontCatalogSearchAdvancedFormSection.SubmitButton}}" stepKey="clickSubmit"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml new file mode 100644 index 000000000000..0ebcf59dae2b --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByAllParametersTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by name, sku, description, short description, price from and price to"/> + <description value="Search product in advanced search by name, sku, description, short description, price from and price to"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="abc_dfj"/> + <argument name="sku" value="abc_dfj"/> + <argument name="description" value="adc_Full"/> + <argument name="short_description" value="abc_short"/> + <argument name="price_to" value="500"/> + <argument name="price_from" value="49"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByDescriptionTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByDescriptionTest.xml new file mode 100644 index 000000000000..5693721e6ed6 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByDescriptionTest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByDescriptionTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by description"/> + <description value="Search product in advanced search by description"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="ABC_123_SimpleProduct" stepKey="createProduct"/> + </before> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="description" value="dfj_full"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml new file mode 100644 index 000000000000..71b6ca064e0c --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByNameSkuDescriptionPriceTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by name, sku, description, short description, price from 49 and price to 50"/> + <description value="Search product in advanced search by name, sku, description, short description, price from 49 and price to 50"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="abc_dfj"/> + <argument name="sku" value="abc_dfj"/> + <argument name="description" value="adc_Full"/> + <argument name="short_description" value="abc_short"/> + <argument name="price_to" value="50"/> + <argument name="price_from" value="49"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml new file mode 100644 index 000000000000..e6020a65cb62 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> + <!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByNameTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by name"/> + <description value="Search product in advanced search by name"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="ABC_123_SimpleProduct" stepKey="createProduct"/> + </before> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="adc_123"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml new file mode 100644 index 000000000000..bf2b2f7bbbee --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPartialNameTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by partial name"/> + <description value="Search product in advanced search by partial name"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="abc"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml new file mode 100644 index 000000000000..2afb4b5a341c --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPartialShortDescriptionTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by partial short description"/> + <description value="Search product in advanced search by partial short description"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="short_description" value="dfj_short"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuAndDescriptionTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuAndDescriptionTest.xml new file mode 100644 index 000000000000..b2b4ef9cc478 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuAndDescriptionTest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPartialSkuAndDescriptionTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by partial sku and description"/> + <description value="Search product in advanced search by partial sku and description"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="sku" value="abc"/> + <argument name="description" value="adc_full"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuTest.xml new file mode 100644 index 000000000000..45cec0a89936 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialSkuTest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPartialSkuTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by partial sku"/> + <description value="Search product in advanced search by partial sku"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="sku" value="abc"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceFromAndPriceToTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceFromAndPriceToTest.xml new file mode 100644 index 000000000000..6b85cdf61c84 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceFromAndPriceToTest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPriceFromAndPriceToTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by price from and price to"/> + <description value="Search product in advanced search by price from and price to"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="price_to" value="50"/> + <argument name="price_from" value="50"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceToTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceToTest.xml new file mode 100644 index 000000000000..755bb92c897e --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPriceToTest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByPriceToTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by price to"/> + <description value="Search product in advanced search by price to"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <createData entity="ABC_123_SimpleProduct" stepKey="createProduct2" after="createProduct"/> + </before> + <after> + <deleteData createDataKey="createProduct2" stepKey="deleteProduct2" after="deleteProduct"/> + </after> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="price_to" value="100"/> + </actionGroup> + <see userInput="2 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$createProduct2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProduct2Name" after="seeProductName"/> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByShortDescriptionTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByShortDescriptionTest.xml new file mode 100644 index 000000000000..c4622d02a515 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByShortDescriptionTest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchByShortDescriptionTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by short description"/> + <description value="Search product in advanced search by short description"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <remove keyForRemoval="createProduct"/> + <remove keyForRemoval="deleteProduct"/> + <remove keyForRemoval="seeProductName"/> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="short_description" value="dfj_short"/> + </actionGroup> + <see userInput="We can't find any items matching these search criteria. Modify your search." selector="{{StorefrontQuickSearchResultsSection.messageSection}}" stepKey="see"/> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchBySkuTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchBySkuTest.xml new file mode 100644 index 000000000000..ca5e23709968 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchBySkuTest.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchBySkuTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Search product in advanced search by sku"/> + <description value="Search product in advanced search by sku"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="sku" value="abc_dfj"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml new file mode 100644 index 000000000000..16bc36f907a6 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Use Advanced Search to Find the Product"/> + <description value="Use Advanced Search to Find the Product"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-12421"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <before> + <!-- Create Data --> + <createData entity="ABC_dfj_SimpleProduct" stepKey="createProduct"/> + </before> + <after> + <!-- Delete data --> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + </after> + + <!-- 1. Navigate to Frontend --> + <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToStorefront"/> + + <!-- 2. Click "Advanced Search" --> + <actionGroup ref="StorefrontOpenAdvancedSearchActionGroup" stepKey="openAdvancedSearch"/> + + <!-- 3. Fill test data in to field(s) 4. Click "Search" button--> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="abc_dfj"/> + <argument name="sku" value="abc_dfj"/> + </actionGroup> + + <!-- 5. Perform all asserts --> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResult"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$createProduct.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productName}}" stepKey="seeProductName"/> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchNegativeProductSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchNegativeProductSearchTest.xml new file mode 100644 index 000000000000..b4f2314295a0 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchNegativeProductSearchTest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchNegativeProductSearchTest" extends="StorefrontAdvancedSearchEntitySimpleProductTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Negative product search"/> + <description value="Negative product search"/> + <testCaseId value="MAGETWO-24729"/> + <severity value="CRITICAL"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <remove keyForRemoval="createProduct"/> + <remove keyForRemoval="deleteProduct"/> + <remove keyForRemoval="seeProductName"/> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> + <argument name="productName" value="Negative_product_search"/> + </actionGroup> + <see userInput="We can't find any items matching these search criteria. Modify your search." selector="{{StorefrontQuickSearchResultsSection.messageSection}}" stepKey="see"/> + </test> +</tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchWithoutEnteringDataTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchWithoutEnteringDataTest.xml new file mode 100644 index 000000000000..8a29ab718bd2 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchWithoutEnteringDataTest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvancedSearchWithoutEnteringDataTest"> + <annotations> + <stories value="Use Advanced Search"/> + <title value="Do Advanced Search without entering data"/> + <description value="'Enter a search term and try again.' error message is missed in Advanced Search"/> + <severity value="CRITICAL"/> + <testCaseId value="MAGETWO-14859"/> + <group value="searchFrontend"/> + <group value="mtf_migrated"/> + </annotations> + <!-- 1. Navigate to Frontend --> + <actionGroup ref="StorefrontOpenHomePageActionGroup" stepKey="goToStorefront"/> + + <!-- 2. Click "Advanced Search" --> + <actionGroup ref="StorefrontOpenAdvancedSearchActionGroup" stepKey="openAdvancedSearch"/> + + <!-- 3. Fill test data in to field(s) 4. Click "Search" button--> + <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"/> + + <!-- 5. Perform all asserts --> + <see userInput="Enter a search term and try again." selector="{{StorefrontQuickSearchResultsSection.messageSection}}" stepKey="see"/> + </test> +</tests> diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.xml index 4744fa7756c4..9a26386c82cb 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.xml @@ -8,7 +8,7 @@ <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd"> <testCase name="Magento\CatalogSearch\Test\TestCase\AdvancedSearchEntityTest" summary="Use Advanced Search" ticketId="MAGETWO-24729"> <variation name="AdvancedSearchEntityTestVariation1" summary="Use Advanced Search to Find the Product" ticketId="MAGETWO-12421"> - <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data> + <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, mftf_migrated:yes</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> <data name="productSearch/data/name" xsi:type="string">abc_dfj</data> @@ -16,6 +16,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation2"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by name</data> <data name="products/simple_1" xsi:type="string">-</data> <data name="products/simple_2" xsi:type="string">Yes</data> @@ -23,6 +24,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation3"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by partial name</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -30,6 +32,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation4"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by sku</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -37,6 +40,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation5"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by partial sku</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -44,6 +48,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation6"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by partial sku and description</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -52,6 +57,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation7"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by description</data> <data name="products/simple_1" xsi:type="string">-</data> <data name="products/simple_2" xsi:type="string">Yes</data> @@ -59,6 +65,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation8"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by short description</data> <data name="products/simple_1" xsi:type="string">-</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -66,6 +73,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation9"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by partial short description</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -73,6 +81,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation10"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by price to</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">Yes</data> @@ -80,6 +89,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation11"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by price from and price to</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -88,6 +98,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation12"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by name, sku, description, short description, price from and price to</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -100,6 +111,7 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation13"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Search product in advanced search by name, sku, description, short description, price from and price to</data> <data name="products/simple_1" xsi:type="string">Yes</data> <data name="products/simple_2" xsi:type="string">-</data> @@ -112,11 +124,13 @@ <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchProductsResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation14"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="description" xsi:type="string">Negative product search</data> <data name="productSearch/data/name" xsi:type="string">Negative_product_search</data> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchNoResult" /> </variation> <variation name="AdvancedSearchEntityTestVariation15" summary="Do Advanced Search without entering data" ticketId="MAGETWO-14859"> + <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="issue" xsi:type="string">MAGETWO-18537: "Enter a search term and try again." error message is missed in Advanced Search</data> <data name="productSearch/data/name" xsi:type="string" /> <constraint name="Magento\CatalogSearch\Test\Constraint\AssertAdvancedSearchEmptyTerm" /> From a2f86726b6c60bf059987ba8fbda7d59c1f1422b Mon Sep 17 00:00:00 2001 From: Viktor Petryk <victor.petryk@transoftgroup.com> Date: Fri, 16 Aug 2019 09:45:46 +0300 Subject: [PATCH 0346/1172] MC-19080: Incorrect behavior after shipping methods disabled --- .../OfflineShipping/Model/CollectRatesTest.php | 2 +- ...ectRatesTest.php => CollectRatesAbstract.php} | 16 ++++++++++------ .../Magento/Ups/Model/CollectRatesTest.php | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) rename dev/tests/integration/testsuite/Magento/Shipping/Model/{CollectRatesTest.php => CollectRatesAbstract.php} (85%) diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php index 910b4f570c36..1b85f99752cf 100644 --- a/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for offline shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesAbstract { /** * @var string diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php similarity index 85% rename from dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php rename to dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php index a5994cc604a6..e120f2f64359 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Model/CollectRatesAbstract.php @@ -15,11 +15,10 @@ use Magento\TestFramework\Helper\Bootstrap; /** - * Integration tests for shipping carriers. + * Abstract class for testing shipping carriers. */ -class CollectRatesTest extends \PHPUnit\Framework\TestCase +abstract class CollectRatesAbstract extends \PHPUnit\Framework\TestCase { - /** * @var ObjectManagerInterface */ @@ -45,14 +44,13 @@ class CollectRatesTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - if (empty($this->carrier) || empty($this->errorMessage)) { - $this->markTestSkipped('Required fields are empty'); - } $this->objectManager = Bootstrap::getObjectManager(); $this->shipping = $this->objectManager->get(Shipping::class); } /** + * Tests that an error message is displayed when the shipping method is enabled and not applicable. + * * @return void */ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() @@ -65,6 +63,8 @@ public function testCollectRatesWhenShippingCarrierIsAvailableAndNotApplicable() } /** + * Tests that shipping rates don't return when the shipping method is disabled and not applicable. + * * @return void */ public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicable() @@ -76,6 +76,8 @@ public function testCollectRatesWhenShippingCarrierIsNotAvailableAndNotApplicabl } /** + * Returns customer address. + * * @return DataObject */ private function getAddress(): DataObject @@ -102,6 +104,8 @@ private function getAddress(): DataObject } /** + * Returns shipping rate by the result. + * * @param Result $result * @return Method|Error */ diff --git a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php index 58f31836a310..7cfaa8c7de73 100644 --- a/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/Ups/Model/CollectRatesTest.php @@ -11,7 +11,7 @@ * Integration tests for online shipping carriers. * @magentoAppIsolation enabled */ -class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesTest +class CollectRatesTest extends \Magento\Shipping\Model\CollectRatesAbstract { /** * @var string From 789ed270d885afd20425da30b71b94cbedb49ce1 Mon Sep 17 00:00:00 2001 From: DianaRusin <rusind95@gmail.com> Date: Fri, 16 Aug 2019 14:42:08 +0300 Subject: [PATCH 0347/1172] MC-19089: OnePageCheckoutDeclinedTest fails on Bamboo. Order is placed with incorrect credit card number --- .../frontend/web/js/view/payment/method-renderer/cc-form.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js index ac97e4fa5eb5..5f06d26e2acf 100644 --- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js +++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js @@ -246,8 +246,10 @@ define( return; } - self.setPaymentPayload(payload); - self.placeOrder(); + if (self.validateCardType()) { + self.setPaymentPayload(payload); + self.placeOrder(); + } }); } }, From 60fc2086c62398f325426c307d8158ff988eb09a Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Fri, 16 Aug 2019 15:43:58 +0300 Subject: [PATCH 0348/1172] MC-19334: Reindex error when website have store without store view --- .../Magento/Store/Model/ScopeTreeProvider.php | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Store/Model/ScopeTreeProvider.php b/app/code/Magento/Store/Model/ScopeTreeProvider.php index da772ec0410e..a22d5abb8c48 100644 --- a/app/code/Magento/Store/Model/ScopeTreeProvider.php +++ b/app/code/Magento/Store/Model/ScopeTreeProvider.php @@ -78,25 +78,30 @@ public function get() 'scopes' => [], ]; - /** @var Group $group */ - foreach ($groups[$website->getId()] as $group) { - $groupScope = [ - 'scope' => ScopeInterface::SCOPE_GROUP, - 'scope_id' => $group->getId(), - 'scopes' => [], - ]; - - /** @var Store $store */ - foreach ($stores[$group->getId()] as $store) { - $storeScope = [ - 'scope' => ScopeInterface::SCOPE_STORES, - 'scope_id' => $store->getId(), + if (!empty($groups[$website->getId()])) { + /** @var Group $group */ + foreach ($groups[$website->getId()] as $group) { + $groupScope = [ + 'scope' => ScopeInterface::SCOPE_GROUP, + 'scope_id' => $group->getId(), 'scopes' => [], ]; - $groupScope['scopes'][] = $storeScope; + + if (!empty($stores[$group->getId()])) { + /** @var Store $store */ + foreach ($stores[$group->getId()] as $store) { + $storeScope = [ + 'scope' => ScopeInterface::SCOPE_STORES, + 'scope_id' => $store->getId(), + 'scopes' => [], + ]; + $groupScope['scopes'][] = $storeScope; + } + } + $websiteScope['scopes'][] = $groupScope; } - $websiteScope['scopes'][] = $groupScope; } + $defaultScope['scopes'][] = $websiteScope; } From 059b5cc7d1d069d870f80e5ecdead1ea54effcf8 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Fri, 16 Aug 2019 12:08:39 -0500 Subject: [PATCH 0349/1172] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 5d96d4bcbf43..0a1632a45cb0 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -819,15 +819,13 @@ protected function _getAllItems() if (!empty($decimalItems)) { foreach ($decimalItems as $decimalItem) { - $fullItems = array_merge( - $fullItems, - array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']) - ); + $fullItems[] = array_fill(0, $decimalItem['qty'] * $qty, $decimalItem['weight']); } } else { - $fullItems = array_merge($fullItems, array_fill(0, $qty, $this->_getWeight($itemWeight))); + $fullItems[] = array_fill(0, $qty, $this->_getWeight($itemWeight)); } } + $fullItems = array_merge(...$fullItems); sort($fullItems); return $fullItems; From 9c4cf858267136c719b960009dcd5319d54add21 Mon Sep 17 00:00:00 2001 From: Mark Berube <berube@adobe.com> Date: Fri, 16 Aug 2019 12:14:47 -0500 Subject: [PATCH 0350/1172] MC-5696: Fixing flaky QueueManagementTest --- .../MysqlMq/Model/QueueManagementTest.php | 84 ++++++++++++++----- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index 56dd77d3da17..abb8205ba886 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -23,27 +23,26 @@ class QueueManagementTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->queueManagement = $this->objectManager->create(\Magento\MysqlMq\Model\QueueManagement::class); + $this->queueManagement = $this->objectManager->create(QueueManagement::class); } /** * @magentoDataFixture Magento/MysqlMq/_files/queues.php */ - public function testAllFlows() + public function testMessageReading() { - $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1', 'queue2']); - $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue2', 'queue3']); - $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1', 'queue3']); - $this->queueManagement->addMessageToQueues('topic4', 'messageBody4', ['queue1', 'queue2', 'queue3']); + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1']); $maxMessagesNumber = 2; - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); $this->assertCount($maxMessagesNumber, $messages); $firstMessage = array_shift($messages); - $this->assertEquals('topic2', $firstMessage[QueueManagement::MESSAGE_TOPIC]); - $this->assertEquals('messageBody2', $firstMessage[QueueManagement::MESSAGE_BODY]); - $this->assertEquals('queue3', $firstMessage[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals('topic1', $firstMessage[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody1', $firstMessage[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $firstMessage[QueueManagement::MESSAGE_QUEUE_NAME]); $this->assertEquals( QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $firstMessage[QueueManagement::MESSAGE_STATUS] @@ -55,9 +54,9 @@ public function testAllFlows() $this->assertCount(12, date_parse($firstMessage[QueueManagement::MESSAGE_UPDATED_AT])); $secondMessage = array_shift($messages); - $this->assertEquals('topic3', $secondMessage[QueueManagement::MESSAGE_TOPIC]); - $this->assertEquals('messageBody3', $secondMessage[QueueManagement::MESSAGE_BODY]); - $this->assertEquals('queue3', $secondMessage[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals('topic2', $secondMessage[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $secondMessage[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $secondMessage[QueueManagement::MESSAGE_QUEUE_NAME]); $this->assertEquals( QueueManagement::MESSAGE_STATUS_IN_PROGRESS, $secondMessage[QueueManagement::MESSAGE_STATUS] @@ -67,35 +66,74 @@ public function testAllFlows() $this->assertTrue(is_numeric($secondMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID])); $this->assertEquals(0, $secondMessage[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); $this->assertCount(12, date_parse($secondMessage[QueueManagement::MESSAGE_UPDATED_AT])); + } + + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testChangingMessageStatus() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue1']); + $this->queueManagement->addMessageToQueues('topic4', 'messageBody4', ['queue1']); + + $maxMessagesNumber = 4; + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $firstMessage = array_shift($messages); + $secondMessage = array_shift($messages); + $thirdMessage = array_shift($messages); + $fourthMessage = array_shift($messages); + + $this->queueManagement->changeStatus( + [ + $firstMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + ], + QueueManagement::MESSAGE_STATUS_ERROR + ); - /** Mark one message as complete or failed and make sure it is not displayed in the list of read messages */ $this->queueManagement->changeStatus( [ $secondMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] ], QueueManagement::MESSAGE_STATUS_COMPLETE ); - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); - $this->assertCount(1, $messages); $this->queueManagement->changeStatus( [ - $firstMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + $thirdMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] ], - QueueManagement::MESSAGE_STATUS_ERROR + QueueManagement::MESSAGE_STATUS_NEW + ); + + $this->queueManagement->changeStatus( + [ + $fourthMessage[QueueManagement::MESSAGE_QUEUE_RELATION_ID] + ], + QueueManagement::MESSAGE_STATUS_RETRY_REQUIRED ); - $messages = $this->queueManagement->readMessages('queue3', $maxMessagesNumber); - $this->assertCount(0, $messages); - /** Ensure that message for retry is still accessible when reading messages from the queue */ - $messages = $this->queueManagement->readMessages('queue2', 1); + $messages = $this->queueManagement->readMessages('queue1'); + $this->assertCount(2, $messages); + } + + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testMessageRetry() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + + $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); $messageRelationId = $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]; for ($i = 0; $i < 2; $i++) { $this->assertEquals($i, $message[QueueManagement::MESSAGE_NUMBER_OF_TRIALS]); $this->queueManagement->pushToQueueForRetry($message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); - $messages = $this->queueManagement->readMessages('queue2', 1); + $messages = $this->queueManagement->readMessages('queue1', 1); $message = array_shift($messages); $this->assertEquals($messageRelationId, $message[QueueManagement::MESSAGE_QUEUE_RELATION_ID]); } From a2397de3e0e26c8c92143069a104403aaa113b91 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Fri, 16 Aug 2019 14:14:20 -0500 Subject: [PATCH 0351/1172] MC-19338: Fix MTF UpgradeSystemTest --- .../tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php index c9b3ce35e84e..7a82b43dba76 100644 --- a/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php +++ b/dev/tests/functional/tests/app/Magento/Setup/Test/TestCase/UpgradeSystemTest.php @@ -132,6 +132,8 @@ public function test( // Check application version $this->adminDashboard->open(); + $this->adminDashboard->getModalMessage()->dismissIfModalAppears(); + $this->adminDashboard->getModalMessage()->waitModalWindowToDisappear(); $assertApplicationVersion->processAssert($this->adminDashboard, $version); } } From 572f40f211edc9ba47241d75d912d251a618e793 Mon Sep 17 00:00:00 2001 From: Mark Berube <berube@adobe.com> Date: Fri, 16 Aug 2019 16:22:16 -0500 Subject: [PATCH 0352/1172] MC-5696: Fixing flaky QueueManagementTest - Adding a test scenario for adding to multiple queues --- .../MysqlMq/Model/QueueManagementTest.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php index abb8205ba886..790e68ee3a72 100644 --- a/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php +++ b/dev/tests/integration/testsuite/Magento/MysqlMq/Model/QueueManagementTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\MysqlMq\Model; /** @@ -68,6 +69,60 @@ public function testMessageReading() $this->assertCount(12, date_parse($secondMessage[QueueManagement::MESSAGE_UPDATED_AT])); } + /** + * @magentoDataFixture Magento/MysqlMq/_files/queues.php + */ + public function testMessageReadingMultipleQueues() + { + $this->queueManagement->addMessageToQueues('topic1', 'messageBody1', ['queue1']); + $this->queueManagement->addMessageToQueues('topic2', 'messageBody2', ['queue1', 'queue2']); + $this->queueManagement->addMessageToQueues('topic3', 'messageBody3', ['queue2']); + + $maxMessagesNumber = 2; + $messages = $this->queueManagement->readMessages('queue1', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $message = array_shift($messages); + $this->assertEquals('topic1', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody1', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $message= array_shift($messages); + $this->assertEquals('topic2', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue1', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $maxMessagesNumber = 2; + $messages = $this->queueManagement->readMessages('queue2', $maxMessagesNumber); + $this->assertCount($maxMessagesNumber, $messages); + + $message= array_shift($messages); + $this->assertEquals('topic2', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody2', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue2', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + + $message = array_shift($messages); + $this->assertEquals('topic3', $message[QueueManagement::MESSAGE_TOPIC]); + $this->assertEquals('messageBody3', $message[QueueManagement::MESSAGE_BODY]); + $this->assertEquals('queue2', $message[QueueManagement::MESSAGE_QUEUE_NAME]); + $this->assertEquals( + QueueManagement::MESSAGE_STATUS_IN_PROGRESS, + $message[QueueManagement::MESSAGE_STATUS] + ); + } + /** * @magentoDataFixture Magento/MysqlMq/_files/queues.php */ From 986bc309fdb9f9eee85af46439e619946dcc324b Mon Sep 17 00:00:00 2001 From: Mila Lesechko <26227105+MilaLesechko@users.noreply.github.com> Date: Mon, 19 Aug 2019 11:30:35 -0500 Subject: [PATCH 0353/1172] Convert AdvancedSearchEntityTest to MFTF --- .../Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml index 95e256c856fb..e87ee83c3c18 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml @@ -51,6 +51,10 @@ <data key="attribute_code">short_description</data> <data key="value">Short Fixedtest 555</data> </entity> + <entity name="ProductDescriptionAdvancedSearchABC" type="custom_attribute"> + <data key="attribute_code">description</data> + <data key="value"><p>adc_Full</p></data> + </entity> <entity name="ProductShortDescriptionAdvancedSearch" type="custom_attribute"> <data key="attribute_code">short_description</data> <data key="value"><p>abc_short</p></data> From 6b42eb2bff1e96c53a602f70f90785607b72c3a3 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Tue, 20 Aug 2019 09:10:12 +0300 Subject: [PATCH 0354/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer module addError -> addErrorMessage addSuccess -> addSuccessMessage addException -> addExceptionMessage --- .../Customer/Controller/Account/Confirm.php | 6 +++--- .../Customer/Controller/Account/Confirmation.php | 6 +++--- .../Customer/Controller/Account/CreatePost.php | 14 +++++++------- .../Customer/Controller/Account/EditPost.php | 8 ++++---- .../Customer/Controller/Account/LoginPost.php | 6 +++--- .../Controller/Account/ResetPasswordPost.php | 12 ++++++------ .../Magento/Customer/Controller/Address/Delete.php | 6 +++--- .../Adminhtml/Customer/InvalidateToken.php | 6 +++--- .../Customer/Controller/Adminhtml/Group/Delete.php | 6 +++--- .../Customer/Controller/Adminhtml/Group/Save.php | 4 ++-- .../Customer/Controller/Adminhtml/Index.php | 4 ++-- .../Adminhtml/Index/AbstractMassAction.php | 2 +- .../Customer/Controller/Adminhtml/Index/Delete.php | 6 +++--- .../Customer/Controller/Adminhtml/Index/Edit.php | 2 +- .../Controller/Adminhtml/Index/InlineEdit.php | 6 +++--- .../Controller/Adminhtml/Index/MassAssignGroup.php | 2 +- .../Controller/Adminhtml/Index/MassDelete.php | 2 +- .../Controller/Adminhtml/Index/MassSubscribe.php | 2 +- .../Controller/Adminhtml/Index/MassUnsubscribe.php | 2 +- .../Controller/Adminhtml/Index/ResetPassword.php | 6 ++++-- .../Customer/Controller/Adminhtml/Index/Save.php | 7 +++++-- .../Customer/Controller/Adminhtml/Locks/Unlock.php | 4 ++-- .../Customer/Observer/AfterAddressSaveObserver.php | 6 +++--- 23 files changed, 65 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php index 2b3cb9aa61ab..4f0fb3ff0855 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirm.php +++ b/app/code/Magento/Customer/Controller/Account/Confirm.php @@ -163,13 +163,13 @@ public function execute() $metadata->setPath('/'); $this->getCookieManager()->deleteCookie('mage-cache-sessid', $metadata); } - $this->messageManager->addSuccess($this->getSuccessMessage()); + $this->messageManager->addSuccessMessage($this->getSuccessMessage()); $resultRedirect->setUrl($this->getSuccessRedirect()); return $resultRedirect; } catch (StateException $e) { - $this->messageManager->addException($e, __('This confirmation key is invalid or has expired.')); + $this->messageManager->addExceptionMessage($e, __('This confirmation key is invalid or has expired.')); } catch (\Exception $e) { - $this->messageManager->addException($e, __('There was an error confirming the account')); + $this->messageManager->addExceptionMessage($e, __('There was an error confirming the account')); } $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); diff --git a/app/code/Magento/Customer/Controller/Account/Confirmation.php b/app/code/Magento/Customer/Controller/Account/Confirmation.php index a3e2db020763..bd9066dcd464 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirmation.php +++ b/app/code/Magento/Customer/Controller/Account/Confirmation.php @@ -91,11 +91,11 @@ public function execute() $email, $this->storeManager->getStore()->getWebsiteId() ); - $this->messageManager->addSuccess(__('Please check your email for confirmation key.')); + $this->messageManager->addSuccessMessage(__('Please check your email for confirmation key.')); } catch (InvalidTransitionException $e) { - $this->messageManager->addSuccess(__('This email does not require confirmation.')); + $this->messageManager->addSuccessMessage(__('This email does not require confirmation.')); } catch (\Exception $e) { - $this->messageManager->addException($e, __('Wrong email.')); + $this->messageManager->addExceptionMessage($e, __('Wrong email.')); $resultRedirect->setPath('*/*/*', ['email' => $email, '_secure' => true]); return $resultRedirect; } diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index 4c9c25b5f33d..510d82879637 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -366,7 +366,7 @@ public function execute() if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) { $email = $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()); // @codingStandardsIgnoreStart - $this->messageManager->addSuccess( + $this->messageManager->addSuccessMessage( __( 'You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', $email @@ -377,7 +377,7 @@ public function execute() $resultRedirect->setUrl($this->_redirect->success($url)); } else { $this->session->setCustomerDataAsLoggedIn($customer); - $this->messageManager->addSuccess($this->getSuccessMessage()); + $this->messageManager->addSuccessMessage($this->getSuccessMessage()); $requestedRedirect = $this->accountRedirect->getRedirectCookie(); if (!$this->scopeConfig->getValue('customer/startup/redirect_dashboard') && $requestedRedirect) { $resultRedirect->setUrl($this->_redirect->success($requestedRedirect)); @@ -401,16 +401,16 @@ public function execute() $url ); // @codingStandardsIgnoreEnd - $this->messageManager->addError($message); + $this->messageManager->addErrorMessage($message); } catch (InputException $e) { - $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); foreach ($e->getErrors() as $error) { - $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage())); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); } } catch (LocalizedException $e) { - $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); } catch (\Exception $e) { - $this->messageManager->addException($e, __('We can\'t save the customer.')); + $this->messageManager->addExceptionMessage($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php index 4eb41cedea29..d2300b7b490c 100644 --- a/app/code/Magento/Customer/Controller/Account/EditPost.php +++ b/app/code/Magento/Customer/Controller/Account/EditPost.php @@ -216,7 +216,7 @@ public function execute() $isPasswordChanged ); $this->dispatchSuccessEvent($customerCandidateDataObject); - $this->messageManager->addSuccess(__('You saved the account information.')); + $this->messageManager->addSuccessMessage(__('You saved the account information.')); return $resultRedirect->setPath('customer/account'); } catch (InvalidEmailOrPasswordException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); @@ -227,7 +227,7 @@ public function execute() ); $this->session->logout(); $this->session->start(); - $this->messageManager->addError($message); + $this->messageManager->addErrorMessage($message); return $resultRedirect->setPath('customer/account/login'); } catch (InputException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); @@ -235,9 +235,9 @@ public function execute() $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); } } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { - $this->messageManager->addException($e, __('We can\'t save the customer.')); + $this->messageManager->addExceptionMessage($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 04051fbbf366..a7632401933e 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -217,17 +217,17 @@ public function execute() $message = $e->getMessage(); } catch (\Exception $e) { // PA DSS violation: throwing or logging an exception here can disclose customer password - $this->messageManager->addError( + $this->messageManager->addErrorMessage( __('An unspecified error occurred. Please contact us for assistance.') ); } finally { if (isset($message)) { - $this->messageManager->addError($message); + $this->messageManager->addErrorMessage($message); $this->session->setUsername($login['username']); } } } else { - $this->messageManager->addError(__('A login and a password are required.')); + $this->messageManager->addErrorMessage(__('A login and a password are required.')); } } diff --git a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php index 27a00f86dd95..a127f2acf538 100644 --- a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php +++ b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php @@ -73,13 +73,13 @@ public function execute() $passwordConfirmation = (string)$this->getRequest()->getPost('password_confirmation'); if ($password !== $passwordConfirmation) { - $this->messageManager->addError(__("New Password and Confirm New Password values didn't match.")); + $this->messageManager->addErrorMessage(__("New Password and Confirm New Password values didn't match.")); $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); return $resultRedirect; } if (iconv_strlen($password) <= 0) { - $this->messageManager->addError(__('Please enter a new password.')); + $this->messageManager->addErrorMessage(__('Please enter a new password.')); $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); return $resultRedirect; @@ -92,17 +92,17 @@ public function execute() $password ); $this->session->unsRpToken(); - $this->messageManager->addSuccess(__('You updated your password.')); + $this->messageManager->addSuccessMessage(__('You updated your password.')); $resultRedirect->setPath('*/*/login'); return $resultRedirect; } catch (InputException $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); foreach ($e->getErrors() as $error) { - $this->messageManager->addError($error->getMessage()); + $this->messageManager->addErrorMessage($error->getMessage()); } } catch (\Exception $exception) { - $this->messageManager->addError(__('Something went wrong while saving the new password.')); + $this->messageManager->addErrorMessage(__('Something went wrong while saving the new password.')); } $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php index a30e15db4b3f..c90489bfc978 100644 --- a/app/code/Magento/Customer/Controller/Address/Delete.php +++ b/app/code/Magento/Customer/Controller/Address/Delete.php @@ -27,12 +27,12 @@ public function execute() $address = $this->_addressRepository->getById($addressId); if ($address->getCustomerId() === $this->_getSession()->getCustomerId()) { $this->_addressRepository->deleteById($addressId); - $this->messageManager->addSuccess(__('You deleted the address.')); + $this->messageManager->addSuccessMessage(__('You deleted the address.')); } else { - $this->messageManager->addError(__('We can\'t delete the address right now.')); + $this->messageManager->addErrorMessage(__('We can\'t delete the address right now.')); } } catch (\Exception $other) { - $this->messageManager->addException($other, __('We can\'t delete the address right now.')); + $this->messageManager->addExceptionMessage($other, __('We can\'t delete the address right now.')); } } return $this->resultRedirectFactory->create()->setPath('*/*/index'); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php b/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php index b69410ecbfce..7747d80595cd 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php @@ -139,14 +139,14 @@ public function execute() if ($customerId = $this->getRequest()->getParam('customer_id')) { try { $this->tokenService->revokeCustomerAccessToken($customerId); - $this->messageManager->addSuccess(__('You have revoked the customer\'s tokens.')); + $this->messageManager->addSuccessMessage(__('You have revoked the customer\'s tokens.')); $resultRedirect->setPath('customer/index/edit', ['id' => $customerId, '_current' => true]); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); $resultRedirect->setPath('customer/index/edit', ['id' => $customerId, '_current' => true]); } } else { - $this->messageManager->addError(__('We can\'t find a customer to revoke.')); + $this->messageManager->addErrorMessage(__('We can\'t find a customer to revoke.')); $resultRedirect->setPath('customer/index/index'); } return $resultRedirect; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php index ab32ea08a44a..819a49178a24 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php @@ -24,12 +24,12 @@ public function execute() if ($id) { try { $this->groupRepository->deleteById($id); - $this->messageManager->addSuccess(__('You deleted the customer group.')); + $this->messageManager->addSuccessMessage(__('You deleted the customer group.')); } catch (NoSuchEntityException $e) { - $this->messageManager->addError(__('The customer group no longer exists.')); + $this->messageManager->addErrorMessage(__('The customer group no longer exists.')); return $resultRedirect->setPath('customer/*/'); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); return $resultRedirect->setPath('customer/group/edit', ['id' => $id]); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php index 5ffce4cbcd98..64c94fa230fb 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php @@ -93,10 +93,10 @@ public function execute() $this->groupRepository->save($customerGroup); - $this->messageManager->addSuccess(__('You saved the customer group.')); + $this->messageManager->addSuccessMessage(__('You saved the customer group.')); $resultRedirect->setPath('customer/group'); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); if ($customerGroup != null) { $this->storeCustomerGroupDataToSession( $this->dataObjectProcessor->buildOutputDataArray( diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Index.php index a0317a51260d..ffae1e9f8bf1 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index.php @@ -311,7 +311,7 @@ protected function _addSessionErrorMessages($messages) protected function actUponMultipleCustomers(callable $singleAction, $customerIds) { if (!is_array($customerIds)) { - $this->messageManager->addError(__('Please select customer(s).')); + $this->messageManager->addErrorMessage(__('Please select customer(s).')); return 0; } $customersUpdated = 0; @@ -320,7 +320,7 @@ protected function actUponMultipleCustomers(callable $singleAction, $customerIds $singleAction($customerId); $customersUpdated++; } catch (\Exception $exception) { - $this->messageManager->addError($exception->getMessage()); + $this->messageManager->addErrorMessage($exception->getMessage()); } } return $customersUpdated; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php index e26b49aaebe7..08c6e5148ade 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php @@ -64,7 +64,7 @@ public function execute() $collection = $this->filter->getCollection($this->collectionFactory->create()); return $this->massAction($collection); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); return $resultRedirect->setPath($this->redirectUrl); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php index ab39ca098162..4b2f2614948c 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php @@ -31,7 +31,7 @@ public function execute() $formKeyIsValid = $this->_formKeyValidator->validate($this->getRequest()); $isPost = $this->getRequest()->isPost(); if (!$formKeyIsValid || !$isPost) { - $this->messageManager->addError(__('Customer could not be deleted.')); + $this->messageManager->addErrorMessage(__('Customer could not be deleted.')); return $resultRedirect->setPath('customer/index'); } @@ -39,9 +39,9 @@ public function execute() if (!empty($customerId)) { try { $this->_customerRepository->deleteById($customerId); - $this->messageManager->addSuccess(__('You deleted the customer.')); + $this->messageManager->addSuccessMessage(__('You deleted the customer.')); } catch (\Exception $exception) { - $this->messageManager->addError($exception->getMessage()); + $this->messageManager->addErrorMessage($exception->getMessage()); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php index 25b4ddd4e173..d4697ecd6169 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php @@ -43,7 +43,7 @@ public function execute() //do nothing } } catch (NoSuchEntityException $e) { - $this->messageManager->addException($e, __('Something went wrong while editing the customer.')); + $this->messageManager->addExceptionMessage($e, __('Something went wrong while editing the customer.')); $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('customer/*/index'); return $resultRedirect; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 7220de035681..41d2c43bdaf7 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -234,13 +234,13 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId($e->getMessage())); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId($e->getMessage())); $this->logger->critical($e); } catch (\Exception $e) { - $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); + $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId('We can\'t save the customer.')); $this->logger->critical($e); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php index 5a9c52bf9b1c..f55c81da7e0b 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php @@ -60,7 +60,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php index edaeea6a15eb..85286573bc5e 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php @@ -58,7 +58,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersDeleted) { - $this->messageManager->addSuccess(__('A total of %1 record(s) were deleted.', $customersDeleted)); + $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were deleted.', $customersDeleted)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php index 25c56ac60c14..e072c5cb4cd4 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php @@ -64,7 +64,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php index 4b40722ba9ab..e52c9a772ed2 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php @@ -64,7 +64,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 1e4fa91cbf89..3b9370c32bf6 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -44,7 +44,9 @@ public function execute() \Magento\Customer\Model\AccountManagement::EMAIL_REMINDER, $customer->getWebsiteId() ); - $this->messageManager->addSuccess(__('The customer will receive an email with a link to reset password.')); + $this->messageManager->addSuccessMessage( + __('The customer will receive an email with a link to reset password.') + ); } catch (NoSuchEntityException $exception) { $resultRedirect->setPath('customer/index'); return $resultRedirect; @@ -57,7 +59,7 @@ public function execute() } catch (SecurityViolationException $exception) { $this->messageManager->addErrorMessage($exception->getMessage()); } catch (\Exception $exception) { - $this->messageManager->addException( + $this->messageManager->addExceptionMessage( $exception, __('Something went wrong while resetting customer password.') ); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 38ed688a835b..3ee33af9ec07 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -354,7 +354,7 @@ public function execute() $this->_getSession()->unsCustomerFormData(); // Done Saving customer, finish save action $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); - $this->messageManager->addSuccess(__('You saved the customer.')); + $this->messageManager->addSuccessMessage(__('You saved the customer.')); $returnToEdit = (bool)$this->getRequest()->getParam('back', false); } catch (\Magento\Framework\Validator\Exception $exception) { $messages = $exception->getMessages(); @@ -378,7 +378,10 @@ public function execute() $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } catch (\Exception $exception) { - $this->messageManager->addException($exception, __('Something went wrong while saving the customer.')); + $this->messageManager->addExceptionMessage( + $exception, + __('Something went wrong while saving the customer.') + ); $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php b/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php index 1fd06a318294..2747ba1a665f 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php @@ -55,10 +55,10 @@ public function execute() // unlock customer if ($customerId) { $this->authentication->unlock($customerId); - $this->getMessageManager()->addSuccess(__('Customer has been unlocked successfully.')); + $this->getMessageManager()->addSuccessMessage(__('Customer has been unlocked successfully.')); } } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ diff --git a/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php b/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php index 41311abee5da..8677abfa8990 100644 --- a/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php +++ b/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php @@ -255,7 +255,7 @@ protected function addValidMessage($customerAddress, $validationResult) : (string)__('You will not be charged tax.'); } - $this->messageManager->addSuccess(implode(' ', $message)); + $this->messageManager->addSuccessMessage(implode(' ', $message)); return $this; } @@ -280,7 +280,7 @@ protected function addInvalidMessage($customerAddress) $message[] = (string)__('You will be charged tax.'); } - $this->messageManager->addError(implode(' ', $message)); + $this->messageManager->addErrorMessage(implode(' ', $message)); return $this; } @@ -307,7 +307,7 @@ protected function addErrorMessage($customerAddress) $email = $this->scopeConfig->getValue('trans_email/ident_support/email', ScopeInterface::SCOPE_STORE); $message[] = (string)__('If you believe this is an error, please contact us at %1', $email); - $this->messageManager->addError(implode(' ', $message)); + $this->messageManager->addErrorMessage(implode(' ', $message)); return $this; } From e56a4c7a62e346472c433f41dabcd320a2ca4cdf Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Tue, 20 Aug 2019 10:02:26 +0300 Subject: [PATCH 0355/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer module Fix. Unit tests --- .../Test/Unit/Controller/Account/ConfirmTest.php | 6 +++--- .../Test/Unit/Controller/Account/CreatePostTest.php | 4 ++-- .../Test/Unit/Controller/Account/LoginPostTest.php | 10 +++++----- .../Test/Unit/Controller/Address/DeleteTest.php | 6 +++--- .../Unit/Controller/Adminhtml/Group/SaveTest.php | 4 ++-- .../Controller/Adminhtml/Index/InlineEditTest.php | 4 ++-- .../Adminhtml/Index/MassAssignGroupTest.php | 4 ++-- .../Controller/Adminhtml/Index/MassDeleteTest.php | 4 ++-- .../Controller/Adminhtml/Index/MassSubscribeTest.php | 4 ++-- .../Adminhtml/Index/MassUnsubscribeTest.php | 4 ++-- .../Controller/Adminhtml/Index/NewsletterTest.php | 2 +- .../Controller/Adminhtml/Index/ResetPasswordTest.php | 6 +++--- .../Unit/Controller/Adminhtml/Index/SaveTest.php | 12 ++++++------ .../Unit/Controller/Adminhtml/Locks/UnlockTest.php | 4 ++-- .../Unit/Observer/AfterAddressSaveObserverTest.php | 6 +++--- 15 files changed, 40 insertions(+), 40 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php index 01fc465d4ae8..0684594d510d 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php @@ -205,7 +205,7 @@ public function testNoCustomerIdInRequest($customerId, $key) $exception = new \Exception('Bad request.'); $this->messageManagerMock->expects($this->once()) - ->method('addException') + ->method('addExceptionMessage') ->with($this->equalTo($exception), $this->equalTo('There was an error confirming the account')); $testUrl = 'http://example.com'; @@ -281,7 +281,7 @@ public function testSuccessMessage($customerId, $key, $vatValidationEnabled, $ad ->willReturnSelf(); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->willReturnSelf(); @@ -399,7 +399,7 @@ public function testSuccessRedirect( ->willReturnSelf(); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->willReturnSelf(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php index f8f47eedba3e..ac52c395d678 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php @@ -371,7 +371,7 @@ public function testSuccessMessage( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); @@ -502,7 +502,7 @@ public function testSuccessRedirect( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 762c76b695de..51b84d807dc1 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -222,7 +222,7 @@ public function testExecuteEmptyLoginData() ->willReturn([]); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with(__('A login and a password are required.')) ->willReturnSelf(); @@ -551,7 +551,7 @@ protected function mockExceptions($exception, $username) $url ); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with($message) ->willReturnSelf(); @@ -563,7 +563,7 @@ protected function mockExceptions($exception, $username) case \Magento\Framework\Exception\AuthenticationException::class: $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with( __( 'The account sign-in was incorrect or your account is disabled temporarily. ' @@ -580,7 +580,7 @@ protected function mockExceptions($exception, $username) case '\Exception': $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with(__('An unspecified error occurred. Please contact us for assistance.')) ->willReturnSelf(); break; @@ -591,7 +591,7 @@ protected function mockExceptions($exception, $username) . 'Please wait and try again later.' ); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with($message) ->willReturnSelf(); $this->session->expects($this->once()) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php index 4064b8586257..7424b0f649fd 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php @@ -146,7 +146,7 @@ public function testExecute() ->method('deleteById') ->with($addressId); $this->messageManager->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('You deleted the address.')); $this->resultRedirect->expects($this->once()) ->method('setPath') @@ -183,11 +183,11 @@ public function testExecuteWithException() ->willReturn(34); $exception = new \Exception('Exception'); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with(__('We can\'t delete the address right now.')) ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addException') + ->method('addExceptionMessage') ->with($exception, __('We can\'t delete the address right now.')); $this->resultRedirect->expects($this->once()) ->method('setPath') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php index 5f7064d5b124..c9f885315b0e 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php @@ -167,7 +167,7 @@ public function testExecuteWithTaxClassAndException() ->method('save') ->with($this->group); $this->messageManager->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('You saved the customer group.')); $exception = new \Exception('Exception'); $this->resultRedirect->expects($this->at(0)) @@ -175,7 +175,7 @@ public function testExecuteWithTaxClassAndException() ->with('customer/group') ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('Exception'); $this->dataObjectProcessorMock->expects($this->once()) ->method('buildOutputDataArray') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 45e64f6557d5..c198eb3a212f 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -366,7 +366,7 @@ public function testExecuteLocalizedException() ->with($this->customerData) ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('[Customer ID: 12] Exception message'); $this->logger->expects($this->once()) ->method('critical') @@ -394,7 +394,7 @@ public function testExecuteException() ->with($this->customerData) ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('[Customer ID: 12] We can\'t save the customer.'); $this->logger->expects($this->once()) ->method('critical') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php index 10144bdc318c..4157359959ae 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php @@ -170,7 +170,7 @@ public function testExecute() ->willReturnMap([[10, $customerMock], [11, $customerMock], [12, $customerMock]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -199,7 +199,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php index 190ff2c06618..b436b5b137c7 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php @@ -155,7 +155,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('A total of %1 record(s) were deleted.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -179,7 +179,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php index daf9c64fe7b7..33e578224400 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php @@ -171,7 +171,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -195,7 +195,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php index 05624661a2de..971efc0e490b 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php @@ -171,7 +171,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -195,7 +195,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php index d2f8b8776081..5ec39360000c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php @@ -150,7 +150,7 @@ protected function setUp() $this->messageManager = $this->getMockBuilder( \Magento\Framework\Message\Manager::class )->disableOriginalConstructor()->setMethods( - ['addSuccess', 'addMessage', 'addException'] + ['addSuccessMessage', 'addMessageMessage', 'addExceptionMessage'] )->getMock(); $contextArgs = [ diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php index 66e5b57eaa42..67ac60e6b905 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -141,7 +141,7 @@ protected function setUp() $this->messageManager = $this->getMockBuilder( \Magento\Framework\Message\Manager::class )->disableOriginalConstructor()->setMethods( - ['addSuccess', 'addMessage', 'addException', 'addErrorMessage'] + ['addSuccessMessage', 'addMessage', 'addExceptionMessage', 'addErrorMessage'] )->getMock(); $this->resultRedirectFactoryMock = $this->getMockBuilder( @@ -442,7 +442,7 @@ public function testResetPasswordActionException() $this->messageManager->expects( $this->once() )->method( - 'addException' + 'addExceptionMessage' )->with( $this->equalTo($exception), $this->equalTo('Something went wrong while resetting customer password.') @@ -502,7 +502,7 @@ public function testResetPasswordActionSendEmail() $this->messageManager->expects( $this->once() )->method( - 'addSuccess' + 'addSuccessMessage' )->with( $this->equalTo('The customer will receive an email with a link to reset password.') ); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php index 57f384d32d98..5f34583c855c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php @@ -475,7 +475,7 @@ public function testExecuteWithExistentCustomer() ->with(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('You saved the customer.')) ->willReturnSelf(); @@ -662,7 +662,7 @@ public function testExecuteWithNewCustomer() ->with(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('You saved the customer.')) ->willReturnSelf(); @@ -804,7 +804,7 @@ public function testExecuteWithNewCustomerAndValidationException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccess'); + ->method('addSuccessMessage'); $this->messageManagerMock->expects($this->once()) ->method('addMessage') @@ -951,7 +951,7 @@ public function testExecuteWithNewCustomerAndLocalizedException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccess'); + ->method('addSuccessMessage'); $this->messageManagerMock->expects($this->once()) ->method('addMessage') @@ -1099,10 +1099,10 @@ public function testExecuteWithNewCustomerAndException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccess'); + ->method('addSuccessMessage'); $this->messageManagerMock->expects($this->once()) - ->method('addException') + ->method('addExceptionMessage') ->with($exception, __('Something went wrong while saving the customer.')); $this->sessionMock->expects($this->once()) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php index c92d4ed7812b..55b4092af714 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php @@ -118,7 +118,7 @@ public function testExecute() ->with($this->equalTo('customer_id')) ->will($this->returnValue($customerId)); $this->authenticationMock->expects($this->once())->method('unlock')->with($customerId); - $this->messageManagerMock->expects($this->once())->method('addSuccess'); + $this->messageManagerMock->expects($this->once())->method('addSuccessMessage'); $this->redirectMock->expects($this->once()) ->method('setPath') ->with($this->equalTo('customer/index/edit')) @@ -141,7 +141,7 @@ public function testExecuteWithException() ->method('unlock') ->with($customerId) ->willThrowException(new \Exception($phrase)); - $this->messageManagerMock->expects($this->once())->method('addError'); + $this->messageManagerMock->expects($this->once())->method('addErrorMessage'); $this->controller->execute(); } } diff --git a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 8592d1bda66c..4501b611aa11 100644 --- a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -575,7 +575,7 @@ public function testAfterAddressSaveNewGroup( if ($resultValidMessage) { $this->messageManager->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($resultValidMessage) ->willReturnSelf(); } @@ -585,7 +585,7 @@ public function testAfterAddressSaveNewGroup( ->with($vatId) ->willReturn($vatId); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with($resultInvalidMessage) ->willReturnSelf(); } @@ -595,7 +595,7 @@ public function testAfterAddressSaveNewGroup( ->with('trans_email/ident_support/email', ScopeInterface::SCOPE_STORE) ->willReturn('admin@example.com'); $this->messageManager->expects($this->once()) - ->method('addError') + ->method('addErrorMessage') ->with($resultErrorMessage) ->willReturnSelf(); } From 5271f434440d2f589c782a996d8d73bedbb36bc8 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 20 Aug 2019 11:32:03 +0300 Subject: [PATCH 0356/1172] MC-19334: Reindex error when website have store without store view --- .../Command/IndexerReindexCommandTest.php | 61 +++++++++++++++++++ ...second_store_group_with_second_website.php | 21 +++++++ ...ore_group_with_second_website_rollback.php | 8 +++ 3 files changed, 90 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php new file mode 100644 index 000000000000..1779281f2cb8 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Indexer\Console\Command; + +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit_Framework_MockObject_MockObject as Mock; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Tests for \Magento\Indexer\Console\Command\IndexerReindexCommand. + * + * @magentoDbIsolation disabled + */ +class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @var InputInterface|Mock + */ + private $inputMock; + + /** + * @var OutputInterface|Mock + */ + private $outputMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + Bootstrap::getInstance()->reinitialize(); + $this->objectManager = Bootstrap::getObjectManager(); + + $this->inputMock = $this->getMockBuilder(InputInterface::class) + ->getMockForAbstractClass(); + $this->outputMock = $this->getMockBuilder(OutputInterface::class) + ->getMockForAbstractClass(); + } + + /** + * @magentoDataFixture Magento/Store/_files/second_store_group_with_second_website.php + */ + public function testReindexAll() + { + $command = $this->objectManager->create(IndexerReindexCommand::class); + $status = $command->run($this->inputMock, $this->outputMock); + $this->assertEquals(0, $status, 'Index wasn\'t success'); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php new file mode 100644 index 000000000000..a66bfb913871 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php @@ -0,0 +1,21 @@ +<?php +/** + * + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require_once __DIR__ . '/website.php'; + +/** + * @var \Magento\Store\Model\Group $storeGroup + */ +$storeGroup = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Group::class); +$storeGroup->setCode('some_group') + ->setName('custom store group') + ->setWebsite($website); +$storeGroup->save($storeGroup); + +/* Refresh stores memory cache */ +$objectManager->get(\Magento\Store\Model\StoreManagerInterface::class)->reinitStores(); diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php new file mode 100644 index 000000000000..e014dc940247 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +require_once __DIR__ . '/website_rollback.php'; From 5bc42334e00cb5bd508a026e1edc1809a258ec36 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Tue, 20 Aug 2019 12:44:04 +0300 Subject: [PATCH 0357/1172] MC-19334: Reindex error when website have store without store view --- .../Command/IndexerReindexCommandTest.php | 24 ++++++++++++------- ...second_store_group_with_second_website.php | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php index 1779281f2cb8..80b6f887d650 100644 --- a/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php +++ b/dev/tests/integration/testsuite/Magento/Indexer/Console/Command/IndexerReindexCommandTest.php @@ -17,6 +17,7 @@ * Tests for \Magento\Indexer\Console\Command\IndexerReindexCommand. * * @magentoDbIsolation disabled + * @magentoAppIsolation enabled */ class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase { @@ -35,18 +36,22 @@ class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase */ private $outputMock; + /** + * @var IndexerReindexCommand + */ + private $command; + /** * @inheritdoc */ protected function setUp() { - Bootstrap::getInstance()->reinitialize(); $this->objectManager = Bootstrap::getObjectManager(); - $this->inputMock = $this->getMockBuilder(InputInterface::class) - ->getMockForAbstractClass(); - $this->outputMock = $this->getMockBuilder(OutputInterface::class) - ->getMockForAbstractClass(); + $this->inputMock = $this->getMockBuilder(InputInterface::class)->getMockForAbstractClass(); + $this->outputMock = $this->getMockBuilder(OutputInterface::class)->getMockForAbstractClass(); + + $this->command = $this->objectManager->get(IndexerReindexCommand::class); } /** @@ -54,8 +59,11 @@ protected function setUp() */ public function testReindexAll() { - $command = $this->objectManager->create(IndexerReindexCommand::class); - $status = $command->run($this->inputMock, $this->outputMock); - $this->assertEquals(0, $status, 'Index wasn\'t success'); + $status = $this->command->run($this->inputMock, $this->outputMock); + $this->assertEquals( + \Magento\Framework\Console\Cli::RETURN_SUCCESS, + $status, + 'Index wasn\'t success' + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php index a66bfb913871..799cda7e9742 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_group_with_second_website.php @@ -11,7 +11,7 @@ /** * @var \Magento\Store\Model\Group $storeGroup */ -$storeGroup = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Group::class); +$storeGroup = $objectManager->create(\Magento\Store\Model\Group::class); $storeGroup->setCode('some_group') ->setName('custom store group') ->setWebsite($website); From 0cfebd6660dbcb89abba40aeb3e03706d80f97bb Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Tue, 20 Aug 2019 14:53:48 +0400 Subject: [PATCH 0358/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Updated automated test script --- .../Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml | 2 +- .../AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml index a944aa72e5cc..c108068b0064 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml @@ -139,7 +139,7 @@ <click selector="{{AdminCategorySidebarTreeSection.expandAll}}" stepKey="expandToSeeAllCategories"/> <dontSee selector="{{AdminCategorySidebarTreeSection.categoryInTree(categoryEntity.name)}}" stepKey="dontSeeCategoryInTree"/> </actionGroup> - <actionGroup name="deleteCategoryByName" extends="DeleteCategory"> + <actionGroup name="AdminDeleteCategoryByName" extends="DeleteCategory"> <arguments> <argument name="categoryName" type="string" defaultValue="category1"/> </arguments> diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index 58997aa7a518..3663035ca47a 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -10,6 +10,7 @@ <test name="AdminCategoryWithRestrictedUrlKeyNotCreatedTest"> <annotations> <features value="CatalogUrlRewrite"/> + <stoty value="Subcategory 'liquid-hand-soap' is not opened in category 'soap'"/> <title value="Category with restricted Url Key cannot be created"/> <description value="Category with restricted Url Key cannot be created"/> <severity value="MAJOR"/> @@ -23,16 +24,16 @@ <after> <!--Delete created categories--> <comment userInput="Delete created categories" stepKey="commentDeleteCreatedCategories"/> - <actionGroup ref="deleteCategoryByName" stepKey="deleteAdminCategory"> + <actionGroup ref="AdminDeleteCategoryByName" stepKey="deleteAdminCategory"> <argument name="categoryName" value="admin"/> </actionGroup> - <actionGroup ref="deleteCategoryByName" stepKey="deleteSoapCategory"> + <actionGroup ref="AdminDeleteCategoryByName" stepKey="deleteSoapCategory"> <argument name="categoryName" value="soap"/> </actionGroup> - <actionGroup ref="deleteCategoryByName" stepKey="deleteRestCategory"> + <actionGroup ref="AdminDeleteCategoryByName" stepKey="deleteRestCategory"> <argument name="categoryName" value="rest"/> </actionGroup> - <actionGroup ref="deleteCategoryByName" stepKey="deleteGraphQlCategory"> + <actionGroup ref="AdminDeleteCategoryByName" stepKey="deleteGraphQlCategory"> <argument name="categoryName" value="graphql"/> </actionGroup> <actionGroup ref="logout" stepKey="logout"/> From 0b8838ccfc4d5d7b86f8646969ec38fddbed2904 Mon Sep 17 00:00:00 2001 From: Mila Lesechko <26227105+MilaLesechko@users.noreply.github.com> Date: Tue, 20 Aug 2019 10:21:53 -0500 Subject: [PATCH 0359/1172] Convert AdvancedSearchEntityTest to MFTF --- .../Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml index e87ee83c3c18..3fbe9f86eab9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CustomAttributeData.xml @@ -63,4 +63,8 @@ <data key="attribute_code">description</data> <data key="value"><p>dfj_full</p></data> </entity> + <entity name="ProductShortDescriptionAdvancedSearchADC123" type="custom_attribute"> + <data key="attribute_code">short_description</data> + <data key="value"><p>dfj_short</p></data> + </entity> </entities> From 4f93f813049504bb89bd9be8826fc9a3358cf2a4 Mon Sep 17 00:00:00 2001 From: Mila Lesechko <26227105+MilaLesechko@users.noreply.github.com> Date: Tue, 20 Aug 2019 10:22:00 -0500 Subject: [PATCH 0360/1172] Convert AdvancedSearchEntityTest to MFTF --- app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 70d58be4b0df..378e41e933fe 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -1236,5 +1236,6 @@ <data key="weight">1</data> <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> <requiredEntity type="custom_attribute_array">ProductDescriptionAdvancedSearchADC123</requiredEntity> + <requiredEntity type="custom_attribute_array">ProductShortDescriptionAdvancedSearchADC123</requiredEntity> </entity> </entities> From 491790e2fec093d8b26c2a52d0aa987b8d1fee61 Mon Sep 17 00:00:00 2001 From: Mila Lesechko <26227105+MilaLesechko@users.noreply.github.com> Date: Tue, 20 Aug 2019 10:22:05 -0500 Subject: [PATCH 0361/1172] Convert AdvancedSearchEntityTest to MFTF --- .../StorefrontAdvancedSearchByPartialShortDescriptionTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml index 2afb4b5a341c..0edc3f31216b 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialShortDescriptionTest.xml @@ -19,7 +19,7 @@ <group value="mtf_migrated"/> </annotations> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> - <argument name="short_description" value="dfj_short"/> + <argument name="short_description" value="abc_short"/> </actionGroup> </test> </tests> From e6cfdb3152d302c092b3420437e481450e28ea7f Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Tue, 20 Aug 2019 13:21:24 -0500 Subject: [PATCH 0362/1172] MC-19500: fix related-product changes affection on third party extensions --- .../Magento/Catalog/view/frontend/web/js/related-products.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js index d17c25d421e0..5845b6d7afe3 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/related-products.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/related-products.js @@ -26,8 +26,8 @@ define([ * @private */ _create: function () { - $(this.options.selectAllLink).on('click', $.proxy(this._selectAllRelated, this)); - $(this.options.relatedCheckbox).on('click', $.proxy(this._addRelatedToProduct, this)); + $(this.options.selectAllLink, this.element).on('click', $.proxy(this._selectAllRelated, this)); + $(this.options.relatedCheckbox, this.element).on('click', $.proxy(this._addRelatedToProduct, this)); this._showRelatedProducts( this.element.find(this.options.elementsSelector), this.element.data('limit'), From 9c4c3a05c7c14de1c1fd3d28f56bd409cd9f2a39 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 21 Aug 2019 09:24:51 +0300 Subject: [PATCH 0363/1172] MC-19415: Displayed incorrect price - revert MC-17919 --- .../Indexer/Stock/DefaultStock.php | 10 ++- .../Model/Indexer/Stock/Action/FullTest.php | 71 ++++--------------- 2 files changed, 21 insertions(+), 60 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index 3670b93b8cb4..519466c50553 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -230,6 +230,8 @@ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = f { $connection = $this->getConnection(); $qtyExpr = $connection->getCheckSql('cisi.qty > 0', 'cisi.qty', 0); + $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); + $linkField = $metadata->getLinkField(); $select = $connection->select()->from( ['e' => $this->getTable('catalog_product_entity')], @@ -243,6 +245,12 @@ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = f ['cisi' => $this->getTable('cataloginventory_stock_item')], 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', [] + )->joinInner( + ['mcpei' => $this->getTable('catalog_product_entity_int')], + 'e.' . $linkField . ' = mcpei.' . $linkField + . ' AND mcpei.attribute_id = ' . $this->_getAttribute('status')->getId() + . ' AND mcpei.value = ' . ProductStatus::STATUS_ENABLED, + [] )->columns( ['qty' => $qtyExpr] )->where( @@ -284,7 +292,6 @@ protected function _prepareIndexTable($entityIds = null) */ protected function _updateIndex($entityIds) { - $this->deleteOldRecords($entityIds); $connection = $this->getConnection(); $select = $this->_getStockStatusSelect($entityIds, true); $select = $this->getQueryProcessorComposite()->processQuery($select, $entityIds, true); @@ -307,6 +314,7 @@ protected function _updateIndex($entityIds) } } + $this->deleteOldRecords($entityIds); $this->_updateIndexTable($data); return $this; diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php index 00c13619ff2c..6bf1f5fbf0be 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php @@ -5,42 +5,24 @@ */ namespace Magento\CatalogInventory\Model\Indexer\Stock\Action; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Framework\ObjectManagerInterface; -use Magento\CatalogInventory\Model\Indexer\Stock\Processor; -use Magento\Catalog\Model\CategoryFactory; -use Magento\Catalog\Block\Product\ListProduct; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; -use Magento\Catalog\Model\Product; -use PHPUnit\Framework\TestCase; - /** * Full reindex Test */ -class FullTest extends TestCase +class FullTest extends \PHPUnit\Framework\TestCase { /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * @var Processor + * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor */ protected $_processor; - /** - * @inheritdoc - */ protected function setUp() { - $this->objectManager = Bootstrap::getObjectManager(); - $this->_processor = $this->objectManager->get(Processor::class); + $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\CatalogInventory\Model\Indexer\Stock\Processor::class + ); } /** - * Reindex all - * * @magentoDbIsolation disabled * @magentoAppIsolation enabled * @magentoDataFixture Magento/Catalog/_files/product_simple.php @@ -49,9 +31,13 @@ public function testReindexAll() { $this->_processor->reindexAll(); - $categoryFactory = $this->objectManager->get(CategoryFactory::class); - /** @var ListProduct $listProduct */ - $listProduct = $this->objectManager->get(ListProduct::class); + $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Model\CategoryFactory::class + ); + /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */ + $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Catalog\Block\Product\ListProduct::class + ); $category = $categoryFactory->create()->load(2); $layer = $listProduct->getLayer(); @@ -75,37 +61,4 @@ public function testReindexAll() $this->assertEquals(100, $product->getQty()); } } - - /** - * Reindex with disabled product - * - * @return void - * @magentoDbIsolation disabled - * @magentoAppIsolation enabled - * @magentoDataFixture Magento/Catalog/_files/products_with_layered_navigation_attribute.php - */ - public function testReindexAllWithDisabledProduct(): void - { - $productCollectionFactory = $this->objectManager->get(CollectionFactory::class); - $productCollection = $productCollectionFactory - ->create() - ->addAttributeToSelect('*') - ->addAttributeToFilter('sku', ['eq' => 'simple3']) - ->addAttributeToSort('created_at', 'DESC') - ->joinField( - 'stock_status', - 'cataloginventory_stock_status', - 'stock_status', - 'product_id=entity_id', - '{{table}}.stock_id=1', - 'left' - )->load(); - - $this->assertCount(1, $productCollection); - - /** @var Product $product */ - foreach ($productCollection as $product) { - $this->assertEquals(1, $product->getData('stock_status')); - } - } } From 39504ceabde0a171af102826095a89df2ab9d058 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Wed, 21 Aug 2019 06:43:30 +0000 Subject: [PATCH 0364/1172] MC-19051: [backport for 2.3.3] Nightly build jobs were failing lately after un-skipping tests in MC-5777 --- .../Catalog/Model/Product/Type/Price.php | 5 +- .../Model/Indexer/ReindexRuleProduct.php | 51 ++++--- .../Model/Indexer/ReindexRuleProductPrice.php | 75 +++++----- .../Product/CollectionProcessor.php | 2 +- ...ProductSelectBuilderByCatalogRulePrice.php | 3 +- ...CatalogProductCollectionPricesObserver.php | 2 +- .../ProcessAdminFinalPriceObserver.php | 3 +- .../ProcessFrontFinalPriceObserver.php | 2 +- .../Pricing/Price/CatalogRulePrice.php | 2 +- .../Indexer/ReindexRuleProductPriceTest.php | 131 ++++++++--------- .../Model/Indexer/ReindexRuleProductTest.php | 135 +++++++++++------- .../Pricing/Price/CatalogRulePriceTest.php | 8 +- 12 files changed, 238 insertions(+), 181 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Product/Type/Price.php b/app/code/Magento/Catalog/Model/Product/Type/Price.php index dc73baef3f76..23a058b5a57c 100644 --- a/app/code/Magento/Catalog/Model/Product/Type/Price.php +++ b/app/code/Magento/Catalog/Model/Product/Type/Price.php @@ -596,7 +596,10 @@ public function calculatePrice( ) { \Magento\Framework\Profiler::start('__PRODUCT_CALCULATE_PRICE__'); if ($wId instanceof Store) { + $sId = $wId->getId(); $wId = $wId->getWebsiteId(); + } else { + $sId = $this->_storeManager->getWebsite($wId)->getDefaultGroup()->getDefaultStoreId(); } $finalPrice = $basePrice; @@ -610,7 +613,7 @@ public function calculatePrice( ); if ($rulePrice === false) { - $date = $this->_localeDate->date(null, null, false); + $date = $this->_localeDate->scopeDate($sId); $rulePrice = $this->_ruleFactory->create()->getRulePrice($date, $wId, $gId, $productId); } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index 55a234bb8ae2..e589c8595ce2 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -8,7 +8,10 @@ use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface as TableSwapper; use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher; -use Magento\Framework\App\ObjectManager; +use Magento\CatalogRule\Model\Rule; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\ScopeInterface; /** * Reindex rule relations with products. @@ -16,7 +19,7 @@ class ReindexRuleProduct { /** - * @var \Magento\Framework\App\ResourceConnection + * @var ResourceConnection */ private $resource; @@ -31,36 +34,40 @@ class ReindexRuleProduct private $tableSwapper; /** - * @param \Magento\Framework\App\ResourceConnection $resource + * @var TimezoneInterface + */ + private $localeDate; + + /** + * @param ResourceConnection $resource * @param ActiveTableSwitcher $activeTableSwitcher - * @param TableSwapper|null $tableSwapper + * @param TableSwapper $tableSwapper + * @param TimezoneInterface $localeDate */ public function __construct( - \Magento\Framework\App\ResourceConnection $resource, + ResourceConnection $resource, ActiveTableSwitcher $activeTableSwitcher, - TableSwapper $tableSwapper = null + TableSwapper $tableSwapper, + TimezoneInterface $localeDate ) { $this->resource = $resource; $this->activeTableSwitcher = $activeTableSwitcher; - $this->tableSwapper = $tableSwapper ?? - ObjectManager::getInstance()->get(TableSwapper::class); + $this->tableSwapper = $tableSwapper; + $this->localeDate = $localeDate; } /** * Reindex information about rule relations with products. * - * @param \Magento\CatalogRule\Model\Rule $rule + * @param Rule $rule * @param int $batchCount * @param bool $useAdditionalTable * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ - public function execute( - \Magento\CatalogRule\Model\Rule $rule, - $batchCount, - $useAdditionalTable = false - ) { + public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) + { if (!$rule->getIsActive() || empty($rule->getWebsiteIds())) { return false; } @@ -84,21 +91,26 @@ public function execute( $ruleId = $rule->getId(); $customerGroupIds = $rule->getCustomerGroupIds(); - $fromTime = strtotime($rule->getFromDate()); - $toTime = strtotime($rule->getToDate()); - $toTime = $toTime ? $toTime + \Magento\CatalogRule\Model\Indexer\IndexBuilder::SECONDS_IN_DAY - 1 : 0; $sortOrder = (int)$rule->getSortOrder(); $actionOperator = $rule->getSimpleAction(); $actionAmount = $rule->getDiscountAmount(); $actionStop = $rule->getStopRulesProcessing(); $rows = []; + foreach ($websiteIds as $websiteId) { + $scopeTz = new \DateTimeZone( + $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) + ); + $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); + $toTime = $rule->getToDate() + ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 + : 0; - foreach ($productIds as $productId => $validationByWebsite) { - foreach ($websiteIds as $websiteId) { + foreach ($productIds as $productId => $validationByWebsite) { if (empty($validationByWebsite[$websiteId])) { continue; } + foreach ($customerGroupIds as $customerGroupId) { $rows[] = [ 'rule_id' => $ruleId, @@ -123,6 +135,7 @@ public function execute( if (!empty($rows)) { $connection->insertMultiple($indexTable, $rows); } + return true; } } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php index 6a87be3c50a6..11ba87730bec 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProductPrice.php @@ -6,54 +6,58 @@ namespace Magento\CatalogRule\Model\Indexer; +use Magento\Catalog\Model\Product; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\StoreManagerInterface; + /** * Reindex product prices according rule settings. */ class ReindexRuleProductPrice { /** - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ private $storeManager; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder + * @var RuleProductsSelectBuilder */ private $ruleProductsSelectBuilder; /** - * @var \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator + * @var ProductPriceCalculator */ private $productPriceCalculator; /** - * @var \Magento\Framework\Stdlib\DateTime\DateTime + * @var TimezoneInterface */ - private $dateTime; + private $localeDate; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor + * @var RuleProductPricesPersistor */ private $pricesPersistor; /** - * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param StoreManagerInterface $storeManager * @param RuleProductsSelectBuilder $ruleProductsSelectBuilder * @param ProductPriceCalculator $productPriceCalculator - * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime - * @param \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor $pricesPersistor + * @param TimezoneInterface $localeDate + * @param RuleProductPricesPersistor $pricesPersistor */ public function __construct( - \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder $ruleProductsSelectBuilder, - \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator $productPriceCalculator, - \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, - \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor $pricesPersistor + StoreManagerInterface $storeManager, + RuleProductsSelectBuilder $ruleProductsSelectBuilder, + ProductPriceCalculator $productPriceCalculator, + TimezoneInterface $localeDate, + RuleProductPricesPersistor $pricesPersistor ) { $this->storeManager = $storeManager; $this->ruleProductsSelectBuilder = $ruleProductsSelectBuilder; $this->productPriceCalculator = $productPriceCalculator; - $this->dateTime = $dateTime; + $this->localeDate = $localeDate; $this->pricesPersistor = $pricesPersistor; } @@ -61,22 +65,16 @@ public function __construct( * Reindex product prices. * * @param int $batchCount - * @param \Magento\Catalog\Model\Product|null $product + * @param Product|null $product * @param bool $useAdditionalTable * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function execute( - $batchCount, - \Magento\Catalog\Model\Product $product = null, - $useAdditionalTable = false - ) { - $fromDate = mktime(0, 0, 0, date('m'), date('d') - 1); - $toDate = mktime(0, 0, 0, date('m'), date('d') + 1); - + public function execute($batchCount, Product $product = null, $useAdditionalTable = false) + { /** * Update products rules prices per each website separately - * because of max join limit in mysql + * because for each website date in website's timezone should be used */ foreach ($this->storeManager->getWebsites() as $website) { $productsStmt = $this->ruleProductsSelectBuilder->build($website->getId(), $product, $useAdditionalTable); @@ -84,6 +82,13 @@ public function execute( $stopFlags = []; $prevKey = null; + $storeGroup = $this->storeManager->getGroup($website->getDefaultGroupId()); + $currentDate = $this->localeDate->scopeDate($storeGroup->getDefaultStoreId(), null, true); + $previousDate = (clone $currentDate)->modify('-1 day'); + $previousDate->setTime(23, 59, 59); + $nextDate = (clone $currentDate)->modify('+1 day'); + $nextDate->setTime(0, 0, 0); + while ($ruleData = $productsStmt->fetch()) { $ruleProductId = $ruleData['product_id']; $productKey = $ruleProductId . @@ -100,12 +105,11 @@ public function execute( } } - $ruleData['from_time'] = $this->roundTime($ruleData['from_time']); - $ruleData['to_time'] = $this->roundTime($ruleData['to_time']); /** * Build prices for each day */ - for ($time = $fromDate; $time <= $toDate; $time += IndexBuilder::SECONDS_IN_DAY) { + foreach ([$previousDate, $currentDate, $nextDate] as $date) { + $time = $date->getTimestamp(); if (($ruleData['from_time'] == 0 || $time >= $ruleData['from_time']) && ($ruleData['to_time'] == 0 || $time <= $ruleData['to_time']) @@ -118,7 +122,7 @@ public function execute( if (!isset($dayPrices[$priceKey])) { $dayPrices[$priceKey] = [ - 'rule_date' => $time, + 'rule_date' => $date, 'website_id' => $ruleData['website_id'], 'customer_group_id' => $ruleData['customer_group_id'], 'product_id' => $ruleProductId, @@ -151,18 +155,7 @@ public function execute( } $this->pricesPersistor->execute($dayPrices, $useAdditionalTable); } - return true; - } - /** - * @param int $timeStamp - * @return int - */ - private function roundTime($timeStamp) - { - if (is_numeric($timeStamp) && $timeStamp != 0) { - $timeStamp = $this->dateTime->timestamp($this->dateTime->date('Y-m-d 00:00:00', $timeStamp)); - } - return $timeStamp; + return true; } } diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php index 0dee9eda5b6e..1fd6f0cbc986 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/CollectionProcessor.php @@ -90,7 +90,7 @@ public function addPriceData(ProductCollection $productCollection, $joinColumn = ), $connection->quoteInto( 'catalog_rule.rule_date = ?', - $this->dateTime->formatDate($this->localeDate->date(null, null, false), false) + $this->dateTime->formatDate($this->localeDate->scopeDate($store->getId()), false) ), ] ), diff --git a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php index 02d2631058a1..48c463fc18b8 100644 --- a/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Model/ResourceModel/Product/LinkedProductSelectBuilderByCatalogRulePrice.php @@ -88,7 +88,8 @@ public function __construct( */ public function build($productId) { - $currentDate = $this->dateTime->formatDate($this->localeDate->date(null, null, false), false); + $timestamp = $this->localeDate->scopeTimeStamp($this->storeManager->getStore()); + $currentDate = $this->dateTime->formatDate($timestamp, false); $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $productTable = $this->resource->getTableName('catalog_product_entity'); diff --git a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php index a635c5611eff..bf0c85e671dd 100644 --- a/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php +++ b/app/code/Magento/CatalogRule/Observer/PrepareCatalogProductCollectionPricesObserver.php @@ -105,7 +105,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->getEvent()->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = $this->localeDate->date(null, null, false); + $date = (new \DateTime())->setTimestamp($this->localeDate->scopeTimeStamp($store)); } $productIds = []; diff --git a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php index 2fd23ae39147..89ed519cfb8c 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessAdminFinalPriceObserver.php @@ -65,7 +65,8 @@ public function __construct( public function execute(\Magento\Framework\Event\Observer $observer) { $product = $observer->getEvent()->getProduct(); - $date = $this->localeDate->date(null, null, false); + $storeId = $product->getStoreId(); + $date = $this->localeDate->scopeDate($storeId); $key = false; $ruleData = $this->coreRegistry->registry('rule_data'); diff --git a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php index b27768ae091e..075fe9e51f7d 100644 --- a/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php +++ b/app/code/Magento/CatalogRule/Observer/ProcessFrontFinalPriceObserver.php @@ -80,7 +80,7 @@ public function execute(\Magento\Framework\Event\Observer $observer) if ($observer->hasDate()) { $date = new \DateTime($observer->getEvent()->getDate()); } else { - $date = $this->localeDate->date(null, null, false); + $date = $this->localeDate->scopeDate($storeId); } if ($observer->hasWebsiteId()) { diff --git a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php index 8bce5456ffa7..7cbbc547571a 100644 --- a/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php +++ b/app/code/Magento/CatalogRule/Pricing/Price/CatalogRulePrice.php @@ -88,7 +88,7 @@ public function getValue() $this->value = (float)$this->product->getData(self::PRICE_CODE) ?: false; } else { $this->value = $this->ruleResource->getRulePrice( - $this->dateTime->date(null, null, false), + $this->dateTime->scopeDate($this->storeManager->getStore()->getId()), $this->storeManager->getStore()->getWebsiteId(), $this->customerSession->getCustomerGroupId(), $this->product->getId() diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php index 6d7f0673ed28..5f63283df676 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductPriceTest.php @@ -6,65 +6,62 @@ namespace Magento\CatalogRule\Test\Unit\Model\Indexer; -use Magento\CatalogRule\Model\Indexer\IndexBuilder; +use Magento\Catalog\Model\Product; +use Magento\CatalogRule\Model\Indexer\ProductPriceCalculator; +use Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice; +use Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor; +use Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Api\Data\GroupInterface; +use Magento\Store\Api\Data\WebsiteInterface; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\MockObject\MockObject; class ReindexRuleProductPriceTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice + * @var ReindexRuleProductPrice */ private $model; /** - * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var StoreManagerInterface|MockObject */ private $storeManagerMock; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder|\PHPUnit_Framework_MockObject_MockObject + * @var RuleProductsSelectBuilder|MockObject */ private $ruleProductsSelectBuilderMock; /** - * @var \Magento\CatalogRule\Model\Indexer\ProductPriceCalculator|\PHPUnit_Framework_MockObject_MockObject + * @var ProductPriceCalculator|MockObject */ private $productPriceCalculatorMock; /** - * @var \Magento\Framework\Stdlib\DateTime\DateTime|\PHPUnit_Framework_MockObject_MockObject + * @var TimezoneInterface|MockObject */ - private $dateTimeMock; + private $localeDate; /** - * @var \Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor|\PHPUnit_Framework_MockObject_MockObject + * @var RuleProductPricesPersistor|MockObject */ private $pricesPersistorMock; protected function setUp() { - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->ruleProductsSelectBuilderMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\RuleProductsSelectBuilder::class) - ->disableOriginalConstructor() - ->getMock(); - $this->productPriceCalculatorMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\ProductPriceCalculator::class) - ->disableOriginalConstructor() - ->getMock(); - $this->dateTimeMock = $this->getMockBuilder(\Magento\Framework\Stdlib\DateTime\DateTime::class) - ->disableOriginalConstructor() - ->getMock(); - $this->pricesPersistorMock = - $this->getMockBuilder(\Magento\CatalogRule\Model\Indexer\RuleProductPricesPersistor::class) - ->disableOriginalConstructor() - ->getMock(); - $this->model = new \Magento\CatalogRule\Model\Indexer\ReindexRuleProductPrice( + $this->storeManagerMock = $this->createMock(StoreManagerInterface::class); + $this->ruleProductsSelectBuilderMock = $this->createMock(RuleProductsSelectBuilder::class); + $this->productPriceCalculatorMock = $this->createMock(ProductPriceCalculator::class); + $this->localeDate = $this->createMock(TimezoneInterface::class); + $this->pricesPersistorMock = $this->createMock(RuleProductPricesPersistor::class); + + $this->model = new ReindexRuleProductPrice( $this->storeManagerMock, $this->ruleProductsSelectBuilderMock, $this->productPriceCalculatorMock, - $this->dateTimeMock, + $this->localeDate, $this->pricesPersistorMock ); } @@ -72,19 +69,32 @@ protected function setUp() public function testExecute() { $websiteId = 234; - $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) - ->disableOriginalConstructor() - ->getMock(); - - $websiteMock = $this->getMockBuilder(\Magento\Store\Api\Data\WebsiteInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $websiteMock->expects($this->once())->method('getId')->willReturn($websiteId); - $this->storeManagerMock->expects($this->once())->method('getWebsites')->willReturn([$websiteMock]); - - $statementMock = $this->getMockBuilder(\Zend_Db_Statement_Interface::class) - ->disableOriginalConstructor() - ->getMock(); + $defaultGroupId = 11; + $defaultStoreId = 22; + + $websiteMock = $this->createMock(WebsiteInterface::class); + $websiteMock->expects($this->once()) + ->method('getId') + ->willReturn($websiteId); + $websiteMock->expects($this->once()) + ->method('getDefaultGroupId') + ->willReturn($defaultGroupId); + $this->storeManagerMock->expects($this->once()) + ->method('getWebsites') + ->willReturn([$websiteMock]); + $groupMock = $this->createMock(GroupInterface::class); + $groupMock->method('getId') + ->willReturn($defaultStoreId); + $groupMock->expects($this->once()) + ->method('getDefaultStoreId') + ->willReturn($defaultStoreId); + $this->storeManagerMock->expects($this->once()) + ->method('getGroup') + ->with($defaultGroupId) + ->willReturn($groupMock); + + $productMock = $this->createMock(Product::class); + $statementMock = $this->createMock(\Zend_Db_Statement_Interface::class); $this->ruleProductsSelectBuilderMock->expects($this->once()) ->method('build') ->with($websiteId, $productMock, true) @@ -99,29 +109,22 @@ public function testExecute() 'action_stop' => true ]; - $this->dateTimeMock->expects($this->at(0)) - ->method('date') - ->with('Y-m-d 00:00:00', $ruleData['from_time']) - ->willReturn($ruleData['from_time']); - $this->dateTimeMock->expects($this->at(1)) - ->method('timestamp') - ->with($ruleData['from_time']) - ->willReturn($ruleData['from_time']); - - $this->dateTimeMock->expects($this->at(2)) - ->method('date') - ->with('Y-m-d 00:00:00', $ruleData['to_time']) - ->willReturn($ruleData['to_time']); - $this->dateTimeMock->expects($this->at(3)) - ->method('timestamp') - ->with($ruleData['to_time']) - ->willReturn($ruleData['to_time']); - - $statementMock->expects($this->at(0))->method('fetch')->willReturn($ruleData); - $statementMock->expects($this->at(1))->method('fetch')->willReturn(false); - - $this->productPriceCalculatorMock->expects($this->atLeastOnce())->method('calculate'); - $this->pricesPersistorMock->expects($this->once())->method('execute'); + $this->localeDate->expects($this->once()) + ->method('scopeDate') + ->with($defaultStoreId, null, true) + ->willReturn(new \DateTime()); + + $statementMock->expects($this->at(0)) + ->method('fetch') + ->willReturn($ruleData); + $statementMock->expects($this->at(1)) + ->method('fetch') + ->willReturn(false); + + $this->productPriceCalculatorMock->expects($this->atLeastOnce()) + ->method('calculate'); + $this->pricesPersistorMock->expects($this->once()) + ->method('execute'); $this->assertTrue($this->model->execute(1, $productMock, true)); } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php index 0dbbaee8d287..ff566fa3cc77 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php @@ -8,89 +8,107 @@ use Magento\Catalog\Model\ResourceModel\Indexer\ActiveTableSwitcher; use Magento\CatalogRule\Model\Indexer\IndexerTableSwapperInterface; +use Magento\CatalogRule\Model\Indexer\ReindexRuleProduct; +use Magento\CatalogRule\Model\Rule; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; +use Magento\Store\Model\ScopeInterface; +use PHPUnit\Framework\MockObject\MockObject; class ReindexRuleProductTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct + * @var ReindexRuleProduct */ private $model; /** - * @var \Magento\Framework\App\ResourceConnection|\PHPUnit_Framework_MockObject_MockObject + * @var ResourceConnection|MockObject */ private $resourceMock; /** - * @var ActiveTableSwitcher|\PHPUnit_Framework_MockObject_MockObject + * @var ActiveTableSwitcher|MockObject */ private $activeTableSwitcherMock; /** - * @var IndexerTableSwapperInterface|\PHPUnit_Framework_MockObject_MockObject + * @var IndexerTableSwapperInterface|MockObject */ private $tableSwapperMock; + /** + * @var TimezoneInterface|MockObject + */ + private $localeDateMock; + protected function setUp() { - $this->resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->activeTableSwitcherMock = $this->getMockBuilder(ActiveTableSwitcher::class) - ->disableOriginalConstructor() - ->getMock(); - $this->tableSwapperMock = $this->getMockForAbstractClass( - IndexerTableSwapperInterface::class - ); - $this->model = new \Magento\CatalogRule\Model\Indexer\ReindexRuleProduct( + $this->resourceMock = $this->createMock(ResourceConnection::class); + $this->activeTableSwitcherMock = $this->createMock(ActiveTableSwitcher::class); + $this->tableSwapperMock = $this->createMock(IndexerTableSwapperInterface::class); + $this->localeDateMock = $this->createMock(TimezoneInterface::class); + + $this->model = new ReindexRuleProduct( $this->resourceMock, $this->activeTableSwitcherMock, - $this->tableSwapperMock + $this->tableSwapperMock, + $this->localeDateMock ); } public function testExecuteIfRuleInactive() { - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(false); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(false); $this->assertFalse($this->model->execute($ruleMock, 100, true)); } public function testExecuteIfRuleWithoutWebsiteIds() { - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); - $ruleMock->expects($this->once())->method('getWebsiteIds')->willReturn(null); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(true); + $ruleMock->expects($this->once()) + ->method('getWebsiteIds') + ->willReturn(null); $this->assertFalse($this->model->execute($ruleMock, 100, true)); } public function testExecute() { + $websiteId = 3; + $websiteTz = 'America/Los_Angeles'; $productIds = [ - 4 => [1 => 1], - 5 => [1 => 1], - 6 => [1 => 1], + 4 => [$websiteId => 1], + 5 => [$websiteId => 1], + 6 => [$websiteId => 1], ]; - $ruleMock = $this->getMockBuilder(\Magento\CatalogRule\Model\Rule::class) - ->disableOriginalConstructor() - ->getMock(); - $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); - $ruleMock->expects($this->exactly(2))->method('getWebsiteIds')->willReturn(1); - $ruleMock->expects($this->once())->method('getMatchingProductIds')->willReturn($productIds); + + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once()) + ->method('getIsActive') + ->willReturn(true); + $ruleMock->expects($this->exactly(2)) + ->method('getWebsiteIds') + ->willReturn([$websiteId]); + $ruleMock->expects($this->once()) + ->method('getMatchingProductIds') + ->willReturn($productIds); $this->tableSwapperMock->expects($this->once()) ->method('getWorkingTableName') ->with('catalogrule_product') ->willReturn('catalogrule_product_replica'); - $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class) - ->disableOriginalConstructor() - ->getMock(); - $this->resourceMock->expects($this->at(0))->method('getConnection')->willReturn($connectionMock); + $connectionMock = $this->createMock(AdapterInterface::class); + $this->resourceMock->expects($this->at(0)) + ->method('getConnection') + ->willReturn($connectionMock); $this->resourceMock->expects($this->at(1)) ->method('getTableName') ->with('catalogrule_product') @@ -100,21 +118,42 @@ public function testExecute() ->with('catalogrule_product_replica') ->willReturn('catalogrule_product_replica'); - $ruleMock->expects($this->once())->method('getId')->willReturn(100); - $ruleMock->expects($this->once())->method('getCustomerGroupIds')->willReturn([10]); - $ruleMock->expects($this->once())->method('getFromDate')->willReturn('2017-06-21'); - $ruleMock->expects($this->once())->method('getToDate')->willReturn('2017-06-30'); - $ruleMock->expects($this->once())->method('getSortOrder')->willReturn(1); - $ruleMock->expects($this->once())->method('getSimpleAction')->willReturn('simple_action'); - $ruleMock->expects($this->once())->method('getDiscountAmount')->willReturn(43); - $ruleMock->expects($this->once())->method('getStopRulesProcessing')->willReturn(true); + $ruleMock->expects($this->once()) + ->method('getId') + ->willReturn(100); + $ruleMock->expects($this->once()) + ->method('getCustomerGroupIds') + ->willReturn([10]); + $ruleMock->expects($this->atLeastOnce()) + ->method('getFromDate') + ->willReturn('2017-06-21'); + $ruleMock->expects($this->atLeastOnce()) + ->method('getToDate') + ->willReturn('2017-06-30'); + $ruleMock->expects($this->once()) + ->method('getSortOrder') + ->willReturn(1); + $ruleMock->expects($this->once()) + ->method('getSimpleAction') + ->willReturn('simple_action'); + $ruleMock->expects($this->once()) + ->method('getDiscountAmount') + ->willReturn(43); + $ruleMock->expects($this->once()) + ->method('getStopRulesProcessing') + ->willReturn(true); + + $this->localeDateMock->expects($this->once()) + ->method('getConfigTimezone') + ->with(ScopeInterface::SCOPE_WEBSITE, $websiteId) + ->willReturn($websiteTz); $batchRows = [ [ 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 4, 'action_operator' => 'simple_action', @@ -126,7 +165,7 @@ public function testExecute() 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 5, 'action_operator' => 'simple_action', @@ -141,7 +180,7 @@ public function testExecute() 'rule_id' => 100, 'from_time' => 1498028400, 'to_time' => 1498892399, - 'website_id' => 1, + 'website_id' => $websiteId, 'customer_group_id' => 10, 'product_id' => 6, 'action_operator' => 'simple_action', diff --git a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php index cb1a7f53f752..7514d2bc4b5c 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Pricing/Price/CatalogRulePriceTest.php @@ -112,6 +112,7 @@ protected function setUp() */ public function testGetValue() { + $storeId = 5; $coreWebsiteId = 2; $productId = 4; $customerGroupId = 3; @@ -120,9 +121,12 @@ public function testGetValue() $catalogRulePrice = 55.12; $convertedPrice = 45.34; + $this->coreStoreMock->expects($this->once()) + ->method('getId') + ->willReturn($storeId); $this->dataTimeMock->expects($this->once()) - ->method('date') - ->with(null, null, false) + ->method('scopeDate') + ->with($storeId) ->willReturn($date); $this->coreStoreMock->expects($this->once()) ->method('getWebsiteId') From a19c9018e5a4b172f8beadb78cc8888c15bbbc62 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Wed, 14 Aug 2019 11:25:28 +0300 Subject: [PATCH 0365/1172] MC-18825: Increase test coverage for Promotion and Loyalty functional area - Integration test for MC-6347 --- ...simple_out_of_stock_without_categories.php | 52 +++++++++ ...t_of_stock_without_categories_rollback.php | 8 ++ .../_files/customer_for_second_store.php | 17 +++ .../customer_for_second_store_rollback.php | 8 ++ .../ProductAlert/Model/ObserverTest.php | 110 ++++++++++++++---- .../ProductAlert/_files/i18n/pt_BR.csv | 1 + .../_files/product_alert_with_store.php | 29 +++++ 7 files changed, 201 insertions(+), 24 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store.php create mode 100644 dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store_rollback.php create mode 100644 dev/tests/integration/testsuite/Magento/ProductAlert/_files/i18n/pt_BR.csv create mode 100644 dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php new file mode 100644 index 000000000000..4bd534b4165b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Type; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\ObjectManager; + +Bootstrap::getInstance()->reinitialize(); + +/** @var ObjectManager $objectManager */ +$objectManager = Bootstrap::getObjectManager(); + +/** @var $product Product */ +$product = $objectManager->create(Product::class); +$product->isObjectNew(true); +$product->setTypeId(Type::TYPE_SIMPLE) + ->setId(1) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Simple Product') + ->setSku('simple') + ->setPrice(10) + ->setWeight(1) + ->setShortDescription("Short description") + ->setTaxClassId(0) + ->setDescription('Description with <b>html tag</b>') + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED) + ->setStockData( + [ + 'use_config_manage_stock' => 1, + 'qty' => 0, + 'is_qty_decimal' => 0, + 'is_in_stock' => 0, + ] + )->setCanSaveCustomOptions(true) + ->setHasOptions(true); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(ProductRepositoryInterface::class); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories_rollback.php new file mode 100644 index 000000000000..4c858f322f8a --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +include __DIR__ . '/product_simple_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store.php new file mode 100644 index 000000000000..d8c56b7bf6f4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store.php @@ -0,0 +1,17 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\CustomerRepositoryInterface; + +require __DIR__ . '/customer.php'; + +$objectManager = Bootstrap::getObjectManager(); +$repository = $objectManager->create(CustomerRepositoryInterface::class); +$customer = $repository->get('customer@example.com'); +$customer->setStoreId(2); +$repository->save($customer); diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store_rollback.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store_rollback.php new file mode 100644 index 000000000000..61cce9dbcc8d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_for_second_store_rollback.php @@ -0,0 +1,8 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +include __DIR__ . '/customer_rollback.php'; diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php index 0fc98d8d8380..0a34711acde7 100644 --- a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php @@ -3,60 +3,122 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\ProductAlert\Model; +use Magento\Customer\Api\AccountManagementInterface; +use Magento\Customer\Model\Session; +use Magento\Framework\App\Area; +use Magento\Framework\Locale\Resolver; +use Magento\Framework\Module\Dir\Reader; +use Magento\Framework\Phrase; +use Magento\Framework\Phrase\Renderer\Translate as PhraseRendererTranslate; +use Magento\Framework\Phrase\RendererInterface; +use Magento\Framework\Translate; +use Magento\Store\Model\StoreRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Helper\CacheCleaner; +use Magento\TestFramework\Mail\Template\TransportBuilderMock; +use Magento\TestFramework\ObjectManager; + /** + * Test for Magento\ProductAlert\Model\Observer + * * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class ObserverTest extends \PHPUnit\Framework\TestCase { /** - * @var \Magento\Framework\ObjectManagerInterface + * @var ObjectManager */ protected $_objectManager; /** - * @var \Magento\Customer\Model\Session + * @var Observer */ - protected $_customerSession; + private $observer; /** - * @var \Magento\Customer\Helper\View + * @var TransportBuilderMock */ - protected $_customerViewHelper; + private $transportBuilder; + /** + * @inheritDoc + */ public function setUp() { - $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->_customerSession = $this->_objectManager->get( - \Magento\Customer\Model\Session::class - ); - $service = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Customer\Api\AccountManagementInterface::class - ); + Bootstrap::getInstance()->loadArea(Area::AREA_FRONTEND); + $this->_objectManager = Bootstrap::getObjectManager(); + $this->observer = $this->_objectManager->get(Observer::class); + $this->transportBuilder = $this->_objectManager->get(TransportBuilderMock::class); + $service = $this->_objectManager->create(AccountManagementInterface::class); $customer = $service->authenticate('customer@example.com', 'password'); - $this->_customerSession->setCustomerDataAsLoggedIn($customer); - $this->_customerViewHelper = $this->_objectManager->create(\Magento\Customer\Helper\View::class); + $customerSession = $this->_objectManager->get(Session::class); + $customerSession->setCustomerDataAsLoggedIn($customer); } /** - * @magentoConfigFixture current_store catalog/productalert/allow_price 1 + * Test process() method * + * @magentoConfigFixture current_store catalog/productalert/allow_price 1 * * @magentoDataFixture Magento/ProductAlert/_files/product_alert.php */ public function testProcess() { - \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND); - $observer = $this->_objectManager->get(\Magento\ProductAlert\Model\Observer::class); - $observer->process(); - - /** @var \Magento\TestFramework\Mail\Template\TransportBuilderMock $transportBuilder */ - $transportBuilder = $this->_objectManager->get( - \Magento\TestFramework\Mail\Template\TransportBuilderMock::class - ); + $this->observer->process(); $this->assertContains( 'John Smith,', - $transportBuilder->getSentMessage()->getRawMessage() + $this->transportBuilder->getSentMessage()->getRawMessage() ); } + + /** + * Check translations for product alerts + * + * @magentoDbIsolation enabled + * @magentoAppArea frontend + * @magentoConfigFixture current_store catalog/productalert/allow_price 1 + * @magentoDataFixture Magento/Store/_files/second_store.php + * @magentoConfigFixture fixture_second_store_store general/locale/code pt_BR + * @magentoDataFixture Magento/ProductAlert/_files/product_alert_with_store.php + */ + public function testProcessPortuguese() + { + // get second store + $storeRepository = $this->_objectManager->create(StoreRepository::class); + $secondStore = $storeRepository->get('fixture_second_store'); + + // check if Portuguese language is specified for the second store + CacheCleaner::cleanAll(); + $storeResolver = $this->_objectManager->get(Resolver::class); + $storeResolver->emulate($secondStore->getId()); + $this->assertEquals('pt_BR', $storeResolver->getLocale()); + + // set translation data and check it + $modulesReader = $this->createPartialMock(Reader::class, ['getModuleDir']); + $modulesReader->expects($this->any()) + ->method('getModuleDir') + ->willReturn(dirname(__DIR__) . '/_files/i18n'); + /** @var Translate $translator */ + $translator = $this->_objectManager->create(Translate::class, ['modulesReader' => $modulesReader]); + $translation = [ + 'Price change alert! We wanted you to know that prices have changed for these products:' => + 'Alerta de mudanca de preco! Queriamos que voce soubesse que os precos mudaram para esses produtos:' + ]; + $translator->loadData(); + $this->assertEquals($translation, $translator->getData()); + $this->_objectManager->addSharedInstance($translator, Translate::class); + $this->_objectManager->removeSharedInstance(PhraseRendererTranslate::class); + Phrase::setRenderer($this->_objectManager->create(RendererInterface::class)); + + // dispatch process() method and check sent message + $this->observer->process(); + $message = $this->transportBuilder->getSentMessage()->getRawMessage(); + $expectedText = array_shift($translation); + $this->assertContains('/frontend/Magento/luma/pt_BR/', $message); + $this->assertContains(substr($expectedText, 0, 50), $message); + } } diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/i18n/pt_BR.csv b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/i18n/pt_BR.csv new file mode 100644 index 000000000000..0c8218a78923 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/i18n/pt_BR.csv @@ -0,0 +1 @@ +"Price change alert! We wanted you to know that prices have changed for these products:","Alerta de mudanca de preco! Queriamos que voce soubesse que os precos mudaram para esses produtos:",Magento_ProductAlert diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store.php b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store.php new file mode 100644 index 000000000000..38f00d49f1d4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/_files/product_alert_with_store.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\ProductAlert\Model\Price; +use Magento\ProductAlert\Model\Stock; + +require __DIR__ . '/../../../Magento/Customer/_files/customer_for_second_store.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php'; + +$objectManager = Bootstrap::getObjectManager(); +$price = $objectManager->create(Price::class); +$price->setCustomerId($customer->getId()) + ->setProductId($product->getId()) + ->setPrice($product->getPrice()+1) + ->setWebsiteId(1) + ->setStoreId(2); +$price->save(); + +$stock = $objectManager->create(Stock::class); +$stock->setCustomerId($customer->getId()) + ->setProductId($product->getId()) + ->setWebsiteId(1) + ->setStoreId(2); +$stock->save(); From 8145725564ebe7b0d6030985e1e821bafeec1f15 Mon Sep 17 00:00:00 2001 From: Stepan Furman <furman.stepan@gmail.com> Date: Wed, 21 Aug 2019 14:00:55 +0300 Subject: [PATCH 0366/1172] MC-13951: Declarative upgrade leads to the re-creation of constraints --- .../Patch/Schema/ChangeTmpTablesEngine.php | 68 ---------------- app/code/Magento/Bundle/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 74 ----------------- app/code/Magento/Catalog/etc/db_schema.xml | 38 ++++----- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 -------------- .../CatalogInventory/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 -------------- .../Magento/Downloadable/etc/db_schema.xml | 2 +- .../Patch/Schema/AddProductIdConstraint.php | 79 ------------------- app/code/Magento/Wishlist/etc/db_schema.xml | 4 + 10 files changed, 30 insertions(+), 369 deletions(-) delete mode 100644 app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php diff --git a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c6a67cc5a110..000000000000 --- a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Bundle\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_bundle_tmp', - 'catalog_product_index_price_bundle_sel_tmp', - 'catalog_product_index_price_bundle_opt_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Bundle/etc/db_schema.xml b/app/code/Magento/Bundle/etc/db_schema.xml index 97e86e5c1735..ade8fbf7cf1c 100644 --- a/app/code/Magento/Bundle/etc/db_schema.xml +++ b/app/code/Magento/Bundle/etc/db_schema.xml @@ -203,7 +203,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -265,7 +265,7 @@ <column name="selection_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Sel Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -320,7 +320,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Opt Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> diff --git a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c39247f9b30d..000000000000 --- a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Catalog\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_cfg_opt_agr_tmp', - 'catalog_product_index_price_cfg_opt_tmp', - 'catalog_product_index_price_final_tmp', - 'catalog_product_index_price_opt_tmp', - 'catalog_product_index_price_opt_agr_tmp', - 'catalog_product_index_eav_tmp', - 'catalog_product_index_eav_decimal_tmp', - 'catalog_product_index_price_tmp', - 'catalog_category_product_index_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 6fef4ca6e912..b5e02b1daaa0 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -1238,7 +1238,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Aggregate Temp Table"> <column xsi:type="int" name="parent_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent ID"/> @@ -1279,7 +1279,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1327,7 +1327,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_final_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_final_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Final Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1375,7 +1375,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1418,7 +1418,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Aggregate Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1470,7 +1470,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1489,13 +1489,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1528,7 +1528,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Decimal Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1547,13 +1547,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1592,7 +1592,7 @@ <column name="min_price"/> </index> </table> - <table name="catalog_product_index_price_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1617,17 +1617,17 @@ <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> </table> - <table name="catalog_category_product_index_tmp" resource="default" engine="memory" + <table name="catalog_category_product_index_tmp" resource="default" engine="innodb" comment="Catalog Category Product Indexer temporary table"> <column xsi:type="int" name="category_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Category ID"/> @@ -1646,7 +1646,7 @@ <column name="product_id"/> <column name="store_id"/> </constraint> - <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> + <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="btree"> <column name="product_id"/> <column name="category_id"/> <column name="store_id"/> diff --git a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index 7f43cd279d4e..000000000000 --- a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('cataloginventory_stock_status_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/CatalogInventory/etc/db_schema.xml b/app/code/Magento/CatalogInventory/etc/db_schema.xml index 5ac7fedc5aa1..67a200eb3712 100644 --- a/app/code/Magento/CatalogInventory/etc/db_schema.xml +++ b/app/code/Magento/CatalogInventory/etc/db_schema.xml @@ -142,7 +142,7 @@ <column name="website_id"/> </index> </table> - <table name="cataloginventory_stock_status_tmp" resource="default" engine="memory" + <table name="cataloginventory_stock_status_tmp" resource="default" engine="innodb" comment="Cataloginventory Stock Status Indexer Tmp"> <column xsi:type="int" name="product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Product Id"/> @@ -159,10 +159,10 @@ <column name="website_id"/> <column name="stock_id"/> </constraint> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index caf2f7745a3d..000000000000 --- a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Downloadable\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('catalog_product_index_price_downlod_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Downloadable/etc/db_schema.xml b/app/code/Magento/Downloadable/etc/db_schema.xml index ccbefa4fb399..ee7b3c5683ea 100644 --- a/app/code/Magento/Downloadable/etc/db_schema.xml +++ b/app/code/Magento/Downloadable/etc/db_schema.xml @@ -233,7 +233,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="innodb" comment="Temporary Indexer Table for price of downloadable products"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> diff --git a/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php b/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php deleted file mode 100644 index 5c65fce10ccd..000000000000 --- a/app/code/Magento/Wishlist/Setup/Patch/Schema/AddProductIdConstraint.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Wishlist\Setup\Patch\Schema; - -use Magento\Framework\DB\Adapter\AdapterInterface; -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Class AddProductIdConstraint - */ -class AddProductIdConstraint implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct( - SchemaSetupInterface $schemaSetup - ) { - $this->schemaSetup = $schemaSetup; - } - - /** - * Run code inside patch. - * - * @return void - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $this->schemaSetup->getConnection()->addForeignKey( - $this->schemaSetup->getConnection()->getForeignKeyName( - $this->schemaSetup->getTable('wishlist_item_option'), - 'product_id', - $this->schemaSetup->getTable('catalog_product_entity'), - 'entity_id' - ), - $this->schemaSetup->getTable('wishlist_item_option'), - 'product_id', - $this->schemaSetup->getTable('catalog_product_entity'), - 'entity_id', - AdapterInterface::FK_ACTION_CASCADE, - true - ); - - $this->schemaSetup->endSetup(); - } - - /** - * Get array of patches that have to be executed prior to this. - * - * @return string[] - */ - public static function getDependencies() - { - return []; - } - - /** - * Get aliases (previous names) for the patch. - * - * @return string[] - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Wishlist/etc/db_schema.xml b/app/code/Magento/Wishlist/etc/db_schema.xml index 8a02f411ad0d..a1c50c240a9f 100644 --- a/app/code/Magento/Wishlist/etc/db_schema.xml +++ b/app/code/Magento/Wishlist/etc/db_schema.xml @@ -77,5 +77,9 @@ <constraint xsi:type="foreign" referenceId="FK_A014B30B04B72DD0EAB3EECD779728D6" table="wishlist_item_option" column="wishlist_item_id" referenceTable="wishlist_item" referenceColumn="wishlist_item_id" onDelete="CASCADE"/> + <constraint xsi:type="foreign" referenceId="WISHLIST_ITEM_OPTION_PRODUCT_ID_CATALOG_PRODUCT_ENTITY_ENTITY_ID" + table="wishlist_item_option" + column="product_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" + onDelete="CASCADE"/> </table> </schema> From 96f56f1354707933aa7f071d05bd6ae4e8cb2c11 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Wed, 21 Aug 2019 14:16:21 +0300 Subject: [PATCH 0367/1172] MC-19415: Displayed incorrect price - revert MC-18009 --- .../Catalog/Model/ProductLink/Search.php | 1 + .../Adminhtml/Product/SearchTest.php | 23 ++----------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index ad7f3370ab3f..681c01bb1281 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -60,6 +60,7 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); + $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 0704d59a1431..8a33543e9343 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,8 +38,7 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEmpty($jsonResponse['options']); + $this->assertContains('{"options":[],"total":0}', $responseBody); } /** @@ -58,24 +57,6 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(1, $jsonResponse['total']); - $this->assertCount(1, $jsonResponse['options']); - } - - /** - * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php - */ - public function testExecuteEnabledAndDisabledProducts() : void - { - $this->getRequest() - ->setPostValue('searchKey', 'simple') - ->setPostValue('page', 1) - ->setPostValue('limit', 50); - $this->dispatch('backend/catalog/product/search'); - $responseBody = $this->getResponse()->getBody(); - $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(7, $jsonResponse['total']); - $this->assertCount(7, $jsonResponse['options']); + $this->assertContains('{"options":[],"total":0}', $responseBody); } } From 3a04bb7564bdb6da33aed7ebf886149d87d612e0 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Wed, 21 Aug 2019 15:20:23 +0300 Subject: [PATCH 0368/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer module --- .../Customer/Controller/Account/CreatePost.php | 12 +++++------- app/code/Magento/Customer/etc/frontend/di.xml | 14 +++++++++++++- .../customerAlreadyExistsErrorMessage.phtml | 10 ++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index 510d82879637..3a6c1945eb9d 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -394,14 +394,12 @@ public function execute() return $resultRedirect; } catch (StateException $e) { - $url = $this->urlModel->getUrl('customer/account/forgotpassword'); - // @codingStandardsIgnoreStart - $message = __( - 'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.', - $url + $this->messageManager->addComplexErrorMessage( + 'customerAlreadyExistsErrorMessage', + [ + 'url' => $this->urlModel->getUrl('customer/account/forgotpassword'), + ] ); - // @codingStandardsIgnoreEnd - $this->messageManager->addErrorMessage($message); } catch (InputException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); foreach ($e->getErrors() as $error) { diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index c31742519e58..db6f2a6fc531 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -77,4 +77,16 @@ </argument> </arguments> </type> -</config> \ No newline at end of file + <type name="Magento\Framework\View\Element\Message\MessageConfigurationsPool"> + <arguments> + <argument name="configurationsMap" xsi:type="array"> + <item name="customerAlreadyExistsErrorMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/customerAlreadyExistsErrorMessage.phtml</item> + </item> + </item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml new file mode 100644 index 000000000000..27ffc1433a36 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\View\Element\Template $block */ +?> + +<?= $block->escapeHtml(__('There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.', $block->getData('url')), ['a']); From 246f2c9fc940408dd97904dd3c5385f8aad9939d Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 21 Aug 2019 16:59:20 +0400 Subject: [PATCH 0369/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Updated automated test script --- .../Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index 3663035ca47a..1e71d8e15265 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -10,7 +10,7 @@ <test name="AdminCategoryWithRestrictedUrlKeyNotCreatedTest"> <annotations> <features value="CatalogUrlRewrite"/> - <stoty value="Subcategory 'liquid-hand-soap' is not opened in category 'soap'"/> + <stories value="Subcategory 'liquid-hand-soap' is not opened in category 'soap'"/> <title value="Category with restricted Url Key cannot be created"/> <description value="Category with restricted Url Key cannot be created"/> <severity value="MAJOR"/> From 444fb5c24fd6ef5e3ac647b08d1e6f2fecf5cfda Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Wed, 21 Aug 2019 18:03:56 +0300 Subject: [PATCH 0370/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer --- .../Customer/Controller/Account/CreatePost.php | 14 ++++++-------- .../Magento/Customer/Controller/Address/Delete.php | 2 +- app/code/Magento/Customer/etc/frontend/di.xml | 12 ++++++++++++ .../messages/confirmAccountSuccessMessage.phtml | 10 ++++++++++ .../messages/unableDeleteAddressMessage.phtml | 10 ++++++++++ 5 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml create mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index 3a6c1945eb9d..6c65d8c8d282 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -364,15 +364,13 @@ public function execute() ); $confirmationStatus = $this->accountManagement->getConfirmationStatus($customer->getId()); if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) { - $email = $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()); - // @codingStandardsIgnoreStart - $this->messageManager->addSuccessMessage( - __( - 'You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', - $email - ) + $this->messageManager->addComplexSuccessMessage( + 'confirmAccountSuccessMessage', + [ + 'url' => $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()), + ] ); - // @codingStandardsIgnoreEnd + $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); $resultRedirect->setUrl($this->_redirect->success($url)); } else { diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php index c90489bfc978..188ed31bed0a 100644 --- a/app/code/Magento/Customer/Controller/Address/Delete.php +++ b/app/code/Magento/Customer/Controller/Address/Delete.php @@ -29,7 +29,7 @@ public function execute() $this->_addressRepository->deleteById($addressId); $this->messageManager->addSuccessMessage(__('You deleted the address.')); } else { - $this->messageManager->addErrorMessage(__('We can\'t delete the address right now.')); + $this->messageManager->addComplexErrorMessage('unableDeleteAddressMessage'); } } catch (\Exception $other) { $this->messageManager->addExceptionMessage($other, __('We can\'t delete the address right now.')); diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index db6f2a6fc531..e43bc4af1fca 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -86,6 +86,18 @@ <item name="template" xsi:type="string">Magento_Customer::messages/customerAlreadyExistsErrorMessage.phtml</item> </item> </item> + <item name="confirmAccountSuccessMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/confirmAccountSuccessMessage.phtml</item> + </item> + </item> + <item name="unableDeleteAddressMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/unableDeleteAddressMessage.phtml</item> + </item> + </item> </argument> </arguments> </type> diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml new file mode 100644 index 000000000000..3356c1248b37 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\View\Element\Template $block */ +?> + +<?= $block->escapeHtml(__('You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', $block->getData('url')), ['a']); diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml new file mode 100644 index 000000000000..c49a1d4e4642 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml @@ -0,0 +1,10 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\View\Element\Template $block */ +?> + +<?= $block->escapeHtml(__('We can\'t delete the address right now.')); From 1e67a692ec0cb57b5fbed607cfb468eb1d987b7a Mon Sep 17 00:00:00 2001 From: Myroslav Dobra <dmaraptor@gmail.com> Date: Wed, 21 Aug 2019 18:34:13 +0300 Subject: [PATCH 0371/1172] MC-19334: Reindex error when website have store without store view --- app/code/Magento/Store/Model/ScopeTreeProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Store/Model/ScopeTreeProvider.php b/app/code/Magento/Store/Model/ScopeTreeProvider.php index a22d5abb8c48..d15030fe88ac 100644 --- a/app/code/Magento/Store/Model/ScopeTreeProvider.php +++ b/app/code/Magento/Store/Model/ScopeTreeProvider.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Store\Model; use Magento\Framework\App\Config\ScopeConfigInterface; From c7436240a4802b45b9fadab1039c8d63a8fd7005 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Wed, 21 Aug 2019 19:09:54 +0300 Subject: [PATCH 0372/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer --- app/code/Magento/Customer/Controller/Address/Delete.php | 2 +- app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php index 188ed31bed0a..9df06c69d4a8 100644 --- a/app/code/Magento/Customer/Controller/Address/Delete.php +++ b/app/code/Magento/Customer/Controller/Address/Delete.php @@ -32,7 +32,7 @@ public function execute() $this->messageManager->addComplexErrorMessage('unableDeleteAddressMessage'); } } catch (\Exception $other) { - $this->messageManager->addExceptionMessage($other, __('We can\'t delete the address right now.')); + $this->messageManager->addException($other, __('We can\'t delete the address right now.')); } } return $this->resultRedirectFactory->create()->setPath('*/*/index'); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php index 64c94fa230fb..bb3589a75f72 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php @@ -96,7 +96,7 @@ public function execute() $this->messageManager->addSuccessMessage(__('You saved the customer group.')); $resultRedirect->setPath('customer/group'); } catch (\Exception $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); if ($customerGroup != null) { $this->storeCustomerGroupDataToSession( $this->dataObjectProcessor->buildOutputDataArray( From e81a669dd943159d11b16f239349c2e0ddcac80a Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Thu, 22 Aug 2019 04:53:16 +0000 Subject: [PATCH 0373/1172] MC-19051: [backport for 2.3.3] Nightly build jobs were failing lately after un-skipping tests in MC-5777 --- .../Model/Indexer/ReindexRuleProductTest.php | 47 +++++-------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php index ff566fa3cc77..a86ab736fb28 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/ReindexRuleProductTest.php @@ -89,17 +89,6 @@ public function testExecute() 6 => [$websiteId => 1], ]; - $ruleMock = $this->createMock(Rule::class); - $ruleMock->expects($this->once()) - ->method('getIsActive') - ->willReturn(true); - $ruleMock->expects($this->exactly(2)) - ->method('getWebsiteIds') - ->willReturn([$websiteId]); - $ruleMock->expects($this->once()) - ->method('getMatchingProductIds') - ->willReturn($productIds); - $this->tableSwapperMock->expects($this->once()) ->method('getWorkingTableName') ->with('catalogrule_product') @@ -118,30 +107,18 @@ public function testExecute() ->with('catalogrule_product_replica') ->willReturn('catalogrule_product_replica'); - $ruleMock->expects($this->once()) - ->method('getId') - ->willReturn(100); - $ruleMock->expects($this->once()) - ->method('getCustomerGroupIds') - ->willReturn([10]); - $ruleMock->expects($this->atLeastOnce()) - ->method('getFromDate') - ->willReturn('2017-06-21'); - $ruleMock->expects($this->atLeastOnce()) - ->method('getToDate') - ->willReturn('2017-06-30'); - $ruleMock->expects($this->once()) - ->method('getSortOrder') - ->willReturn(1); - $ruleMock->expects($this->once()) - ->method('getSimpleAction') - ->willReturn('simple_action'); - $ruleMock->expects($this->once()) - ->method('getDiscountAmount') - ->willReturn(43); - $ruleMock->expects($this->once()) - ->method('getStopRulesProcessing') - ->willReturn(true); + $ruleMock = $this->createMock(Rule::class); + $ruleMock->expects($this->once())->method('getIsActive')->willReturn(true); + $ruleMock->expects($this->exactly(2))->method('getWebsiteIds')->willReturn([$websiteId]); + $ruleMock->expects($this->once())->method('getMatchingProductIds')->willReturn($productIds); + $ruleMock->expects($this->once())->method('getId')->willReturn(100); + $ruleMock->expects($this->once())->method('getCustomerGroupIds')->willReturn([10]); + $ruleMock->expects($this->atLeastOnce())->method('getFromDate')->willReturn('2017-06-21'); + $ruleMock->expects($this->atLeastOnce())->method('getToDate')->willReturn('2017-06-30'); + $ruleMock->expects($this->once())->method('getSortOrder')->willReturn(1); + $ruleMock->expects($this->once())->method('getSimpleAction')->willReturn('simple_action'); + $ruleMock->expects($this->once())->method('getDiscountAmount')->willReturn(43); + $ruleMock->expects($this->once())->method('getStopRulesProcessing')->willReturn(true); $this->localeDateMock->expects($this->once()) ->method('getConfigTimezone') From 0bf86e6a094e56ff945fc39a48459cfb574c6b0c Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Wed, 21 Aug 2019 23:27:51 +0300 Subject: [PATCH 0374/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer --- .../Customer/Controller/Account/Confirm.php | 4 +- .../Controller/Account/Confirmation.php | 4 +- .../Customer/Controller/Account/LoginPost.php | 1 + .../Controller/Adminhtml/Group/Delete.php | 4 +- .../Adminhtml/Index/AbstractMassAction.php | 1 + .../Controller/Adminhtml/Index/Edit.php | 16 +- .../Controller/Adminhtml/Index/InlineEdit.php | 20 ++- .../Unit/Controller/Account/ConfirmTest.php | 22 +-- .../Controller/Account/CreatePostTest.php | 34 +++-- .../Unit/Controller/Account/LoginPostTest.php | 54 ++++--- .../Unit/Controller/Address/DeleteTest.php | 2 +- .../Controller/Adminhtml/Group/SaveTest.php | 2 +- .../Adminhtml/Index/InlineEditTest.php | 20 ++- .../Controller/Adminhtml/Index/SaveTest.php | 80 ++++++---- .../Observer/AfterAddressSaveObserverTest.php | 138 ++++++++++-------- .../confirmAccountSuccessMessage.phtml | 1 - .../messages/unableDeleteAddressMessage.phtml | 1 - 17 files changed, 239 insertions(+), 165 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php index 4f0fb3ff0855..3b19a8b33512 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirm.php +++ b/app/code/Magento/Customer/Controller/Account/Confirm.php @@ -151,7 +151,9 @@ public function execute() $customerId = $this->getRequest()->getParam('id', false); $key = $this->getRequest()->getParam('key', false); if (empty($customerId) || empty($key)) { - throw new \Exception(__('Bad request.')); + $this->messageManager->addErrorMessage(__('Bad request.')); + $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); + return $resultRedirect->setUrl($this->_redirect->error($url)); } // log in and send greeting email diff --git a/app/code/Magento/Customer/Controller/Account/Confirmation.php b/app/code/Magento/Customer/Controller/Account/Confirmation.php index bd9066dcd464..aebc0547f353 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirmation.php +++ b/app/code/Magento/Customer/Controller/Account/Confirmation.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -15,6 +14,9 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Framework\Exception\State\InvalidTransitionException; +/** + * Class Confirmation + */ class Confirmation extends \Magento\Customer\Controller\AbstractAccount { /** diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index a7632401933e..046ae5c70276 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -26,6 +26,7 @@ use Magento\Framework\Phrase; /** + * Class LoginPost * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class LoginPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php index 819a49178a24..661ef1cace69 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -9,6 +8,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; +/** + * Class Delete + */ class Delete extends \Magento\Customer\Controller\Adminhtml\Group implements HttpPostActionInterface { /** diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php index 08c6e5148ade..e2bde42351d4 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php @@ -73,6 +73,7 @@ public function execute() /** * Return component referer url + * * TODO: Technical dept referer url should be implement as a part of Action configuration in appropriate way * * @return null|string diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php index d4697ecd6169..3d7f75884057 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php @@ -9,6 +9,9 @@ use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\Exception\NoSuchEntityException; +/** + * Class Edit + */ class Edit extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** @@ -33,14 +36,11 @@ public function execute() $customer = $this->_customerRepository->getById($customerId); $customerData['account'] = $this->customerMapper->toFlatArray($customer); $customerData['account'][CustomerInterface::ID] = $customerId; - try { - $addresses = $customer->getAddresses(); - foreach ($addresses as $address) { - $customerData['address'][$address->getId()] = $this->addressMapper->toFlatArray($address); - $customerData['address'][$address->getId()]['id'] = $address->getId(); - } - } catch (NoSuchEntityException $e) { - //do nothing + + $addresses = $customer->getAddresses(); + foreach ($addresses as $address) { + $customerData['address'][$address->getId()] = $this->addressMapper->toFlatArray($address); + $customerData['address'][$address->getId()]['id'] = $address->getId(); } } catch (NoSuchEntityException $e) { $this->messageManager->addExceptionMessage($e, __('Something went wrong while editing the customer.')); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index 41d2c43bdaf7..ba8c84a0ac27 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -128,10 +128,12 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]); + return $resultJson->setData( + [ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ] + ); } foreach (array_keys($postItems) as $customerId) { @@ -147,10 +149,12 @@ public function execute() $this->getEmailNotification()->credentialsChanged($this->getCustomer(), $currentCustomer->getEmail()); } - return $resultJson->setData([ - 'messages' => $this->getErrorMessages(), - 'error' => $this->isErrorExists() - ]); + return $resultJson->setData( + [ + 'messages' => $this->getErrorMessages(), + 'error' => $this->isErrorExists() + ] + ); } /** diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php index 0684594d510d..335d1068206b 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php @@ -255,10 +255,12 @@ public function testSuccessMessage($customerId, $key, $vatValidationEnabled, $ad $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['id', false, $customerId], - ['key', false, $key], - ]); + ->willReturnMap( + [ + ['id', false, $customerId], + ['key', false, $key], + ] + ); $this->customerRepositoryMock->expects($this->any()) ->method('getById') @@ -372,11 +374,13 @@ public function testSuccessRedirect( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['id', false, $customerId], - ['key', false, $key], - ['back_url', false, $backUrl], - ]); + ->willReturnMap( + [ + ['id', false, $customerId], + ['key', false, $key], + ['back_url', false, $backUrl], + ] + ); $this->customerRepositoryMock->expects($this->any()) ->method('getById') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php index ac52c395d678..faf55347dba7 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php @@ -346,11 +346,13 @@ public function testSuccessMessage( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ]); + ->willReturnMap( + [ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ] + ); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -477,11 +479,13 @@ public function testSuccessRedirect( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ]); + ->willReturnMap( + [ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ] + ); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -508,10 +512,12 @@ public function testSuccessRedirect( $this->urlMock->expects($this->any()) ->method('getUrl') - ->willReturnMap([ - ['*/*/index', ['_secure' => true], $successUrl], - ['*/*/create', ['_secure' => true], $successUrl], - ]); + ->willReturnMap( + [ + ['*/*/index', ['_secure' => true], $successUrl], + ['*/*/create', ['_secure' => true], $successUrl], + ] + ); $this->redirectMock->expects($this->once()) ->method('success') ->with($this->equalTo($successUrl)) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index 51b84d807dc1..fd70a55ad7de 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -93,12 +93,14 @@ protected function setUp() $this->session = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods([ - 'isLoggedIn', - 'setCustomerDataAsLoggedIn', - 'regenerateId', - 'setUsername', - ]) + ->setMethods( + [ + 'isLoggedIn', + 'setCustomerDataAsLoggedIn', + 'regenerateId', + 'setUsername', + ] + ) ->getMock(); $this->accountManagement = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) @@ -253,10 +255,12 @@ public function testExecuteSuccessCustomRedirect() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -335,10 +339,12 @@ public function testExecuteSuccess() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -426,10 +432,12 @@ public function testExecuteWithException( $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn([ - 'username' => $username, - 'password' => $password, - ]); + ->willReturn( + [ + 'username' => $username, + 'password' => $password, + ] + ); $exception = new $exceptionData['exception'](__($exceptionData['message'])); @@ -488,10 +496,12 @@ protected function prepareContext() $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) ->disableOriginalConstructor() - ->setMethods([ - 'isPost', - 'getPost', - ]) + ->setMethods( + [ + 'isPost', + 'getPost', + ] + ) ->getMock(); $this->resultRedirect = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php index 7424b0f649fd..3634aaf469f9 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php @@ -183,7 +183,7 @@ public function testExecuteWithException() ->willReturn(34); $exception = new \Exception('Exception'); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addComplexErrorMessage') ->with(__('We can\'t delete the address right now.')) ->willThrowException($exception); $this->messageManager->expects($this->once()) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php index c9f885315b0e..b0b8075325f8 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php @@ -175,7 +175,7 @@ public function testExecuteWithTaxClassAndException() ->with('customer/group') ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('Exception'); $this->dataObjectProcessorMock->expects($this->once()) ->method('buildOutputDataArray') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index c198eb3a212f..769c77dfcb4e 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -291,10 +291,12 @@ protected function prepareMocksForErrorMessagesProcessing() ->willReturn('Error text'); $this->resultJson->expects($this->once()) ->method('setData') - ->with([ - 'messages' => ['Error text'], - 'error' => true, - ]) + ->with( + [ + 'messages' => ['Error text'], + 'error' => true, + ] + ) ->willReturnSelf(); } @@ -340,10 +342,12 @@ public function testExecuteWithoutItems() $this->resultJson ->expects($this->once()) ->method('setData') - ->with([ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ]) + ->with( + [ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ] + ) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php index 5f34583c855c..9724ac13dde8 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php @@ -338,10 +338,12 @@ public function testExecuteWithExistentCustomer() $this->requestMock->expects($this->atLeastOnce()) ->method('getPostValue') - ->willReturnMap([ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ]); + ->willReturnMap( + [ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ] + ); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -542,10 +544,12 @@ public function testExecuteWithNewCustomer() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap([ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ]); + ->willReturnMap( + [ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ] + ); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -723,10 +727,12 @@ public function testExecuteWithNewCustomerAndValidationException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap([ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ]); + ->willReturnMap( + [ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ] + ); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -812,10 +818,12 @@ public function testExecuteWithNewCustomerAndValidationException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with([ - 'customer' => $extractedData, - 'subscription' => $subscription, - ]); + ->with( + [ + 'customer' => $extractedData, + 'subscription' => $subscription, + ] + ); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -870,10 +878,12 @@ public function testExecuteWithNewCustomerAndLocalizedException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap([ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ]); + ->willReturnMap( + [ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ] + ); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -959,10 +969,12 @@ public function testExecuteWithNewCustomerAndLocalizedException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with([ - 'customer' => $extractedData, - 'subscription' => $subscription, - ]); + ->with( + [ + 'customer' => $extractedData, + 'subscription' => $subscription, + ] + ); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -1017,10 +1029,12 @@ public function testExecuteWithNewCustomerAndException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap([ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ]); + ->willReturnMap( + [ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ] + ); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -1107,10 +1121,12 @@ public function testExecuteWithNewCustomerAndException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with([ - 'customer' => $extractedData, - 'subscription' => $subscription, - ]); + ->with( + [ + 'customer' => $extractedData, + 'subscription' => $subscription, + ] + ); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) diff --git a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 4501b611aa11..79766178a767 100644 --- a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -210,9 +210,11 @@ public function testAfterAddressSaveRestricted( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomerAddress', - ]) + ->setMethods( + [ + 'getCustomerAddress', + ] + ) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -225,10 +227,12 @@ public function testAfterAddressSaveRestricted( $this->registry->expects($this->any()) ->method('registry') - ->willReturnMap([ - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, $processedFlag], - [BeforeAddressSaveObserver::VIV_CURRENTLY_SAVED_ADDRESS, $registeredAddressId], - ]); + ->willReturnMap( + [ + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, $processedFlag], + [BeforeAddressSaveObserver::VIV_CURRENTLY_SAVED_ADDRESS, $registeredAddressId], + ] + ); $this->helperAddress->expects($this->any()) ->method('getTaxCalculationAddressType') @@ -266,11 +270,13 @@ public function testAfterAddressSaveException() $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomer', - 'getForceProcess', - 'getVatId', - ]) + ->setMethods( + [ + 'getCustomer', + 'getForceProcess', + 'getVatId', + ] + ) ->getMock(); $address->expects($this->any()) ->method('getCustomer') @@ -284,9 +290,11 @@ public function testAfterAddressSaveException() $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomerAddress', - ]) + ->setMethods( + [ + 'getCustomerAddress', + ] + ) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -303,10 +311,12 @@ public function testAfterAddressSaveException() ->willReturn(false); $this->registry->expects($this->any()) ->method('register') - ->willReturnMap([ - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, true, false, $this->registry], - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, false, true, $this->registry], - ]); + ->willReturnMap( + [ + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, true, false, $this->registry], + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, false, true, $this->registry], + ] + ); $this->model->execute($observer); } @@ -336,13 +346,15 @@ public function testAfterAddressSaveDefaultGroup( $customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getStore', - 'getDisableAutoGroupChange', - 'getGroupId', - 'setGroupId', - 'save', - ]) + ->setMethods( + [ + 'getStore', + 'getDisableAutoGroupChange', + 'getGroupId', + 'setGroupId', + 'save', + ] + ) ->getMock(); $customer->expects($this->exactly(2)) ->method('getStore') @@ -363,12 +375,14 @@ public function testAfterAddressSaveDefaultGroup( $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomer', - 'getForceProcess', - 'getVatId', - 'getCountry', - ]) + ->setMethods( + [ + 'getCustomer', + 'getForceProcess', + 'getVatId', + 'getCountry', + ] + ) ->getMock(); $address->expects($this->once()) ->method('getCustomer') @@ -385,9 +399,11 @@ public function testAfterAddressSaveDefaultGroup( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomerAddress', - ]) + ->setMethods( + [ + 'getCustomerAddress', + ] + ) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -457,10 +473,12 @@ public function testAfterAddressSaveNewGroup( $validationResult = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() - ->setMethods([ - 'getIsValid', - 'getRequestSuccess', - ]) + ->setMethods( + [ + 'getIsValid', + 'getRequestSuccess', + ] + ) ->getMock(); $validationResult->expects($this->any()) ->method('getIsValid') @@ -471,13 +489,15 @@ public function testAfterAddressSaveNewGroup( $customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getStore', - 'getDisableAutoGroupChange', - 'getGroupId', - 'setGroupId', - 'save', - ]) + ->setMethods( + [ + 'getStore', + 'getDisableAutoGroupChange', + 'getGroupId', + 'setGroupId', + 'save', + ] + ) ->getMock(); $customer->expects($this->exactly(2)) ->method('getStore') @@ -503,14 +523,16 @@ public function testAfterAddressSaveNewGroup( $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomer', - 'getForceProcess', - 'getVatId', - 'getCountryId', - 'getCountry', - 'setVatValidationResult', - ]) + ->setMethods( + [ + 'getCustomer', + 'getForceProcess', + 'getVatId', + 'getCountryId', + 'getCountry', + 'setVatValidationResult', + ] + ) ->getMock(); $address->expects($this->any()) ->method('getCustomer') @@ -534,9 +556,11 @@ public function testAfterAddressSaveNewGroup( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods([ - 'getCustomerAddress', - ]) + ->setMethods( + [ + 'getCustomerAddress', + ] + ) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml index 3356c1248b37..a2edb20e967c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/messages/confirmAccountSuccessMessage.phtml @@ -6,5 +6,4 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> - <?= $block->escapeHtml(__('You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', $block->getData('url')), ['a']); diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml index c49a1d4e4642..a5313078e13c 100644 --- a/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml @@ -6,5 +6,4 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> - <?= $block->escapeHtml(__('We can\'t delete the address right now.')); From 60823ed12471599b895a700c0c3724a5b6d87572 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Thu, 22 Aug 2019 10:12:58 +0300 Subject: [PATCH 0375/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento_Customer --- app/code/Magento/Customer/Controller/Account/Confirm.php | 4 +++- app/code/Magento/Customer/Controller/Account/EditPost.php | 2 ++ .../Customer/Test/Unit/Controller/Account/ConfirmTest.php | 2 +- .../Customer/Test/Unit/Controller/Address/DeleteTest.php | 6 +++--- .../messages/customerAlreadyExistsErrorMessage.phtml | 1 - 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php index 3b19a8b33512..6809442bbc92 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirm.php +++ b/app/code/Magento/Customer/Controller/Account/Confirm.php @@ -24,7 +24,9 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Confirm extends \Magento\Customer\Controller\AbstractAccount +class Confirm + extends \Magento\Customer\Controller\AbstractAccount + implements \Magento\Framework\App\Action\Action\ActionInterface { /** * @var \Magento\Framework\App\Config\ScopeConfigInterface diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php index d2300b7b490c..0203226fc2e3 100644 --- a/app/code/Magento/Customer/Controller/Account/EditPost.php +++ b/app/code/Magento/Customer/Controller/Account/EditPost.php @@ -345,9 +345,11 @@ private function processChangeEmailRequest(\Magento\Customer\Api\Data\CustomerIn $this->getRequest()->getPost('current_password') ); } catch (InvalidEmailOrPasswordException $e) { + // @codingStandardsIgnoreStart throw new InvalidEmailOrPasswordException( __("The password doesn't match this account. Verify the password and try again.") ); + // @codingStandardsIgnoreEnd } } } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php index 335d1068206b..61efd9d562b4 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php @@ -205,7 +205,7 @@ public function testNoCustomerIdInRequest($customerId, $key) $exception = new \Exception('Bad request.'); $this->messageManagerMock->expects($this->once()) - ->method('addExceptionMessage') + ->method('addException') ->with($this->equalTo($exception), $this->equalTo('There was an error confirming the account')); $testUrl = 'http://example.com'; diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php index 3634aaf469f9..046c023d35c6 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php @@ -184,10 +184,10 @@ public function testExecuteWithException() $exception = new \Exception('Exception'); $this->messageManager->expects($this->once()) ->method('addComplexErrorMessage') - ->with(__('We can\'t delete the address right now.')) - ->willThrowException($exception); + ->with('unableDeleteAddressMessage') + ->willReturnSelf(); $this->messageManager->expects($this->once()) - ->method('addExceptionMessage') + ->method('addException') ->with($exception, __('We can\'t delete the address right now.')); $this->resultRedirect->expects($this->once()) ->method('setPath') diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml index 27ffc1433a36..32982551b5b1 100644 --- a/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/messages/customerAlreadyExistsErrorMessage.phtml @@ -6,5 +6,4 @@ /** @var \Magento\Framework\View\Element\Template $block */ ?> - <?= $block->escapeHtml(__('There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.', $block->getData('url')), ['a']); From 3910cacc104294b5fb92d562034620300461cfc6 Mon Sep 17 00:00:00 2001 From: Andrii Meysar <andrii.meysar@transoftgroup.com> Date: Thu, 22 Aug 2019 13:48:36 +0300 Subject: [PATCH 0376/1172] MC-19566: Failing Integration Magento.Catalog.Model.Indexer.Product.Flat.Action.RelationTest.testExecute --- .../Catalog/Model/Indexer/Product/Flat/AbstractAction.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php index ebad10e19762..a0acacd4dfd2 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/AbstractAction.php @@ -254,10 +254,12 @@ protected function _updateRelationProducts($storeId, $productIds = null) * * @param int $storeId * @return \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function _cleanRelationProducts($storeId) { - if (!$this->_productIndexerHelper->isAddChildData()) { + if (!$this->_productIndexerHelper->isAddChildData() || !$this->_isFlatTableExists($storeId)) { return $this; } From 81c566a0f0d396e0382fea0877526e7702defb02 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Thu, 22 Aug 2019 17:53:18 +0400 Subject: [PATCH 0377/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11701 --- ...gRefreshCaptchaImageProductionModeTest.xml | 16 ++++--------- .../Test/Mftf/Data/DeveloperJsConfigs.xml | 22 ------------------ .../Metadata/developer_js_config-meta.xml | 23 ------------------- 3 files changed, 5 insertions(+), 56 deletions(-) delete mode 100644 app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml delete mode 100644 app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml index 08bc3dbd0241..e2c4e929741b 100644 --- a/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml +++ b/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml @@ -20,9 +20,6 @@ <group value="captcha"/> </annotations> <before> - <!--Switch to developer mode--> - <comment userInput="Switch to developer mode" stepKey="commentSwitchDevMode"/> - <magentoCLI command="deploy:mode:set developer" stepKey="switchToDeveloperMode"/> <!--Enable JavaScript setting--> <comment userInput="Enable JavaScript setting" stepKey="commentEnableJSSettings"/> <magentoCLI command="config:set dev/js/enable_js_bundling 1" stepKey="enableJSBundling"/> @@ -32,13 +29,13 @@ <magentoCLI command="config:set admin/captcha/enable 1" stepKey="enableAdminCaptcha"/> <!--Clean cache--> <comment userInput="Clean cache" stepKey="commentCleanCache"/> - <!--<magentoCLI command="cache:clean" stepKey="cleanCaches"/>--> + <magentoCLI command="cache:clean" stepKey="cleanCaches"/> </before> <after> - <!--Set default settings--> - <comment userInput="Set default settings" stepKey="commentSetDafault"/> - <createData entity="SetDefaultJavaScriptBundling" stepKey="setDefaultJavaScriptBundling"/> - <createData entity="SetDefaultMinifyJavaScriptFiles" stepKey="setDefaultMinifyJavaScriptFiles"/> + <!--Disable JavaScript setting--> + <comment userInput="Disable JavaScript setting" stepKey="commentDisableJSSettings"/> + <magentoCLI command="config:set dev/js/enable_js_bundling 0" stepKey="disableJSBundling"/> + <magentoCLI command="config:set dev/js/minify_files 0" stepKey="disableMinifyJSFiles"/> </after> <!--Go to forgot password--> <comment userInput="Go to forgot password" stepKey="commentGoToForgotPassword"/> @@ -49,9 +46,6 @@ <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageAfterRefresh"/> <assertNotEquals expected="$grabCaptchaImageBeforeRefresh" expectedType="variable" actual="$grabCaptchaImageAfterRefresh" actualType="variable" stepKey="assertCaptchaImagesNotEquals"/> - <!--Switch to production mode--> - <comment userInput="Switch to production mode" stepKey="commentSwitchProdMode"/> - <magentoCLI command="deploy:mode:set production" stepKey="switchToProductionMode"/> <amOnPage url="{{AdminForgotPasswordPage.url}}" stepKey="navigateToForgotPasswordPagePageProdMode"/> <waitForPageLoad stepKey="waitForPageLoadProdMode"/> <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageBeforeRefreshProdMode"/> diff --git a/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml b/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml deleted file mode 100644 index e490ef62bbed..000000000000 --- a/app/code/Magento/Developer/Test/Mftf/Data/DeveloperJsConfigs.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="SetDefaultJavaScriptBundling" type="dev_js_settings"> - <requiredEntity type="default_bundling">DefaultJSBundling</requiredEntity> - </entity> - <entity name="DefaultJSBundling" type="default_bundling"> - <data key="inherit">1</data> - </entity> - <entity name="SetDefaultMinifyJavaScriptFiles" type="dev_js_settings"> - <requiredEntity type="default_bundling">DefaultJSBundling</requiredEntity> - </entity> - <entity name="DefaultMinifyJSFiles" type="default_minify_files"> - <data key="inherit">1</data> - </entity> -</entities> diff --git a/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml b/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml deleted file mode 100644 index b56c88a22dd1..000000000000 --- a/app/code/Magento/Developer/Test/Mftf/Metadata/developer_js_config-meta.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<operations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataOperation.xsd"> - <operation name="DeveloperJSConfig" dataType="developer_js_config" type="create" auth="adminFormKey" url="/admin/system_config/save/section/dev/" method="POST"> - <object key="groups" dataType="dev_js_settings"> - <object key="js" dataType="dev_js_settings"> - <object key="fields" dataType="dev_js_settings"> - <object key="minify_files" dataType="default_minify_files"> - <field key="inherit">string</field> - </object> - <object key="enable_js_bundling" dataType="default_bundling"> - <field key="inherit">string</field> - </object> - </object> - </object> - </object> - </operation> -</operations> From 4d338c7df9e23c178e7f09bd9a201942113e1152 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun <ogorkun@magento.com> Date: Thu, 22 Aug 2019 10:57:21 -0500 Subject: [PATCH 0378/1172] MC-19145: [CLOUD] Internal error after DHL was configured --- app/code/Magento/Dhl/Model/Carrier.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php index 0a1632a45cb0..0890466e8a40 100644 --- a/app/code/Magento/Dhl/Model/Carrier.php +++ b/app/code/Magento/Dhl/Model/Carrier.php @@ -825,8 +825,10 @@ protected function _getAllItems() $fullItems[] = array_fill(0, $qty, $this->_getWeight($itemWeight)); } } - $fullItems = array_merge(...$fullItems); - sort($fullItems); + if ($fullItems) { + $fullItems = array_merge(...$fullItems); + sort($fullItems); + } return $fullItems; } From 7035daca3f6b47038d120813ec7164b76ac4bc94 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Thu, 22 Aug 2019 13:42:48 -0500 Subject: [PATCH 0379/1172] MC-19184: Quick Search is broken --- .../CatalogSearch/view/frontend/templates/result.phtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml index c63e6ff4abe0..921e1a81d871 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +/** This changes need to valid applying filters and configuration before search process is started. */ +$productList = $block->getProductListHtml(); ?> <?php if ($block->getResultCount()) : ?> <?= /* @noEscape */ $block->getChildHtml('tagged_product_list_rss_link') ?> @@ -16,7 +19,7 @@ </div> </div> <?php endif; ?> - <?= $block->getProductListHtml() ?> + <?= $productList ?> </div> <?php else : ?> From 302070f611e884abbda6460cb6231101a2eefcb4 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Fri, 23 Aug 2019 07:56:11 -0500 Subject: [PATCH 0380/1172] MC-19184: Quick Search is broken - fixed static tests --- .../Magento/CatalogSearch/view/frontend/templates/result.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml index 921e1a81d871..32b26eec9dbe 100644 --- a/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml +++ b/app/code/Magento/CatalogSearch/view/frontend/templates/result.phtml @@ -19,7 +19,7 @@ $productList = $block->getProductListHtml(); </div> </div> <?php endif; ?> - <?= $productList ?> + <?= /* @noEscape */ $productList ?> </div> <?php else : ?> From 35b8a04d5a0f7c919e02c2727bd0a5778fe39e90 Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov <vzabaznov@magento.com> Date: Fri, 23 Aug 2019 09:50:54 -0500 Subject: [PATCH 0381/1172] MC-19612: Revert MC-15378 --- app/code/Magento/Customer/Model/Visitor.php | 5 +++++ .../Magento/Customer/Controller/AccountTest.php | 15 --------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php index 4f129f05aa82..17394c4d9412 100644 --- a/app/code/Magento/Customer/Model/Visitor.php +++ b/app/code/Magento/Customer/Model/Visitor.php @@ -169,6 +169,11 @@ public function initByRequest($observer) $this->setLastVisitAt((new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)); + // prevent saving Visitor for safe methods, e.g. GET request + if ($this->requestSafety->isSafeMethod()) { + return $this; + } + if (!$this->getId()) { $this->setSessionId($this->session->getSessionId()); $this->save(); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php index 566dfbadedd2..32f12dada57a 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php @@ -798,21 +798,6 @@ public function loginPostRedirectDataProvider() ]; } - /** - * @magentoDataFixture Magento/Customer/_files/customer.php - * @magentoDataFixture Magento/Customer/_files/customer_address.php - * @magentoAppArea frontend - */ - public function testCheckVisitorModel() - { - /** @var \Magento\Customer\Model\Visitor $visitor */ - $visitor = $this->_objectManager->get(\Magento\Customer\Model\Visitor::class); - $this->login(1); - $this->assertNull($visitor->getId()); - $this->dispatch('customer/account/index'); - $this->assertNotNull($visitor->getId()); - } - /** * @param string $email * @return void From 6e66e2a2f9aac92be2f1e80ff5a6ed5ae7277120 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Fri, 23 Aug 2019 15:26:19 -0500 Subject: [PATCH 0382/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage fixed as per review comments --- ...tStorefrontCheckoutSuccessActionGroup.xml} | 2 +- ...ntPayOrderOnPayPalCheckoutActionGroup.xml} | 2 +- .../Test/Mftf/Data/PaypalConfigData.xml | 52 +++++++++++++++++++ .../Paypal/Test/Mftf/Data/PaypalData.xml | 17 +++--- .../Magento/Paypal/Test/Mftf/Suite/suite.xml | 6 +-- ...faultValueOfPayPalCustomizeButtonTest.xml} | 8 +-- ...ontCheckCreditButtonConfigurationTest.xml} | 8 +-- ...ntPaypalSmartButtonInCheckoutPageTest.xml} | 30 +++++------ 8 files changed, 90 insertions(+), 35 deletions(-) rename app/code/Magento/Checkout/Test/Mftf/ActionGroup/{VerifyCheckoutSuccessActionGroup.xml => AssertStorefrontCheckoutSuccessActionGroup.xml} (92%) rename app/code/Magento/Paypal/Test/Mftf/ActionGroup/{PayOrderOnPayPalCheckoutActionGroup.xml => StorefrontPayOrderOnPayPalCheckoutActionGroup.xml} (93%) create mode 100644 app/code/Magento/Paypal/Test/Mftf/Data/PaypalConfigData.xml rename app/code/Magento/Paypal/Test/Mftf/Test/{CheckDefaultValueOfPayPalCustomizeButtonTest.xml => AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml} (89%) rename app/code/Magento/Paypal/Test/Mftf/Test/{CheckCreditButtonConfiguration.xml => StorefrontCheckCreditButtonConfigurationTest.xml} (97%) rename app/code/Magento/Paypal/Test/Mftf/Test/{PayPalSmartButtonInCheckoutPage.xml => StorefrontPaypalSmartButtonInCheckoutPageTest.xml} (57%) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCheckoutSuccessActionGroup.xml similarity index 92% rename from app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml rename to app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCheckoutSuccessActionGroup.xml index 5048bcf37b32..9ff7e5a96fae 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/VerifyCheckoutSuccessActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontCheckoutSuccessActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="VerifyCheckoutSuccessActionGroup"> + <actionGroup name="AssertStorefrontCheckoutSuccessActionGroup"> <annotations> <description>Verifies if the order is placed successfully on the 'one page checkout' page.</description> </annotations> diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/StorefrontPayOrderOnPayPalCheckoutActionGroup.xml similarity index 93% rename from app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml rename to app/code/Magento/Paypal/Test/Mftf/ActionGroup/StorefrontPayOrderOnPayPalCheckoutActionGroup.xml index 13409b16b56b..392014d876e4 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayOrderOnPayPalCheckoutActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/StorefrontPayOrderOnPayPalCheckoutActionGroup.xml @@ -8,7 +8,7 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="PayOrderOnPayPalCheckoutActionGroup"> + <actionGroup name="StorefrontPayOrderOnPayPalCheckoutActionGroup"> <annotations> <description>Verifies product name on Paypal cart and clicks 'Pay Now' on PayPal payment checkout page.</description> </annotations> diff --git a/app/code/Magento/Paypal/Test/Mftf/Data/PaypalConfigData.xml b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalConfigData.xml new file mode 100644 index 000000000000..074420749410 --- /dev/null +++ b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalConfigData.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="StorefrontPaypalEnableConfigData"> + <data key="path">payment/paypal_express/active</data> + <data key="scope_id">1</data> + <data key="label">Yes</data> + <data key="value">1</data> + </entity> + <entity name="StorefrontPaypalDisableConfigData"> + <data key="path">payment/paypal_express/active</data> + <data key="scope_id">1</data> + <data key="label">No</data> + <data key="value">0</data> + </entity> + <entity name="StorefrontPaypalMerchantAccountIdConfigData"> + <data key="path">payment/paypal_express/merchant_id</data> + <data key="scope_id">1</data> + <data key="value">''</data> + </entity> + <entity name="StorefrontPaypalEnableSkipOrderReviewStepConfigData"> + <data key="path">payment/paypal_express/skip_order_review_step</data> + <data key="scope_id">1</data> + <data key="label">Yes</data> + <data key="value">1</data> + </entity> + <entity name="StorefrontPaypalDisableSkipOrderReviewStepConfigData"> + <data key="path">payment/paypal_express/skip_order_review_step</data> + <data key="scope_id">1</data> + <data key="label">No</data> + <data key="value">0</data> + </entity> + <entity name="StorefrontPaypalEnableInContextCheckoutConfigData"> + <data key="path">payment/paypal_express/in_context</data> + <data key="scope_id">1</data> + <data key="label">Yes</data> + <data key="value">1</data> + </entity> + <entity name="StorefrontPaypalDisableInContextCheckoutConfigData"> + <data key="path">payment/paypal_express/active</data> + <data key="scope_id">1</data> + <data key="label">No</data> + <data key="value">0</data> + </entity> +</entities> diff --git a/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml index b8994f0e4bc0..ba56243fdb39 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Data/PaypalData.xml @@ -109,24 +109,27 @@ <requiredEntity type="use_proxy">UseProxy</requiredEntity> </entity> <entity name="BusinessAccount" type="business_account"> - <data key="value">{{_CREDS.magento/paypal_express_checkout_us_business_account}}</data> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_business_account}}</data> </entity> <entity name="ApiUsername" type="api_username"> - <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_username}}</data> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_username}}</data> </entity> <entity name="ApiPassword" type="api_password"> - <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_password}}</data> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_password}}</data> </entity> <entity name="ApiSignature" type="api_signature"> - <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_signature}}</data> + <data key="value">{{_CREDS.magento/paypal_express_checkout_us_api_signature}}</data> </entity> <entity name="ApiAuthentication" type="api_authentication"> - <data key="value">0</data> + <data key="value">0</data> </entity> <entity name="SandboxFlag" type="sandbox_flag"> - <data key="value">1</data> + <data key="value">1</data> </entity> <entity name="UseProxy" type="use_proxy"> - <data key="value">0</data> + <data key="value">0</data> + </entity> + <entity name="Payer"> + <data key="firstName">Alex</data> </entity> </entities> diff --git a/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml b/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml index 621f2e6a6768..d1b7937180a0 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml @@ -8,9 +8,9 @@ <suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> <suite name="PaypalTestSuite"> <include> - <test name="CheckDefaultValueOfPayPalCustomizeButtonTest"/> - <test name="PayPalSmartButtonInCheckoutPage"/> - <test name="CheckCreditButtonConfiguration"/> + <test name="AdminCheckDefaultValueOfPayPalCustomizeButtonTest"/> + <test name="StorefrontPayPalSmartButtonInCheckoutPageTest"/> + <test name="StorefrontCheckCreditButtonConfigurationTest"/> </include> </suite> </suites> \ No newline at end of file diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml similarity index 89% rename from app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml rename to app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml index 0a90295c5528..4b28f00a132a 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/CheckDefaultValueOfPayPalCustomizeButtonTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml @@ -8,12 +8,12 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="CheckDefaultValueOfPayPalCustomizeButtonTest"> + <test name="AdminCheckDefaultValueOfPayPalCustomizeButtonTest"> <annotations> - <features value="PayPal"/> + <features value="Paypal"/> <stories value="Button Configuration"/> - <title value="Check Default Value Of PayPal Customize Button"/> - <description value="Default value of PayPal Customize Button should be NO"/> + <title value="Check Default Value Of Paypal Customize Button"/> + <description value="Default value of Paypal Customize Button should be NO"/> <severity value="AVERAGE"/> <testCaseId value="MC-10904"/> <skip> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml similarity index 97% rename from app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml rename to app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml index a0f13e8ae661..96213831cdd0 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/CheckCreditButtonConfiguration.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml @@ -8,9 +8,9 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="CheckCreditButtonConfiguration"> + <test name="StorefrontCheckCreditButtonConfigurationTest"> <annotations> - <features value="PayPal"/> + <features value="Paypal"/> <stories value="Button Configuration"/> <title value="Check Credit Button Configuration"/> <description value="Admin is able to customize Credit button"/> @@ -48,8 +48,8 @@ <!--Verify Credit Button value--> <comment userInput="Verify Credit Button value" stepKey="commentVerifyDefaultValue2"/> <selectOption selector="{{ButtonCustomization.label}}" userInput="{{PayPalLabel.credit}}" stepKey="selectCreditAsLabel"/> - <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize2"/> - <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape2"/> + <seeElement selector="{{ButtonCustomization.size}}" stepKey="seeSize"/> + <seeElement selector="{{ButtonCustomization.shape}}" stepKey="seeShape"/> <dontSeeElement selector="{{ButtonCustomization.layout}}" stepKey="dontSeeLayout"/> <dontSeeElement selector="{{ButtonCustomization.color}}" stepKey="dontSeeColor"/> <!--Customize Credit Button--> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml similarity index 57% rename from app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml rename to app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml index 5fd81d408900..4f28c52679a8 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/PayPalSmartButtonInCheckoutPage.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml @@ -8,12 +8,12 @@ <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="PayPalSmartButtonInCheckoutPage"> + <test name="StorefrontPaypalSmartButtonInCheckoutPageTest"> <annotations> - <features value="PayPal"/> + <features value="Paypal"/> <stories value="Generic checkout skeleton flow"/> - <title value="Mainflow of PayPal Smart Button"/> - <description value="Users are able to place order using PayPal Smart Button"/> + <title value="Mainflow of Paypal Smart Button"/> + <description value="Users are able to place order using Paypal Smart Button"/> <severity value="CRITICAL"/> <testCaseId value="MC-13690"/> <skip> @@ -32,10 +32,10 @@ <createData entity="Simple_US_Customer" stepKey="createCustomer"/> <!-- Set Paypal express config --> - <magentoCLI command="config:set payment/paypal_express/active 1" stepKey="enablePaypal"/> - <magentoCLI command="config:set payment/paypal_express/in_context 1" stepKey="enableInContextPayPal"/> - <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 1" stepKey="enableSkipOrderReview"/> - <magentoCLI command="config:set payment/paypal_express/merchant_id {{_CREDS.magento/paypal_express_checkout_us_merchant_id}}" stepKey="setMerchantId"/> + <magentoCLI command="config:set {{StorefrontPaypalEnableConfigData.path}} {{StorefrontPaypalEnableConfigData.value}}" stepKey="enablePaypal"/> + <magentoCLI command="config:set {{StorefrontPaypalEnableInContextCheckoutConfigData.path}} {{StorefrontPaypalEnableInContextCheckoutConfigData.value}}" stepKey="enableInContextPayPal"/> + <magentoCLI command="config:set {{StorefrontPaypalEnableSkipOrderReviewStepConfigData.path}} {{StorefrontPaypalEnableSkipOrderReviewStepConfigData.value}}" stepKey="enableSkipOrderReview"/> + <magentoCLI command="config:set {{StorefrontPaypalMerchantAccountIdConfigData.path}} {{_CREDS.magento/paypal_express_checkout_us_merchant_id}}" stepKey="setMerchantId"/> <createData entity="PaypalConfig" stepKey="createPaypalExpressConfig"/> <!-- Login --> @@ -43,10 +43,10 @@ </before> <after> <!-- Cleanup Paypal configurations --> - <magentoCLI command="config:set payment/paypal_express/merchant_id ''" stepKey="deleteMerchantId"/> - <magentoCLI command="config:set payment/paypal_express/skip_order_review_step 0" stepKey="disableSkipOrderReview"/> - <magentoCLI command="config:set payment/paypal_express/in_context 0" stepKey="disableInContextPayPal"/> - <magentoCLI command="config:set payment/paypal_express/active 0" stepKey="disablePaypal"/> + <magentoCLI command="config:set {{StorefrontPaypalMerchantAccountIdConfigData.path}} {{StorefrontPaypalMerchantAccountIdConfigData.value}}" stepKey="deleteMerchantId"/> + <magentoCLI command="config:set {{StorefrontPaypalDisableSkipOrderReviewStepConfigData.path}} {{StorefrontPaypalDisableSkipOrderReviewStepConfigData.value}}" stepKey="disableSkipOrderReview"/> + <magentoCLI command="config:set {{StorefrontPaypalDisableInContextCheckoutConfigData.path}} {{StorefrontPaypalDisableInContextCheckoutConfigData.value}}" stepKey="disableInContextPayPal"/> + <magentoCLI command="config:set {{StorefrontPaypalDisableConfigData.path}} {{StorefrontPaypalDisableConfigData.value}}" stepKey="disablePaypal"/> <createData entity="SamplePaypalConfig" stepKey="setDefaultPaypalConfig"/> <!-- Delete product --> @@ -68,15 +68,15 @@ <!-- Place an order using PayPal payment method --> <actionGroup ref="CreatePayPalOrderWithSelectedPaymentMethodActionGroup" stepKey="createPayPalOrder"> <argument name="Category" value="$$createCategory$$"/> - <argument name="payerName" value="Alex"/> + <argument name="payerName" value="{{Payer.firstName}}"/> </actionGroup> <!-- PayPal checkout --> - <actionGroup ref="PayOrderOnPayPalCheckoutActionGroup" stepKey="payOrderOnPayPalCheckout"> + <actionGroup ref="StorefrontPayOrderOnPayPalCheckoutActionGroup" stepKey="payOrderOnPayPalCheckout"> <argument name="productName" value="$$createProduct.name$$"/> </actionGroup> <!-- I see order successful Page instead of Order Review Page --> - <actionGroup ref="VerifyCheckoutSuccessActionGroup" stepKey="verifyCheckoutSuccess"/> + <actionGroup ref="AssertStorefrontCheckoutSuccessActionGroup" stepKey="assertCheckoutSuccess"/> </test> </tests> From 6b6013db8c53b47116cd64eeaaf28d0223fbf4e8 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Fri, 23 Aug 2019 15:42:51 -0500 Subject: [PATCH 0383/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage fixed as per review comments --- .../Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml b/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml index 0be7a7873825..382033f249ce 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Section/PayPalExpressCheckoutConfigSection.xml @@ -54,7 +54,7 @@ <element name="email" type="input" selector="//input[contains(@name, 'email') and not(contains(@style, 'display:none'))]"/> <element name="password" type="input" selector="//input[contains(@name, 'password') and not(contains(@style, 'display:none'))]"/> <element name="loginBtn" type="input" selector="button#btnLogin"/> - <element name="reviewUserInfo" type="text" selector="//p[@id='reviewUserInfo']"/> + <element name="reviewUserInfo" type="text" selector="#reviewUserInfo"/> <element name="cartIcon" type="text" selector="#transactionCart"/> <element name="itemName" type="text" selector="//span[@title='{{productName}}']" parameterized="true"/> <element name="PayPalSubmitBtn" type="text" selector="//input[@type='submit']"/> From 0023dcec912a1a442d67ab0c8d9cab36490c8be2 Mon Sep 17 00:00:00 2001 From: Vitaliy Honcharenko <vgoncharenko@magento.com> Date: Fri, 23 Aug 2019 16:31:54 -0500 Subject: [PATCH 0384/1172] MC-19184: Quick Search is broken - fixed performance tests --- .../ResourceModel/Fulltext/Collection/SearchResultApplier.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php index 3ae2d384782c..b15d99dcc2df 100644 --- a/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php +++ b/app/code/Magento/Elasticsearch/Model/ResourceModel/Fulltext/Collection/SearchResultApplier.php @@ -50,7 +50,6 @@ public function apply() foreach ($this->searchResult->getItems() as $item) { $ids[] = (int)$item->getId(); } - $this->collection->setPageSize(null); $this->collection->getSelect()->where('e.entity_id IN (?)', $ids); $orderList = join(',', $ids); $this->collection->getSelect()->reset(\Magento\Framework\DB\Select::ORDER); From f0bb8d5beb29e9b9db7c9f660650919a4efa59f5 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 23 Aug 2019 23:08:13 -0400 Subject: [PATCH 0385/1172] Correct cart_item_id source for address items [`\Magento\Quote\Model\Quote\Address::getAllItems`](https://github.com/magento/magento2/blob/cf4dc427fed594f74b7168735ee1eb93febfc143/app/code/Magento/Quote/Model/Quote/Address.php#L592-L636) returns `\Magento\Quote\Model\Quote\Address\Item[]` when the quote has multiple shipping addresses and `Magento\Quote\Model\Quote\Item[]` with a single shipping address. These objects have different methods for accessing the quote item id and both variants need to be accommodated in the extractor. Fixes magento/graphql-ce#822 --- .../Model/Cart/ExtractQuoteAddressData.php | 8 +++- .../Guest/GetAvailableShippingMethodsTest.php | 48 ++++++++++--------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php index c4d795293220..ce14bcf2d71e 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php @@ -61,8 +61,14 @@ public function execute(QuoteAddress $address): array $addressItemsData = []; foreach ($address->getAllItems() as $addressItem) { + if ($addressItem instanceof \Magento\Quote\Model\Quote\Item) { + $itemId = $addressItem->getItemId(); + } else { + $itemId = $addressItem->getQuoteItemId(); + } + $addressItemsData[] = [ - 'cart_item_id' => $addressItem->getQuoteItemId(), + 'cart_item_id' => $itemId, 'quantity' => $addressItem->getQty() ]; } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php index 5d90d26d4983..ff20274d6930 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php @@ -139,29 +139,33 @@ private function getQuery(string $maskedQuoteId): string query { cart (cart_id: "{$maskedQuoteId}") { shipping_addresses { - available_shipping_methods { - amount { - value - currency - } - base_amount { - value - currency - } - carrier_code - carrier_title - error_message - method_code - method_title - price_excl_tax { - value - currency - } - price_incl_tax { - value - currency - } + cart_items { + cart_item_id + quantity + } + available_shipping_methods { + amount { + value + currency } + base_amount { + value + currency + } + carrier_code + carrier_title + error_message + method_code + method_title + price_excl_tax { + value + currency + } + price_incl_tax { + value + currency + } + } } } } From b2a21ede77296e921f2c43833e3de85004d6e9d3 Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Fri, 23 Aug 2019 23:54:42 -0400 Subject: [PATCH 0386/1172] Fix static test and remove unused import --- .../Model/Cart/ExtractQuoteAddressData.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php index ce14bcf2d71e..27dd1959cb5d 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/ExtractQuoteAddressData.php @@ -7,7 +7,6 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Customer\Model\Address\AbstractAddress; use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Quote\Api\Data\AddressInterface; use Magento\Quote\Model\Quote\Address as QuoteAddress; @@ -41,19 +40,22 @@ public function execute(QuoteAddress $address): array $addressData = $this->dataObjectConverter->toFlatArray($address, [], AddressInterface::class); $addressData['model'] = $address; - $addressData = array_merge($addressData, [ - 'country' => [ - 'code' => $address->getCountryId(), - 'label' => $address->getCountry() - ], - 'region' => [ - 'code' => $address->getRegionCode(), - 'label' => $address->getRegion() - ], - 'street' => $address->getStreet(), - 'items_weight' => $address->getWeight(), - 'customer_notes' => $address->getCustomerNotes() - ]); + $addressData = array_merge( + $addressData, + [ + 'country' => [ + 'code' => $address->getCountryId(), + 'label' => $address->getCountry() + ], + 'region' => [ + 'code' => $address->getRegionCode(), + 'label' => $address->getRegion() + ], + 'street' => $address->getStreet(), + 'items_weight' => $address->getWeight(), + 'customer_notes' => $address->getCustomerNotes() + ] + ); if (!$address->hasItems()) { return $addressData; From 5b360cb19ff4bc8c3ad6c75d98dcb92044eba97d Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Sun, 25 Aug 2019 07:19:30 +0300 Subject: [PATCH 0387/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento/Customer/Controller/Account/CreatePost.php --- .../Customer/Controller/Account/Confirm.php | 14 +- .../Controller/Account/Confirmation.php | 10 +- .../Controller/Account/CreatePost.php | 49 +++--- .../Customer/Controller/Account/EditPost.php | 10 +- .../Customer/Controller/Account/LoginPost.php | 7 +- .../Controller/Account/ResetPasswordPost.php | 12 +- .../Customer/Controller/Address/Delete.php | 4 +- .../Adminhtml/Customer/InvalidateToken.php | 6 +- .../Controller/Adminhtml/Group/Delete.php | 10 +- .../Controller/Adminhtml/Group/Save.php | 2 +- .../Customer/Controller/Adminhtml/Index.php | 4 +- .../Adminhtml/Index/AbstractMassAction.php | 3 +- .../Controller/Adminhtml/Index/Delete.php | 6 +- .../Controller/Adminhtml/Index/Edit.php | 18 +-- .../Controller/Adminhtml/Index/InlineEdit.php | 26 ++-- .../Adminhtml/Index/MassAssignGroup.php | 2 +- .../Controller/Adminhtml/Index/MassDelete.php | 2 +- .../Adminhtml/Index/MassSubscribe.php | 2 +- .../Adminhtml/Index/MassUnsubscribe.php | 2 +- .../Adminhtml/Index/ResetPassword.php | 6 +- .../Controller/Adminhtml/Index/Save.php | 7 +- .../Controller/Adminhtml/Locks/Unlock.php | 4 +- .../Observer/AfterAddressSaveObserver.php | 6 +- .../StorefrontClearAllCompareProductsTest.xml | 1 + .../Unit/Controller/Account/ConfirmTest.php | 26 ++-- .../Controller/Account/CreatePostTest.php | 38 ++--- .../Unit/Controller/Account/LoginPostTest.php | 64 ++++---- .../Unit/Controller/Address/DeleteTest.php | 8 +- .../Controller/Adminhtml/Group/SaveTest.php | 2 +- .../Adminhtml/Index/InlineEditTest.php | 24 ++- .../Adminhtml/Index/MassAssignGroupTest.php | 4 +- .../Adminhtml/Index/MassDeleteTest.php | 4 +- .../Adminhtml/Index/MassSubscribeTest.php | 4 +- .../Adminhtml/Index/MassUnsubscribeTest.php | 4 +- .../Adminhtml/Index/NewsletterTest.php | 2 +- .../Adminhtml/Index/ResetPasswordTest.php | 6 +- .../Controller/Adminhtml/Index/SaveTest.php | 92 +++++------ .../Controller/Adminhtml/Locks/UnlockTest.php | 4 +- .../Observer/AfterAddressSaveObserverTest.php | 144 ++++++++---------- app/code/Magento/Customer/etc/frontend/di.xml | 26 +--- .../messages/unableDeleteAddressMessage.phtml | 9 -- 41 files changed, 281 insertions(+), 393 deletions(-) delete mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php index 6809442bbc92..2b3cb9aa61ab 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirm.php +++ b/app/code/Magento/Customer/Controller/Account/Confirm.php @@ -24,9 +24,7 @@ * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class Confirm - extends \Magento\Customer\Controller\AbstractAccount - implements \Magento\Framework\App\Action\Action\ActionInterface +class Confirm extends \Magento\Customer\Controller\AbstractAccount { /** * @var \Magento\Framework\App\Config\ScopeConfigInterface @@ -153,9 +151,7 @@ public function execute() $customerId = $this->getRequest()->getParam('id', false); $key = $this->getRequest()->getParam('key', false); if (empty($customerId) || empty($key)) { - $this->messageManager->addErrorMessage(__('Bad request.')); - $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); - return $resultRedirect->setUrl($this->_redirect->error($url)); + throw new \Exception(__('Bad request.')); } // log in and send greeting email @@ -167,13 +163,13 @@ public function execute() $metadata->setPath('/'); $this->getCookieManager()->deleteCookie('mage-cache-sessid', $metadata); } - $this->messageManager->addSuccessMessage($this->getSuccessMessage()); + $this->messageManager->addSuccess($this->getSuccessMessage()); $resultRedirect->setUrl($this->getSuccessRedirect()); return $resultRedirect; } catch (StateException $e) { - $this->messageManager->addExceptionMessage($e, __('This confirmation key is invalid or has expired.')); + $this->messageManager->addException($e, __('This confirmation key is invalid or has expired.')); } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('There was an error confirming the account')); + $this->messageManager->addException($e, __('There was an error confirming the account')); } $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); diff --git a/app/code/Magento/Customer/Controller/Account/Confirmation.php b/app/code/Magento/Customer/Controller/Account/Confirmation.php index aebc0547f353..a3e2db020763 100644 --- a/app/code/Magento/Customer/Controller/Account/Confirmation.php +++ b/app/code/Magento/Customer/Controller/Account/Confirmation.php @@ -1,5 +1,6 @@ <?php /** + * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -14,9 +15,6 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Framework\Exception\State\InvalidTransitionException; -/** - * Class Confirmation - */ class Confirmation extends \Magento\Customer\Controller\AbstractAccount { /** @@ -93,11 +91,11 @@ public function execute() $email, $this->storeManager->getStore()->getWebsiteId() ); - $this->messageManager->addSuccessMessage(__('Please check your email for confirmation key.')); + $this->messageManager->addSuccess(__('Please check your email for confirmation key.')); } catch (InvalidTransitionException $e) { - $this->messageManager->addSuccessMessage(__('This email does not require confirmation.')); + $this->messageManager->addSuccess(__('This email does not require confirmation.')); } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('Wrong email.')); + $this->messageManager->addException($e, __('Wrong email.')); $resultRedirect->setPath('*/*/*', ['email' => $email, '_secure' => true]); return $resultRedirect; } diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index 6c65d8c8d282..a2be0f68b56c 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Customer\Controller\Account; use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository; @@ -349,33 +351,34 @@ public function execute() $confirmation = $this->getRequest()->getParam('password_confirmation'); $redirectUrl = $this->session->getBeforeAuthUrl(); $this->checkPasswordConfirmation($password, $confirmation); + + $extensionAttributes = $customer->getExtensionAttributes(); + $extensionAttributes->setIsSubscribed($this->getRequest()->getParam('is_subscribed', false)); + $customer->setExtensionAttributes($extensionAttributes); + $customer = $this->accountManagement ->createAccount($customer, $password, $redirectUrl); - if ($this->getRequest()->getParam('is_subscribed', false)) { - $extensionAttributes = $customer->getExtensionAttributes(); - $extensionAttributes->setIsSubscribed(true); - $customer->setExtensionAttributes($extensionAttributes); - $this->customerRepository->save($customer); - } $this->_eventManager->dispatch( 'customer_register_success', ['account_controller' => $this, 'customer' => $customer] ); $confirmationStatus = $this->accountManagement->getConfirmationStatus($customer->getId()); if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) { - $this->messageManager->addComplexSuccessMessage( - 'confirmAccountSuccessMessage', - [ - 'url' => $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()), - ] + $email = $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()); + // @codingStandardsIgnoreStart + $this->messageManager->addSuccess( + __( + 'You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', + $email + ) ); - + // @codingStandardsIgnoreEnd $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); $resultRedirect->setUrl($this->_redirect->success($url)); } else { $this->session->setCustomerDataAsLoggedIn($customer); - $this->messageManager->addSuccessMessage($this->getSuccessMessage()); + $this->messageManager->addSuccess($this->getSuccessMessage()); $requestedRedirect = $this->accountRedirect->getRedirectCookie(); if (!$this->scopeConfig->getValue('customer/startup/redirect_dashboard') && $requestedRedirect) { $resultRedirect->setUrl($this->_redirect->success($requestedRedirect)); @@ -392,21 +395,23 @@ public function execute() return $resultRedirect; } catch (StateException $e) { - $this->messageManager->addComplexErrorMessage( - 'customerAlreadyExistsErrorMessage', - [ - 'url' => $this->urlModel->getUrl('customer/account/forgotpassword'), - ] + $url = $this->urlModel->getUrl('customer/account/forgotpassword'); + // @codingStandardsIgnoreStart + $message = __( + 'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.', + $url ); + // @codingStandardsIgnoreEnd + $this->messageManager->addError($message); } catch (InputException $e) { - $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); foreach ($e->getErrors() as $error) { - $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); + $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage())); } } catch (LocalizedException $e) { - $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('We can\'t save the customer.')); + $this->messageManager->addException($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php index 0203226fc2e3..4eb41cedea29 100644 --- a/app/code/Magento/Customer/Controller/Account/EditPost.php +++ b/app/code/Magento/Customer/Controller/Account/EditPost.php @@ -216,7 +216,7 @@ public function execute() $isPasswordChanged ); $this->dispatchSuccessEvent($customerCandidateDataObject); - $this->messageManager->addSuccessMessage(__('You saved the account information.')); + $this->messageManager->addSuccess(__('You saved the account information.')); return $resultRedirect->setPath('customer/account'); } catch (InvalidEmailOrPasswordException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); @@ -227,7 +227,7 @@ public function execute() ); $this->session->logout(); $this->session->start(); - $this->messageManager->addErrorMessage($message); + $this->messageManager->addError($message); return $resultRedirect->setPath('customer/account/login'); } catch (InputException $e) { $this->messageManager->addErrorMessage($this->escaper->escapeHtml($e->getMessage())); @@ -235,9 +235,9 @@ public function execute() $this->messageManager->addErrorMessage($this->escaper->escapeHtml($error->getMessage())); } } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); } catch (\Exception $e) { - $this->messageManager->addExceptionMessage($e, __('We can\'t save the customer.')); + $this->messageManager->addException($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); @@ -345,11 +345,9 @@ private function processChangeEmailRequest(\Magento\Customer\Api\Data\CustomerIn $this->getRequest()->getPost('current_password') ); } catch (InvalidEmailOrPasswordException $e) { - // @codingStandardsIgnoreStart throw new InvalidEmailOrPasswordException( __("The password doesn't match this account. Verify the password and try again.") ); - // @codingStandardsIgnoreEnd } } } diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php index 046ae5c70276..04051fbbf366 100644 --- a/app/code/Magento/Customer/Controller/Account/LoginPost.php +++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php @@ -26,7 +26,6 @@ use Magento\Framework\Phrase; /** - * Class LoginPost * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class LoginPost extends AbstractAccount implements CsrfAwareActionInterface, HttpPostActionInterface @@ -218,17 +217,17 @@ public function execute() $message = $e->getMessage(); } catch (\Exception $e) { // PA DSS violation: throwing or logging an exception here can disclose customer password - $this->messageManager->addErrorMessage( + $this->messageManager->addError( __('An unspecified error occurred. Please contact us for assistance.') ); } finally { if (isset($message)) { - $this->messageManager->addErrorMessage($message); + $this->messageManager->addError($message); $this->session->setUsername($login['username']); } } } else { - $this->messageManager->addErrorMessage(__('A login and a password are required.')); + $this->messageManager->addError(__('A login and a password are required.')); } } diff --git a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php index a127f2acf538..27a00f86dd95 100644 --- a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php +++ b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php @@ -73,13 +73,13 @@ public function execute() $passwordConfirmation = (string)$this->getRequest()->getPost('password_confirmation'); if ($password !== $passwordConfirmation) { - $this->messageManager->addErrorMessage(__("New Password and Confirm New Password values didn't match.")); + $this->messageManager->addError(__("New Password and Confirm New Password values didn't match.")); $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); return $resultRedirect; } if (iconv_strlen($password) <= 0) { - $this->messageManager->addErrorMessage(__('Please enter a new password.')); + $this->messageManager->addError(__('Please enter a new password.')); $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); return $resultRedirect; @@ -92,17 +92,17 @@ public function execute() $password ); $this->session->unsRpToken(); - $this->messageManager->addSuccessMessage(__('You updated your password.')); + $this->messageManager->addSuccess(__('You updated your password.')); $resultRedirect->setPath('*/*/login'); return $resultRedirect; } catch (InputException $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); foreach ($e->getErrors() as $error) { - $this->messageManager->addErrorMessage($error->getMessage()); + $this->messageManager->addError($error->getMessage()); } } catch (\Exception $exception) { - $this->messageManager->addErrorMessage(__('Something went wrong while saving the new password.')); + $this->messageManager->addError(__('Something went wrong while saving the new password.')); } $resultRedirect->setPath('*/*/createPassword', ['token' => $resetPasswordToken]); diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php index 9df06c69d4a8..a30e15db4b3f 100644 --- a/app/code/Magento/Customer/Controller/Address/Delete.php +++ b/app/code/Magento/Customer/Controller/Address/Delete.php @@ -27,9 +27,9 @@ public function execute() $address = $this->_addressRepository->getById($addressId); if ($address->getCustomerId() === $this->_getSession()->getCustomerId()) { $this->_addressRepository->deleteById($addressId); - $this->messageManager->addSuccessMessage(__('You deleted the address.')); + $this->messageManager->addSuccess(__('You deleted the address.')); } else { - $this->messageManager->addComplexErrorMessage('unableDeleteAddressMessage'); + $this->messageManager->addError(__('We can\'t delete the address right now.')); } } catch (\Exception $other) { $this->messageManager->addException($other, __('We can\'t delete the address right now.')); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php b/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php index 7747d80595cd..b69410ecbfce 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Customer/InvalidateToken.php @@ -139,14 +139,14 @@ public function execute() if ($customerId = $this->getRequest()->getParam('customer_id')) { try { $this->tokenService->revokeCustomerAccessToken($customerId); - $this->messageManager->addSuccessMessage(__('You have revoked the customer\'s tokens.')); + $this->messageManager->addSuccess(__('You have revoked the customer\'s tokens.')); $resultRedirect->setPath('customer/index/edit', ['id' => $customerId, '_current' => true]); } catch (\Exception $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); $resultRedirect->setPath('customer/index/edit', ['id' => $customerId, '_current' => true]); } } else { - $this->messageManager->addErrorMessage(__('We can\'t find a customer to revoke.')); + $this->messageManager->addError(__('We can\'t find a customer to revoke.')); $resultRedirect->setPath('customer/index/index'); } return $resultRedirect; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php index 661ef1cace69..ab32ea08a44a 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php @@ -1,5 +1,6 @@ <?php /** + * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,9 +9,6 @@ use Magento\Framework\App\Action\HttpPostActionInterface; use Magento\Framework\Exception\NoSuchEntityException; -/** - * Class Delete - */ class Delete extends \Magento\Customer\Controller\Adminhtml\Group implements HttpPostActionInterface { /** @@ -26,12 +24,12 @@ public function execute() if ($id) { try { $this->groupRepository->deleteById($id); - $this->messageManager->addSuccessMessage(__('You deleted the customer group.')); + $this->messageManager->addSuccess(__('You deleted the customer group.')); } catch (NoSuchEntityException $e) { - $this->messageManager->addErrorMessage(__('The customer group no longer exists.')); + $this->messageManager->addError(__('The customer group no longer exists.')); return $resultRedirect->setPath('customer/*/'); } catch (\Exception $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); return $resultRedirect->setPath('customer/group/edit', ['id' => $id]); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php index bb3589a75f72..5ffce4cbcd98 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php @@ -93,7 +93,7 @@ public function execute() $this->groupRepository->save($customerGroup); - $this->messageManager->addSuccessMessage(__('You saved the customer group.')); + $this->messageManager->addSuccess(__('You saved the customer group.')); $resultRedirect->setPath('customer/group'); } catch (\Exception $e) { $this->messageManager->addError($e->getMessage()); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Index.php index ffae1e9f8bf1..a0317a51260d 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index.php @@ -311,7 +311,7 @@ protected function _addSessionErrorMessages($messages) protected function actUponMultipleCustomers(callable $singleAction, $customerIds) { if (!is_array($customerIds)) { - $this->messageManager->addErrorMessage(__('Please select customer(s).')); + $this->messageManager->addError(__('Please select customer(s).')); return 0; } $customersUpdated = 0; @@ -320,7 +320,7 @@ protected function actUponMultipleCustomers(callable $singleAction, $customerIds $singleAction($customerId); $customersUpdated++; } catch (\Exception $exception) { - $this->messageManager->addErrorMessage($exception->getMessage()); + $this->messageManager->addError($exception->getMessage()); } } return $customersUpdated; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php index e2bde42351d4..e26b49aaebe7 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/AbstractMassAction.php @@ -64,7 +64,7 @@ public function execute() $collection = $this->filter->getCollection($this->collectionFactory->create()); return $this->massAction($collection); } catch (\Exception $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); return $resultRedirect->setPath($this->redirectUrl); @@ -73,7 +73,6 @@ public function execute() /** * Return component referer url - * * TODO: Technical dept referer url should be implement as a part of Action configuration in appropriate way * * @return null|string diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php index 4b2f2614948c..ab39ca098162 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php @@ -31,7 +31,7 @@ public function execute() $formKeyIsValid = $this->_formKeyValidator->validate($this->getRequest()); $isPost = $this->getRequest()->isPost(); if (!$formKeyIsValid || !$isPost) { - $this->messageManager->addErrorMessage(__('Customer could not be deleted.')); + $this->messageManager->addError(__('Customer could not be deleted.')); return $resultRedirect->setPath('customer/index'); } @@ -39,9 +39,9 @@ public function execute() if (!empty($customerId)) { try { $this->_customerRepository->deleteById($customerId); - $this->messageManager->addSuccessMessage(__('You deleted the customer.')); + $this->messageManager->addSuccess(__('You deleted the customer.')); } catch (\Exception $exception) { - $this->messageManager->addErrorMessage($exception->getMessage()); + $this->messageManager->addError($exception->getMessage()); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php index 3d7f75884057..25b4ddd4e173 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php @@ -9,9 +9,6 @@ use Magento\Customer\Api\Data\CustomerInterface; use Magento\Framework\Exception\NoSuchEntityException; -/** - * Class Edit - */ class Edit extends \Magento\Customer\Controller\Adminhtml\Index implements HttpGetActionInterface { /** @@ -36,14 +33,17 @@ public function execute() $customer = $this->_customerRepository->getById($customerId); $customerData['account'] = $this->customerMapper->toFlatArray($customer); $customerData['account'][CustomerInterface::ID] = $customerId; - - $addresses = $customer->getAddresses(); - foreach ($addresses as $address) { - $customerData['address'][$address->getId()] = $this->addressMapper->toFlatArray($address); - $customerData['address'][$address->getId()]['id'] = $address->getId(); + try { + $addresses = $customer->getAddresses(); + foreach ($addresses as $address) { + $customerData['address'][$address->getId()] = $this->addressMapper->toFlatArray($address); + $customerData['address'][$address->getId()]['id'] = $address->getId(); + } + } catch (NoSuchEntityException $e) { + //do nothing } } catch (NoSuchEntityException $e) { - $this->messageManager->addExceptionMessage($e, __('Something went wrong while editing the customer.')); + $this->messageManager->addException($e, __('Something went wrong while editing the customer.')); $resultRedirect = $this->resultRedirectFactory->create(); $resultRedirect->setPath('customer/*/index'); return $resultRedirect; diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php index ba8c84a0ac27..7220de035681 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/InlineEdit.php @@ -128,12 +128,10 @@ public function execute() $postItems = $this->getRequest()->getParam('items', []); if (!($this->getRequest()->getParam('isAjax') && count($postItems))) { - return $resultJson->setData( - [ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ] - ); + return $resultJson->setData([ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ]); } foreach (array_keys($postItems) as $customerId) { @@ -149,12 +147,10 @@ public function execute() $this->getEmailNotification()->credentialsChanged($this->getCustomer(), $currentCustomer->getEmail()); } - return $resultJson->setData( - [ - 'messages' => $this->getErrorMessages(), - 'error' => $this->isErrorExists() - ] - ); + return $resultJson->setData([ + 'messages' => $this->getErrorMessages(), + 'error' => $this->isErrorExists() + ]); } /** @@ -238,13 +234,13 @@ protected function saveCustomer(CustomerInterface $customer) $this->disableAddressValidation($customer); $this->customerRepository->save($customer); } catch (\Magento\Framework\Exception\InputException $e) { - $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); $this->logger->critical($e); } catch (\Magento\Framework\Exception\LocalizedException $e) { - $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId($e->getMessage())); + $this->getMessageManager()->addError($this->getErrorWithCustomerId($e->getMessage())); $this->logger->critical($e); } catch (\Exception $e) { - $this->getMessageManager()->addErrorMessage($this->getErrorWithCustomerId('We can\'t save the customer.')); + $this->getMessageManager()->addError($this->getErrorWithCustomerId('We can\'t save the customer.')); $this->logger->critical($e); } } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php index f55c81da7e0b..5a9c52bf9b1c 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php @@ -60,7 +60,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php index 85286573bc5e..edaeea6a15eb 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php @@ -58,7 +58,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersDeleted) { - $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were deleted.', $customersDeleted)); + $this->messageManager->addSuccess(__('A total of %1 record(s) were deleted.', $customersDeleted)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php index e072c5cb4cd4..25c56ac60c14 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php @@ -64,7 +64,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php index e52c9a772ed2..4b40722ba9ab 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php @@ -64,7 +64,7 @@ protected function massAction(AbstractCollection $collection) } if ($customersUpdated) { - $this->messageManager->addSuccessMessage(__('A total of %1 record(s) were updated.', $customersUpdated)); + $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated)); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php index 3b9370c32bf6..1e4fa91cbf89 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php @@ -44,9 +44,7 @@ public function execute() \Magento\Customer\Model\AccountManagement::EMAIL_REMINDER, $customer->getWebsiteId() ); - $this->messageManager->addSuccessMessage( - __('The customer will receive an email with a link to reset password.') - ); + $this->messageManager->addSuccess(__('The customer will receive an email with a link to reset password.')); } catch (NoSuchEntityException $exception) { $resultRedirect->setPath('customer/index'); return $resultRedirect; @@ -59,7 +57,7 @@ public function execute() } catch (SecurityViolationException $exception) { $this->messageManager->addErrorMessage($exception->getMessage()); } catch (\Exception $exception) { - $this->messageManager->addExceptionMessage( + $this->messageManager->addException( $exception, __('Something went wrong while resetting customer password.') ); diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php index 3ee33af9ec07..38ed688a835b 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php @@ -354,7 +354,7 @@ public function execute() $this->_getSession()->unsCustomerFormData(); // Done Saving customer, finish save action $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); - $this->messageManager->addSuccessMessage(__('You saved the customer.')); + $this->messageManager->addSuccess(__('You saved the customer.')); $returnToEdit = (bool)$this->getRequest()->getParam('back', false); } catch (\Magento\Framework\Validator\Exception $exception) { $messages = $exception->getMessages(); @@ -378,10 +378,7 @@ public function execute() $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } catch (\Exception $exception) { - $this->messageManager->addExceptionMessage( - $exception, - __('Something went wrong while saving the customer.') - ); + $this->messageManager->addException($exception, __('Something went wrong while saving the customer.')); $this->_getSession()->setCustomerFormData($this->retrieveFormattedFormData()); $returnToEdit = true; } diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php b/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php index 2747ba1a665f..1fd06a318294 100644 --- a/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php +++ b/app/code/Magento/Customer/Controller/Adminhtml/Locks/Unlock.php @@ -55,10 +55,10 @@ public function execute() // unlock customer if ($customerId) { $this->authentication->unlock($customerId); - $this->getMessageManager()->addSuccessMessage(__('Customer has been unlocked successfully.')); + $this->getMessageManager()->addSuccess(__('Customer has been unlocked successfully.')); } } catch (\Exception $e) { - $this->messageManager->addErrorMessage($e->getMessage()); + $this->messageManager->addError($e->getMessage()); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ diff --git a/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php b/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php index 8677abfa8990..41311abee5da 100644 --- a/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php +++ b/app/code/Magento/Customer/Observer/AfterAddressSaveObserver.php @@ -255,7 +255,7 @@ protected function addValidMessage($customerAddress, $validationResult) : (string)__('You will not be charged tax.'); } - $this->messageManager->addSuccessMessage(implode(' ', $message)); + $this->messageManager->addSuccess(implode(' ', $message)); return $this; } @@ -280,7 +280,7 @@ protected function addInvalidMessage($customerAddress) $message[] = (string)__('You will be charged tax.'); } - $this->messageManager->addErrorMessage(implode(' ', $message)); + $this->messageManager->addError(implode(' ', $message)); return $this; } @@ -307,7 +307,7 @@ protected function addErrorMessage($customerAddress) $email = $this->scopeConfig->getValue('trans_email/ident_support/email', ScopeInterface::SCOPE_STORE); $message[] = (string)__('If you believe this is an error, please contact us at %1', $email); - $this->messageManager->addErrorMessage(implode(' ', $message)); + $this->messageManager->addError(implode(' ', $message)); return $this; } diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml index d7372b07de14..ada3adbfeb83 100644 --- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontClearAllCompareProductsTest.xml @@ -116,6 +116,7 @@ <deleteData createDataKey="createSimpleCategory1" stepKey="deleteSimpleCategory1"/> <deleteData createDataKey="createSimpleProduct1" stepKey="deleteSimpleProduct1"/> <deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/> + <deleteData createDataKey="createConfigChildProduct" stepKey="deleteConfigChildProduct"/> <deleteData createDataKey="createConfigProduct1" stepKey="deleteConfigProduct1"/> <deleteData createDataKey="createVirtualProduct1" stepKey="deleteVirtualProduct1"/> <deleteData createDataKey="createBundleProduct1" stepKey="deleteBundleProduct1"/> diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php index 61efd9d562b4..01fc465d4ae8 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/ConfirmTest.php @@ -255,12 +255,10 @@ public function testSuccessMessage($customerId, $key, $vatValidationEnabled, $ad $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap( - [ - ['id', false, $customerId], - ['key', false, $key], - ] - ); + ->willReturnMap([ + ['id', false, $customerId], + ['key', false, $key], + ]); $this->customerRepositoryMock->expects($this->any()) ->method('getById') @@ -283,7 +281,7 @@ public function testSuccessMessage($customerId, $key, $vatValidationEnabled, $ad ->willReturnSelf(); $this->messageManagerMock->expects($this->any()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with($this->stringContains($successMessage)) ->willReturnSelf(); @@ -374,13 +372,11 @@ public function testSuccessRedirect( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap( - [ - ['id', false, $customerId], - ['key', false, $key], - ['back_url', false, $backUrl], - ] - ); + ->willReturnMap([ + ['id', false, $customerId], + ['key', false, $key], + ['back_url', false, $backUrl], + ]); $this->customerRepositoryMock->expects($this->any()) ->method('getById') @@ -403,7 +399,7 @@ public function testSuccessRedirect( ->willReturnSelf(); $this->messageManagerMock->expects($this->any()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with($this->stringContains($successMessage)) ->willReturnSelf(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php index faf55347dba7..f8f47eedba3e 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php @@ -346,13 +346,11 @@ public function testSuccessMessage( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap( - [ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ] - ); + ->willReturnMap([ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ]); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -373,7 +371,7 @@ public function testSuccessMessage( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); @@ -479,13 +477,11 @@ public function testSuccessRedirect( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap( - [ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ] - ); + ->willReturnMap([ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ]); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -506,18 +502,16 @@ public function testSuccessRedirect( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); $this->urlMock->expects($this->any()) ->method('getUrl') - ->willReturnMap( - [ - ['*/*/index', ['_secure' => true], $successUrl], - ['*/*/create', ['_secure' => true], $successUrl], - ] - ); + ->willReturnMap([ + ['*/*/index', ['_secure' => true], $successUrl], + ['*/*/create', ['_secure' => true], $successUrl], + ]); $this->redirectMock->expects($this->once()) ->method('success') ->with($this->equalTo($successUrl)) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php index fd70a55ad7de..762c76b695de 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/LoginPostTest.php @@ -93,14 +93,12 @@ protected function setUp() $this->session = $this->getMockBuilder(\Magento\Customer\Model\Session::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'isLoggedIn', - 'setCustomerDataAsLoggedIn', - 'regenerateId', - 'setUsername', - ] - ) + ->setMethods([ + 'isLoggedIn', + 'setCustomerDataAsLoggedIn', + 'regenerateId', + 'setUsername', + ]) ->getMock(); $this->accountManagement = $this->getMockBuilder(\Magento\Customer\Api\AccountManagementInterface::class) @@ -224,7 +222,7 @@ public function testExecuteEmptyLoginData() ->willReturn([]); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with(__('A login and a password are required.')) ->willReturnSelf(); @@ -255,12 +253,10 @@ public function testExecuteSuccessCustomRedirect() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn( - [ - 'username' => $username, - 'password' => $password, - ] - ); + ->willReturn([ + 'username' => $username, + 'password' => $password, + ]); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -339,12 +335,10 @@ public function testExecuteSuccess() $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn( - [ - 'username' => $username, - 'password' => $password, - ] - ); + ->willReturn([ + 'username' => $username, + 'password' => $password, + ]); $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMockForAbstractClass(); @@ -432,12 +426,10 @@ public function testExecuteWithException( $this->request->expects($this->once()) ->method('getPost') ->with('login') - ->willReturn( - [ - 'username' => $username, - 'password' => $password, - ] - ); + ->willReturn([ + 'username' => $username, + 'password' => $password, + ]); $exception = new $exceptionData['exception'](__($exceptionData['message'])); @@ -496,12 +488,10 @@ protected function prepareContext() $this->request = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'isPost', - 'getPost', - ] - ) + ->setMethods([ + 'isPost', + 'getPost', + ]) ->getMock(); $this->resultRedirect = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -561,7 +551,7 @@ protected function mockExceptions($exception, $username) $url ); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with($message) ->willReturnSelf(); @@ -573,7 +563,7 @@ protected function mockExceptions($exception, $username) case \Magento\Framework\Exception\AuthenticationException::class: $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with( __( 'The account sign-in was incorrect or your account is disabled temporarily. ' @@ -590,7 +580,7 @@ protected function mockExceptions($exception, $username) case '\Exception': $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with(__('An unspecified error occurred. Please contact us for assistance.')) ->willReturnSelf(); break; @@ -601,7 +591,7 @@ protected function mockExceptions($exception, $username) . 'Please wait and try again later.' ); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with($message) ->willReturnSelf(); $this->session->expects($this->once()) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php index 046c023d35c6..4064b8586257 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Address/DeleteTest.php @@ -146,7 +146,7 @@ public function testExecute() ->method('deleteById') ->with($addressId); $this->messageManager->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('You deleted the address.')); $this->resultRedirect->expects($this->once()) ->method('setPath') @@ -183,9 +183,9 @@ public function testExecuteWithException() ->willReturn(34); $exception = new \Exception('Exception'); $this->messageManager->expects($this->once()) - ->method('addComplexErrorMessage') - ->with('unableDeleteAddressMessage') - ->willReturnSelf(); + ->method('addError') + ->with(__('We can\'t delete the address right now.')) + ->willThrowException($exception); $this->messageManager->expects($this->once()) ->method('addException') ->with($exception, __('We can\'t delete the address right now.')); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php index b0b8075325f8..5f7064d5b124 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Group/SaveTest.php @@ -167,7 +167,7 @@ public function testExecuteWithTaxClassAndException() ->method('save') ->with($this->group); $this->messageManager->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('You saved the customer group.')); $exception = new \Exception('Exception'); $this->resultRedirect->expects($this->at(0)) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php index 769c77dfcb4e..45e64f6557d5 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/InlineEditTest.php @@ -291,12 +291,10 @@ protected function prepareMocksForErrorMessagesProcessing() ->willReturn('Error text'); $this->resultJson->expects($this->once()) ->method('setData') - ->with( - [ - 'messages' => ['Error text'], - 'error' => true, - ] - ) + ->with([ + 'messages' => ['Error text'], + 'error' => true, + ]) ->willReturnSelf(); } @@ -342,12 +340,10 @@ public function testExecuteWithoutItems() $this->resultJson ->expects($this->once()) ->method('setData') - ->with( - [ - 'messages' => [__('Please correct the data sent.')], - 'error' => true, - ] - ) + ->with([ + 'messages' => [__('Please correct the data sent.')], + 'error' => true, + ]) ->willReturnSelf(); $this->assertSame($this->resultJson, $this->controller->execute()); } @@ -370,7 +366,7 @@ public function testExecuteLocalizedException() ->with($this->customerData) ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('[Customer ID: 12] Exception message'); $this->logger->expects($this->once()) ->method('critical') @@ -398,7 +394,7 @@ public function testExecuteException() ->with($this->customerData) ->willThrowException($exception); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('[Customer ID: 12] We can\'t save the customer.'); $this->logger->expects($this->once()) ->method('critical') diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php index 4157359959ae..10144bdc318c 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassAssignGroupTest.php @@ -170,7 +170,7 @@ public function testExecute() ->willReturnMap([[10, $customerMock], [11, $customerMock], [12, $customerMock]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -199,7 +199,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php index b436b5b137c7..190ff2c06618 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassDeleteTest.php @@ -155,7 +155,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('A total of %1 record(s) were deleted.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -179,7 +179,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php index 33e578224400..daf9c64fe7b7 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassSubscribeTest.php @@ -171,7 +171,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -195,7 +195,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php index 971efc0e490b..05624661a2de 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/MassUnsubscribeTest.php @@ -171,7 +171,7 @@ public function testExecute() ->willReturnMap([[10, true], [11, true], [12, true]]); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('A total of %1 record(s) were updated.', count($customersIds))); $this->resultRedirectMock->expects($this->any()) @@ -195,7 +195,7 @@ public function testExecuteWithException() ->willThrowException(new \Exception('Some message.')); $this->messageManagerMock->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with('Some message.'); $this->massAction->execute(); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php index 5ec39360000c..d2f8b8776081 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/NewsletterTest.php @@ -150,7 +150,7 @@ protected function setUp() $this->messageManager = $this->getMockBuilder( \Magento\Framework\Message\Manager::class )->disableOriginalConstructor()->setMethods( - ['addSuccessMessage', 'addMessageMessage', 'addExceptionMessage'] + ['addSuccess', 'addMessage', 'addException'] )->getMock(); $contextArgs = [ diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php index 67ac60e6b905..66e5b57eaa42 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php @@ -141,7 +141,7 @@ protected function setUp() $this->messageManager = $this->getMockBuilder( \Magento\Framework\Message\Manager::class )->disableOriginalConstructor()->setMethods( - ['addSuccessMessage', 'addMessage', 'addExceptionMessage', 'addErrorMessage'] + ['addSuccess', 'addMessage', 'addException', 'addErrorMessage'] )->getMock(); $this->resultRedirectFactoryMock = $this->getMockBuilder( @@ -442,7 +442,7 @@ public function testResetPasswordActionException() $this->messageManager->expects( $this->once() )->method( - 'addExceptionMessage' + 'addException' )->with( $this->equalTo($exception), $this->equalTo('Something went wrong while resetting customer password.') @@ -502,7 +502,7 @@ public function testResetPasswordActionSendEmail() $this->messageManager->expects( $this->once() )->method( - 'addSuccessMessage' + 'addSuccess' )->with( $this->equalTo('The customer will receive an email with a link to reset password.') ); diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php index 9724ac13dde8..57f384d32d98 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php @@ -338,12 +338,10 @@ public function testExecuteWithExistentCustomer() $this->requestMock->expects($this->atLeastOnce()) ->method('getPostValue') - ->willReturnMap( - [ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ] - ); + ->willReturnMap([ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ]); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -477,7 +475,7 @@ public function testExecuteWithExistentCustomer() ->with(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('You saved the customer.')) ->willReturnSelf(); @@ -544,12 +542,10 @@ public function testExecuteWithNewCustomer() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap( - [ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ] - ); + ->willReturnMap([ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ]); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -666,7 +662,7 @@ public function testExecuteWithNewCustomer() ->with(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId); $this->messageManagerMock->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with(__('You saved the customer.')) ->willReturnSelf(); @@ -727,12 +723,10 @@ public function testExecuteWithNewCustomerAndValidationException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap( - [ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ] - ); + ->willReturnMap([ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ]); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -810,7 +804,7 @@ public function testExecuteWithNewCustomerAndValidationException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccessMessage'); + ->method('addSuccess'); $this->messageManagerMock->expects($this->once()) ->method('addMessage') @@ -818,12 +812,10 @@ public function testExecuteWithNewCustomerAndValidationException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with( - [ - 'customer' => $extractedData, - 'subscription' => $subscription, - ] - ); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -878,12 +870,10 @@ public function testExecuteWithNewCustomerAndLocalizedException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap( - [ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ] - ); + ->willReturnMap([ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ]); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -961,7 +951,7 @@ public function testExecuteWithNewCustomerAndLocalizedException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccessMessage'); + ->method('addSuccess'); $this->messageManagerMock->expects($this->once()) ->method('addMessage') @@ -969,12 +959,10 @@ public function testExecuteWithNewCustomerAndLocalizedException() $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with( - [ - 'customer' => $extractedData, - 'subscription' => $subscription, - ] - ); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) @@ -1029,12 +1017,10 @@ public function testExecuteWithNewCustomerAndException() $this->requestMock->expects($this->any()) ->method('getPostValue') - ->willReturnMap( - [ - [null, null, $postValue], - [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], - ] - ); + ->willReturnMap([ + [null, null, $postValue], + [CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER, null, $postValue['customer']], + ]); $this->requestMock->expects($this->atLeastOnce()) ->method('getPost') ->willReturnMap( @@ -1113,20 +1099,18 @@ public function testExecuteWithNewCustomerAndException() ->method('register'); $this->messageManagerMock->expects($this->never()) - ->method('addSuccessMessage'); + ->method('addSuccess'); $this->messageManagerMock->expects($this->once()) - ->method('addExceptionMessage') + ->method('addException') ->with($exception, __('Something went wrong while saving the customer.')); $this->sessionMock->expects($this->once()) ->method('setCustomerFormData') - ->with( - [ - 'customer' => $extractedData, - 'subscription' => $subscription, - ] - ); + ->with([ + 'customer' => $extractedData, + 'subscription' => $subscription, + ]); /** @var Redirect|\PHPUnit_Framework_MockObject_MockObject $redirectMock */ $redirectMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Redirect::class) diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php index 55b4092af714..c92d4ed7812b 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Locks/UnlockTest.php @@ -118,7 +118,7 @@ public function testExecute() ->with($this->equalTo('customer_id')) ->will($this->returnValue($customerId)); $this->authenticationMock->expects($this->once())->method('unlock')->with($customerId); - $this->messageManagerMock->expects($this->once())->method('addSuccessMessage'); + $this->messageManagerMock->expects($this->once())->method('addSuccess'); $this->redirectMock->expects($this->once()) ->method('setPath') ->with($this->equalTo('customer/index/edit')) @@ -141,7 +141,7 @@ public function testExecuteWithException() ->method('unlock') ->with($customerId) ->willThrowException(new \Exception($phrase)); - $this->messageManagerMock->expects($this->once())->method('addErrorMessage'); + $this->messageManagerMock->expects($this->once())->method('addError'); $this->controller->execute(); } } diff --git a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php index 79766178a767..8592d1bda66c 100644 --- a/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php +++ b/app/code/Magento/Customer/Test/Unit/Observer/AfterAddressSaveObserverTest.php @@ -210,11 +210,9 @@ public function testAfterAddressSaveRestricted( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomerAddress', - ] - ) + ->setMethods([ + 'getCustomerAddress', + ]) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -227,12 +225,10 @@ public function testAfterAddressSaveRestricted( $this->registry->expects($this->any()) ->method('registry') - ->willReturnMap( - [ - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, $processedFlag], - [BeforeAddressSaveObserver::VIV_CURRENTLY_SAVED_ADDRESS, $registeredAddressId], - ] - ); + ->willReturnMap([ + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, $processedFlag], + [BeforeAddressSaveObserver::VIV_CURRENTLY_SAVED_ADDRESS, $registeredAddressId], + ]); $this->helperAddress->expects($this->any()) ->method('getTaxCalculationAddressType') @@ -270,13 +266,11 @@ public function testAfterAddressSaveException() $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomer', - 'getForceProcess', - 'getVatId', - ] - ) + ->setMethods([ + 'getCustomer', + 'getForceProcess', + 'getVatId', + ]) ->getMock(); $address->expects($this->any()) ->method('getCustomer') @@ -290,11 +284,9 @@ public function testAfterAddressSaveException() $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomerAddress', - ] - ) + ->setMethods([ + 'getCustomerAddress', + ]) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -311,12 +303,10 @@ public function testAfterAddressSaveException() ->willReturn(false); $this->registry->expects($this->any()) ->method('register') - ->willReturnMap( - [ - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, true, false, $this->registry], - [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, false, true, $this->registry], - ] - ); + ->willReturnMap([ + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, true, false, $this->registry], + [AfterAddressSaveObserver::VIV_PROCESSED_FLAG, false, true, $this->registry], + ]); $this->model->execute($observer); } @@ -346,15 +336,13 @@ public function testAfterAddressSaveDefaultGroup( $customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getStore', - 'getDisableAutoGroupChange', - 'getGroupId', - 'setGroupId', - 'save', - ] - ) + ->setMethods([ + 'getStore', + 'getDisableAutoGroupChange', + 'getGroupId', + 'setGroupId', + 'save', + ]) ->getMock(); $customer->expects($this->exactly(2)) ->method('getStore') @@ -375,14 +363,12 @@ public function testAfterAddressSaveDefaultGroup( $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomer', - 'getForceProcess', - 'getVatId', - 'getCountry', - ] - ) + ->setMethods([ + 'getCustomer', + 'getForceProcess', + 'getVatId', + 'getCountry', + ]) ->getMock(); $address->expects($this->once()) ->method('getCustomer') @@ -399,11 +385,9 @@ public function testAfterAddressSaveDefaultGroup( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomerAddress', - ] - ) + ->setMethods([ + 'getCustomerAddress', + ]) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -473,12 +457,10 @@ public function testAfterAddressSaveNewGroup( $validationResult = $this->getMockBuilder(\Magento\Framework\DataObject::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getIsValid', - 'getRequestSuccess', - ] - ) + ->setMethods([ + 'getIsValid', + 'getRequestSuccess', + ]) ->getMock(); $validationResult->expects($this->any()) ->method('getIsValid') @@ -489,15 +471,13 @@ public function testAfterAddressSaveNewGroup( $customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getStore', - 'getDisableAutoGroupChange', - 'getGroupId', - 'setGroupId', - 'save', - ] - ) + ->setMethods([ + 'getStore', + 'getDisableAutoGroupChange', + 'getGroupId', + 'setGroupId', + 'save', + ]) ->getMock(); $customer->expects($this->exactly(2)) ->method('getStore') @@ -523,16 +503,14 @@ public function testAfterAddressSaveNewGroup( $address = $this->getMockBuilder(\Magento\Customer\Model\Address::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomer', - 'getForceProcess', - 'getVatId', - 'getCountryId', - 'getCountry', - 'setVatValidationResult', - ] - ) + ->setMethods([ + 'getCustomer', + 'getForceProcess', + 'getVatId', + 'getCountryId', + 'getCountry', + 'setVatValidationResult', + ]) ->getMock(); $address->expects($this->any()) ->method('getCustomer') @@ -556,11 +534,9 @@ public function testAfterAddressSaveNewGroup( $observer = $this->getMockBuilder(\Magento\Framework\Event\Observer::class) ->disableOriginalConstructor() - ->setMethods( - [ - 'getCustomerAddress', - ] - ) + ->setMethods([ + 'getCustomerAddress', + ]) ->getMock(); $observer->expects($this->once()) ->method('getCustomerAddress') @@ -599,7 +575,7 @@ public function testAfterAddressSaveNewGroup( if ($resultValidMessage) { $this->messageManager->expects($this->once()) - ->method('addSuccessMessage') + ->method('addSuccess') ->with($resultValidMessage) ->willReturnSelf(); } @@ -609,7 +585,7 @@ public function testAfterAddressSaveNewGroup( ->with($vatId) ->willReturn($vatId); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with($resultInvalidMessage) ->willReturnSelf(); } @@ -619,7 +595,7 @@ public function testAfterAddressSaveNewGroup( ->with('trans_email/ident_support/email', ScopeInterface::SCOPE_STORE) ->willReturn('admin@example.com'); $this->messageManager->expects($this->once()) - ->method('addErrorMessage') + ->method('addError') ->with($resultErrorMessage) ->willReturnSelf(); } diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index e43bc4af1fca..c31742519e58 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -77,28 +77,4 @@ </argument> </arguments> </type> - <type name="Magento\Framework\View\Element\Message\MessageConfigurationsPool"> - <arguments> - <argument name="configurationsMap" xsi:type="array"> - <item name="customerAlreadyExistsErrorMessage" xsi:type="array"> - <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> - <item name="data" xsi:type="array"> - <item name="template" xsi:type="string">Magento_Customer::messages/customerAlreadyExistsErrorMessage.phtml</item> - </item> - </item> - <item name="confirmAccountSuccessMessage" xsi:type="array"> - <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> - <item name="data" xsi:type="array"> - <item name="template" xsi:type="string">Magento_Customer::messages/confirmAccountSuccessMessage.phtml</item> - </item> - </item> - <item name="unableDeleteAddressMessage" xsi:type="array"> - <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> - <item name="data" xsi:type="array"> - <item name="template" xsi:type="string">Magento_Customer::messages/unableDeleteAddressMessage.phtml</item> - </item> - </item> - </argument> - </arguments> - </type> -</config> +</config> \ No newline at end of file diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml deleted file mode 100644 index a5313078e13c..000000000000 --- a/app/code/Magento/Customer/view/frontend/templates/messages/unableDeleteAddressMessage.phtml +++ /dev/null @@ -1,9 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/** @var \Magento\Framework\View\Element\Template $block */ -?> -<?= $block->escapeHtml(__('We can\'t delete the address right now.')); From d12a2ab560aab2290df06cac5047be3edbb09991 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Sun, 25 Aug 2019 08:13:11 +0300 Subject: [PATCH 0388/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento/Customer/Controller/Account/CreatePost.php --- .../Controller/Account/CreatePost.php | 78 ++++++++++++++----- .../Controller/Account/CreatePostTest.php | 38 +++++---- app/code/Magento/Customer/etc/frontend/di.xml | 32 +++++++- ...tomerVatBillingAddressSuccessMessage.phtml | 9 +++ ...omerVatShippingAddressSuccessMessage.phtml | 9 +++ 5 files changed, 129 insertions(+), 37 deletions(-) create mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/customerVatBillingAddressSuccessMessage.phtml create mode 100644 app/code/Magento/Customer/view/frontend/templates/messages/customerVatShippingAddressSuccessMessage.phtml diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index a2be0f68b56c..2145d7dba004 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -21,6 +21,7 @@ use Magento\Framework\App\RequestInterface; use Magento\Framework\Controller\Result\Redirect; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Message\MessageInterface; use Magento\Framework\Phrase; use Magento\Store\Model\StoreManagerInterface; use Magento\Customer\Api\AccountManagementInterface; @@ -118,6 +119,11 @@ class CreatePost extends AbstractAccount implements CsrfAwareActionInterface, Ht */ protected $session; + /** + * @var StoreManagerInterface + */ + protected $storeManager; + /** * @var AccountRedirect */ @@ -365,20 +371,19 @@ public function execute() ); $confirmationStatus = $this->accountManagement->getConfirmationStatus($customer->getId()); if ($confirmationStatus === AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED) { - $email = $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()); - // @codingStandardsIgnoreStart - $this->messageManager->addSuccess( - __( - 'You must confirm your account. Please check your email for the confirmation link or <a href="%1">click here</a> for a new link.', - $email - ) + $this->messageManager->addComplexSuccessMessage( + 'confirmAccountSuccessMessage', + [ + 'url' => $this->customerUrl->getEmailConfirmationUrl($customer->getEmail()), + ] ); - // @codingStandardsIgnoreEnd $url = $this->urlModel->getUrl('*/*/index', ['_secure' => true]); $resultRedirect->setUrl($this->_redirect->success($url)); } else { $this->session->setCustomerDataAsLoggedIn($customer); - $this->messageManager->addSuccess($this->getSuccessMessage()); + + $this->messageManager->addMessage($this->getMessageManagerSuccessMessage()); + $requestedRedirect = $this->accountRedirect->getRedirectCookie(); if (!$this->scopeConfig->getValue('customer/startup/redirect_dashboard') && $requestedRedirect) { $resultRedirect->setUrl($this->_redirect->success($requestedRedirect)); @@ -395,23 +400,21 @@ public function execute() return $resultRedirect; } catch (StateException $e) { - $url = $this->urlModel->getUrl('customer/account/forgotpassword'); - // @codingStandardsIgnoreStart - $message = __( - 'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.', - $url + $this->messageManager->addComplexErrorMessage( + 'customerAlreadyExistsErrorMessage', + [ + 'url' => $this->urlModel->getUrl('customer/account/forgotpassword'), + ] ); - // @codingStandardsIgnoreEnd - $this->messageManager->addError($message); } catch (InputException $e) { - $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addErrorMessage($e->getMessage()); foreach ($e->getErrors() as $error) { - $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage())); + $this->messageManager->addErrorMessage($error->getMessage()); } } catch (LocalizedException $e) { - $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage())); + $this->messageManager->addErrorMessage($e->getMessage()); } catch (\Exception $e) { - $this->messageManager->addException($e, __('We can\'t save the customer.')); + $this->messageManager->addExceptionMessage($e, __('We can\'t save the customer.')); } $this->session->setCustomerFormData($this->getRequest()->getPostValue()); @@ -437,6 +440,8 @@ protected function checkPasswordConfirmation($password, $confirmation) /** * Retrieve success message * + * @deprecated + * @see getMessageManagerSuccessMessage() * @return string */ protected function getSuccessMessage() @@ -462,4 +467,37 @@ protected function getSuccessMessage() } return $message; } + + /** + * Retrieve success message manager message + * + * @return MessageInterface + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + protected function getMessageManagerSuccessMessage(): MessageInterface + { + if ($this->addressHelper->isVatValidationEnabled()) { + if ($this->addressHelper->getTaxCalculationAddressType() == Address::TYPE_SHIPPING) { + $identifier = 'customerVatShippingAddressSuccessMessage'; + } else { + $identifier = 'customerVatBillingAddressSuccessMessage'; + } + + $message = $this->messageManager + ->createMessage(MessageInterface::TYPE_SUCCESS, $identifier) + ->setData( + [ + 'url' => $this->urlModel->getUrl('customer/address/edit'), + ] + ); + } else { + $message = $this->messageManager + ->createMessage(MessageInterface::TYPE_SUCCESS) + ->setText( + __('Thank you for registering with %1.', $this->storeManager->getStore()->getFrontendName()) + ); + } + + return $message; + } } diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php index f8f47eedba3e..faf55347dba7 100644 --- a/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php +++ b/app/code/Magento/Customer/Test/Unit/Controller/Account/CreatePostTest.php @@ -346,11 +346,13 @@ public function testSuccessMessage( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ]); + ->willReturnMap( + [ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ] + ); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -371,7 +373,7 @@ public function testSuccessMessage( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); @@ -477,11 +479,13 @@ public function testSuccessRedirect( $this->requestMock->expects($this->any()) ->method('getParam') - ->willReturnMap([ - ['password', null, $password], - ['password_confirmation', null, $password], - ['is_subscribed', false, true], - ]); + ->willReturnMap( + [ + ['password', null, $password], + ['password_confirmation', null, $password], + ['is_subscribed', false, true], + ] + ); $this->customerMock->expects($this->once()) ->method('setAddresses') @@ -502,16 +506,18 @@ public function testSuccessRedirect( ->with($this->equalTo($customerId)); $this->messageManagerMock->expects($this->any()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with($this->stringContains($successMessage)) ->will($this->returnSelf()); $this->urlMock->expects($this->any()) ->method('getUrl') - ->willReturnMap([ - ['*/*/index', ['_secure' => true], $successUrl], - ['*/*/create', ['_secure' => true], $successUrl], - ]); + ->willReturnMap( + [ + ['*/*/index', ['_secure' => true], $successUrl], + ['*/*/create', ['_secure' => true], $successUrl], + ] + ); $this->redirectMock->expects($this->once()) ->method('success') ->with($this->equalTo($successUrl)) diff --git a/app/code/Magento/Customer/etc/frontend/di.xml b/app/code/Magento/Customer/etc/frontend/di.xml index c31742519e58..3b9675178c05 100644 --- a/app/code/Magento/Customer/etc/frontend/di.xml +++ b/app/code/Magento/Customer/etc/frontend/di.xml @@ -77,4 +77,34 @@ </argument> </arguments> </type> -</config> \ No newline at end of file + <type name="Magento\Framework\View\Element\Message\MessageConfigurationsPool"> + <arguments> + <argument name="configurationsMap" xsi:type="array"> + <item name="customerAlreadyExistsErrorMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/customerAlreadyExistsErrorMessage.phtml</item> + </item> + </item> + <item name="confirmAccountSuccessMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/confirmAccountSuccessMessage.phtml</item> + </item> + </item> + <item name="customerVatShippingAddressSuccessMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/customerVatShippingAddressSuccessMessage.phtml</item> + </item> + </item> + <item name="customerVatBillingAddressSuccessMessage" xsi:type="array"> + <item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item> + <item name="data" xsi:type="array"> + <item name="template" xsi:type="string">Magento_Customer::messages/customerVatBillingAddressSuccessMessage.phtml</item> + </item> + </item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/customerVatBillingAddressSuccessMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/customerVatBillingAddressSuccessMessage.phtml new file mode 100644 index 000000000000..294412cbc706 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/templates/messages/customerVatBillingAddressSuccessMessage.phtml @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\View\Element\Template $block */ +?> +<?= $block->escapeHtml(__('If you are a registered VAT customer, please <a href="%1">click here</a> to enter your billing address for proper VAT calculation.', $block->getData('url')), ['a']); diff --git a/app/code/Magento/Customer/view/frontend/templates/messages/customerVatShippingAddressSuccessMessage.phtml b/app/code/Magento/Customer/view/frontend/templates/messages/customerVatShippingAddressSuccessMessage.phtml new file mode 100644 index 000000000000..72dbf3f5e03d --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/templates/messages/customerVatShippingAddressSuccessMessage.phtml @@ -0,0 +1,9 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\View\Element\Template $block */ +?> +<?= $block->escapeHtml(__('If you are a registered VAT customer, please <a href="%1">click here</a> to enter your shipping address for proper VAT calculation.', $block->getData('url')), ['a']); From dd344523c67bf0af3d1f8e6a43af62a8e993bf26 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Sun, 25 Aug 2019 14:36:48 +0300 Subject: [PATCH 0389/1172] magento/magento2#: Replace deprecated addError, addSuccess, addException methods in Magento/Customer/Controller/Account/CreatePost.php --- app/code/Magento/Customer/Controller/Account/CreatePost.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php index 2145d7dba004..57b670684411 100644 --- a/app/code/Magento/Customer/Controller/Account/CreatePost.php +++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php @@ -474,7 +474,7 @@ protected function getSuccessMessage() * @return MessageInterface * @throws \Magento\Framework\Exception\NoSuchEntityException */ - protected function getMessageManagerSuccessMessage(): MessageInterface + private function getMessageManagerSuccessMessage(): MessageInterface { if ($this->addressHelper->isVatValidationEnabled()) { if ($this->addressHelper->getTaxCalculationAddressType() == Address::TYPE_SHIPPING) { From 78fd8117df9a6fc72e51a14786d58eb5504417fb Mon Sep 17 00:00:00 2001 From: Nathan Smith <nathsmit@adobe.com> Date: Mon, 26 Aug 2019 10:01:00 -0500 Subject: [PATCH 0390/1172] MC-19072: Braintree: Unable to fill "Credit Card Number" and "Expiration Date" fields on Checkout page if "CVV Verification" = No --- .../Braintree/view/frontend/web/template/payment/form.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html index 9bcb5dad8b63..8da8927a3b24 100644 --- a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html +++ b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html @@ -23,7 +23,7 @@ <!-- ko template: getTemplate() --><!-- /ko --> <!--/ko--> </div> - <form id="co-transparent-form-braintree" class="form" data-bind="" method="post" action="#" novalidate="novalidate"> + <form id="co-transparent-form-braintree" class="form" data-bind="afterRender: initHostedFields" method="post" action="#" novalidate="novalidate"> <fieldset data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}"> <legend class="legend"> <span><!-- ko i18n: 'Credit Card Information'--><!-- /ko --></span> @@ -87,7 +87,7 @@ <span><!-- ko i18n: 'Card Verification Number'--><!-- /ko --></span> </label> <div class="control _with-tooltip"> - <div data-bind="afterRender: initHostedFields, attr: {id: getCode() + '_cc_cid'}" class="hosted-control hosted-cid"></div> + <div data-bind="attr: {id: getCode() + '_cc_cid'}" class="hosted-control hosted-cid"></div> <div class="hosted-error"><!-- ko i18n: 'Please, enter valid Card Verification Number'--><!-- /ko --></div> <div class="field-tooltip toggle"> From dc084e09e1a55cc4349453b236cfaa6213313317 Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Mon, 26 Aug 2019 14:27:47 -0500 Subject: [PATCH 0391/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage removed suite and added groups instead --- .../Magento/Paypal/Test/Mftf/Suite/suite.xml | 16 ---------------- ...ckDefaultValueOfPayPalCustomizeButtonTest.xml | 1 + ...refrontCheckCreditButtonConfigurationTest.xml | 1 + ...efrontPaypalSmartButtonInCheckoutPageTest.xml | 4 +--- 4 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml diff --git a/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml b/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml deleted file mode 100644 index d1b7937180a0..000000000000 --- a/app/code/Magento/Paypal/Test/Mftf/Suite/suite.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> - <suite name="PaypalTestSuite"> - <include> - <test name="AdminCheckDefaultValueOfPayPalCustomizeButtonTest"/> - <test name="StorefrontPayPalSmartButtonInCheckoutPageTest"/> - <test name="StorefrontCheckCreditButtonConfigurationTest"/> - </include> - </suite> -</suites> \ No newline at end of file diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml index 4b28f00a132a..5c10bc9536fc 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/AdminCheckDefaultValueOfPayPalCustomizeButtonTest.xml @@ -16,6 +16,7 @@ <description value="Default value of Paypal Customize Button should be NO"/> <severity value="AVERAGE"/> <testCaseId value="MC-10904"/> + <group value="paypal"/> <skip> <issueId value="DEVOPS-3311"/> </skip> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml index 96213831cdd0..d8cea82bcc2f 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontCheckCreditButtonConfigurationTest.xml @@ -16,6 +16,7 @@ <description value="Admin is able to customize Credit button"/> <severity value="AVERAGE"/> <testCaseId value="MC-10900"/> + <group value="paypal"/> <skip> <issueId value="DEVOPS-3311"/> </skip> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml index 4f28c52679a8..fea1cf3966b9 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml @@ -16,9 +16,7 @@ <description value="Users are able to place order using Paypal Smart Button"/> <severity value="CRITICAL"/> <testCaseId value="MC-13690"/> - <skip> - <issueId value="DEVOPS-3311"/> - </skip> + <group value="paypal"/> </annotations> <before> From d110db27a979202df882c88c42fc2d0833683659 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Mon, 26 Aug 2019 16:05:24 -0500 Subject: [PATCH 0392/1172] MC-18532: Update Changelog based on delivered scope Update Changelog for 2.3.3-develop --- CHANGELOG.md | 417 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fb46a825f6..4f760535cb91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,420 @@ +2.3.3 +============= +* GitHub issues: + * [#533](https://github.com/magento/magento2/issues/533) -- By default Allow all access in .htaccess (fixed in [magento/graphql-ce#578](https://github.com/magento/graphql-ce/pull/578)) + * [#601](https://github.com/magento/magento2/issues/601) -- Admin tabs js error. (fixed in [magento/graphql-ce#632](https://github.com/magento/graphql-ce/pull/632)) + * [#631](https://github.com/magento/magento2/issues/631) -- Image Management / Editing (fixed in [magento/graphql-ce#634](https://github.com/magento/graphql-ce/pull/634)) + * [#20124](https://github.com/magento/magento2/issues/20124) -- Sort By label is hidden by Shop By Menu on listing page in iphone5 device (fixed in [magento/magento2#20135](https://github.com/magento/magento2/pull/20135)) + * [#21978](https://github.com/magento/magento2/issues/21978) -- Adding product image: File doesn't exist (fixed in [magento/magento2#22020](https://github.com/magento/magento2/pull/22020)) + * [#22045](https://github.com/magento/magento2/issues/22045) -- Instant Purchase on product page not working properly. (fixed in [magento/magento2#22260](https://github.com/magento/magento2/pull/22260)) + * [#22134](https://github.com/magento/magento2/issues/22134) -- Paypal buttons disable issue - Magento 2.3.1 (fixed in [magento/magento2#22260](https://github.com/magento/magento2/pull/22260)) + * [#22249](https://github.com/magento/magento2/issues/22249) -- Configurable Product Gallery Images Out of Order when More than 10 images (fixed in [magento/magento2#22287](https://github.com/magento/magento2/pull/22287)) + * [#22527](https://github.com/magento/magento2/issues/22527) -- Wishlist and compare icon align issue in product listing page (fixed in [magento/magento2#22532](https://github.com/magento/magento2/pull/22532)) + * [#628](https://github.com/magento/magento2/issues/628) -- Feature Request: Parent entities links in child entities grid. (fixed in [magento/graphql-ce#636](https://github.com/magento/graphql-ce/pull/636)) + * [#640](https://github.com/magento/magento2/issues/640) -- [Insight] Files should not be executable (fixed in [magento/graphql-ce#648](https://github.com/magento/graphql-ce/pull/648)) + * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though 'I've read OSL licence' is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) + * [#22406](https://github.com/magento/magento2/issues/22406) -- Store view specific labels cut in left navigation menu (fixed in [magento/magento2#22423](https://github.com/magento/magento2/pull/22423)) + * [#19515](https://github.com/magento/magento2/issues/19515) -- Create new order from backend saves the credit card when it is told not to (fixed in [magento/magento2#19767](https://github.com/magento/magento2/pull/19767)) + * [#21473](https://github.com/magento/magento2/issues/21473) -- Form element validation is not triggered when validation rules change (fixed in [magento/magento2#21992](https://github.com/magento/magento2/pull/21992)) + * [#22641](https://github.com/magento/magento2/issues/22641) -- Typo Issue and Missing header title at Customer Sales order grid (fixed in [magento/magento2#22643](https://github.com/magento/magento2/pull/22643)) + * [#22647](https://github.com/magento/magento2/issues/22647) -- In customer account create page word not readable, should use '-' after break to new line In mobile view (fixed in [magento/magento2#22656](https://github.com/magento/magento2/pull/22656)) + * [#22395](https://github.com/magento/magento2/issues/22395) -- config:set -le and -lc short form options don't work (fixed in [magento/magento2#22720](https://github.com/magento/magento2/pull/22720)) + * [#198](https://github.com/magento/magento2/issues/198) -- Better Search Please!! NOW (fixed in [magento/graphql-ce#371](https://github.com/magento/graphql-ce/pull/371)) + * [#436](https://github.com/magento/magento2/issues/436) -- [Feature request]custom option attach an image (fixed in [magento/graphql-ce#445](https://github.com/magento/graphql-ce/pull/445)) + * [#309](https://github.com/magento/magento2/issues/309) -- Terrible UI in Backend (fixed in [magento/graphql-ce#504](https://github.com/magento/graphql-ce/pull/504)) + * [#535](https://github.com/magento/magento2/issues/535) -- A few bugs (fixed in [magento/graphql-ce#650](https://github.com/magento/graphql-ce/pull/650)) + * [#658](https://github.com/magento/magento2/issues/658) -- Inline translate malfunctioning (fixed in [magento/graphql-ce#665](https://github.com/magento/graphql-ce/pull/665) and [magento/graphql-ce#744](https://github.com/magento/graphql-ce/pull/744)) + * [#657](https://github.com/magento/magento2/issues/657) -- Feature Request: Grid paging options at the top and the bottom of the grid. (fixed in [magento/graphql-ce#666](https://github.com/magento/graphql-ce/pull/666)) + * [#12612](https://github.com/magento/magento2/issues/12612) -- Array to String conversion error on checkout page when changin country - how to debug (fixed in [magento/magento2#22558](https://github.com/magento/magento2/pull/22558)) + * [#22556](https://github.com/magento/magento2/issues/22556) -- VatValidator::validate returns error if region in quoteAddress is not set (fixed in [magento/magento2#22558](https://github.com/magento/magento2/pull/22558)) + * [#20843](https://github.com/magento/magento2/issues/20843) -- Uncaught TypeError: panel.addClass is not a function when Swatches are disabled (fixed in [magento/magento2#22560](https://github.com/magento/magento2/pull/22560)) + * [#22636](https://github.com/magento/magento2/issues/22636) -- arrow toggle not changing only showing to down It should be toggle as every where is working (fixed in [magento/magento2#22644](https://github.com/magento/magento2/pull/22644)) + * [#22640](https://github.com/magento/magento2/issues/22640) -- Add tax rule form checkbox design is not as per the magento admin panel checkbox design, It is showing default design (fixed in [magento/magento2#22655](https://github.com/magento/magento2/pull/22655)) + * [#20906](https://github.com/magento/magento2/issues/20906) -- Magento backend catalog "Cost" without currency symbol (fixed in [magento/magento2#22739](https://github.com/magento/magento2/pull/22739)) + * [#22771](https://github.com/magento/magento2/issues/22771) -- Magento 2.3.0 can't change text area field height admin form using Ui component (fixed in [magento/magento2#22779](https://github.com/magento/magento2/pull/22779)) + * [#22788](https://github.com/magento/magento2/issues/22788) -- New Shipment emails do not generate (fixed in [magento/magento2#22791](https://github.com/magento/magento2/pull/22791)) + * [#18651](https://github.com/magento/magento2/issues/18651) -- Tierprice can't save float percentage value (fixed in [magento/magento2#19584](https://github.com/magento/magento2/pull/19584)) + * [#21672](https://github.com/magento/magento2/issues/21672) -- Database Media Storage - Design Config fails to save transactional email logo correctly (fixed in [magento/magento2#21675](https://github.com/magento/magento2/pull/21675) and [magento/magento2#21674](https://github.com/magento/magento2/pull/21674)) + * [#22028](https://github.com/magento/magento2/issues/22028) -- Unable to update products via csv file, when products ids from file are from wide id range (fixed in [magento/magento2#22575](https://github.com/magento/magento2/pull/22575)) + * [#21558](https://github.com/magento/magento2/issues/21558) -- Navigation issue of review from product listing when click on review count (fixed in [magento/magento2#22794](https://github.com/magento/magento2/pull/22794)) + * [#22127](https://github.com/magento/magento2/issues/22127) -- Magento 2.3.0: getSize call on configurable collection leads to exception, if no product filters are applied (fixed in [magento/magento2#22186](https://github.com/magento/magento2/pull/22186)) + * [#22639](https://github.com/magento/magento2/issues/22639) -- Without select attribute click on add attribute it display all selected when add attribute again. (fixed in [magento/magento2#22724](https://github.com/magento/magento2/pull/22724)) + * [#22676](https://github.com/magento/magento2/issues/22676) -- Compare Products counter, and My Wish List counter vertical not aligned (fixed in [magento/magento2#22742](https://github.com/magento/magento2/pull/22742)) + * [#6659](https://github.com/magento/magento2/issues/6659) -- Disabled payment methods show in Customer Dashboard (fixed in [magento/magento2#22850](https://github.com/magento/magento2/pull/22850)) + * [#4628](https://github.com/magento/magento2/issues/4628) -- .lib-font-face mixin - Fixed font formats (fixed in [magento/magento2#22854](https://github.com/magento/magento2/pull/22854)) + * [#3795](https://github.com/magento/magento2/issues/3795) -- Validation messages missing from datepicker form elements (fixed in [magento/magento2#21397](https://github.com/magento/magento2/pull/21397)) + * [#22786](https://github.com/magento/magento2/issues/22786) -- The validation for UPS configurations triggers even if UPS is disabled for checkout (fixed in [magento/magento2#22787](https://github.com/magento/magento2/pull/22787)) + * [#22822](https://github.com/magento/magento2/issues/22822) -- [Shipping] The contact us link isn't showing on order tracking page (fixed in [magento/magento2#22823](https://github.com/magento/magento2/pull/22823)) + * [#21852](https://github.com/magento/magento2/issues/21852) -- Random Error while waiting for package deployed (fixed in [magento/magento2#22607](https://github.com/magento/magento2/pull/22607)) + * [#22563](https://github.com/magento/magento2/issues/22563) -- Parallelised execution of static content deploy is broken on 2.3-develop (fixed in [magento/magento2#22607](https://github.com/magento/magento2/pull/22607)) + * [#22736](https://github.com/magento/magento2/issues/22736) -- Cursor position not in right side of search keyword in search box when click on search again (Mobile issue) (fixed in [magento/magento2#22795](https://github.com/magento/magento2/pull/22795)) + * [#22875](https://github.com/magento/magento2/issues/22875) -- Billing Agreements page title need to be improved (fixed in [magento/magento2#22876](https://github.com/magento/magento2/pull/22876)) + * [#21214](https://github.com/magento/magento2/issues/21214) -- Luma theme Apply Discount Code section design improvement (fixed in [magento/magento2#21215](https://github.com/magento/magento2/pull/21215)) + * [#22143](https://github.com/magento/magento2/issues/22143) -- Varnish health check failing due to presence of id_prefix in env.php (fixed in [magento/magento2#22307](https://github.com/magento/magento2/pull/22307)) + * [#22317](https://github.com/magento/magento2/issues/22317) -- CodeSniffer should not mark correctly aligned DocBlock elements as code style violation. (fixed in [magento/magento2#22444](https://github.com/magento/magento2/pull/22444)) + * [#22396](https://github.com/magento/magento2/issues/22396) -- config:set fails with JSON values (fixed in [magento/magento2#22513](https://github.com/magento/magento2/pull/22513)) + * [#22506](https://github.com/magento/magento2/issues/22506) -- Search suggestion panel overlapping on advance reporting button (fixed in [magento/magento2#22520](https://github.com/magento/magento2/pull/22520)) + * [#22869](https://github.com/magento/magento2/issues/22869) -- REST: Updating a customer without store_id sets the store_id to default (fixed in [magento/magento2#22893](https://github.com/magento/magento2/pull/22893)) + * [#22924](https://github.com/magento/magento2/issues/22924) -- Store view label not in the middle of panel (fixed in [magento/magento2#22926](https://github.com/magento/magento2/pull/22926)) + * [#20186](https://github.com/magento/magento2/issues/20186) -- phpcs error on rule classes - must be of the type integer (fixed in [magento/magento2#22947](https://github.com/magento/magento2/pull/22947)) + * [#574](https://github.com/magento/magento2/issues/574) -- Maximum function nesting level of '100' reached (fixed in [magento/graphql-ce#694](https://github.com/magento/graphql-ce/pull/694)) + * [#686](https://github.com/magento/magento2/issues/686) -- Product save validation errors in the admin don't hide the overlay (fixed in [magento/graphql-ce#695](https://github.com/magento/graphql-ce/pull/695)) + * [#22380](https://github.com/magento/magento2/issues/22380) -- Checkout totals order in specific store (fixed in [magento/magento2#22387](https://github.com/magento/magento2/pull/22387)) + * [#18183](https://github.com/magento/magento2/issues/18183) -- Magento 2.2.6 coupon codes don't work anymore (fixed in [magento/magento2#22718](https://github.com/magento/magento2/pull/22718)) + * [#22899](https://github.com/magento/magento2/issues/22899) -- Incorrect return type at getListByCustomerId in PaymentTokenManagementInterface (fixed in [magento/magento2#22914](https://github.com/magento/magento2/pull/22914)) + * [#22686](https://github.com/magento/magento2/issues/22686) -- Shipment Create via API salesShipmentRepositoryV1 throw Fatal error in Admin Order -> Shipment -> View (fixed in [magento/magento2#22687](https://github.com/magento/magento2/pull/22687)) + * [#22767](https://github.com/magento/magento2/issues/22767) -- Not clear logic for loading CMS Pages with setStoreId function (fixed in [magento/magento2#22772](https://github.com/magento/magento2/pull/22772)) + * [#20788](https://github.com/magento/magento2/issues/20788) -- Listing page no equal spacing in product in list view (fixed in [magento/magento2#22931](https://github.com/magento/magento2/pull/22931)) + * [#23030](https://github.com/magento/magento2/issues/23030) -- Magento2 Swatch change Image does not slide to first Image (fixed in [magento/magento2#23033](https://github.com/magento/magento2/pull/23033)) + * [#23034](https://github.com/magento/magento2/issues/23034) -- Wrong behaviour of validation scroll (fixed in [magento/magento2#23035](https://github.com/magento/magento2/pull/23035)) + * [#12696](https://github.com/magento/magento2/issues/12696) -- Integration tests create stub modules in app/code (fixed in [magento/magento2#18459](https://github.com/magento/magento2/pull/18459)) + * [#13266](https://github.com/magento/magento2/issues/13266) -- Topmenu 'last' class not being set if the a parent is inactive (fixed in [magento/magento2#22071](https://github.com/magento/magento2/pull/22071)) + * [#22882](https://github.com/magento/magento2/issues/22882) -- Static content deploy - Don't shows error message, just stack trace (fixed in [magento/magento2#22884](https://github.com/magento/magento2/pull/22884)) + * [#23045](https://github.com/magento/magento2/issues/23045) -- Exceptions from data patches do not show root cause (fixed in [magento/magento2#23046](https://github.com/magento/magento2/pull/23046)) + * [#16446](https://github.com/magento/magento2/issues/16446) -- magento 2.2.2 text swatch switches product image even if attribute feature is disabled (fixed in [magento/magento2#19184](https://github.com/magento/magento2/pull/19184)) + * [#14492](https://github.com/magento/magento2/issues/14492) -- Creating Customer without password is directly confirmed (fixed in [magento/magento2#21394](https://github.com/magento/magento2/pull/21394)) + * [#21671](https://github.com/magento/magento2/issues/21671) -- Database Media Storage - Transaction emails logo not used when pub/media cleared (fixed in [magento/magento2#21674](https://github.com/magento/magento2/pull/21674)) + * [#22425](https://github.com/magento/magento2/issues/22425) -- wrong url redirect when edit product review from Customer view page (fixed in [magento/magento2#22426](https://github.com/magento/magento2/pull/22426)) + * [#22511](https://github.com/magento/magento2/issues/22511) -- Special From Date set to today's date when Use Default Date checked in Store scope (fixed in [magento/magento2#22521](https://github.com/magento/magento2/pull/22521)) + * [#23080](https://github.com/magento/magento2/issues/23080) -- Missing whitespace in mobile navigation for non-English websites (fixed in [magento/magento2#23081](https://github.com/magento/magento2/pull/23081)) + * [#19872](https://github.com/magento/magento2/issues/19872) -- Magento 2.3 category edit page "Select from gallery" button not working. (fixed in [magento/magento2#21131](https://github.com/magento/magento2/pull/21131)) + * [#22092](https://github.com/magento/magento2/issues/22092) -- Assigning Catalog Image from Gallery, then Saving Twice, Clears Image (fixed in [magento/magento2#21131](https://github.com/magento/magento2/pull/21131)) + * [#22087](https://github.com/magento/magento2/issues/22087) -- Products Ordered Report - Not grouped by product (fixed in [magento/magento2#22646](https://github.com/magento/magento2/pull/22646)) + * [#21546](https://github.com/magento/magento2/issues/21546) -- [2.3] Database Media Storage - New Product Images fail to be processed correctly (fixed in [magento/magento2#21605](https://github.com/magento/magento2/pull/21605)) + * [#21604](https://github.com/magento/magento2/issues/21604) -- Database Media Storage - Admin Product Edit page does not handle product images correctly in database storage mode (fixed in [magento/magento2#21605](https://github.com/magento/magento2/pull/21605)) + * [#4247](https://github.com/magento/magento2/issues/4247) -- getProductUrl does not allow to override the scope in backend context (fixed in [magento/magento2#21876](https://github.com/magento/magento2/pull/21876)) + * [#22940](https://github.com/magento/magento2/issues/22940) -- Reset feature does not clear the date (fixed in [magento/magento2#23007](https://github.com/magento/magento2/pull/23007)) + * [#23053](https://github.com/magento/magento2/issues/23053) -- Sendfriend works for products with visibility not visible individually (fixed in [magento/magento2#23118](https://github.com/magento/magento2/pull/23118)) + * [#675](https://github.com/magento/magento2/issues/675) -- Textarea element cols and rows (fixed in [magento/graphql-ce#677](https://github.com/magento/graphql-ce/pull/677)) + * [#682](https://github.com/magento/magento2/issues/682) -- \Magento\Framework\Pricing\PriceCurrencyInterface depends on Magento application code (fixed in [magento/graphql-ce#700](https://github.com/magento/graphql-ce/pull/700)) + * [#681](https://github.com/magento/magento2/issues/681) -- Magento\Framework\Xml\Parser class issues (fixed in [magento/graphql-ce#711](https://github.com/magento/graphql-ce/pull/711)) + * [#22484](https://github.com/magento/magento2/issues/22484) -- Customer address States are duplicated in backend (fixed in [magento/magento2#22637](https://github.com/magento/magento2/pull/22637)) + * [#23138](https://github.com/magento/magento2/issues/23138) -- Magento_Theme. Incorrect configuration file location (fixed in [magento/magento2#23140](https://github.com/magento/magento2/pull/23140)) + * [#22004](https://github.com/magento/magento2/issues/22004) -- ce231 - can't update attribute for all product (fixed in [magento/magento2#22704](https://github.com/magento/magento2/pull/22704)) + * [#22870](https://github.com/magento/magento2/issues/22870) -- ProductRepository fails to update an existing product with a changed SKU (fixed in [magento/magento2#22933](https://github.com/magento/magento2/pull/22933)) + * [#22808](https://github.com/magento/magento2/issues/22808) -- php bin/magento catalog:image:resize error if image is missing (fixed in [magento/magento2#23005](https://github.com/magento/magento2/pull/23005)) + * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) + * [#683](https://github.com/magento/magento2/issues/683) -- CMS Router not routing correctly (fixed in [magento/graphql-ce#717](https://github.com/magento/graphql-ce/pull/717)) + * [#9113](https://github.com/magento/magento2/issues/9113) -- [Bug or Feature?] url_path attribute value is not populated for any product (fixed in [magento/graphql-ce#721](https://github.com/magento/graphql-ce/pull/721)) + * [#18337](https://github.com/magento/magento2/issues/18337) -- #search input is missing required attribute aria-expanded. (fixed in [magento/magento2#22942](https://github.com/magento/magento2/pull/22942)) + * [#23213](https://github.com/magento/magento2/issues/23213) -- Static content deploy showing percentage(%) two times in progress bar (fixed in [magento/magento2#23216](https://github.com/magento/magento2/pull/23216)) + * [#23238](https://github.com/magento/magento2/issues/23238) -- Apply coupon button act like remove coupon while create new order from admin (fixed in [magento/magento2#23250](https://github.com/magento/magento2/pull/23250)) + * [#4788](https://github.com/magento/magento2/issues/4788) -- Wrong sitemap product url (fixed in [magento/magento2#23129](https://github.com/magento/magento2/pull/23129)) + * [#22934](https://github.com/magento/magento2/issues/22934) -- Incorrect work of "Use Categories Path for Product URLs" in sitemap generation. (fixed in [magento/magento2#23129](https://github.com/magento/magento2/pull/23129)) + * [#23266](https://github.com/magento/magento2/issues/23266) -- Cannot filter admin user by ID (fixed in [magento/magento2#23267](https://github.com/magento/magento2/pull/23267)) + * [#23285](https://github.com/magento/magento2/issues/23285) -- Credit memo submit button(refund) stays disable after validation fails & unable to enable button (fixed in [magento/magento2#23286](https://github.com/magento/magento2/pull/23286)) + * [#486](https://github.com/magento/magento2/issues/486) -- Take inspiration from other frameworks (fixed in [magento/graphql-ce#714](https://github.com/magento/graphql-ce/pull/714)) + * [#716](https://github.com/magento/magento2/issues/716) -- Wrong mimetype returned by getMimeType from Magento library (fixed in [magento/graphql-ce#723](https://github.com/magento/graphql-ce/pull/723)) + * [#687](https://github.com/magento/magento2/issues/687) -- Improvement Idea: /var/cache/mage--X (fixed in [magento/graphql-ce#749](https://github.com/magento/graphql-ce/pull/749)) + * [#20038](https://github.com/magento/magento2/issues/20038) -- loading icon disappearing before background process completes for braintree payment (Admin order) (fixed in [magento/magento2#22675](https://github.com/magento/magento2/pull/22675)) + * [#23074](https://github.com/magento/magento2/issues/23074) -- Magento 2.3.1 - URL rewrite rules are not creating for product after update url key (fixed in [magento/magento2#23309](https://github.com/magento/magento2/pull/23309)) + * [#622](https://github.com/magento/magento2/issues/622) -- FIX Magento Search Please! (fixed in [magento/graphql-ce#626](https://github.com/magento/graphql-ce/pull/626)) + * [#732](https://github.com/magento/magento2/issues/732) -- Inconsistency between Select and Multiselect form elements. (fixed in [magento/graphql-ce#734](https://github.com/magento/graphql-ce/pull/734)) + * [#13227](https://github.com/magento/magento2/issues/13227) -- Knockout Recently Viewed contains wrong product url (with category path), also not correct url <meta property="og:url"> on product view page (fixed in [magento/magento2#22650](https://github.com/magento/magento2/pull/22650)) + * [#22638](https://github.com/magento/magento2/issues/22638) -- Asterisk(*) sign position does not consistent in admin (fixed in [magento/magento2#22800](https://github.com/magento/magento2/pull/22800)) + * [#22266](https://github.com/magento/magento2/issues/22266) -- Product Alert after login shows 404 page (fixed in [magento/magento2#23218](https://github.com/magento/magento2/pull/23218)) + * [#23230](https://github.com/magento/magento2/issues/23230) -- Sticky header floating under top when there is no buttons in the toolbar (fixed in [magento/magento2#23247](https://github.com/magento/magento2/pull/23247)) + * [#23333](https://github.com/magento/magento2/issues/23333) -- Incorrect payment method translation in order emails (fixed in [magento/magento2#23338](https://github.com/magento/magento2/pull/23338)) + * [#23346](https://github.com/magento/magento2/issues/23346) -- 'Test Connection' button is over-spanned (fixed in [magento/magento2#23367](https://github.com/magento/magento2/pull/23367)) + * [#21380](https://github.com/magento/magento2/issues/21380) -- Cron schedule is being duplicated (fixed in [magento/magento2#23312](https://github.com/magento/magento2/pull/23312)) + * [#21136](https://github.com/magento/magento2/issues/21136) -- Magento installation via metapackage: checkExtensions fails (fixed in [magento/magento2#22116](https://github.com/magento/magento2/pull/22116)) + * [#23233](https://github.com/magento/magento2/issues/23233) -- Alert widget doesn't trigger always method on showing the message (fixed in [magento/magento2#23234](https://github.com/magento/magento2/pull/23234)) + * [#21974](https://github.com/magento/magento2/issues/21974) -- Changes for PayPal affect core config fields with tooltip (fixed in [magento/magento2#23393](https://github.com/magento/magento2/pull/23393)) + * [#23377](https://github.com/magento/magento2/issues/23377) -- Mini cart loader not working first time magento2 (fixed in [magento/magento2#23394](https://github.com/magento/magento2/pull/23394)) + * [#22998](https://github.com/magento/magento2/issues/22998) -- POST on /orders fails when properties in the body are out of sequence (fixed in [magento/magento2#23048](https://github.com/magento/magento2/pull/23048)) + * [#23522](https://github.com/magento/magento2/issues/23522) -- UPS shipping booking and label generation gives error when shipper's street given more than 35 chars (fixed in [magento/magento2#23523](https://github.com/magento/magento2/pull/23523)) + * [#8298](https://github.com/magento/magento2/issues/8298) -- Mobile Menu Behavior at Incorrect Breakpoint (fixed in [magento/magento2#23528](https://github.com/magento/magento2/pull/23528)) + * [#22103](https://github.com/magento/magento2/issues/22103) -- Character Encoding in Plain Text Emails Fails since 2.2.8/2.3.0 due to emails no longer being sent as MIME (fixed in [magento/magento2#23535](https://github.com/magento/magento2/pull/23535)) + * [#23199](https://github.com/magento/magento2/issues/23199) -- NO sender in email header for magento 2 sales order and password change emails to customer (fixed in [magento/magento2#23535](https://github.com/magento/magento2/pull/23535)) + * [#23538](https://github.com/magento/magento2/issues/23538) -- wrong validation happen for max-words validation class (fixed in [magento/magento2#23541](https://github.com/magento/magento2/pull/23541)) + * [#21126](https://github.com/magento/magento2/issues/21126) -- Backend Import behavior design break (fixed in [magento/magento2#21128](https://github.com/magento/magento2/pull/21128)) + * [#23471](https://github.com/magento/magento2/issues/23471) -- Tooltip missing at store view lable in Cms page and Cms block (fixed in [magento/magento2#23474](https://github.com/magento/magento2/pull/23474)) + * [#23466](https://github.com/magento/magento2/issues/23466) -- Cart empty after update qty with -1 and change address. (fixed in [magento/magento2#23477](https://github.com/magento/magento2/pull/23477)) + * [#23467](https://github.com/magento/magento2/issues/23467) -- Phone and Zip not update if customer have no saved address (fixed in [magento/magento2#23494](https://github.com/magento/magento2/pull/23494)) + * [#23222](https://github.com/magento/magento2/issues/23222) -- setup:upgrade should return failure when app:config:import failed (fixed in [magento/magento2#23310](https://github.com/magento/magento2/pull/23310)) + * [#23354](https://github.com/magento/magento2/issues/23354) -- Data saving problem error showing when leave blank qty and update it (fixed in [magento/magento2#23360](https://github.com/magento/magento2/pull/23360)) + * [#23424](https://github.com/magento/magento2/issues/23424) -- Search by keyword didn't work properly with "0" value (fixed in [magento/magento2#23427](https://github.com/magento/magento2/pull/23427)) + * [#16234](https://github.com/magento/magento2/issues/16234) -- Unable to enter `+` character in widget content (fixed in [magento/magento2#23496](https://github.com/magento/magento2/pull/23496)) + * [#9798](https://github.com/magento/magento2/issues/9798) -- Problem adding attribute options to configurable product via REST Api (fixed in [magento/magento2#23529](https://github.com/magento/magento2/pull/23529)) + * [#6287](https://github.com/magento/magento2/issues/6287) -- Customer Admin Shopping Cart View Missing (fixed in [magento/magento2#20918](https://github.com/magento/magento2/pull/20918)) + * [#8258](https://github.com/magento/magento2/issues/8258) -- M2.1.3 : Form validation with identical field names does not work as expected. (fixed in [magento/magento2#15383](https://github.com/magento/magento2/pull/15383)) + * [#13561](https://github.com/magento/magento2/issues/13561) -- Magento 2 and SSL connection to MySQL (fixed in [magento/magento2#18075](https://github.com/magento/magento2/pull/18075)) + * [#22545](https://github.com/magento/magento2/issues/22545) -- Status downloadable product stays pending after succesfull payment (fixed in [magento/magento2#22658](https://github.com/magento/magento2/pull/22658)) + * [#23383](https://github.com/magento/magento2/issues/23383) -- Products which are not assigned to any store are automatically being force-assigned a store ID after being saved (fixed in [magento/magento2#23500](https://github.com/magento/magento2/pull/23500)) + * [#22950](https://github.com/magento/magento2/issues/22950) -- Spacing issue for Gift message section in my account (fixed in [magento/magento2#23226](https://github.com/magento/magento2/pull/23226)) + * [#23606](https://github.com/magento/magento2/issues/23606) -- Default value for report filters might result in errors (fixed in [magento/magento2#23607](https://github.com/magento/magento2/pull/23607)) + * [#736](https://github.com/magento/magento2/issues/736) -- Access to Zend Framework classes (fixed in [magento/graphql-ce#747](https://github.com/magento/graphql-ce/pull/747)) + * [#739](https://github.com/magento/magento2/issues/739) -- Command line install script no longer exists. (fixed in [magento/graphql-ce#753](https://github.com/magento/graphql-ce/pull/753)) + * [#23435](https://github.com/magento/magento2/issues/23435) -- Catalog Products Filter in 2.3.2 (fixed in [magento/magento2#23444](https://github.com/magento/magento2/pull/23444)) + * [#12817](https://github.com/magento/magento2/issues/12817) -- Coupon code with canceled order (fixed in [magento/magento2#20579](https://github.com/magento/magento2/pull/20579)) + * [#23386](https://github.com/magento/magento2/issues/23386) -- Copy Service does not works properly for Entities which extends Data Object and implements ExtensibleDataInterface (fixed in [magento/magento2#23387](https://github.com/magento/magento2/pull/23387)) + * [#23345](https://github.com/magento/magento2/issues/23345) -- Creditmemo getOrder() method loads order incorrectly (fixed in [magento/magento2#23358](https://github.com/magento/magento2/pull/23358)) + * [#22814](https://github.com/magento/magento2/issues/22814) -- Product stock alert - unsubscribe not working (fixed in [magento/magento2#23459](https://github.com/magento/magento2/pull/23459)) + * [#23594](https://github.com/magento/magento2/issues/23594) -- Database Media Storage : php bin/magento catalog:images:resize fails when image does not exist locally (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23595](https://github.com/magento/magento2/issues/23595) -- Database Media Storage : php bin/magento catalog:images:resize fails to generate cached images in database (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23596](https://github.com/magento/magento2/issues/23596) -- Database Media Storage : Add new product image, cached images not generated (fixed in [magento/magento2#23598](https://github.com/magento/magento2/pull/23598)) + * [#23643](https://github.com/magento/magento2/issues/23643) -- Mime parts of email are no more encoded with quoted printable (fixed in [magento/magento2#23649](https://github.com/magento/magento2/pull/23649)) + * [#23597](https://github.com/magento/magento2/issues/23597) -- Database Media Storage : Difficulty changing mode to database media storage due to poor "Use Default Value" checkbox behaviour (fixed in [magento/magento2#23710](https://github.com/magento/magento2/pull/23710)) + * [#23510](https://github.com/magento/magento2/issues/23510) -- Product customizable options of Area type render issue in Dashboard (fixed in [magento/magento2#23524](https://github.com/magento/magento2/pull/23524)) + * [#22890](https://github.com/magento/magento2/issues/22890) -- Disabled config can be overwritten via admin (fixed in [magento/magento2#22891](https://github.com/magento/magento2/pull/22891)) + * [#23054](https://github.com/magento/magento2/issues/23054) -- Cron job not running after crashed once (fixed in [magento/magento2#23125](https://github.com/magento/magento2/pull/23125)) + * [#23135](https://github.com/magento/magento2/issues/23135) -- Insert Variable popup missing template variables for new templates (fixed in [magento/magento2#23173](https://github.com/magento/magento2/pull/23173)) + * [#23211](https://github.com/magento/magento2/issues/23211) -- Zero Subtotal Checkout erroneously says the default value for "Automatically Invoice All Items" is "Yes" (fixed in [magento/magento2#23688](https://github.com/magento/magento2/pull/23688)) + * [#23624](https://github.com/magento/magento2/issues/23624) -- [Authorize.net accept.js] "Place Order" button not being disabled (fixed in [magento/magento2#23718](https://github.com/magento/magento2/pull/23718)) + * [#23717](https://github.com/magento/magento2/issues/23717) -- dependency injection fails for \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface (fixed in [magento/magento2#23753](https://github.com/magento/magento2/pull/23753)) + * [#758](https://github.com/magento/magento2/issues/758) -- Coding standards: arrays (fixed in [magento/graphql-ce#759](https://github.com/magento/graphql-ce/pull/759)) + * [#14071](https://github.com/magento/magento2/issues/14071) -- Not able to change a position of last two related products in case of I've 20+ related products. (fixed in [magento/magento2#22984](https://github.com/magento/magento2/pull/22984)) + * [#22112](https://github.com/magento/magento2/issues/22112) -- Shipping address information is lost in billing step (fixed in [magento/magento2#23656](https://github.com/magento/magento2/pull/23656)) + * [#23654](https://github.com/magento/magento2/issues/23654) -- Frontend Label For Custom Order Status not Editable in Magento Admin in Single Store Mode (fixed in [magento/magento2#23681](https://github.com/magento/magento2/pull/23681)) + * [#23751](https://github.com/magento/magento2/issues/23751) -- Database Media Storage : PDF Logo file not database aware (fixed in [magento/magento2#23752](https://github.com/magento/magento2/pull/23752)) + * [#23678](https://github.com/magento/magento2/issues/23678) -- Can't see "Zero Subtotal Checkout" payment method settings if "Offline Payments" module is disabled (fixed in [magento/magento2#23679](https://github.com/magento/magento2/pull/23679)) + * [#23777](https://github.com/magento/magento2/issues/23777) -- "Discount Amount" field is validated after the page load without any action from user in Create New Catalog Rule form (fixed in [magento/magento2#23779](https://github.com/magento/magento2/pull/23779)) + * [#23789](https://github.com/magento/magento2/issues/23789) -- CommentLevelsSniff works incorrect with @magento_import statement. (fixed in [magento/magento2#23790](https://github.com/magento/magento2/pull/23790)) + * [#22702](https://github.com/magento/magento2/issues/22702) -- Toggle icon not working in create configuration Product creation Page (fixed in [magento/magento2#23803](https://github.com/magento/magento2/pull/23803)) + * [#167](https://github.com/magento/magento2/issues/167) -- Fatal error: Class 'Mage' not found (fixed in [magento/graphql-ce#351](https://github.com/magento/graphql-ce/pull/351)) + * [#438](https://github.com/magento/magento2/issues/438) -- [Feature request] Price slider (fixed in [magento/graphql-ce#699](https://github.com/magento/graphql-ce/pull/699)) + * [#702](https://github.com/magento/magento2/issues/702) -- Base table or view not found (fixed in [magento/graphql-ce#779](https://github.com/magento/graphql-ce/pull/779)) + * [#738](https://github.com/magento/magento2/issues/738) -- pub/setup missing in 0.1.0-alpha103 (fixed in [magento/graphql-ce#789](https://github.com/magento/graphql-ce/pull/789)) + * [#23405](https://github.com/magento/magento2/issues/23405) -- 2.3.2 installed and bin/magento setup:upgrade not working (fixed in [magento/magento2#23866](https://github.com/magento/magento2/pull/23866)) + * [#23900](https://github.com/magento/magento2/issues/23900) -- Report->Product->Downloads has wrong ACL (fixed in [magento/magento2#23901](https://github.com/magento/magento2/pull/23901)) + * [#23904](https://github.com/magento/magento2/issues/23904) -- No auto-focus after validation at "Create Configurations" button => User can not see the error message (fixed in [magento/magento2#23905](https://github.com/magento/magento2/pull/23905)) + * [#23916](https://github.com/magento/magento2/issues/23916) -- Missing Validation at some Payment Method Settings (fixed in [magento/magento2#23917](https://github.com/magento/magento2/pull/23917)) + * [#23932](https://github.com/magento/magento2/issues/23932) -- Decimal quantity is not displayed for wishlist items. (fixed in [magento/magento2#23933](https://github.com/magento/magento2/pull/23933)) +* GitHub pull requests: + * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing… (by @cedarvinda) + * [magento/magento2#22020](https://github.com/magento/magento2/pull/22020) -- Non existing file, when adding image to gallery with move option. Fix for #21978 (by @dudzio12) + * [magento/magento2#22260](https://github.com/magento/magento2/pull/22260) -- Disabling "Display on Product Details Page" the button is shown anyway. (by @Nazar65) + * [magento/magento2#22287](https://github.com/magento/magento2/pull/22287) -- #222249 configurable product images wrong sorting fix (by @Wirson) + * [magento/magento2#22526](https://github.com/magento/magento2/pull/22526) -- code cleanup (http to https) (by @ravi-chandra3197) + * [magento/magento2#22532](https://github.com/magento/magento2/pull/22532) -- fixed issue 22527 wishlist and compare icon alignment (by @sanjaychouhan-webkul) + * [magento/magento2#22423](https://github.com/magento/magento2/pull/22423) -- Store view specific labels cut in left navigation menu #22406 (by @sudhanshu-bajaj) + * [magento/magento2#22561](https://github.com/magento/magento2/pull/22561) -- [Catalog|Eav] Revert change of PR magento/magento2#13302 not included into revert commit (by @Den4ik) + * [magento/magento2#22569](https://github.com/magento/magento2/pull/22569) -- 2.3 develop pr1 (by @abhinay111222) + * [magento/magento2#22594](https://github.com/magento/magento2/pull/22594) -- Fixed typo issue (by @AfreenScarlet) + * [magento/magento2#22599](https://github.com/magento/magento2/pull/22599) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22621](https://github.com/magento/magento2/pull/22621) -- Resolved Typo (by @UdgamN) + * [magento/magento2#19767](https://github.com/magento/magento2/pull/19767) -- Prevent display of token when save for later is not selected (by @pmclain) + * [magento/magento2#21744](https://github.com/magento/magento2/pull/21744) -- Custom option type select - Allow modify list of single selection option types (by @ihor-sviziev) + * [magento/magento2#21992](https://github.com/magento/magento2/pull/21992) -- #21473: Form element validation is not triggered when validation rules... (by @kisroman) + * [magento/magento2#22493](https://github.com/magento/magento2/pull/22493) -- Update credit-card-number-validator.js (by @justin-at-bounteous) + * [magento/magento2#22643](https://github.com/magento/magento2/pull/22643) -- Fixed typo issue and added missing header in customer sales order grid (by @vishal-7037) + * [magento/magento2#22656](https://github.com/magento/magento2/pull/22656) -- issues #22647 fixed, In customer account create page word not readable, should use '-' after break to new line In mobile view (by @cedarvinda) + * [magento/magento2#22720](https://github.com/magento/magento2/pull/22720) -- Fixed:#22395 (by @satyaprakashpatel) + * [magento/magento2#22558](https://github.com/magento/magento2/pull/22558) -- Additional condition in getRegion() method (by @Leone) + * [magento/magento2#22560](https://github.com/magento/magento2/pull/22560) -- Fix undefined methods 'addClass' and `removeClass` on a PrototypeJS Element (by @markvds) + * [magento/magento2#22606](https://github.com/magento/magento2/pull/22606) -- Fix Exception While Creating an Order in the Admin (by @justin-at-bounteous) + * [magento/magento2#22628](https://github.com/magento/magento2/pull/22628) -- Add a missting colon in the pdf page. (by @Hailong) + * [magento/magento2#22644](https://github.com/magento/magento2/pull/22644) -- Issue fixed #22636 arrow toggle not changing only showing to down It should be toggle as every where is working (by @cedarvinda) + * [magento/magento2#22664](https://github.com/magento/magento2/pull/22664) -- Fixed Typo Error (by @LuciferStrome) + * [magento/magento2#22729](https://github.com/magento/magento2/pull/22729) -- Fixed Typo Issue (by @jitendra-cedcoss) + * [magento/magento2#22734](https://github.com/magento/magento2/pull/22734) -- Ignores allure-results in git. (by @hostep) + * [magento/magento2#22758](https://github.com/magento/magento2/pull/22758) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22798](https://github.com/magento/magento2/pull/22798) -- Disable Travis builds - 2.3-develop (by @okorshenko) + * [magento/magento2#22126](https://github.com/magento/magento2/pull/22126) -- Remove unnecessary form on order success page (by @danielgoodwin97) + * [magento/magento2#22655](https://github.com/magento/magento2/pull/22655) -- Fixed Issue #22640 (by @Surabhi-Cedcoss) + * [magento/magento2#22657](https://github.com/magento/magento2/pull/22657) -- 404 not found form validation url when updating quantity in cart page (by @gulshanchitransh) + * [magento/magento2#22739](https://github.com/magento/magento2/pull/22739) -- Revert "Magento backend catalog cost without currency symbol" as Cost... (by @orlangur) + * [magento/magento2#22779](https://github.com/magento/magento2/pull/22779) -- #22771 Remove hardcoded height for admin textarea (by @serhiyzhovnir) + * [magento/magento2#22791](https://github.com/magento/magento2/pull/22791) -- Fixed issue #22788 (by @gauravagarwal1001) + * [magento/magento2#19584](https://github.com/magento/magento2/pull/19584) -- Tierprice can t save float percentage value 18651 (by @novikor) + * [magento/magento2#21675](https://github.com/magento/magento2/pull/21675) -- [2.3] Database Media Storage - Design Config Save functions to be Database Media Storage aware (by @gwharton) + * [magento/magento2#21917](https://github.com/magento/magento2/pull/21917) -- Prevent duplicate variation error during import of configurable products with numerical SKUs (by @alexander-aleman) + * [magento/magento2#22463](https://github.com/magento/magento2/pull/22463) -- Set timezone on DateTime object not in constructor (by @NathMorgan) + * [magento/magento2#22575](https://github.com/magento/magento2/pull/22575) -- Fix for update products via csv file (fix for 22028) (by @mtwegrzycki) + * [magento/magento2#22794](https://github.com/magento/magento2/pull/22794) -- fixed issue #21558 - Navigation issue of review from product listing (by @sanjaychouhan-webkul) + * [magento/magento2#22844](https://github.com/magento/magento2/pull/22844) -- Allow to specify a field to be checked in the response (by @diazwatson) + * [magento/magento2#22186](https://github.com/magento/magento2/pull/22186) -- 22127: check that products is set (by @davidverholen) + * [magento/magento2#22418](https://github.com/magento/magento2/pull/22418) -- Patch the prototype pollution vulnerability in jQuery < 3.4.0 (CVE-2019-11358) (by @DanielRuf) + * [magento/magento2#22724](https://github.com/magento/magento2/pull/22724) -- Fixed issue #22639: Without select attribute click on add attribute it display all selected when add attribute again. (by @maheshWebkul721) + * [magento/magento2#22742](https://github.com/magento/magento2/pull/22742) -- issue #22676 fixed - Compare Products counter, and My Wish List count... (by @sanjaychouhan-webkul) + * [magento/magento2#22850](https://github.com/magento/magento2/pull/22850) -- only show customer account sections if payment method is active (by @torhoehn) + * [magento/magento2#22854](https://github.com/magento/magento2/pull/22854) -- fix #4628 font-face mixin add fromat option (by @Karlasa) + * [magento/magento2#22868](https://github.com/magento/magento2/pull/22868) -- fix date calculation for report's years interval (by @polkan-msk) + * [magento/magento2#21397](https://github.com/magento/magento2/pull/21397) -- Fixed Validation messages missing from datepicker form elements (by @ravi-chandra3197) + * [magento/magento2#22694](https://github.com/magento/magento2/pull/22694) -- Fixed Issue #20234 (by @surbhi-ranosys) + * [magento/magento2#22787](https://github.com/magento/magento2/pull/22787) -- #22786 Add dependency for UPS required fields to avoid validation for these fields if UPS Shipping is not active (by @serhiyzhovnir) + * [magento/magento2#22823](https://github.com/magento/magento2/pull/22823) -- [Shipping] Adjusting the Contact Us Xpath (by @eduard13) + * [magento/magento2#22830](https://github.com/magento/magento2/pull/22830) -- Removing "if" block and making code more legible (by @matheusgontijo) + * [magento/magento2#22839](https://github.com/magento/magento2/pull/22839) -- FIX: Add missing Stories and Severity to Test cases (by @lbajsarowicz) + * [magento/magento2#22858](https://github.com/magento/magento2/pull/22858) -- Grammatical mistake in the comments (by @sudhanshu-bajaj) + * [magento/magento2#22889](https://github.com/magento/magento2/pull/22889) -- Replace hardcoded CarierCode from createShippingMethod() (by @wigman) + * [magento/magento2#22922](https://github.com/magento/magento2/pull/22922) -- [BUGFIX] Set correct cron instance for catalog_product_frontend_actio... (by @lewisvoncken) + * [magento/magento2#22607](https://github.com/magento/magento2/pull/22607) -- Implement Better Error Handling and Fix Waits on Null PIDs in Parallel SCD Execution (by @davidalger) + * [magento/magento2#22795](https://github.com/magento/magento2/pull/22795) -- fixed issue #22736 - Cursor position not in right side of search keyword in mobile (by @sanjaychouhan-webkul) + * [magento/magento2#22876](https://github.com/magento/magento2/pull/22876) -- Fixed issue #22875 Billing Agreements page title need to be improved (by @amitvishvakarma) + * [magento/magento2#21215](https://github.com/magento/magento2/pull/21215) -- fixed-Discount-Code-improvement-21214 (by @abrarpathan19) + * [magento/magento2#22307](https://github.com/magento/magento2/pull/22307) -- Varnish health check failing due to presence of id_prefix in env.php (by @Nazar65) + * [magento/magento2#22444](https://github.com/magento/magento2/pull/22444) -- magento/magento2#22317: PR#22321 fix. (by @p-bystritsky) + * [magento/magento2#22513](https://github.com/magento/magento2/pull/22513) -- Fixed #22396 config:set fails with JSON values (by @shikhamis11) + * [magento/magento2#22520](https://github.com/magento/magento2/pull/22520) -- Fixed #22506: Search suggestion panel overlapping on advance reporting button (by @webkul-ajaysaini) + * [magento/magento2#22760](https://github.com/magento/magento2/pull/22760) -- [Forwardport] Magento Catalog - fix custom option type text price conversion for mu... (by @ihor-sviziev) + * [magento/magento2#22893](https://github.com/magento/magento2/pull/22893) -- #22869 - defaulting customer storeId fix (by @Wirson) + * [magento/magento2#22926](https://github.com/magento/magento2/pull/22926) -- Store view label not in the middle of panel (by @speedy008) + * [magento/magento2#22947](https://github.com/magento/magento2/pull/22947) -- phpcs error on rule classes - must be of the type integer (by @Nazar65) + * [magento/magento2#22951](https://github.com/magento/magento2/pull/22951) -- Update the contributing.md to match the new beginners guide (by @dmanners) + * [magento/magento2#22387](https://github.com/magento/magento2/pull/22387) -- Checkout totals order in specific store (by @krnshah) + * [magento/magento2#22718](https://github.com/magento/magento2/pull/22718) -- Resolved issue coupon codes don't work anymore #18183 (by @this-adarsh) + * [magento/magento2#22914](https://github.com/magento/magento2/pull/22914) -- #22899 Fix the issue with Incorrect return type at getListByCustomerId in PaymentTokenManagementInterface (by @serhiyzhovnir) + * [magento/magento2#22687](https://github.com/magento/magento2/pull/22687) -- #22686 Shipment view fixed for Fatal error. (by @milindsingh) + * [magento/magento2#22772](https://github.com/magento/magento2/pull/22772) -- Fixed issue #22767: Not clear logic for loading CMS Pages with setStoreId function (by @maheshWebkul721) + * [magento/magento2#22931](https://github.com/magento/magento2/pull/22931) -- [Fixed-20788: Listing page no equal spacing in product in list view] (by @hitesh-wagento) + * [magento/magento2#22965](https://github.com/magento/magento2/pull/22965) -- Simplify if else catalog search full text data provider (by @sankalpshekhar) + * [magento/magento2#23011](https://github.com/magento/magento2/pull/23011) -- Fix typehint (by @amenk) + * [magento/magento2#22920](https://github.com/magento/magento2/pull/22920) -- Mview Indexers getList should return integer values of id's and not strings (by @mhodge13) + * [magento/magento2#23020](https://github.com/magento/magento2/pull/23020) -- Remove direct use of object manager (by @AnshuMishra17) + * [magento/magento2#23033](https://github.com/magento/magento2/pull/23033) -- Issue fix #23030: Swatch change Image does not slide to first Image (by @milindsingh) + * [magento/magento2#23035](https://github.com/magento/magento2/pull/23035) -- [Validator] Fix wrong behaviour of validation scroll (by @Den4ik) + * [magento/magento2#18459](https://github.com/magento/magento2/pull/18459) -- 12696 Delete all test modules after integration tests (by @avstudnitz) + * [magento/magento2#19897](https://github.com/magento/magento2/pull/19897) -- Re-enable PriceBox block caching (by @brucemead) + * [magento/magento2#21200](https://github.com/magento/magento2/pull/21200) -- [FEATURE] Don't load product collection in review observer (by @Den4ik) + * [magento/magento2#22071](https://github.com/magento/magento2/pull/22071) -- Make sure 'last' class is set on top menu (by @arnoudhgz) + * [magento/magento2#22821](https://github.com/magento/magento2/pull/22821) -- Customer Account Forgot Password page title fix (by @textarea) + * [magento/magento2#22884](https://github.com/magento/magento2/pull/22884) -- Show exception message during SCD failure (by @ihor-sviziev) + * [magento/magento2#22989](https://github.com/magento/magento2/pull/22989) -- Properly transliterate German Umlauts (by @amenk) + * [magento/magento2#23036](https://github.com/magento/magento2/pull/23036) -- [Framework] Reassign fields variable after converting to array (by @Den4ik) + * [magento/magento2#23040](https://github.com/magento/magento2/pull/23040) -- Don't create a new account-nav block - use existing instead. (by @vovayatsyuk) + * [magento/magento2#23046](https://github.com/magento/magento2/pull/23046) -- Add more descriptive exception when data patch fails to apply. (by @ashsmith) + * [magento/magento2#23067](https://github.com/magento/magento2/pull/23067) -- Create Security.md file to show on GitHub Security/Policy page (by @piotrekkaminski) + * [magento/magento2#14384](https://github.com/magento/magento2/pull/14384) -- Don't throw shipping method exception when creating quote with only virtual products in API (by @Maikel-Koek) + * [magento/magento2#19184](https://github.com/magento/magento2/pull/19184) -- Fixed magento text swatch switches product image even if attribute feature is disabled #16446 (by @ravi-chandra3197) + * [magento/magento2#21394](https://github.com/magento/magento2/pull/21394) -- [2.3]creating customer without password is directly confirmed 14492 (by @novikor) + * [magento/magento2#21674](https://github.com/magento/magento2/pull/21674) -- [2.3] Database Media Storage - Transactional Emails will now extract image from database in Database Media Storage mode (by @gwharton) + * [magento/magento2#22336](https://github.com/magento/magento2/pull/22336) -- fix clean_cache plugin flush mode (by @thomas-kl1) + * [magento/magento2#22426](https://github.com/magento/magento2/pull/22426) -- Fixed wrong url redirect when edit product review from Customer view page (by @ravi-chandra3197) + * [magento/magento2#22521](https://github.com/magento/magento2/pull/22521) -- Fixed 22511 (by @maheshWebkul721) + * [magento/magento2#22626](https://github.com/magento/magento2/pull/22626) -- resolved typo error (by @nehaguptacedcoss) + * [magento/magento2#22834](https://github.com/magento/magento2/pull/22834) -- #16445 - getRegionHtmlSelect does not have configuration - resolved (by @nikunjskd20) + * [magento/magento2#22937](https://github.com/magento/magento2/pull/22937) -- Mark Elasticsearch 6 support for synonyms (by @aapokiiso) + * [magento/magento2#23081](https://github.com/magento/magento2/pull/23081) -- Fix missing whitespace in mobile navigation for non-English websites (by @alexeya-ven) + * [magento/magento2#21131](https://github.com/magento/magento2/pull/21131) -- Fix Issue #19872 - checking if image is in media directory (by @Bartlomiejsz) + * [magento/magento2#22341](https://github.com/magento/magento2/pull/22341) -- Apply coupoun and scroll top to check. applied successfully or not (by @krnshah) + * [magento/magento2#22646](https://github.com/magento/magento2/pull/22646) -- Fixed Issue #22087 (by @Surabhi-Cedcoss) + * [magento/magento2#23025](https://github.com/magento/magento2/pull/23025) -- Re-enable XML as request and response types within the SwaggerUI (by @sweikenb) + * [magento/magento2#20848](https://github.com/magento/magento2/pull/20848) -- Partial docs fixes in Newsletter module (by @SikailoISM) + * [magento/magento2#21605](https://github.com/magento/magento2/pull/21605) -- [2.3] Database Media Storage - Admin Product Edit Page handles recreates images correctly when pub/media/catalog is cleared. (by @gwharton) + * [magento/magento2#21876](https://github.com/magento/magento2/pull/21876) -- $product->getUrlInStore() does not allow to override the scope in backend context (by @Nazar65) + * [magento/magento2#23007](https://github.com/magento/magento2/pull/23007) -- [Fixed] Reset feature does not clear the date (by @niravkrish) + * [magento/magento2#23118](https://github.com/magento/magento2/pull/23118) -- #23053 : sendfriend verifies product visibility instead of status (by @Wirson) + * [magento/magento2#18748](https://github.com/magento/magento2/pull/18748) -- Add a module manager to the Magento Framework API (by @navarr) + * [magento/magento2#22637](https://github.com/magento/magento2/pull/22637) -- Fixed #22484 Customer address States are duplicated in backend (by @shikhamis11) + * [magento/magento2#23140](https://github.com/magento/magento2/pull/23140) -- magento/magento2#23138: Magento_Theme. Incorrect configuration file location (by @atwixfirster) + * [magento/magento2#23179](https://github.com/magento/magento2/pull/23179) -- Fix for translation function (by @kkdg) + * [magento/magento2#22704](https://github.com/magento/magento2/pull/22704) -- Fixed #22004 can't update attribute for all product (by @shikhamis11) + * [magento/magento2#22933](https://github.com/magento/magento2/pull/22933) -- magento/magento2#22870: ProductRepository fails to update an existing product with a changed SKU. (by @p-bystritsky) + * [magento/magento2#23005](https://github.com/magento/magento2/pull/23005) -- Improve command catalog:images:resize (by @tdgroot) + * [magento/magento2#22942](https://github.com/magento/magento2/pull/22942) -- Fixed issue #18337 (by @geet07) + * [magento/magento2#23216](https://github.com/magento/magento2/pull/23216) -- Fixed #23213 Static content deploy showing percentage symbol two times in progress bar (by @amitvishvakarma) + * [magento/magento2#23244](https://github.com/magento/magento2/pull/23244) -- Update CONTRIBUTING.md (by @diazwatson) + * [magento/magento2#23248](https://github.com/magento/magento2/pull/23248) -- fix tooltip toggle selector typo (by @Karlasa) + * [magento/magento2#23250](https://github.com/magento/magento2/pull/23250) -- Fixed #23238 Apply button act like remove button while create new order from admin (by @gauravagarwal1001) + * [magento/magento2#22211](https://github.com/magento/magento2/pull/22211) -- Show converted value for validateForRefund error message (by @kassner) + * [magento/magento2#23129](https://github.com/magento/magento2/pull/23129) -- #22934 Improved sitemap product generation logic (by @sergiy-v) + * [magento/magento2#23201](https://github.com/magento/magento2/pull/23201) -- MFTF: Use AdminLoginActionGroup for AdminLoginTest - easiest use of ActionGroup (by @lbajsarowicz) + * [magento/magento2#23100](https://github.com/magento/magento2/pull/23100) -- Resolve issue with improper EAV attribute join statement (by @udovicic) + * [magento/magento2#23267](https://github.com/magento/magento2/pull/23267) -- Add filter index for ID column in adminhtml user grid (by @JeroenVanLeusden) + * [magento/magento2#23286](https://github.com/magento/magento2/pull/23286) -- Fixed Credit memo submit button(refund) stays disable after validation fails & unable to enable button issue. (by @nishantjariwala) + * [magento/magento2#23292](https://github.com/magento/magento2/pull/23292) -- revert Properly transliterate German Umlauts (by @Nazar65) + * [magento/magento2#23307](https://github.com/magento/magento2/pull/23307) -- [Ui] Allow to define listing configuration via ui component xml (by @Den4ik) + * [magento/magento2#23335](https://github.com/magento/magento2/pull/23335) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#22675](https://github.com/magento/magento2/pull/22675) -- Fixed #20038 loading icon disappearing before background process completes for Braintree payment in Admin (by @kunal-rtpl) + * [magento/magento2#23174](https://github.com/magento/magento2/pull/23174) -- Move Quote related Plugins to correct module (by @sankalpshekhar) + * [magento/magento2#23309](https://github.com/magento/magento2/pull/23309) -- magento/magento2#23074: update correct product URL rewrites after changing category url key (by @sta1r) + * [magento/magento2#23347](https://github.com/magento/magento2/pull/23347) -- Fixes incorrect file reference in a comment in a .htaccess file. (by @hostep) + * [magento/magento2#22650](https://github.com/magento/magento2/pull/22650) -- Fixes issue #13227 (by @atishgoswami) + * [magento/magento2#22800](https://github.com/magento/magento2/pull/22800) -- fixed issue #22638 - Asterisk(*) sign position does not consistent in admin (by @sanjaychouhan-webkul) + * [magento/magento2#22910](https://github.com/magento/magento2/pull/22910) -- Do an empty check instead of isset check on image removed (by @arnoudhgz) + * [magento/magento2#23218](https://github.com/magento/magento2/pull/23218) -- Fixed #22266: 404 message for product alerts when not logged in (by @ArjenMiedema) + * [magento/magento2#23247](https://github.com/magento/magento2/pull/23247) -- Fixed 23230 : Sticky header floating under top when there is no buttons in the toolbar (by @konarshankar07) + * [magento/magento2#23338](https://github.com/magento/magento2/pull/23338) -- Fix issue with incorrect payment translation in sales emails (by @alexeya-ven) + * [magento/magento2#23366](https://github.com/magento/magento2/pull/23366) -- Correct spelling (by @ravi-chandra3197) + * [magento/magento2#23367](https://github.com/magento/magento2/pull/23367) -- #23346: 'Test Connection' button is over-spanned (by @konarshankar07) + * [magento/magento2#22671](https://github.com/magento/magento2/pull/22671) -- Change exportButton option cvs (by @ajeetsinghcedcoss) + * [magento/magento2#23240](https://github.com/magento/magento2/pull/23240) -- Refactor: Improve mview code readability (by @lbajsarowicz) + * [magento/magento2#23280](https://github.com/magento/magento2/pull/23280) -- Ensure page is loaded after order click actions (by @fooman) + * [magento/magento2#23306](https://github.com/magento/magento2/pull/23306) -- FS/23038 Decimal qty with Increment is with specific values are not adding in cart (by @sertlab) + * [magento/magento2#23312](https://github.com/magento/magento2/pull/23312) -- Added function to check against running/pending/successful cron tasks (by @chickenland) + * [magento/magento2#22116](https://github.com/magento/magento2/pull/22116) -- Fix magento root package identification for metapackage installation (by @oleksii-lisovyi) + * [magento/magento2#23234](https://github.com/magento/magento2/pull/23234) -- [Ui] Calling the always action on opening and closing the modal. (by @eduard13) + * [magento/magento2#23353](https://github.com/magento/magento2/pull/23353) -- Get review entity id by code instead hard-coded. (by @DaniloEmpire) + * [magento/magento2#23393](https://github.com/magento/magento2/pull/23393) -- Fixed issue #21974 (by @geet07) + * [magento/magento2#23394](https://github.com/magento/magento2/pull/23394) -- Fixed issue #23377 (by @geet07) + * [magento/magento2#23403](https://github.com/magento/magento2/pull/23403) -- Remove rogue closing tag from store-switcher template (by @sta1r) + * [magento/magento2#22987](https://github.com/magento/magento2/pull/22987) -- Fixed apply discount coupons for bundle product (by @NikolasSumrak) + * [magento/magento2#23048](https://github.com/magento/magento2/pull/23048) -- #22998 : failing order creation with api when no address email is provided (by @Wirson) + * [magento/magento2#23390](https://github.com/magento/magento2/pull/23390) -- Changed logic so that _scrollToTopIfVisible is called only if element is in viewport. Previously it was called only when the element was outside it. (by @oskarolaussen) + * [magento/magento2#23425](https://github.com/magento/magento2/pull/23425) -- The best practices for SEO meta sequence. (by @vaseemishak) + * [magento/magento2#23523](https://github.com/magento/magento2/pull/23523) -- Issue #23522 UPS shipping booking and label generation gives error when shipper's street given more than 35 chars (by @ankurvr) + * [magento/magento2#23528](https://github.com/magento/magento2/pull/23528) -- move breakpoint by -1px to make nav work correctly at viewport 768 (by @bobemoe) + * [magento/magento2#23532](https://github.com/magento/magento2/pull/23532) -- Correct array type hints in Visibility model (by @pmclain) + * [magento/magento2#23535](https://github.com/magento/magento2/pull/23535) -- [2.3] Plain Text Emails are now sent with correct MIME Encoding (by @gwharton) + * [magento/magento2#23541](https://github.com/magento/magento2/pull/23541) -- fix validation class for max-words (by @sunilit42) + * [magento/magento2#21128](https://github.com/magento/magento2/pull/21128) -- Fix issue 21126 : Import design break issue resolved (by @speedy008) + * [magento/magento2#22213](https://github.com/magento/magento2/pull/22213) -- Date column ui component locale date format (by @Karlasa) + * [magento/magento2#23457](https://github.com/magento/magento2/pull/23457) -- Update CartTotalRepository.php (by @UlyanaKiklevich) + * [magento/magento2#23474](https://github.com/magento/magento2/pull/23474) -- Fixed tooltip missing at store view lable in Cms page and Cms block (by @dipeshrangani) + * [magento/magento2#23477](https://github.com/magento/magento2/pull/23477) -- Added quantity validation on Shipping Multiple Address Page (by @nirmalraval18) + * [magento/magento2#23494](https://github.com/magento/magento2/pull/23494) -- Removed editor from phone and zipcode (by @kazim-krish) + * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app… (by @ProcessEight) + * [magento/magento2#23360](https://github.com/magento/magento2/pull/23360) -- #23354 : Data saving problem error showing when leave blank qty and update it (by @konarshankar07) + * [magento/magento2#23427](https://github.com/magento/magento2/pull/23427) -- 23424: fixed search with 0 (by @jeysmook) + * [magento/magento2#23496](https://github.com/magento/magento2/pull/23496) -- Resolved + character issue in custom widget (by @sarfarazbheda) + * [magento/magento2#23529](https://github.com/magento/magento2/pull/23529) -- Feature/9798 updating configurable product options based on produc id and sku (by @lpouwelse) + * [magento/magento2#20918](https://github.com/magento/magento2/pull/20918) -- Enabled 'Shopping Cart' tab for customer edit interface in admin (by @rav-redchamps) + * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) + * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) + * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) + * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu… (by @shikhamis11) + * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) + * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) + * [magento/magento2#23272](https://github.com/magento/magento2/pull/23272) -- hide or show the select for regions instead of enabling/disabling in customer registration (by @UB3RL33T) + * [magento/magento2#23593](https://github.com/magento/magento2/pull/23593) -- A small fix to improve format customer acl xml. (by @mrkhoa99) + * [magento/magento2#23607](https://github.com/magento/magento2/pull/23607) -- Default filter for reports set to past month (by @rogyar) + * [magento/magento2#22138](https://github.com/magento/magento2/pull/22138) -- BeanShells are changed to correct using of variables (by @AnnaShepa) + * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i… (by @hostep) + * [magento/magento2#23351](https://github.com/magento/magento2/pull/23351) -- Fix some framework coding issues (by @fooman) + * [magento/magento2#23444](https://github.com/magento/magento2/pull/23444) -- Fix missing attribute_id condition from filter (by @mattijv) + * [magento/magento2#20579](https://github.com/magento/magento2/pull/20579) -- magento/magento2#12817: [Forwardport] Coupon code with canceled order. (by @p-bystritsky) + * [magento/magento2#23387](https://github.com/magento/magento2/pull/23387) -- magento/magento2#23386: Copy Service does not work properly for Entities which extends Data Object and implements ExtensibleDataInterface. (by @swnsma) + * [magento/magento2#23358](https://github.com/magento/magento2/pull/23358) -- magento/magento2#23345: Creditmemo getOrder() method loads order incorrectly. (by @p-bystritsky) + * [magento/magento2#23459](https://github.com/magento/magento2/pull/23459) -- magento/magento2#22814: Product stock alert - unsubscribe not working (by @yuriichayka) + * [magento/magento2#23598](https://github.com/magento/magento2/pull/23598) -- [2.3] magento catalog:images:resize now Database Media Storage mode aware (by @gwharton) + * [magento/magento2#23291](https://github.com/magento/magento2/pull/23291) -- Optimized dev:urn-catalog:generate for PHPStorm (by @JeroenBoersma) + * [magento/magento2#23592](https://github.com/magento/magento2/pull/23592) -- [Unit] Fix broken unit tests (by @Den4ik) + * [magento/magento2#23649](https://github.com/magento/magento2/pull/23649) -- [2.3] Transfer Encoding of emails changed to QUOTED-PRINTABLE (by @gwharton) + * [magento/magento2#23652](https://github.com/magento/magento2/pull/23652) -- Add missing getClass() to image.phtml so it is more like image_with_borders.phtml (by @woutersamaey) + * [magento/magento2#23710](https://github.com/magento/magento2/pull/23710) -- [2.3] Improve Database Media Storage Configuration settings usability (by @gwharton) + * [magento/magento2#23735](https://github.com/magento/magento2/pull/23735) -- Fixed typo in deploy module README.md (by @arnolds) + * [magento/magento2#22717](https://github.com/magento/magento2/pull/22717) -- Getting 404 url while updating quantity on multiple address cart page (by @vikalps4) + * [magento/magento2#23166](https://github.com/magento/magento2/pull/23166) -- Fix 22085 (by @geet07) + * [magento/magento2#23524](https://github.com/magento/magento2/pull/23524) -- remove html tag from option html from order page (by @sunilit42) + * [magento/magento2#22891](https://github.com/magento/magento2/pull/22891) -- Check if setting is disabled on default scope (by @kassner) + * [magento/magento2#23099](https://github.com/magento/magento2/pull/23099) -- fix customer data race condition when bundling is enabled (by @davidverholen) + * [magento/magento2#23125](https://github.com/magento/magento2/pull/23125) -- Catch throwables in mview updating (by @QuentinFarizonAfrimarket) + * [magento/magento2#23173](https://github.com/magento/magento2/pull/23173) -- Fixed issue #23135: Insert Variable popup missing template variables for new templates (by @maheshWebkul721) + * [magento/magento2#23688](https://github.com/magento/magento2/pull/23688) -- Resolve "Automatically Invoice All Items" is "Yes" but no invoice is created (Zero Subtotal Checkout) (by @edenduong) + * [magento/magento2#23718](https://github.com/magento/magento2/pull/23718) -- Resolve [Authorize.net accept.js] "Place Order" button not being disabled when editing billing address (by @edenduong) + * [magento/magento2#23753](https://github.com/magento/magento2/pull/23753) -- Add Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface to di.xml in issue23717 (by @edenduong) + * [magento/magento2#22984](https://github.com/magento/magento2/pull/22984) -- magento/magento2#14071: Not able to change a position of last two rel... (by @m-a-x-i-m) + * [magento/magento2#23656](https://github.com/magento/magento2/pull/23656) -- Fixes issue 22112 (https://github.com/magento/magento2/issues/22112) ... (by @rsimmons07) + * [magento/magento2#23666](https://github.com/magento/magento2/pull/23666) -- magento/magento2#: Fix storeId param type in the EmailNotification::newAccount, EmailNotificationInterface::newAccount methods (by @atwixfirster) + * [magento/magento2#23681](https://github.com/magento/magento2/pull/23681) -- Resolve Frontend Label For Custom Order Status not Editable in Magento Admin in Single Store Mode (by @edenduong) + * [magento/magento2#23752](https://github.com/magento/magento2/pull/23752) -- [2.3] Database Media Storage : PDF Logo file now database aware (by @gwharton) + * [magento/magento2#23679](https://github.com/magento/magento2/pull/23679) -- Moved Zero Subtotal Checkout Payment Settings (by @textarea) + * [magento/magento2#23779](https://github.com/magento/magento2/pull/23779) -- Resolve "Discount Amount" field is validated after the page load without any action from user in Create New Catalog Rule form issue23777 (by @edenduong) + * [magento/magento2#23787](https://github.com/magento/magento2/pull/23787) -- Fix for PHP_CodeSniffer error after app:config:dump (by @dng-dev) + * [magento/magento2#23790](https://github.com/magento/magento2/pull/23790) -- magento/magento2#23789: CommentLevelsSniff works incorrect with @magento_import statement. (by @p-bystritsky) + * [magento/magento2#23794](https://github.com/magento/magento2/pull/23794) -- Remove duplicate declaration (by @gfernandes410) + * [magento/magento2#23803](https://github.com/magento/magento2/pull/23803) -- Resolve Toggle icon not working in create configuration Product creation Page issue 22702 (by @edenduong) + * [magento/magento2#23782](https://github.com/magento/magento2/pull/23782) -- Cleaning some code gaps (by @Stepa4man) + * [magento/magento2#23840](https://github.com/magento/magento2/pull/23840) -- Fix regular expression comment on function isNameValid() in ImageContentValidator.php (by @nimbus2300) + * [magento/magento2#23845](https://github.com/magento/magento2/pull/23845) -- Add custom added url key to decoded directive string in WYSIWYG editor (by @JeroenVanLeusden) + * [magento/magento2#23866](https://github.com/magento/magento2/pull/23866) -- additional check for correct version of sodium (by @matei) + * [magento/magento2#23901](https://github.com/magento/magento2/pull/23901) -- Resolve Report->Product->Downloads has wrong ACL issue 23900 (by @edenduong) + * [magento/magento2#23905](https://github.com/magento/magento2/pull/23905) -- Resolve No auto-focus after validation at "Create Configurations" button => User can not see the error message issue23904 (by @edenduong) + * [magento/magento2#23917](https://github.com/magento/magento2/pull/23917) -- Resolve Missing Validation at some Payment Method Settings issue 23916 (by @edenduong) + * [magento/magento2#23919](https://github.com/magento/magento2/pull/23919) -- class ApplyAttributesUpdate should use \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE instead of fixing "bundle" (by @edenduong) + * [magento/magento2#23933](https://github.com/magento/magento2/pull/23933) -- Fix display of decimal quantities for wishlist items (by @mfickers) + 2.3.2 ============= * GitHub issues: From 5d7082f2217912839f6684cfe1c8b7639d807c92 Mon Sep 17 00:00:00 2001 From: Kieu Phan <kphan@adobe.com> Date: Mon, 26 Aug 2019 16:39:46 -0500 Subject: [PATCH 0393/1172] MC-18532: Update Changelog based on delivered scope Update Changelog for 2.3.3-develop --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f760535cb91..24e445b043bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -354,7 +354,7 @@ * [magento/magento2#23474](https://github.com/magento/magento2/pull/23474) -- Fixed tooltip missing at store view lable in Cms page and Cms block (by @dipeshrangani) * [magento/magento2#23477](https://github.com/magento/magento2/pull/23477) -- Added quantity validation on Shipping Multiple Address Page (by @nirmalraval18) * [magento/magento2#23494](https://github.com/magento/magento2/pull/23494) -- Removed editor from phone and zipcode (by @kazim-krish) - * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app… (by @ProcessEight) + * [magento/magento2#23310](https://github.com/magento/magento2/pull/23310) -- magento/magento-2#23222: setup:upgrade should return failure when app... (by @ProcessEight) * [magento/magento2#23360](https://github.com/magento/magento2/pull/23360) -- #23354 : Data saving problem error showing when leave blank qty and update it (by @konarshankar07) * [magento/magento2#23427](https://github.com/magento/magento2/pull/23427) -- 23424: fixed search with 0 (by @jeysmook) * [magento/magento2#23496](https://github.com/magento/magento2/pull/23496) -- Resolved + character issue in custom widget (by @sarfarazbheda) @@ -363,14 +363,14 @@ * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) - * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu… (by @shikhamis11) + * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu... (by @shikhamis11) * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) * [magento/magento2#23272](https://github.com/magento/magento2/pull/23272) -- hide or show the select for regions instead of enabling/disabling in customer registration (by @UB3RL33T) * [magento/magento2#23593](https://github.com/magento/magento2/pull/23593) -- A small fix to improve format customer acl xml. (by @mrkhoa99) * [magento/magento2#23607](https://github.com/magento/magento2/pull/23607) -- Default filter for reports set to past month (by @rogyar) * [magento/magento2#22138](https://github.com/magento/magento2/pull/22138) -- BeanShells are changed to correct using of variables (by @AnnaShepa) - * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i… (by @hostep) + * [magento/magento2#22733](https://github.com/magento/magento2/pull/22733) -- Adds module:config:status command which checks if the module config i... (by @hostep) * [magento/magento2#23351](https://github.com/magento/magento2/pull/23351) -- Fix some framework coding issues (by @fooman) * [magento/magento2#23444](https://github.com/magento/magento2/pull/23444) -- Fix missing attribute_id condition from filter (by @mattijv) * [magento/magento2#20579](https://github.com/magento/magento2/pull/20579) -- magento/magento2#12817: [Forwardport] Coupon code with canceled order. (by @p-bystritsky) From 9377d04ac9ff7d4603759e0b4a944fa89eeef423 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Tue, 27 Aug 2019 13:50:10 +0400 Subject: [PATCH 0394/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6411 --- ...EditCustomerInformationFromActionGroup.xml | 7 ++ ...inOrderSelectShippingMethodActionGroup.xml | 23 ++++ .../AdminInvoicePaymentShippingSection.xml | 4 +- ...leRatesShippingMethodStatusActionGroup.xml | 7 ++ ...ustomStoreShippingMethodTableRatesTest.xml | 119 ++++++++++++++++++ .../tests/_data/test_tablerates.csv | 13 ++ 6 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml create mode 100644 dev/tests/acceptance/tests/_data/test_tablerates.csv diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml index 09033955ecc6..fa8931bc5314 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml @@ -30,4 +30,11 @@ <waitForPageLoad stepKey="wait"/> <scrollToTopOfPage stepKey="scrollToTop"/> </actionGroup> + <actionGroup name="AdminAssociateCustomerToCustomWebsiteActionGroup"> + <arguments> + <argument name="websiteName" type="string" defaultValue="secondWebsite"/> + </arguments> + <conditionalClick selector="{{AdminCustomerAccountInformationSection.accountInformationTab}}" dependentSelector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" visible="false" stepKey="goToAccountInformation"/> + <selectOption selector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" userInput="{{websiteName}}" stepKey="selectWebSite"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml new file mode 100644 index 000000000000..87f0c4d7e470 --- /dev/null +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminOrderSelectShippingMethodActionGroup"> + <arguments> + <argument name="methodTitle" type="string" defaultValue="Flat Rate"/> + <argument name="methodName" type="string" defaultValue="Fixed"/> + </arguments> + <waitForElementVisible selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" stepKey="waitForShippingMethodsOpen"/> + <click selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" stepKey="openShippingMethod"/> + <conditionalClick selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" dependentSelector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" visible="false" stepKey="openShippingMethodSecondTime"/> + <waitForElementVisible selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" stepKey="waitForShippingMethod"/> + <click selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" stepKey="chooseShippingMethod"/> + <waitForPageLoad stepKey="waitForPageToLoad"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml index fda886a83980..a0b93c66f3a5 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml @@ -17,5 +17,7 @@ <element name="CreateShipment" type="checkbox" selector=".order-shipping-address input[name='invoice[do_shipment]']"/> <element name="getShippingMethodAndRates" type="button" selector="//span[text()='Get shipping methods and rates']" timeout="60"/> <element name="shippingMethod" type="button" selector="//label[contains(text(), 'Fixed')]" timeout="60"/> + <element name="fixedPriceShippingMethod" type="button" selector="//*[contains(text(), '{{methodTitle}}')]/parent::dl//label[contains(text(), '{{methodName}}')]" parameterized="true"/> + <element name="getShippingMethod" type="button" selector="#order-shipping-method-summary a"/> </section> -</sections> \ No newline at end of file +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml index e506ca3a7662..2df78f3a0d1a 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml @@ -17,4 +17,11 @@ <uncheckOption selector="{{AdminShippingMethodTableRatesSection.enabledUseSystemValue}}" stepKey="uncheckUseSystemValue"/> <selectOption selector="{{AdminShippingMethodTableRatesSection.carriersTableRateActive}}" userInput="{{status}}" stepKey="changeTableRatesMethodStatus"/> </actionGroup> + <actionGroup name="AdminImportFileTableRatesShippingMethodActionGroup"> + <arguments> + <argument name="file" type="string" defaultValue="test_tablerates.csv"/> + </arguments> + <conditionalClick selector="{{AdminShippingMethodTableRatesSection.carriersTableRateTab}}" dependentSelector="{{AdminShippingMethodTableRatesSection.carriersTableRateActive}}" visible="false" stepKey="expandTab"/> + <attachFile selector="{{AdminShippingMethodTableRatesSection.importFile}}" userInput="{{file}}" stepKey="attachFileForImport"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml new file mode 100644 index 000000000000..bfb94c429313 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreateOrderCustomStoreShippingMethodTableRatesTest"> + <annotations> + <features value="Shipping"/> + <stories value="Shipping method Table Rates settings gets from wrong store"/> + <title value="Create order on second store with shipping method Table Rates"/> + <description value="Create order on second store with shipping method Table Rates"/> + <severity value="MAJOR"/> + <testCaseId value="MC-6411"/> + <useCaseId value="MAGETWO-91702"/> + <group value="shipping"/> + </annotations> + <before> + <!--Create product and customer--> + <comment userInput="Create product and customer" stepKey="commentCreateProductAndCustomer"/> + <createData entity="SimpleProduct2" stepKey="createProduct"/> + <createData entity="Simple_Customer_Without_Address" stepKey="createCustomer"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create website, store group and store view--> + <comment userInput="Create website, store group and store view" stepKey="commentCreateWebsiteStoreAndView"/> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> + <argument name="newWebsiteName" value="{{customWebsite.name}}"/> + <argument name="websiteCode" value="{{customWebsite.code}}"/> + </actionGroup> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="{{customWebsite.name}}"/> + <argument name="storeGroupName" value="{{customStoreGroup.name}}"/> + <argument name="storeGroupCode" value="{{customStoreGroup.code}}"/> + </actionGroup> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createCustomStoreView"> + <argument name="StoreGroup" value="customStoreGroup"/> + <argument name="customStore" value="customStore"/> + </actionGroup> + <!--Enable Table Rate method and import csv file--> + <comment userInput="Enable Table Rate method and import csv file" stepKey="commentEnableTableRates"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="switchDefaultWebsite"> + <argument name="website" value="_defaultWebsite"/> + </actionGroup> + <actionGroup ref="AdminChangeTableRatesShippingMethodStatusActionGroup" stepKey="enableTableRatesShippingMethodForDefaultWebsite"> + <argument name="status" value="0"/> + </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfigForDefaultWebsite"/> + <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="switchCustomWebsite"> + <argument name="website" value="customWebsite"/> + </actionGroup> + <actionGroup ref="AdminChangeTableRatesShippingMethodStatusActionGroup" stepKey="enableTableRatesShippingMethod"> + <argument name="status" value="1"/> + </actionGroup> + <actionGroup ref="AdminImportFileTableRatesShippingMethodActionGroup" stepKey="importCSVFile"> + <argument name="file" value="test_tablerates.csv"/> + </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <!--Delete created data--> + <comment userInput="Delete created data" stepKey="commetnDeleteCreatedData"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <actionGroup ref="AdminDeleteCustomerActionGroup" stepKey="deleteSecondCreatedCustomer"> + <argument name="customerEmail" value="$$createCustomer.id$$"/> + </actionGroup> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="DeleteWebsite"> + <argument name="websiteName" value="{{customWebsite.name}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Assign product to custom website--> + <comment userInput="Assign product to custom website" stepKey="commentAssignProductToWebsite"/> + <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="goToProductEditPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <actionGroup ref="unassignWebsiteFromProductActionGroup" stepKey="unassignWebsiteInProduct"> + <argument name="website" value="{{_defaultWebsite.name}}"/> + </actionGroup> + <actionGroup ref="SelectProductInWebsitesActionGroup" stepKey="selectWebsiteInProduct"> + <argument name="website" value="{{customWebsite.name}}"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <!--Assign customer to custom website--> + <comment userInput="Assign customer to custom website" stepKey="commentAssignCustomerToWebsite"/> + <actionGroup ref="AdminOpenCustomerEditPageActionGroup" stepKey="openCustomerEditPage"> + <argument name="customerId" value="$$createCustomer.id$$"/> + </actionGroup> + <actionGroup ref="AdminAssociateCustomerToCustomWebsiteActionGroup" stepKey="associateCustomerToWebsite"> + <argument name="websiteName" value="{{customWebsite.name}}"/> + </actionGroup> + <actionGroup ref="AdminSaveCustomerAndAssertSuccessMessage" stepKey="saveAndCheckSuccessMessage"/> + <!--Create order--> + <comment userInput="Create order" stepKey="commentCreateOrder"/> + <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> + <argument name="customer" value="$$createCustomer$$"/> + <argument name="storeView" value="customStore"/> + </actionGroup> + <actionGroup ref="addSimpleProductToOrder" stepKey="addSimpleProductToTheOrder"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <actionGroup ref="fillOrderCustomerInformation" stepKey="fillCustomerInfo"> + <argument name="customer" value="$$createCustomer$$"/> + <argument name="address" value="US_Address_TX"/> + </actionGroup> + <!--Choose Best Way shipping Method--> + <comment userInput="Choose Best Way shipping Method" stepKey="commentChooseShippingMethod"/> + <actionGroup ref="AdminOrderSelectShippingMethodActionGroup" stepKey="chooseBestWayMethod"> + <argument name="methodTitle" value="Best Way"/> + <argument name="methodName" value="Table Rate"/> + </actionGroup> + <actionGroup ref="AdminSubmitOrderActionGroup" stepKey="submitOrder"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/_data/test_tablerates.csv b/dev/tests/acceptance/tests/_data/test_tablerates.csv new file mode 100644 index 000000000000..d5a59ae6bccf --- /dev/null +++ b/dev/tests/acceptance/tests/_data/test_tablerates.csv @@ -0,0 +1,13 @@ +Country,Region/State,"Zip/Postal Code","Order Subtotal (and above)","Shipping Price" +USA,*,*,0.0000,7.9900 +USA,*,*,7.0000,6.9900 +USA,*,*,13.0000,5.9900 +USA,*,*,25.9900,4.9900 +USA,AK,*,0.0000,8.9900 +USA,AK,*,7.0000,7.9900 +USA,AK,*,13.0000,6.9900 +USA,AK,*,25.9900,5.9900 +USA,HI,*,0.0000,8.9900 +USA,HI,*,7.0000,7.9900 +USA,HI,*,13.0000,6.9900 +USA,HI,*,25.9900,5.9900 From 54d6fa00a60a03049fc2db82193addd0850f5f71 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 27 Aug 2019 09:50:54 -0500 Subject: [PATCH 0395/1172] MC-19633: Disabled Products Do Not Appear in Search Results of Link Attribute - update to show all products regardless of status --- .../Catalog/Model/ProductLink/Search.php | 1 - .../Adminhtml/Product/SearchTest.php | 23 +++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ProductLink/Search.php b/app/code/Magento/Catalog/Model/ProductLink/Search.php index 681c01bb1281..ad7f3370ab3f 100644 --- a/app/code/Magento/Catalog/Model/ProductLink/Search.php +++ b/app/code/Magento/Catalog/Model/ProductLink/Search.php @@ -60,7 +60,6 @@ public function prepareCollection( ): \Magento\Catalog\Model\ResourceModel\Product\Collection { $productCollection = $this->productCollectionFactory->create(); $productCollection->addAttributeToSelect(ProductInterface::NAME); - $productCollection->setVisibility($this->catalogVisibility->getVisibleInCatalogIds()); $productCollection->setPage($pageNum, $limit); $this->filter->addFilter($productCollection, 'fulltext', ['fulltext' => $searchKey]); $productCollection->setPage($pageNum, $limit); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 8a33543e9343..0704d59a1431 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -38,7 +38,8 @@ public function testExecuteNonExistingSearchKey() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody, true); + $this->assertEmpty($jsonResponse['options']); } /** @@ -57,6 +58,24 @@ public function testExecuteNotVisibleIndividuallyProducts() : void ->setPostValue('limit', 50); $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); - $this->assertContains('{"options":[],"total":0}', $responseBody); + $jsonResponse = json_decode($responseBody, true); + $this->assertEquals(1, $jsonResponse['total']); + $this->assertCount(1, $jsonResponse['options']); + } + + /** + * @magentoDataFixture Magento/Catalog/_files/multiple_mixed_products.php + */ + public function testExecuteEnabledAndDisabledProducts() : void + { + $this->getRequest() + ->setPostValue('searchKey', 'simple') + ->setPostValue('page', 1) + ->setPostValue('limit', 50); + $this->dispatch('backend/catalog/product/search'); + $responseBody = $this->getResponse()->getBody(); + $jsonResponse = json_decode($responseBody, true); + $this->assertEquals(7, $jsonResponse['total']); + $this->assertCount(7, $jsonResponse['options']); } } From 2cee2dcaefb851350ed10a18450cc1f010aa3922 Mon Sep 17 00:00:00 2001 From: Dave Macaulay <macaulay@adobe.com> Date: Tue, 27 Aug 2019 11:10:19 -0500 Subject: [PATCH 0396/1172] MC-18995: Page Builder & PWA Studio Compatibility - Fix Product Widget list rendering through GraphQL --- .../CmsGraphQl/Plugin/DesignLoader.php | 68 +++++++++++++++++++ .../Magento/CmsGraphQl/etc/graphql/di.xml | 3 + 2 files changed, 71 insertions(+) create mode 100644 app/code/Magento/CmsGraphQl/Plugin/DesignLoader.php diff --git a/app/code/Magento/CmsGraphQl/Plugin/DesignLoader.php b/app/code/Magento/CmsGraphQl/Plugin/DesignLoader.php new file mode 100644 index 000000000000..d1df15c7026d --- /dev/null +++ b/app/code/Magento/CmsGraphQl/Plugin/DesignLoader.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CmsGraphQl\Plugin; + +use Magento\Catalog\Model\Product; +use Magento\Framework\Message\MessageInterface; + +/** + * Load necessary design files for GraphQL + */ +class DesignLoader +{ + /** + * @var \Magento\Framework\View\DesignLoader + */ + protected $designLoader; + + /** + * @var \Magento\Framework\Message\ManagerInterface + */ + protected $messageManager; + + /** + * @param \Magento\Framework\View\DesignLoader $designLoader + * @param \Magento\Framework\Message\ManagerInterface $messageManager + */ + public function __construct( + \Magento\Framework\View\DesignLoader $designLoader, + \Magento\Framework\Message\ManagerInterface $messageManager + ) { + $this->designLoader = $designLoader; + $this->messageManager = $messageManager; + } + + /** + * Before create load the design files + * + * @param \Magento\Catalog\Block\Product\ImageFactory $subject + * @param Product $product + * @param string $imageId + * @param array|null $attributes + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeCreate( + \Magento\Catalog\Block\Product\ImageFactory $subject, + Product $product, + string $imageId, + array $attributes = null + ) { + try { + $this->designLoader->load(); + } catch (\Magento\Framework\Exception\LocalizedException $e) { + if ($e->getPrevious() instanceof \Magento\Framework\Config\Dom\ValidationException) { + /** @var MessageInterface $message */ + $message = $this->messageManager + ->createMessage(MessageInterface::TYPE_ERROR) + ->setText($e->getMessage()); + $this->messageManager->addUniqueMessages([$message]); + } + } + } +} \ No newline at end of file diff --git a/app/code/Magento/CmsGraphQl/etc/graphql/di.xml b/app/code/Magento/CmsGraphQl/etc/graphql/di.xml index 78c1071d8e07..1be6d819a0dc 100644 --- a/app/code/Magento/CmsGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CmsGraphQl/etc/graphql/di.xml @@ -18,4 +18,7 @@ </argument> </arguments> </type> + <type name="Magento\Catalog\Block\Product\ImageFactory"> + <plugin name="designLoader" type="Magento\CmsGraphQl\Plugin\DesignLoader" /> + </type> </config> From 60dc36c70b9de9a03bf3554c1f01be9e11bd2818 Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Tue, 27 Aug 2019 16:48:47 -0500 Subject: [PATCH 0397/1172] MC-19633: Disabled Products Do Not Appear in Search Results of Link Attribute - fix test --- .../Catalog/Controller/Adminhtml/Product/SearchTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php index 0704d59a1431..cfa8b6022963 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/SearchTest.php @@ -75,7 +75,7 @@ public function testExecuteEnabledAndDisabledProducts() : void $this->dispatch('backend/catalog/product/search'); $responseBody = $this->getResponse()->getBody(); $jsonResponse = json_decode($responseBody, true); - $this->assertEquals(7, $jsonResponse['total']); - $this->assertCount(7, $jsonResponse['options']); + $this->assertEquals(6, $jsonResponse['total']); + $this->assertCount(6, $jsonResponse['options']); } } From bce207730cb040446d4ce68651b391d4970c14bd Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 28 Aug 2019 16:37:19 +0400 Subject: [PATCH 0398/1172] MC-18821: Increase test coverage for Catalog functional area - Automation test for MC-13641 --- .../Suite/MagentoDeveloperModeTestSuite.xml | 20 ++++ ...TabForSwatchProductAtributeActionGroup.xml | 8 ++ .../Mftf/Section/AdminManageSwatchSection.xml | 1 + ...fProductWithCustomProductAttributeTest.xml | 97 +++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml create mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml diff --git a/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml b/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml new file mode 100644 index 000000000000..750f7233342b --- /dev/null +++ b/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> + <suite name="MagentoDeveloperModeTestSuite"> + <before> + <magentoCLI command="deploy:mode:set developer" stepKey="enableDeveloperMode"/> + </before> + <after> + <magentoCLI command="deploy:mode:set production" stepKey="enableProductionMode"/> + </after> + <include> + <test name="AdminSaveConfProductWithCustomProductAttributeTest"/> + </include> + </suite> +</suites> diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml index 05ab5a53468a..879487d93a65 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml @@ -20,6 +20,14 @@ <fillField selector="{{AdminNewAttributePanel.lastVisualSwatchOptionAdminValue}}" userInput="{{swatchOption.admin_label}}" stepKey="fillAdminLabel"/> <fillField selector="{{AdminNewAttributePanel.lastVisualSwatchOptionDefaultStoreValue}}" userInput="{{swatchOption.default_label}}" stepKey="fillDefaultStoreLabel"/> </actionGroup> + <actionGroup name="AdminAddPreviewImageSwatchOption"> + <arguments> + <argument name="image" type="entity" defaultValue="MagentoLogo"/> + <argument name="index" type="string" defaultValue="1"/> + </arguments> + <click selector="{{AdminManageSwatchSection.nthUploadFile(index)}}" stepKey="clickUploadFile"/> + <attachFile selector="{{AdminManageSwatchSection.file}}" userInput="{{image.file}}" stepKey="attachFile"/> + </actionGroup> <!--You are on ProductAttributePage--> <!--Select value for option "Update Product Preview Image"--> diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index c3ef0a7324bf..899a032488c5 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -21,6 +21,7 @@ <element name="swatchAdminDescriptionByIndex" type="input" selector="input[name='optiontext[value][option_{{index}}][0]']" parameterized="true"/> <element name="nthChooseColor" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.colorpicker_handler" parameterized="true"/> <element name="nthUploadFile" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.btn_choose_file_upload" parameterized="true"/> + <element name="file" type="input" selector="input[name='datafile']"/> <element name="nthDelete" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) button.delete-option" parameterized="true"/> <element name="deleteBtn" type="button" selector="#manage-options-panel:nth-of-type({{var}}) button.delete-option" parameterized="true"/> </section> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml new file mode 100644 index 000000000000..a7e1d5cad65e --- /dev/null +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminSaveConfProductWithCustomProductAttributeTest"> + <annotations> + <features value="Swatches"/> + <stories value="Configurable product with custom product images as swatches attribute"/> + <title value="Saving configurable product with custom product attribute (images as swatches)"/> + <description value="Saving configurable product with custom product attribute (images as swatches)"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-13641"/> + <useCaseId value="MC-10968"/> + <group value="swatches"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create configurable product--> + <comment userInput="Create configurable product" stepKey="commentCreateConfProduct"/> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + </before> + <after> + <!--Delete created data--> + <comment userInput="Delete created data" stepKey="commentDeleteCreatedData"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToProductIndexPage"/> + <actionGroup ref="deleteProductsIfTheyExist" stepKey="deleteAllProducts"/> + <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> + <argument name="ProductAttribute" value="VisualSwatchProductAttribute"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Create Visual swatch with preview image--> + <comment userInput="Create Visual swatch with preview image" stepKey="commentCreateAttribute"/> + <amOnPage url="{{ProductAttributePage.url}}" stepKey="goToNewProductAttributePage"/> + <actionGroup ref="AdminFillProductAttributePropertiesActionGroup" stepKey="fillProductAttributeProperties"> + <argument name="attributeName" value="{{VisualSwatchProductAttribute.attribute_code}}"/> + <argument name="attributeType" value="{{VisualSwatchProductAttribute.frontend_input}}"/> + </actionGroup> + <!--Add first option--> + <comment userInput="Add first option" stepKey="commentAddFirstOption"/> + <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addFirstSwatchOptionAndFillFields"> + <argument name="swatchOption" value="visualSwatchOption1"/> + </actionGroup> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSFirstSwatch"> + <argument name="index" value="0"/> + </actionGroup> + <actionGroup ref="AdminAddPreviewImageSwatchOption" stepKey="addFirstOptionImage"> + <argument name="image" value="MagentoLogo"/> + <argument name="index" value="1"/> + </actionGroup> + <!--Add second option--> + <comment userInput="Add second option" stepKey="commentAddSecondOption"/> + <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addSecondSwatchOptionAndFillFields"> + <argument name="swatchOption" value="visualSwatchOption2"/> + </actionGroup> + <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSecondSwatch"> + <argument name="index" value="1"/> + </actionGroup> + <actionGroup ref="AdminAddPreviewImageSwatchOption" stepKey="addSecondOptionImage"> + <argument name="image" value="MagentoLogo"/> + <argument name="index" value="2"/> + </actionGroup> + <actionGroup ref="AdminSwitchScopeForProductAttributeActionGroup" stepKey="switchScopeForProductAttribute"/> + <actionGroup ref="ClickSaveButtonActionGroup" stepKey="clickSaveAttribute"> + <argument name="message" value="You saved the product attribute."/> + </actionGroup> + <!--Create configurations for product--> + <comment userInput="Create configurations for product" stepKey="commentCreateConfigsForProduct"/> + <amOnPage url="{{AdminProductEditPage.url($$createConfigProduct.id$$)}}" stepKey="goToProductEditPage"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <actionGroup ref="StartCreateConfigurationsForAttribute" stepKey="createConfigurations"> + <argument name="attributeCode" value="{{VisualSwatchProductAttribute.attribute_code}}"/> + </actionGroup> + <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionOne"> + <argument name="image" value="TestImageAdobe"/> + <argument name="frontend_label" value="{{VisualSwatchProductAttribute.attribute_code}}"/> + <argument name="label" value="{{visualSwatchOption1.default_label}}"/> + </actionGroup> + <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionTwo"> + <argument name="image" value="ImageUpload3"/> + <argument name="frontend_label" value="{{VisualSwatchProductAttribute.attribute_code}}"/> + <argument name="label" value="{{visualSwatchOption2.default_label}}"/> + </actionGroup> + <actionGroup ref="GenerateAndSaveConfiguredProductAfterSettingOptions" stepKey="saveProductForm"/> + </test> +</tests> From bfd31af036aa66fff3a4fcbe9c1f5ce4f66ec6f3 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 28 Aug 2019 10:45:22 -0500 Subject: [PATCH 0399/1172] MC-19684: Some minute values cannot be set for Analytics data collection --- .../AdminConfigurationTimeToSendDataTest.xml | 6 +-- .../Block/Agreement/Edit/AgreementsForm.xml | 2 +- .../Customer/Test/Block/Form/CustomerForm.php | 2 +- .../Block/Adminhtml/Queue/Edit/QueueForm.xml | 2 +- .../Block/Adminhtml/Sales/Coupons/Filter.xml | 2 +- .../Block/Adminhtml/Sales/TaxRule/Filter.xml | 2 +- .../Adminhtml/Rating/Edit/RatingForm.xml | 2 +- .../Block/Adminhtml/Report/Filter/Form.xml | 2 +- lib/web/mage/validation.js | 45 ------------------- lib/web/mage/validation/validation.js | 22 ++++----- 10 files changed, 18 insertions(+), 69 deletions(-) diff --git a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml index 58e62500b820..8ebd8cb594be 100644 --- a/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml +++ b/app/code/Magento/Analytics/Test/Mftf/Test/AdminConfigurationTimeToSendDataTest.xml @@ -25,9 +25,9 @@ <amOnPage url="{{AdminConfigGeneralAnalyticsPage.url}}" stepKey="amOnAdminConfig"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingService}}" userInput="Enable" stepKey="selectAdvancedReportingServiceEnabled"/> <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingIndustry}}" userInput="Apps and Games" stepKey="selectAdvancedReportingIndustry"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="11" stepKey="selectAdvancedReportingHour"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="11" stepKey="selectAdvancedReportingMinute"/> - <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="00" stepKey="selectAdvancedReportingSeconds"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingHour}}" userInput="23" stepKey="selectAdvancedReportingHour"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingMinute}}" userInput="59" stepKey="selectAdvancedReportingMinute"/> + <selectOption selector="{{AdminConfigAdvancedReportingSection.advancedReportingSeconds}}" userInput="59" stepKey="selectAdvancedReportingSeconds"/> <click selector="{{AdminMainActionsSection.save}}" stepKey="clickSaveConfigButton"/> <see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeSuccess"/> </test> diff --git a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml index 95d99f9fa76c..f98f9ca7cfe2 100644 --- a/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml +++ b/dev/tests/functional/tests/app/Magento/CheckoutAgreements/Test/Block/Adminhtml/Block/Agreement/Edit/AgreementsForm.xml @@ -18,7 +18,7 @@ <input>select</input> </mode> <stores> - <selector>[name="stores[0]"]</selector> + <selector>[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <checkbox_text /> diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php index 61166339475b..dc1e901a3fea 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/CustomerForm.php @@ -29,7 +29,7 @@ class CustomerForm extends Form * * @var string */ - protected $customerAttribute = "[orig-name='%s[]']"; + protected $customerAttribute = "[name='%s[]']"; /** * Validation text message for a field. diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml index 4d2acc76c870..c1970955013e 100644 --- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml +++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Queue/Edit/QueueForm.xml @@ -11,7 +11,7 @@ <selector>input[name='start_at']</selector> </queue_start_at> <stores> - <selector>select[name="stores[0]"]</selector> + <selector>select[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <newsletter_subject> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml index 51809448e4ed..d66c3b702f07 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/Coupons/Filter.xml @@ -29,7 +29,7 @@ <input>select</input> </price_rule_type> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <rules_list> diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml index 5820de6772e1..08e783e1329a 100644 --- a/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml +++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Block/Adminhtml/Sales/TaxRule/Filter.xml @@ -23,7 +23,7 @@ <input>select</input> </show_order_statuses> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <show_empty_rows> diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml index 504ce64bf2a7..3e1a1c727c66 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml +++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml @@ -12,7 +12,7 @@ <strategy>css selector</strategy> <fields> <stores> - <selector>[name="stores[0]"]</selector> + <selector>[name="stores[]"]</selector> <input>multiselectgrouplist</input> </stores> <is_active> diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml index 294f64966bde..d868798eba79 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Report/Filter/Form.xml @@ -26,7 +26,7 @@ <input>select</input> </show_order_statuses> <order_statuses> - <selector>[name="order_statuses[0]"]</selector> + <selector>[name="order_statuses[]"]</selector> <input>multiselect</input> </order_statuses> <show_actual_columns> diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index b284f0002bc6..55921c054e61 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1925,7 +1925,6 @@ * @protected */ _create: function () { - this._prepareArrayInputs(); this.validate = this.element.validate(this.options); // ARIA (adding aria-required attribute) @@ -1938,50 +1937,6 @@ this._listenFormValidate(); }, - /** - * Validation creation. - * - * @protected - */ - _prepareArrayInputs: function () { - /* Store original names for array inputs */ - var originalElements = [], - originalSubmitHandler = this.options.submitHandler; - - /* For all array inputs, assign index so that validation is proper */ - this.element.find('[name$="[]"]').each(function (key, input) { - var originalName, name; - - input = $(input); - originalName = input.attr('name'); - name = originalName.replace('[]', '[' + key + ']'); - $(input).attr('name', name); - $(input).attr('orig-name', originalName); - originalElements.push({ - element: $(input), - name: originalName - }); - }); - - if (originalElements.length) { - /** - * Before submitting the actual form, remove the previously assigned indices - * @param {Object} form - */ - this.options.submitHandler = function (form) { - originalElements.forEach(function (element) { - element.element.attr('name', element.name); - element.element.removeAttr('orig-name'); - }); - - console.error(this.submit); - - /* Call the originalSubmitHandler if it's a function */ - typeof originalSubmitHandler === 'function' ? originalSubmitHandler(form) : form.submit(); - }; - } - }, - /** * Validation listening. * diff --git a/lib/web/mage/validation/validation.js b/lib/web/mage/validation/validation.js index 69cb984b0d82..74b00e34e916 100644 --- a/lib/web/mage/validation/validation.js +++ b/lib/web/mage/validation/validation.js @@ -49,23 +49,17 @@ 'validate-one-checkbox-required-by-name': [ function (value, element, params) { var checkedCount = 0, - selector, - container, - origNameSelector, - nameSelector; + container; if (element.type === 'checkbox') { - /* If orig-name attribute is present, use it for validation. Else use name */ - origNameSelector = '[orig-name="' + element.getAttribute('orig-name') + '"]'; - nameSelector = '[name="' + element.name + '"]'; - selector = element.getAttribute('orig-name') ? origNameSelector : nameSelector; - $(selector).each(function () { - if ($(this).is(':checked')) { - checkedCount += 1; - - return false; + $('[name="' + element.name + '"]').each( + function () { + if ($(this).is(':checked')) { + checkedCount += 1; + return false; + } } - }); + ); } container = '#' + params; From d617c3ca6541d1528bf26c26738b909d55424def Mon Sep 17 00:00:00 2001 From: Oleksii Lisovyi <olexii.lisovyi@ven.com> Date: Wed, 28 Aug 2019 18:51:39 +0300 Subject: [PATCH 0400/1172] Sales - fix displaying available allowed countries while editing order address in Admin panel --- .../Block/Adminhtml/Order/Address/Form.php | 8 +++++ .../Adminhtml/Order/Create/Form/Address.php | 31 +++++++++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Address/Form.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Address/Form.php index 12e59e63f6f7..1efa149b390e 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Address/Form.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Address/Form.php @@ -136,4 +136,12 @@ public function getFormValues() { return $this->_getAddress()->getData(); } + + /** + * @inheritDoc + */ + protected function getAddressStoreId() + { + return $this->_getAddress()->getOrder()->getStoreId(); + } } diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Address.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Address.php index e4b9dd4c63b9..3fe943c1b194 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Address.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/Address.php @@ -271,21 +271,24 @@ protected function _prepareForm() $this->_form->setValues($this->getFormValues()); - if ($this->_form->getElement('country_id')->getValue()) { - $countryId = $this->_form->getElement('country_id')->getValue(); - $this->_form->getElement('country_id')->setValue(null); - foreach ($this->_form->getElement('country_id')->getValues() as $country) { + $countryElement = $this->_form->getElement('country_id'); + + $this->processCountryOptions($countryElement); + + if ($countryElement->getValue()) { + $countryId = $countryElement->getValue(); + $countryElement->setValue(null); + foreach ($countryElement->getValues() as $country) { if ($country['value'] == $countryId) { - $this->_form->getElement('country_id')->setValue($countryId); + $countryElement->setValue($countryId); } } } - if ($this->_form->getElement('country_id')->getValue() === null) { - $this->_form->getElement('country_id')->setValue( + if ($countryElement->getValue() === null) { + $countryElement->setValue( $this->directoryHelper->getDefaultCountry($this->getStore()) ); } - $this->processCountryOptions($this->_form->getElement('country_id')); // Set custom renderer for VAT field if needed $vatIdElement = $this->_form->getElement('vat_id'); if ($vatIdElement && $this->getDisplayVatValidationButton() !== false) { @@ -309,7 +312,7 @@ protected function _prepareForm() */ private function processCountryOptions(\Magento\Framework\Data\Form\Element\AbstractElement $countryElement) { - $storeId = $this->getBackendQuoteSession()->getStoreId(); + $storeId = $this->getAddressStoreId(); $options = $this->getCountriesCollection() ->loadByStore($storeId) ->toOptionArray(); @@ -388,4 +391,14 @@ public function getAddressAsString(\Magento\Customer\Api\Data\AddressInterface $ return $this->escapeHtml($result); } + + /** + * Return address store id. + * + * @return int + */ + protected function getAddressStoreId() + { + return $this->getBackendQuoteSession()->getStoreId(); + } } From eba1d8dfff69a3c4eef6fa63e593b5f384adda27 Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Wed, 28 Aug 2019 11:41:53 -0500 Subject: [PATCH 0401/1172] MC-19684: Some minute values cannot be set for Analytics data collection --- lib/web/mage/validation/validation.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/web/mage/validation/validation.js b/lib/web/mage/validation/validation.js index 74b00e34e916..0f2c4c06b119 100644 --- a/lib/web/mage/validation/validation.js +++ b/lib/web/mage/validation/validation.js @@ -56,6 +56,7 @@ function () { if ($(this).is(':checked')) { checkedCount += 1; + return false; } } From f29efd3e44ecbf424d9e3126f3b968b286abff5e Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Thu, 29 Aug 2019 13:29:25 +0300 Subject: [PATCH 0402/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../SaveQuoteAddressToCustomerAddressBook.php | 95 +++++++++++++++++++ .../Model/Cart/SetBillingAddressOnCart.php | 18 +++- .../Model/Cart/SetShippingAddressesOnCart.php | 20 +++- .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- 4 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php new file mode 100644 index 000000000000..e9aa4ba745b9 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php @@ -0,0 +1,95 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart\Address; + +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Customer\Api\Data\RegionInterface; +use Magento\Customer\Api\Data\RegionInterfaceFactory; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Quote\Model\Quote\Address as QuoteAddress; + +/** + * Save Address to Customer Address Book. + */ +class SaveQuoteAddressToCustomerAddressBook +{ + /** + * @var AddressInterfaceFactory + */ + private $addressFactory; + + /** + * @var AddressRepositoryInterface + */ + private $addressRepository; + + /** + * @var RegionInterfaceFactory + */ + private $regionFactory; + + /** + * @param AddressInterfaceFactory $addressFactory + * @param AddressRepositoryInterface $addressRepository + * @param RegionInterfaceFactory $regionFactory + */ + public function __construct( + AddressInterfaceFactory $addressFactory, + AddressRepositoryInterface $addressRepository, + RegionInterfaceFactory $regionFactory + ) { + $this->addressFactory = $addressFactory; + $this->addressRepository = $addressRepository; + $this->regionFactory = $regionFactory; + } + + /** + * + * @param QuoteAddress $quoteAddress + * @param int $customerId + * + * @return void + * @throws GraphQlInputException + */ + public function execute(QuoteAddress $quoteAddress, int $customerId): void + { + try { + /** @var AddressInterface $customerAddress */ + $customerAddress = $this->addressFactory->create(); + $customerAddress->setFirstname($quoteAddress->getFirstname()) + ->setLastname($quoteAddress->getLastname()) + ->setMiddlename($quoteAddress->getMiddlename()) + ->setPrefix($quoteAddress->getPrefix()) + ->setSuffix($quoteAddress->getSuffix()) + ->setVatId($quoteAddress->getVatId()) + ->setCountryId($quoteAddress->getCountryId()) + ->setCompany($quoteAddress->getCompany()) + ->setRegionId($quoteAddress->getRegionId()) + ->setFax($quoteAddress->getFax()) + ->setCity($quoteAddress->getCity()) + ->setPostcode($quoteAddress->getPostcode()) + ->setStreet($quoteAddress->getStreet()) + ->setTelephone($quoteAddress->getTelephone()) + ->setCustomerId($customerId); + + /** @var RegionInterface $region */ + $region = $this->regionFactory->create(); + $region->setRegionCode($quoteAddress->getRegionCode()) + ->setRegion($quoteAddress->getRegion()) + ->setRegionId($quoteAddress->getRegionId()); + $customerAddress->setRegion($region); + + $this->addressRepository->save($customerAddress); + } catch (LocalizedException $e) { + throw new GraphQlInputException(__($e->getMessage()), $e); + } + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php index 673debefd087..22dff2d5550b 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php @@ -13,6 +13,7 @@ use Magento\GraphQl\Model\Query\ContextInterface; use Magento\Quote\Api\Data\CartInterface; use Magento\Quote\Model\Quote\Address; +use Magento\QuoteGraphQl\Model\Cart\Address\SaveQuoteAddressToCustomerAddressBook; /** * Set billing address for a specified shopping cart @@ -29,16 +30,24 @@ class SetBillingAddressOnCart */ private $assignBillingAddressToCart; + /** + * @var SaveQuoteAddressToCustomerAddressBook + */ + private $saveQuoteAddressToCustomerAddressBook; + /** * @param QuoteAddressFactory $quoteAddressFactory * @param AssignBillingAddressToCart $assignBillingAddressToCart + * @param SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook */ public function __construct( QuoteAddressFactory $quoteAddressFactory, - AssignBillingAddressToCart $assignBillingAddressToCart + AssignBillingAddressToCart $assignBillingAddressToCart, + SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook ) { $this->quoteAddressFactory = $quoteAddressFactory; $this->assignBillingAddressToCart = $assignBillingAddressToCart; + $this->saveQuoteAddressToCustomerAddressBook = $saveQuoteAddressToCustomerAddressBook; } /** @@ -101,6 +110,12 @@ private function createBillingAddress( ): Address { if (null === $customerAddressId) { $billingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); + + $customerId = $context->getUserId(); + // need to save address only for registered user and if save_in_address_book = true + if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { + $this->saveQuoteAddressToCustomerAddressBook->execute($billingAddress, $customerId); + } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); @@ -111,6 +126,7 @@ private function createBillingAddress( (int)$context->getUserId() ); } + return $billingAddress; } } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index 77719bed5b16..c3d147bb4727 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -11,6 +11,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Model\Query\ContextInterface; use Magento\Quote\Api\Data\CartInterface; +use Magento\QuoteGraphQl\Model\Cart\Address\SaveQuoteAddressToCustomerAddressBook; /** * Set single shipping address for a specified shopping cart @@ -27,16 +28,24 @@ class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface */ private $assignShippingAddressToCart; + /** + * @var SaveQuoteAddressToCustomerAddressBook + */ + private $saveQuoteAddressToCustomerAddressBook; + /** * @param QuoteAddressFactory $quoteAddressFactory * @param AssignShippingAddressToCart $assignShippingAddressToCart + * @param SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook */ public function __construct( QuoteAddressFactory $quoteAddressFactory, - AssignShippingAddressToCart $assignShippingAddressToCart + AssignShippingAddressToCart $assignShippingAddressToCart, + SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook ) { $this->quoteAddressFactory = $quoteAddressFactory; $this->assignShippingAddressToCart = $assignShippingAddressToCart; + $this->saveQuoteAddressToCustomerAddressBook = $saveQuoteAddressToCustomerAddressBook; } /** @@ -65,8 +74,15 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } + $customerId = $context->getUserId(); + if (null === $customerAddressId) { $shippingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); + + // need to save address only for registered user and if save_in_address_book = true + if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { + $this->saveQuoteAddressToCustomerAddressBook->execute($shippingAddress, $customerId); + } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); @@ -74,7 +90,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s $shippingAddress = $this->quoteAddressFactory->createBasedOnCustomerAddress( (int)$customerAddressId, - $context->getUserId() + $customerId ); } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 6d7f4daf40de..b9199a0774c2 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -108,7 +108,7 @@ input CartAddressInput { postcode: String country_code: String! telephone: String! - save_in_address_book: Boolean! + save_in_address_book: Boolean } input SetShippingMethodsOnCartInput { From 883d9f52e1b360b5c3c3b9b9f0a7f512531dfe83 Mon Sep 17 00:00:00 2001 From: Oleksii Lisovyi <olexii.lisovyi@ven.com> Date: Thu, 29 Aug 2019 15:25:58 +0300 Subject: [PATCH 0403/1172] Sales - fix displaying available allowed countries while editing order address in Admin panel - fixed unit test --- .../Test/Unit/Block/Adminhtml/Order/Address/FormTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Address/FormTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Address/FormTest.php index 94148cc51538..2b08daf02134 100644 --- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Address/FormTest.php +++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/Address/FormTest.php @@ -95,6 +95,11 @@ protected function setUp() '_orderCreate' => $this->orderCreate ] ); + + // Do not display VAT validation button on edit order address form + // Emulate fix done in controller + /** @see \Magento\Sales\Controller\Adminhtml\Order\Address::execute */ + $this->addressBlock->setDisplayVatValidationButton(false); } public function testGetForm() From 1a7bbc4b1d23a5bbaa555893f3a1406121b3ec28 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Fri, 30 Aug 2019 11:59:42 +0300 Subject: [PATCH 0404/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Quote/Customer/CheckoutEndToEndTest.php | 2 - .../Customer/SetBillingAddressOnCartTest.php | 160 ++++++++++++++++- .../Customer/SetShippingAddressOnCartTest.php | 165 +++++++++++++++++- .../Guest/AllowGuestCheckoutOptionTest.php | 2 - .../Quote/Guest/CheckoutEndToEndTest.php | 2 - .../Guest/SetBillingAddressOnCartTest.php | 7 - .../Guest/SetShippingAddressOnCartTest.php | 6 - 7 files changed, 313 insertions(+), 31 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php index 5a4cc88d6962..578c7faa3c6e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php @@ -259,7 +259,6 @@ private function setBillingAddress(string $cartId): void telephone: "88776655" region: "TX" country_code: "US" - save_in_address_book: false } } } @@ -298,7 +297,6 @@ private function setShippingAddress(string $cartId): array postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php index 011930e72327..9a9c50c14057 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php @@ -7,6 +7,9 @@ namespace Magento\GraphQl\Quote\Customer; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\Quote\Model\QuoteFactory; @@ -45,6 +48,19 @@ class SetBillingAddressOnCartTest extends GraphQlAbstract */ private $customerTokenService; + /** + * @var AddressRepositoryInterface + */ + private $customerAddressRepository; + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + /** + * @var CustomerRepositoryInterface + */ + private $customerRepository; + protected function setUp() { $objectManager = Bootstrap::getObjectManager(); @@ -53,6 +69,9 @@ protected function setUp() $this->quoteFactory = $objectManager->get(QuoteFactory::class); $this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->customerAddressRepository = $objectManager->get(AddressRepositoryInterface::class); + $this->searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); + $this->customerRepository = $objectManager->get(CustomerRepositoryInterface::class); } /** @@ -81,7 +100,6 @@ public function testSetNewBillingAddress() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -140,7 +158,6 @@ public function testSetNewBillingAddressWithUseForShippingParameter() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } use_for_shipping: true } @@ -301,7 +318,6 @@ public function testSetNewBillingAddressAndFromAddressBookAtSameTime() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -383,7 +399,6 @@ public function testSetNewBillingAddressWithUseForShippingAndMultishipping() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } use_for_shipping: true } @@ -620,7 +635,6 @@ public function testSetNewBillingAddressWithRedundantStreetLine() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -663,7 +677,6 @@ public function testSetBillingAddressWithLowerCaseCountry() postcode: "887766" country_code: "us" telephone: "88776655" - save_in_address_book: false } } } @@ -696,6 +709,141 @@ public function testSetBillingAddressWithLowerCaseCountry() $this->assertNewAddressFields($billingAddressResponse); } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetNewBillingAddressWithSaveInAddressBook() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $query = <<<QUERY +mutation { + setBillingAddressOnCart( + input: { + cart_id: "$maskedQuoteId" + billing_address: { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: true + } + } + } + ) { + cart { + billing_address { + firstname + lastname + company + street + city + postcode + telephone + country { + code + label + } + __typename + } + } + } +} +QUERY; + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $customer = $this->customerRepository->get('customer@example.com'); + $searchCriteria = $this->searchCriteriaBuilder->addFilter('parent_id', $customer->getId())->create(); + $addresses = $this->customerAddressRepository->getList($searchCriteria)->getItems(); + + self::assertCount(1, $addresses); + self::assertArrayHasKey('cart', $response['setBillingAddressOnCart']); + + $cartResponse = $response['setBillingAddressOnCart']['cart']; + self::assertArrayHasKey('billing_address', $cartResponse); + $billingAddressResponse = $cartResponse['billing_address']; + $this->assertNewAddressFields($billingAddressResponse); + + foreach ($addresses as $address) { + $this->customerAddressRepository->delete($address); + } + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetNewBillingAddressWithNotSaveInAddressBook() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $query = <<<QUERY +mutation { + setBillingAddressOnCart( + input: { + cart_id: "$maskedQuoteId" + billing_address: { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + } + ) { + cart { + billing_address { + firstname + lastname + company + street + city + postcode + telephone + country { + code + label + } + __typename + } + } + } +} +QUERY; + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $customer = $this->customerRepository->get('customer@example.com'); + $searchCriteria = $this->searchCriteriaBuilder->addFilter('parent_id', $customer->getId())->create(); + $addresses = $this->customerAddressRepository->getList($searchCriteria)->getItems(); + + self::assertCount(0, $addresses); + self::assertArrayHasKey('cart', $response['setBillingAddressOnCart']); + + $cartResponse = $response['setBillingAddressOnCart']['cart']; + self::assertArrayHasKey('billing_address', $cartResponse); + $billingAddressResponse = $cartResponse['billing_address']; + $this->assertNewAddressFields($billingAddressResponse); + + foreach ($addresses as $address) { + $this->customerAddressRepository->delete($address); + } + } + /** * Verify the all the whitelisted fields for a New Address Object * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php index 15ee12595506..72b6a4aea673 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php @@ -7,6 +7,9 @@ namespace Magento\GraphQl\Quote\Customer; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\Integration\Api\CustomerTokenServiceInterface; use Magento\Quote\Model\QuoteFactory; @@ -45,6 +48,21 @@ class SetShippingAddressOnCartTest extends GraphQlAbstract */ private $customerTokenService; + /** + * @var AddressRepositoryInterface + */ + private $customerAddressRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var CustomerRepositoryInterface + */ + private $customerRepository; + protected function setUp() { $objectManager = Bootstrap::getObjectManager(); @@ -53,6 +71,9 @@ protected function setUp() $this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class); $this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); $this->customerTokenService = $objectManager->get(CustomerTokenServiceInterface::class); + $this->customerAddressRepository = $objectManager->get(AddressRepositoryInterface::class); + $this->searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); + $this->customerRepository = $objectManager->get(CustomerRepositoryInterface::class); } /** @@ -82,7 +103,6 @@ public function testSetNewShippingAddressOnCartWithSimpleProduct() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -146,7 +166,6 @@ public function testSetNewShippingAddressOnCartWithVirtualProduct() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -274,7 +293,6 @@ public function testSetNewShippingAddressAndFromAddressBookAtSameTime() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -456,7 +474,6 @@ public function testSetMultipleNewShippingAddresses() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } }, { @@ -470,7 +487,6 @@ public function testSetMultipleNewShippingAddresses() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -514,7 +530,6 @@ public function testSetNewShippingAddressOnCartWithRedundantStreetLine() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -655,6 +670,144 @@ public function testSetShippingAddressWithLowerCaseCountry() $this->assertEquals('CA', $address['region']['code']); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetNewShippingAddressWithSaveInAddressBook() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: true + } + } + ] + } + ) { + cart { + shipping_addresses { + firstname + lastname + company + street + city + postcode + telephone + country { + code + label + } + __typename + } + } + } +} +QUERY; + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $customer = $this->customerRepository->get('customer@example.com'); + $searchCriteria = $this->searchCriteriaBuilder->addFilter('parent_id', $customer->getId())->create(); + $addresses = $this->customerAddressRepository->getList($searchCriteria)->getItems(); + + self::assertCount(1, $addresses); + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('shipping_addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['shipping_addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + + foreach ($addresses as $address) { + $this->customerAddressRepository->delete($address); + } + } + + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetNewShippingAddressWithNotSaveInAddressBook() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + $query = <<<QUERY +mutation { + setShippingAddressesOnCart( + input: { + cart_id: "$maskedQuoteId" + shipping_addresses: [ + { + address: { + firstname: "test firstname" + lastname: "test lastname" + company: "test company" + street: ["test street 1", "test street 2"] + city: "test city" + region: "test region" + postcode: "887766" + country_code: "US" + telephone: "88776655" + save_in_address_book: false + } + } + ] + } + ) { + cart { + shipping_addresses { + firstname + lastname + company + street + city + postcode + telephone + country { + code + label + } + __typename + } + } + } +} +QUERY; + $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); + $customer = $this->customerRepository->get('customer@example.com'); + $searchCriteria = $this->searchCriteriaBuilder->addFilter('parent_id', $customer->getId())->create(); + $addresses = $this->customerAddressRepository->getList($searchCriteria)->getItems(); + + self::assertCount(0, $addresses); + self::assertArrayHasKey('cart', $response['setShippingAddressesOnCart']); + + $cartResponse = $response['setShippingAddressesOnCart']['cart']; + self::assertArrayHasKey('shipping_addresses', $cartResponse); + $shippingAddressResponse = current($cartResponse['shipping_addresses']); + $this->assertNewShippingAddressFields($shippingAddressResponse); + + foreach ($addresses as $address) { + $this->customerAddressRepository->delete($address); + } + } + /** * Verify the all the whitelisted fields for a New Address Object * diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php index 16f291be9107..23128e55af32 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php @@ -108,7 +108,6 @@ public function testSetBillingAddressToGuestCustomerCart() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -221,7 +220,6 @@ public function testSetNewShippingAddressOnCartWithGuestCheckoutDisabled() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php index ed5aa9303d87..04ecde833de8 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php @@ -219,7 +219,6 @@ private function setBillingAddress(string $cartId): void telephone: "88776655" region: "TX" country_code: "US" - save_in_address_book: false } } } @@ -258,7 +257,6 @@ private function setShippingAddress(string $cartId): array postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetBillingAddressOnCartTest.php index 730e65b4ba8a..5a3d45005c91 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetBillingAddressOnCartTest.php @@ -52,7 +52,6 @@ public function testSetNewBillingAddress() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -110,7 +109,6 @@ public function testSetNewBillingAddressWithUseForShippingParameter() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } use_for_shipping: true } @@ -186,7 +184,6 @@ public function testSetBillingAddressToCustomerCart() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -263,7 +260,6 @@ public function testSetBillingAddressOnNonExistentCart() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -391,7 +387,6 @@ public function testSetNewBillingAddressWithUseForShippingAndMultishipping() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } use_for_shipping: true } @@ -437,7 +432,6 @@ public function testSetNewBillingAddressRedundantStreetLine() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } @@ -480,7 +474,6 @@ public function testSetBillingAddressWithLowerCaseCountry() postcode: "887766" country_code: "us" telephone: "88776655" - save_in_address_book: false } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetShippingAddressOnCartTest.php index 537c8f09a0a9..262aac45a968 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetShippingAddressOnCartTest.php @@ -53,7 +53,6 @@ public function testSetNewShippingAddressOnCartWithSimpleProduct() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -116,7 +115,6 @@ public function testSetNewShippingAddressOnCartWithVirtualProduct() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -268,7 +266,6 @@ public function testSetNewShippingAddressOnCartWithRedundantStreetLine() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -337,7 +334,6 @@ public function testSetMultipleNewShippingAddresses() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } }, { @@ -351,7 +347,6 @@ public function testSetMultipleNewShippingAddresses() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } ] @@ -391,7 +386,6 @@ public function testSetShippingAddressOnNonExistentCart() postcode: "887766" country_code: "US" telephone: "88776655" - save_in_address_book: false } } } From 973eb86f7b4157e2452201039416f617ae58cdb5 Mon Sep 17 00:00:00 2001 From: Alex Kolesnyk <kolesnyk@adobe.com> Date: Fri, 30 Aug 2019 13:26:20 -0500 Subject: [PATCH 0405/1172] MQE-1715: .credentials file must exist but it should not have to --- composer.json | 2 +- composer.lock | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 8b2cb0b53972..e4596256f442 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,7 @@ "friendsofphp/php-cs-fixer": "~2.14.0", "lusitanian/oauth": "~0.8.10", "magento/magento-coding-standard": "~3.0.0", - "magento/magento2-functional-testing-framework": "2.4.4", + "magento/magento2-functional-testing-framework": "2.4.5", "pdepend/pdepend": "2.5.2", "phpmd/phpmd": "@stable", "phpunit/phpunit": "~6.5.0", diff --git a/composer.lock b/composer.lock index 8af9ead67d9c..ae4219a2fd5d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8819d140d0951fefd8e14b052ff0f61a", + "content-hash": "d6f99cc06f1aa39a903b382958676ba2", "packages": [ { "name": "braintree/braintree_php", @@ -6814,16 +6814,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.4.4", + "version": "2.4.5", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb" + "reference": "d9de524babec36919b3ef73f3af03fbce99d427a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/ab347cf23d01f6bb9d158ab37d2dc56594999beb", - "reference": "ab347cf23d01f6bb9d158ab37d2dc56594999beb", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/d9de524babec36919b3ef73f3af03fbce99d427a", + "reference": "d9de524babec36919b3ef73f3af03fbce99d427a", "shasum": "" }, "require": { @@ -6885,7 +6885,7 @@ "magento", "testing" ], - "time": "2019-08-15T14:46:36+00:00" + "time": "2019-08-30T18:17:27+00:00" }, { "name": "mikey179/vfsstream", From f577a003344330ab97b606117e1f8f92d0ec1faf Mon Sep 17 00:00:00 2001 From: Max Lesechko <mlesechko@magento.com> Date: Fri, 30 Aug 2019 16:55:43 -0500 Subject: [PATCH 0406/1172] MC-19740: Set of InnoDB tables is converted to Memory tables after setup:upgrade --- .../Patch/Schema/ChangeTmpTablesEngine.php | 68 ----------------- app/code/Magento/Bundle/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 74 ------------------- app/code/Magento/Catalog/etc/db_schema.xml | 38 +++++----- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 --------------- .../CatalogInventory/etc/db_schema.xml | 6 +- .../Patch/Schema/ChangeTmpTablesEngine.php | 61 --------------- .../Magento/Downloadable/etc/db_schema.xml | 2 +- 8 files changed, 26 insertions(+), 290 deletions(-) delete mode 100644 app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php delete mode 100644 app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php diff --git a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c6a67cc5a110..000000000000 --- a/app/code/Magento/Bundle/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Bundle\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_bundle_tmp', - 'catalog_product_index_price_bundle_sel_tmp', - 'catalog_product_index_price_bundle_opt_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Bundle/etc/db_schema.xml b/app/code/Magento/Bundle/etc/db_schema.xml index 97e86e5c1735..ade8fbf7cf1c 100644 --- a/app/code/Magento/Bundle/etc/db_schema.xml +++ b/app/code/Magento/Bundle/etc/db_schema.xml @@ -203,7 +203,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -265,7 +265,7 @@ <column name="selection_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_sel_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Sel Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -320,7 +320,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_bundle_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Index Price Bundle Opt Tmp"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> diff --git a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index c39247f9b30d..000000000000 --- a/app/code/Magento/Catalog/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Catalog\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tables = [ - 'catalog_product_index_price_cfg_opt_agr_tmp', - 'catalog_product_index_price_cfg_opt_tmp', - 'catalog_product_index_price_final_tmp', - 'catalog_product_index_price_opt_tmp', - 'catalog_product_index_price_opt_agr_tmp', - 'catalog_product_index_eav_tmp', - 'catalog_product_index_eav_decimal_tmp', - 'catalog_product_index_price_tmp', - 'catalog_category_product_index_tmp', - ]; - foreach ($tables as $table) { - $tableName = $this->schemaSetup->getTable($table); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Catalog/etc/db_schema.xml b/app/code/Magento/Catalog/etc/db_schema.xml index 6fef4ca6e912..b5e02b1daaa0 100644 --- a/app/code/Magento/Catalog/etc/db_schema.xml +++ b/app/code/Magento/Catalog/etc/db_schema.xml @@ -1238,7 +1238,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Aggregate Temp Table"> <column xsi:type="int" name="parent_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Parent ID"/> @@ -1279,7 +1279,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_cfg_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Config Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1327,7 +1327,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_final_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_final_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Final Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1375,7 +1375,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1418,7 +1418,7 @@ <column name="option_id"/> </constraint> </table> - <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_opt_agr_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Option Aggregate Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1470,7 +1470,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1489,13 +1489,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1528,7 +1528,7 @@ <column name="value"/> </index> </table> - <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="memory" + <table name="catalog_product_index_eav_decimal_tmp" resource="default" engine="innodb" comment="Catalog Product EAV Decimal Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1547,13 +1547,13 @@ <column name="value"/> <column name="source_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_ATTRIBUTE_ID" indexType="btree"> <column name="attribute_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_STORE_ID" indexType="btree"> <column name="store_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_EAV_DECIMAL_TMP_VALUE" indexType="btree"> <column name="value"/> </index> </table> @@ -1592,7 +1592,7 @@ <column name="min_price"/> </index> </table> - <table name="catalog_product_index_price_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_tmp" resource="default" engine="innodb" comment="Catalog Product Price Indexer Temp Table"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> @@ -1617,17 +1617,17 @@ <column name="customer_group_id"/> <column name="website_id"/> </constraint> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_CUSTOMER_GROUP_ID" indexType="btree"> <column name="customer_group_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> - <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="hash"> + <index referenceId="CATALOG_PRODUCT_INDEX_PRICE_TMP_MIN_PRICE" indexType="btree"> <column name="min_price"/> </index> </table> - <table name="catalog_category_product_index_tmp" resource="default" engine="memory" + <table name="catalog_category_product_index_tmp" resource="default" engine="innodb" comment="Catalog Category Product Indexer temporary table"> <column xsi:type="int" name="category_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Category ID"/> @@ -1646,7 +1646,7 @@ <column name="product_id"/> <column name="store_id"/> </constraint> - <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="hash"> + <index referenceId="CAT_CTGR_PRD_IDX_TMP_PRD_ID_CTGR_ID_STORE_ID" indexType="btree"> <column name="product_id"/> <column name="category_id"/> <column name="store_id"/> diff --git a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index 7f43cd279d4e..000000000000 --- a/app/code/Magento/CatalogInventory/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('cataloginventory_stock_status_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/CatalogInventory/etc/db_schema.xml b/app/code/Magento/CatalogInventory/etc/db_schema.xml index 5ac7fedc5aa1..67a200eb3712 100644 --- a/app/code/Magento/CatalogInventory/etc/db_schema.xml +++ b/app/code/Magento/CatalogInventory/etc/db_schema.xml @@ -142,7 +142,7 @@ <column name="website_id"/> </index> </table> - <table name="cataloginventory_stock_status_tmp" resource="default" engine="memory" + <table name="cataloginventory_stock_status_tmp" resource="default" engine="innodb" comment="Cataloginventory Stock Status Indexer Tmp"> <column xsi:type="int" name="product_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Product Id"/> @@ -159,10 +159,10 @@ <column name="website_id"/> <column name="stock_id"/> </constraint> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_STOCK_ID" indexType="btree"> <column name="stock_id"/> </index> - <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="hash"> + <index referenceId="CATALOGINVENTORY_STOCK_STATUS_TMP_WEBSITE_ID" indexType="btree"> <column name="website_id"/> </index> </table> diff --git a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php b/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php deleted file mode 100644 index caf2f7745a3d..000000000000 --- a/app/code/Magento/Downloadable/Setup/Patch/Schema/ChangeTmpTablesEngine.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\Downloadable\Setup\Patch\Schema; - -use Magento\Framework\Setup\Patch\SchemaPatchInterface; -use Magento\Framework\Setup\SchemaSetupInterface; - -/** - * Change engine for temporary tables to InnoDB. - */ -class ChangeTmpTablesEngine implements SchemaPatchInterface -{ - /** - * @var SchemaSetupInterface - */ - private $schemaSetup; - - /** - * @param SchemaSetupInterface $schemaSetup - */ - public function __construct(SchemaSetupInterface $schemaSetup) - { - $this->schemaSetup = $schemaSetup; - } - - /** - * @inheritdoc - */ - public function apply() - { - $this->schemaSetup->startSetup(); - - $tableName = $this->schemaSetup->getTable('catalog_product_index_price_downlod_tmp'); - if ($this->schemaSetup->getConnection()->isTableExists($tableName)) { - $this->schemaSetup->getConnection()->changeTableEngine($tableName, 'InnoDB'); - } - - $this->schemaSetup->endSetup(); - } - - /** - * @inheritdoc - */ - public static function getDependencies() - { - return []; - } - - /** - * @inheritdoc - */ - public function getAliases() - { - return []; - } -} diff --git a/app/code/Magento/Downloadable/etc/db_schema.xml b/app/code/Magento/Downloadable/etc/db_schema.xml index ccbefa4fb399..ee7b3c5683ea 100644 --- a/app/code/Magento/Downloadable/etc/db_schema.xml +++ b/app/code/Magento/Downloadable/etc/db_schema.xml @@ -233,7 +233,7 @@ <column name="website_id"/> </constraint> </table> - <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="memory" + <table name="catalog_product_index_price_downlod_tmp" resource="default" engine="innodb" comment="Temporary Indexer Table for price of downloadable products"> <column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" comment="Entity ID"/> From 5d620d111d52b8274ec94bc1e628c05b48ad120d Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 30 Aug 2019 18:33:01 -0500 Subject: [PATCH 0407/1172] MC-19247: Broken translations with advanced bundling --- .../Backend/view/adminhtml/layout/default.xml | 1 - .../Theme/view/frontend/layout/default.xml | 1 - .../Block/Html/Head/Dictionary.php | 58 +++++++++++++++++++ .../Magento/Translation/Model/FileManager.php | 20 +++++++ .../Translation/view/base/layout/default.xml | 14 +++++ .../view/base/templates/dictionary.phtml | 18 ++++++ lib/web/mage/translate.js | 21 +++---- 7 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 app/code/Magento/Translation/Block/Html/Head/Dictionary.php create mode 100644 app/code/Magento/Translation/view/base/layout/default.xml create mode 100644 app/code/Magento/Translation/view/base/templates/dictionary.phtml diff --git a/app/code/Magento/Backend/view/adminhtml/layout/default.xml b/app/code/Magento/Backend/view/adminhtml/layout/default.xml index a7faab0bc467..b450102d7fc3 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/default.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/default.xml @@ -77,7 +77,6 @@ <referenceContainer name="after.body.start"> <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/> <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> - <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/> <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Backend::page/js/components.phtml"/> <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="Magento_Backend::page/js/calendar.phtml"/> </referenceContainer> diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index 07d344cb3658..e783648f7e3e 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -12,7 +12,6 @@ <referenceContainer name="after.body.start"> <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/> <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> - <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/> <block class="Magento\Framework\View\Element\Js\Cookie" name="js_cookies" template="Magento_Theme::js/cookie.phtml"/> <block class="Magento\Theme\Block\Html\Notices" name="global_notices" template="Magento_Theme::html/notices.phtml"/> </referenceContainer> diff --git a/app/code/Magento/Translation/Block/Html/Head/Dictionary.php b/app/code/Magento/Translation/Block/Html/Head/Dictionary.php new file mode 100644 index 000000000000..ef7b6d0ac8bf --- /dev/null +++ b/app/code/Magento/Translation/Block/Html/Head/Dictionary.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Translation\Block\Html\Head; + +use Magento\Framework\View\Element\Template; +use Magento\Translation\Model\FileManager; +use Magento\Framework\View\Page\Config as PageConfig; +use Magento\Translation\Model\Js\Config as JsConfig; + +/** + * Block responsible for getting translate dictionary file for the layout. + */ +class Dictionary extends Template +{ + /** + * @var FileManager + */ + private $fileManager; + + /** + * @var PageConfig + */ + protected $pageConfig; + + /** + * @param Template\Context $context + * @param PageConfig $pageConfig + * @param FileManager $fileManager + * @param array $data + */ + public function __construct( + Template\Context $context, + PageConfig $pageConfig, + FileManager $fileManager, + array $data = [] + ) { + parent::__construct($context, $data); + $this->pageConfig = $pageConfig; + $this->fileManager = $fileManager; + } + + /** + * Get translation dictionary file as an asset for the page. + * + * @return string + */ + public function getTranslationDictionaryFile(): string + { + $translateDictionaryConfig = $this->fileManager->createTranslateDictionaryConfigAsset(JsConfig::DICTIONARY_FILE_NAME); + $translateDictionaryConfigRelPath = $translateDictionaryConfig->getFilePath(); + + return $this->_assetRepo->getUrl($translateDictionaryConfigRelPath); + } +} diff --git a/app/code/Magento/Translation/Model/FileManager.php b/app/code/Magento/Translation/Model/FileManager.php index 387173f6de0b..43bd357c5069 100644 --- a/app/code/Magento/Translation/Model/FileManager.php +++ b/app/code/Magento/Translation/Model/FileManager.php @@ -8,6 +8,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Translation\Model\Inline\File as TranslationFile; +use Magento\Framework\View\Asset\File\FallbackContext as FileFallbackContext; +use Magento\Framework\View\Asset\File; /** * A service for handling Translation config files @@ -39,6 +41,11 @@ class FileManager */ private $translationFile; + /** + * @var FileFallbackContext + */ + private $staticContext; + /** * @param \Magento\Framework\View\Asset\Repository $assetRepo * @param \Magento\Framework\App\Filesystem\DirectoryList $directoryList @@ -55,6 +62,7 @@ public function __construct( $this->directoryList = $directoryList; $this->driverFile = $driverFile; $this->translationFile = $translationFile ?: ObjectManager::getInstance()->get(TranslationFile::class); + $this->staticContext = $assetRepo->getStaticViewFileContext(); } /** @@ -137,4 +145,16 @@ public function getTranslationFileVersion() return sha1($translationFileHash . $this->getTranslationFilePath()); } + + /** + * Create a view asset for translate dictionary config. + * + * @param string $fileName + * @return File + */ + public function createTranslateDictionaryConfigAsset(string $fileName): File + { + $relPath = $this->staticContext->getConfigPath() . '/' . $fileName; + return $this->assetRepo->createArbitrary($relPath, ''); + } } diff --git a/app/code/Magento/Translation/view/base/layout/default.xml b/app/code/Magento/Translation/view/base/layout/default.xml new file mode 100644 index 000000000000..76f93e625d1e --- /dev/null +++ b/app/code/Magento/Translation/view/base/layout/default.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <body> + <referenceBlock name="head.additional"> + <block class="Magento\Translation\Block\Html\Head\Dictionary" name="translation_dictionary" template="Magento_Translation::dictionary.phtml"/> + </referenceBlock> + </body> +</page> diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml new file mode 100644 index 000000000000..93b4a7c84def --- /dev/null +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Translation\Block\Html\Head\Dictionary $block */ +?> +<link rel="preload" as="script" src="<?= $block->getTranslationDictionaryFile() ?>"> +<script> + require.config({ + map: { + '*': { + 'dictionary': '<?= $block->getTranslationDictionaryFile() ?>' + } + } + }); +</script> diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index a9c30bf57791..261d680c9ffa 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -3,17 +3,12 @@ * See COPYING.txt for license details. */ -/* eslint-disable strict */ -(function (factory) { - if (typeof define === 'function' && define.amd) { - define([ - 'jquery', - 'mage/mage' - ], factory); - } else { - factory(jQuery); - } -}(function ($) { +define([ + 'jquery', + 'mage/mage', + 'text!dictionary' +], function ($, mage, d) { + var dictionary = JSON.parse(d); $.extend(true, $, { mage: { translate: (function () { @@ -22,7 +17,7 @@ * @type {Object} * @private */ - var _data = {}; + var _data = dictionary; /** * Add new translation (two string parameters) or several translations (object) @@ -51,4 +46,4 @@ $.mage.__ = $.proxy($.mage.translate.translate, $.mage.translate); return $.mage.__; -})); +}); From 7563129bcce08c1d99347eba76f1af9d564b7039 Mon Sep 17 00:00:00 2001 From: "bruce.ayko" <bruce@ayko.com> Date: Mon, 2 Sep 2019 17:43:19 +0100 Subject: [PATCH 0408/1172] Price Indexer Performance Issue With Out of Stock Products - Relates to issue https://github.com/magento/magento2/issues/24414 --- .../Model/Indexer/ProductPriceIndexFilter.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php index f9a49d4f8d12..8bcc5ea1dc2c 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php @@ -104,6 +104,14 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = $select->where('stock_item.use_config_manage_stock = 0 AND stock_item.manage_stock = 1'); } + if ($entityIds !== null) { + if (count($entityIds) > 1) { + $select->where('stock_item.product_id in (?)', $entityIds); + } else { + $select->where('stock_item.product_id = ?', $entityIds); + } + } + $select->group('stock_item.product_id'); $select->having('max_is_in_stock = 0'); From 475518eb607bd879a21f149cc186119992b46299 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Tue, 3 Sep 2019 10:58:24 +0400 Subject: [PATCH 0409/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../Section/AdminShippingMethodDHLSection.xml | 31 +++ .../AdminShippingMethodFedExSection.xml | 33 +++ .../AdminShippingMethodFlatRateSection.xml | 6 + ...AdminShippingMethodFreeShippingSection.xml | 20 ++ .../AdminShippingMethodTableRatesSection.xml | 8 + .../Section/AdminShippingMethodUPSSection.xml | 39 +++ .../AdminShippingMethodUSPSSection.xml | 34 +++ .../Test/Mftf/Suite/AppConfigDumpSuite.xml | 19 ++ ...utFieldsDisabledAfterAppConfigDumpTest.xml | 247 ++++++++++++++++++ 9 files changed, 437 insertions(+) create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFreeShippingSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml new file mode 100644 index 000000000000..de603d281153 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShippingMethodDHLSection"> + <element name="carriersDHLTab" type="button" selector="#carriers_dhl-head"/> + <element name="carriersDHLActive" type="input" selector="#carriers_dhl_active_inherit"/> + <element name="carriersDHLActiveRMA" type="select" selector="#carriers_dhl_active_rma"/> + <element name="carriersDHLTitle" type="input" selector="#carriers_dhl_title_inherit"/> + <element name="carriersDHLAccessId" type="input" selector="#carriers_dhl_id"/> + <element name="carriersDHLPassword" type="input" selector="#carriers_dhl_password"/> + <element name="carriersDHLAccount" type="input" selector="#carriers_dhl_account_inherit"/> + <element name="carriersDHLContentType" type="input" selector="#carriers_dhl_content_type_inherit"/> + <element name="carriersDHLHandlingType" type="input" selector="#carriers_dhl_handling_type_inherit"/> + <element name="carriersDHLHandlingAction" type="input" selector="#carriers_dhl_handling_action_inherit"/> + <element name="carriersDHLDivideOrderWeight" type="input" selector="#carriers_dhl_divide_order_weight_inherit"/> + <element name="carriersDHLUnitOfMeasure" type="input" selector="#carriers_dhl_unit_of_measure_inherit"/> + <element name="carriersDHLSize" type="input" selector="#carriers_dhl_size_inherit"/> + <element name="carriersDHLNonDocAllowedMethod" type="input" selector="#carriers_dhl_nondoc_methods_inherit"/> + <element name="carriersDHLSmartPostHubId" type="input" selector="#carriers_dhl_doc_methods_inherit"/> + <element name="carriersDHLSpecificErrMsg" type="input" selector="#carriers_dhl_specificerrmsg_inherit"/> + <element name="carriersDHLAllowSpecific" type="input" selector="#carriers_dhl_sallowspecific_inherit"/> + <element name="carriersDHLSpecificCountry" type="input" selector="#carriers_dhl_specificcountry"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml new file mode 100644 index 000000000000..61902a96030b --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShippingMethodFedExSection"> + <element name="carriersFedExTab" type="button" selector="#carriers_fedex-head"/> + <element name="carriersFedExActive" type="input" selector="#carriers_fedex_active_inherit"/> + <element name="carriersFedExActiveRMA" type="select" selector="#carriers_fedex_active_rma"/> + <element name="carriersFedExTitle" type="input" selector="#carriers_fedex_title_inherit"/> + <element name="carriersFedExAccountId" type="input" selector="#carriers_fedex_account"/> + <element name="carriersFedExMeterNumber" type="input" selector="#carriers_fedex_meter_number"/> + <element name="carriersFedExKey" type="input" selector="#carriers_fedex_key"/> + <element name="carriersFedExPassword" type="input" selector="#carriers_fedex_password"/> + <element name="carriersFedExSandboxMode" type="input" selector="#carriers_fedex_sandbox_mode_inherit"/> + <element name="carriersFedExShipmentRequestType" type="input" selector="#carriers_fedex_shipment_requesttype_inherit"/> + <element name="carriersFedExPackaging" type="input" selector="#carriers_fedex_packaging_inherit"/> + <element name="carriersFedExDropoff" type="input" selector="#carriers_fedex_dropoff_inherit"/> + <element name="carriersFedExUnitOfMeasure" type="input" selector="#carriers_fedex_unit_of_measure_inherit"/> + <element name="carriersFedExMaxPackageWeight" type="input" selector="#carriers_fedex_max_package_weight_inherit"/> + <element name="carriersFedExHandlingType" type="input" selector="#carriers_fedex_handling_type_inherit"/> + <element name="carriersFedExHandlingAction" type="select" selector="#carriers_fedex_handling_action_inherit"/> + <element name="carriersFedExFreeMethod" type="input" selector="#carriers_fedex_free_method_inherit"/> + <element name="carriersFedExSpecificErrMsg" type="input" selector="#carriers_fedex_specificerrmsg_inherit"/> + <element name="carriersFedExAllowSpecific" type="input" selector="#carriers_fedex_sallowspecific_inherit"/> + <element name="carriersFedExSpecificCountry" type="input" selector="#carriers_fedex_specificcountry"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFlatRateSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFlatRateSection.xml index a7ed0ab498be..99c191a5225c 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFlatRateSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFlatRateSection.xml @@ -11,5 +11,11 @@ <section name="AdminShippingMethodFlatRateSection"> <element name="carriersFlatRateTab" type="button" selector="#carriers_flatrate-head"/> <element name="carriersFlatRateActive" type="select" selector="#carriers_flatrate_active"/> + <element name="carriersEnableFlatRateActive" type="input" selector="#carriers_flatrate_active_inherit"/> + <element name="carriersFlatRateTitle" type="input" selector="#carriers_flatrate_title_inherit"/> + <element name="carriersFlatRateName" type="input" selector="#carriers_flatrate_name_inherit"/> + <element name="carriersFlatRateSpecificErrMsg" type="input" selector="#carriers_flatrate_specificerrmsg_inherit"/> + <element name="carriersFlatRateAllowSpecific" type="input" selector="#carriers_flatrate_sallowspecific_inherit"/> + <element name="carriersFlatRateSpecificCountry" type="input" selector="#carriers_flatrate_specificcountry"/> </section> </sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFreeShippingSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFreeShippingSection.xml new file mode 100644 index 000000000000..bf8b5b9c3367 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFreeShippingSection.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShippingMethodFreeShippingSection"> + <element name="carriersFreeShippingSectionHead" type="button" selector="#carriers_freeshipping-head"/> + <element name="carriersFreeShippingActive" type="input" selector="#carriers_freeshipping_active_inherit"/> + <element name="carriersFreeShippingTitle" type="input" selector="#carriers_freeshipping_title_inherit"/> + <element name="carriersFreeShippingName" type="input" selector="#carriers_freeshipping_name_inherit"/> + <element name="carriersFreeShippingSpecificErrMsg" type="input" selector="#carriers_freeshipping_specificerrmsg_inherit"/> + <element name="carriersFreeShippingAllowSpecific" type="input" selector="#carriers_freeshipping_sallowspecific_inherit"/> + <element name="carriersFreeShippingSpecificCountry" type="input" selector="#carriers_freeshipping_specificcountry"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodTableRatesSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodTableRatesSection.xml index 3c570201c997..944fc06047aa 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodTableRatesSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodTableRatesSection.xml @@ -14,5 +14,13 @@ <element name="carriersTableRateActive" type="select" selector="#carriers_tablerate_active"/> <element name="condition" type="select" selector="#carriers_tablerate_condition_name"/> <element name="importFile" type="input" selector="#carriers_tablerate_import"/> + <element name="carriersTableRateTitle" type="input" selector="#carriers_tablerate_title_inherit"/> + <element name="carriersTableRateName" type="input" selector="#carriers_tablerate_name_inherit"/> + <element name="carriersTableRateConditionName" type="input" selector="#carriers_tablerate_condition_name_inherit"/> + <element name="carriersTableRateIncludeVirtualPrice" type="input" selector="#carriers_tablerate_include_virtual_price_inherit"/> + <element name="carriersTableRateHandlingType" type="input" selector="#carriers_tablerate_handling_type_inherit"/> + <element name="carriersTableRateSpecificErrMsg" type="input" selector="#carriers_tablerate_specificerrmsg_inherit"/> + <element name="carriersTableRateAllowSpecific" type="input" selector="#carriers_tablerate_sallowspecific_inherit"/> + <element name="carriersTableRateSpecificCountry" type="input" selector="#carriers_tablerate_specificcountry"/> </section> </sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml new file mode 100644 index 000000000000..3eda77a31b42 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShippingMethodUPSSection"> + <element name="carriersUPSTab" type="button" selector="#carriers_ups-head"/> + <element name="carriersUPSActive" type="input" selector="#carriers_ups_active_inherit"/> + <element name="carriersUPSActiveRMA" type="select" selector="#carriers_ups_active_rma"/> + <element name="carriersUPSType" type="input" selector="#carriers_ups_type_inherit"/> + <element name="carriersUPSAccountLive" type="input" selector="#carriers_ups_is_account_live_inherit"/> + <element name="carriersUPSGatewayXMLUrl" type="input" selector="#carriers_ups_gateway_xml_url_inherit"/> + <element name="carriersUPSModeXML" type="input" selector="#carriers_ups_mode_xml_inherit"/> + <element name="carriersUPSOriginShipment" type="input" selector="#carriers_ups_origin_shipment_inherit"/> + <element name="carriersUPSTitle" type="input" selector="#carriers_ups_title_inherit"/> + <element name="carriersUPSNegotiatedActive" type="input" selector="#carriers_ups_negotiated_active_inherit"/> + <element name="carriersUPSIncludeTaxes" type="input" selector="#carriers_ups_include_taxes_inherit"/> + <element name="carriersUPSShipmentRequestType" type="input" selector="#carriers_ups_shipment_requesttype_inherit"/> + <element name="carriersUPSContainer" type="input" selector="#carriers_ups_container_inherit"/> + <element name="carriersUPSDestType" type="input" selector="#carriers_ups_dest_type_inherit"/> + <element name="carriersUPSTrackingXmlUrl" type="input" selector="#carriers_ups_tracking_xml_url_inherit"/> + <element name="carriersUPSUnitOfMeasure" type="input" selector="#carriers_ups_unit_of_measure_inherit"/> + <element name="carriersUPSMaxPackageWeight" type="input" selector="#carriers_ups_max_package_weight_inherit"/> + <element name="carriersUPSPickup" type="input" selector="#carriers_ups_pickup_inherit"/> + <element name="carriersUPSMinPackageWeight" type="input" selector="#carriers_ups_min_package_weight_inherit"/> + <element name="carriersUPSHandlingType" type="input" selector="#carriers_ups_handling_type_inherit"/> + <element name="carriersUPSHandlingAction" type="input" selector="#carriers_ups_handling_action_inherit"/> + <element name="carriersUPSAllowedMethods" type="input" selector="#carriers_ups_allowed_methods_inherit"/> + <element name="carriersUPSFreeMethod" type="input" selector="#carriers_ups_free_method_inherit"/> + <element name="carriersUPSSpecificErrMsg" type="input" selector="#carriers_ups_specificerrmsg_inherit"/> + <element name="carriersUPSAllowSpecific" type="input" selector="#carriers_ups_sallowspecific_inherit"/> + <element name="carriersUPSSpecificCountry" type="input" selector="#carriers_ups_specificcountry"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml new file mode 100644 index 000000000000..c85883fcd887 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShippingMethodUSPSSection"> + <element name="carriersUSPSTab" type="button" selector="#carriers_usps-head"/> + <element name="carriersUSPSActive" type="input" selector="#carriers_usps_active_inherit"/> + <element name="carriersUSPSActiveRMA" type="select" selector="#carriers_usps_active_rma"/> + <element name="carriersUSPSGatewayXMLUrl" type="input" selector="#carriers_usps_gateway_url_inherit"/> + <element name="carriersUSPSGatewaySecureUrl" type="input" selector="#carriers_usps_gateway_secure_url_inherit"/> + <element name="carriersUSPSTitle" type="input" selector="#carriers_usps_title_inherit"/> + <element name="carriersUSPSUserId" type="input" selector="#carriers_usps_userid"/> + <element name="carriersUSPSPassword" type="input" selector="#carriers_usps_password"/> + <element name="carriersUSPSShipmentRequestType" type="select" selector="#carriers_usps_shipment_requesttype_inherit"/> + <element name="carriersUSPSContainer" type="input" selector="#carriers_usps_container_inherit"/> + <element name="carriersUSPSSize" type="input" selector="#carriers_usps_size_inherit"/> + <element name="carriersUSPSDestType" type="input" selector="#carriers_usps_machinable_inherit"/> + <element name="carriersUSPSMachinable" type="input" selector="#carriers_ups_tracking_xml_url_inherit"/> + <element name="carriersUSPSMaxPackageWeight" type="input" selector="#carriers_usps_max_package_weight_inherit"/> + <element name="carriersUSPSHandlingType" type="input" selector="#carriers_usps_handling_type_inherit"/> + <element name="carriersUSPSHandlingAction" type="input" selector="#carriers_usps_handling_action_inherit"/> + <element name="carriersUSPSAllowedMethods" type="input" selector="#carriers_usps_allowed_methods_inherit"/> + <element name="carriersUSPSFreeMethod" type="input" selector="#carriers_usps_free_method_inherit"/> + <element name="carriersUSPSSpecificErrMsg" type="input" selector="#carriers_usps_specificerrmsg_inherit"/> + <element name="carriersUSPSAllowSpecific" type="input" selector="#carriers_usps_sallowspecific_inherit"/> + <element name="carriersUSPSSpecificCountry" type="input" selector="#carriers_usps_specificcountry"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml b/app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml new file mode 100644 index 000000000000..762d17bdf87f --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> + <suite name="AppConfigDumpSuite"> + <before> + <magentoCLI command="app:config:dump" stepKey="configDump"/> + </before> + <after> + </after> + <include> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"/> + </include> + </suite> +</suites> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml new file mode 100644 index 000000000000..519fecc313f7 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -0,0 +1,247 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> + <annotations> + <features value="Config"/> + <stories value="App:config:dump doesn't lock all the settings in Magento backend"/> + <title value="Check that all input fields disabled after executing CLI app:config:dump"/> + <description value="Check that all input fields disabled after executing CLI app:config:dump"/> + <severity value="MAJOR"/> + <testCaseId value="MC-11158"/> + <useCaseId value="MAGETWO-96428"/> + <group value="configuration"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Assert configuration are disabled in Flat Rate section--> + <comment userInput="Assert configuration are disabled in Flat Rate section" stepKey="commentSeeDisabledFlatRateConfigs"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <conditionalClick selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateTab}}" dependentSelector="{{AdminShippingMethodFlatRateSection.carriersFlatRateActive}}" visible="false" stepKey="expandFlatRateTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersEnableFlatRateActive}}" userInput="disabled" stepKey="grabFlatRateActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateActiveDisabled" stepKey="assertFlatRateActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateTitle}}" userInput="disabled" stepKey="grabFlatRateTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateTitleDisabled" stepKey="assertFlatRateTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateName}}" userInput="disabled" stepKey="grabFlatRateNameDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateNameDisabled" stepKey="assertFlatRateNameDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateSpecificErrMsg}}" userInput="disabled" stepKey="grabFlatRateSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateSpecificErrMsgDisabled" stepKey="assertFlatRateSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateAllowSpecific}}" userInput="disabled" stepKey="grabFlatRateAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateAllowSpecificDisabled" stepKey="assertFlatRateAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateSpecificCountry}}" userInput="disabled" stepKey="grabFlatRateSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFlatRateSpecificCountryDisabled" stepKey="assertFlatRateSpecificCountryDisabled"/> + <!--Assert configuration are disabled in Free Shipping section--> + <comment userInput="Assert configuration are disabled in Free Shipping section" stepKey="commentSeeDisabledFreeShippingConfigs"/> + <conditionalClick selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingSectionHead}}" dependentSelector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingActive}}" visible="false" stepKey="expandFreeShippingTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingActive}}" userInput="disabled" stepKey="grabFreeShippingActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingActiveDisabled" stepKey="assertFreeShippingActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingTitle}}" userInput="disabled" stepKey="grabFreeShippingTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingTitleDisabled" stepKey="assertFreeShippingTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingName}}" userInput="disabled" stepKey="grabFreeShippingNameDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingNameDisabled" stepKey="assertFreeShippingNameDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingSpecificErrMsg}}" userInput="disabled" stepKey="grabFreeShippingSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingSpecificErrMsgDisabled" stepKey="assertFreeShippingSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingAllowSpecific}}" userInput="disabled" stepKey="grabFreeShippingAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingAllowSpecificDisabled" stepKey="assertFreeShippingAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingSpecificCountry}}" userInput="disabled" stepKey="grabFreeShippingSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingSpecificCountryDisabled" stepKey="assertFreeShippingSpecificCountryDisabled"/> + <!--Assert configuration are disabled in Table Rates section--> + <comment userInput="Assert configuration are disabled in Table Rates section" stepKey="commentSeeDisabledTableRatesConfigs"/> + <conditionalClick selector="{{AdminShippingMethodTableRatesSection.carriersTableRateTab}}" dependentSelector="{{AdminShippingMethodTableRatesSection.carriersTableRateActive}}" visible="false" stepKey="expandTableRateTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.enabledUseSystemValue}}" userInput="disabled" stepKey="grabTableRateActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateActiveDisabled" stepKey="assertTableRateActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateTitle}}" userInput="disabled" stepKey="grabTableRateTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateTitleDisabled" stepKey="assertTableRateTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateName}}" userInput="disabled" stepKey="grabTableRateNameDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateNameDisabled" stepKey="assertTableRateNameDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateConditionName}}" userInput="disabled" stepKey="grabTableRateConditionNameDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateConditionNameDisabled" stepKey="assertTableRateConditionNameDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateIncludeVirtualPrice}}" userInput="disabled" stepKey="grabTableRateIncludeVirtualPriceDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateIncludeVirtualPriceDisabled" stepKey="assertTableRateIncludeVirtualPriceDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateHandlingType}}" userInput="disabled" stepKey="grabTableRateHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateHandlingTypeDisabled" stepKey="assertTableRateHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateSpecificErrMsg}}" userInput="disabled" stepKey="grabTableRateSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateSpecificErrMsgDisabled" stepKey="assertTableRateSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateAllowSpecific}}" userInput="disabled" stepKey="grabTableRateAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateAllowSpecificDisabled" stepKey="assertTableRateAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateSpecificCountry}}" userInput="disabled" stepKey="grabTableRateSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabTableRateSpecificCountryDisabled" stepKey="assertTableRateSpecificCountryDisabled"/> + <!--Assert configuration are disabled in UPS section--> + <comment userInput="Assert configuration are disabled in UPS section" stepKey="commentSeeDisabledUPSConfigs"/> + <conditionalClick selector="{{AdminShippingMethodUPSSection.carriersUPSTab}}" dependentSelector="{{AdminShippingMethodUPSSection.carriersUPSActive}}" visible="false" stepKey="expandUPSTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSActive}}" userInput="disabled" stepKey="grabUPSActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveDisabled" stepKey="assertUPSActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSActiveRMA}}" userInput="disabled" stepKey="grabUPSActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveRMADisabled" stepKey="assertUPSActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSType}}" userInput="disabled" stepKey="grabUPSTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTypeDisabled" stepKey="assertUPSTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAccountLive}}" userInput="disabled" stepKey="grabUPSAccountLiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAccountLiveDisabled" stepKey="assertUPSAccountLiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUPSGatewayXMLUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSGatewayXMLUrlDisabled" stepKey="assertUPSGatewayXMLUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSModeXML}}" userInput="disabled" stepKey="grabUPSModeXMLDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSModeXMLDisabled" stepKey="assertUPSModeXMLDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSOriginShipment}}" userInput="disabled" stepKey="grabUPSOriginShipmentDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSOriginShipmentDisabled" stepKey="assertUPSOriginShipmentDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSTitle}}" userInput="disabled" stepKey="grabUPSTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTitleDisabled" stepKey="assertUPSTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSNegotiatedActive}}" userInput="disabled" stepKey="grabUPSNegotiatedActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSNegotiatedActiveDisabled" stepKey="assertUPSNegotiatedActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSIncludeTaxes}}" userInput="disabled" stepKey="grabUPSIncludeTaxesDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSIncludeTaxesDisabled" stepKey="assertUPSIncludeTaxesDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSShipmentRequestType}}" userInput="disabled" stepKey="grabUPSShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSShipmentRequestTypeDisabled" stepKey="assertUPSShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSContainer}}" userInput="disabled" stepKey="grabUPSContainerDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSContainerDisabled" stepKey="assertUPSContainerDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSDestType}}" userInput="disabled" stepKey="grabUPSDestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSDestTypeDisabled" stepKey="assertUPSDestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSTrackingXmlUrl}}" userInput="disabled" stepKey="grabUPSTrackingXmlUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTrackingXmlUrlDisabled" stepKey="assertUPSTrackingXmlUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSUnitOfMeasure}}" userInput="disabled" stepKey="grabUPSUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSUnitOfMeasureDisabled" stepKey="assertUPSUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUPSMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSMaxPackageWeightDisabled" stepKey="assertUPSMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSPickup}}" userInput="disabled" stepKey="grabUPSPickupDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSPickupDisabled" stepKey="assertUPSPickupDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSMinPackageWeight}}" userInput="disabled" stepKey="grabUPSMinPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSMinPackageWeightDisabled" stepKey="assertUPSMinPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSHandlingType}}" userInput="disabled" stepKey="grabUPSHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingTypeDisabled" stepKey="assertUPSHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSHandlingAction}}" userInput="disabled" stepKey="grabUPSHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingActionDisabled" stepKey="assertUPSHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAllowedMethods}}" userInput="disabled" stepKey="grabUPSAllowedMethodsDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowedMethodsDisabled" stepKey="assertUPSAllowedMethodsDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSFreeMethod}}" userInput="disabled" stepKey="grabUPSFreeMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSFreeMethodDisabled" stepKey="assertUPSFreeMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUPSSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificErrMsgDisabled" stepKey="assertUPSSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAllowSpecific}}" userInput="disabled" stepKey="grabUPSAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowSpecificDisabled" stepKey="assertUPSAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSSpecificCountry}}" userInput="disabled" stepKey="grabUPSSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificCountryDisabled" stepKey="assertUPSSpecificCountryDisabled"/> + <!--Assert configuration are disabled in USPS section--> + <comment userInput="Assert configuration are disabled in USPS section" stepKey="commentSeeDisabledUSPSConfigs"/> + <conditionalClick selector="{{AdminShippingMethodUSPSSection.carriersUSPSTab}}" dependentSelector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" visible="false" stepKey="expandUSPSTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" userInput="disabled" stepKey="grabUSPSActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSActiveDisabled" stepKey="assertUSPSActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUSPSGatewayXMLUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewayXMLUrlDisabled" stepKey="assertUSPSGatewayXMLUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewaySecureUrl}}" userInput="disabled" stepKey="grabUSPSGatewaySecureUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewaySecureUrlDisabled" stepKey="assertUSPSGatewaySecureUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSTitle}}" userInput="disabled" stepKey="grabUSPSTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSTitleDisabled" stepKey="assertUSPSTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSUserId}}" userInput="disabled" stepKey="grabUSPSUserIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSUserIdDisabled" stepKey="assertUSPSUserIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSPassword}}" userInput="disabled" stepKey="grabUSPSPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSPasswordDisabled" stepKey="assertUSPSPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSShipmentRequestType}}" userInput="disabled" stepKey="grabUSPSShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSShipmentRequestTypeDisabled" stepKey="assertUSPSShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSContainer}}" userInput="disabled" stepKey="grabUSPSContainerDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSContainerDisabled" stepKey="assertUSPSContainerDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSize}}" userInput="disabled" stepKey="grabUSPSSizeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSizeDisabled" stepKey="assertUSPSSizeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSDestType}}" userInput="disabled" stepKey="grabUSPSDestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSDestTypeDisabled" stepKey="assertUSPSDestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMachinable}}" userInput="disabled" stepKey="grabUSPSMachinableDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSMachinableDisabled" stepKey="assertUSPSMachinableDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUSPSMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSMaxPackageWeightDisabled" stepKey="assertUSPSMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingType}}" userInput="disabled" stepKey="grabUSPSHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingTypeDisabled" stepKey="assertUSPSHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingAction}}" userInput="disabled" stepKey="grabUSPSHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingActionDisabled" stepKey="assertUSPSHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowedMethods}}" userInput="disabled" stepKey="grabUSPSAllowedMethodsDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowedMethodsDisabled" stepKey="assertUSPSAllowedMethodsDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSFreeMethod}}" userInput="disabled" stepKey="grabUSPSFreeMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSFreeMethodDisabled" stepKey="assertUSPSFreeMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUSPSSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificErrMsgDisabled" stepKey="assertUSPSSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowSpecific}}" userInput="disabled" stepKey="grabUSPSAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowSpecificDisabled" stepKey="assertUSPSAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificCountry}}" userInput="disabled" stepKey="grabUSPSSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificCountryDisabled" stepKey="assertUSPSSpecificCountryDisabled"/> + <!--Assert configuration are disabled in FedEx section--> + <comment userInput="Assert configuration are disabled in FedEx section" stepKey="commentSeeDisabledFedExConfigs"/> + <conditionalClick selector="{{AdminShippingMethodFedExSection.carriersFedExTab}}" dependentSelector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" visible="false" stepKey="expandFedExTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" userInput="disabled" stepKey="grabFedExActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveDisabled" stepKey="assertFedExActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActiveRMA}}" userInput="disabled" stepKey="grabFedExActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveRMADisabled" stepKey="assertFedExActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExTitle}}" userInput="disabled" stepKey="grabFedExTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExTitleDisabled" stepKey="assertFedExTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAccountId}}" userInput="disabled" stepKey="grabFedExAccountIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExAccountIdDisabled" stepKey="assertFedExAccountIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMeterNumber}}" userInput="disabled" stepKey="grabFedExMeterNumberDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExMeterNumberDisabled" stepKey="assertFedExMeterNumberDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExKey}}" userInput="disabled" stepKey="grabFedExKeyDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExKeyDisabled" stepKey="assertFedExKeyDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPassword}}" userInput="disabled" stepKey="grabFedExPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExPasswordDisabled" stepKey="assertFedExPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSandboxMode}}" userInput="disabled" stepKey="grabFedExSandboxDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSandboxDisabled" stepKey="assertFedExSandboxDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExShipmentRequestType}}" userInput="disabled" stepKey="grabFedExShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExShipmentRequestTypeDisabled" stepKey="assertFedExShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPackaging}}" userInput="disabled" stepKey="grabFedExPackagingDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExPackagingDisabled" stepKey="assertFedExPackagingDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExDropoff}}" userInput="disabled" stepKey="grabFedExDropoffDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExDropoffDisabled" stepKey="assertFedExDropoffDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExUnitOfMeasure}}" userInput="disabled" stepKey="grabFedExUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExUnitOfMeasureDisabled" stepKey="assertFedExUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMaxPackageWeight}}" userInput="disabled" stepKey="grabFedExMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExMaxPackageWeightDisabled" stepKey="assertFedExMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingType}}" userInput="disabled" stepKey="grabFedExHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingTypeDisabled" stepKey="assertFedExHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingAction}}" userInput="disabled" stepKey="grabFedExHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingActionDisabled" stepKey="assertFedExHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificErrMsg}}" userInput="disabled" stepKey="grabFedExSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificErrMsgDisabled" stepKey="assertFedExSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAllowSpecific}}" userInput="disabled" stepKey="grabFedExAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExAllowSpecificDisabled" stepKey="assertFedExAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificCountry}}" userInput="disabled" stepKey="grabFedExSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificCountryDisabled" stepKey="assertFedExSpecificCountryDisabled"/> + <!--Assert configuration are disabled in DHL section--> + <comment userInput="Assert configuration are disabled in DHL section" stepKey="commentSeeDisabledDHLConfigs"/> + <conditionalClick selector="{{AdminShippingMethodDHLSection.carriersDHLTab}}" dependentSelector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" visible="false" stepKey="expandDHLTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" userInput="disabled" stepKey="grabDHLActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveDisabled" stepKey="assertDHLActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActiveRMA}}" userInput="disabled" stepKey="grabDHLActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveRMADisabled" stepKey="assertDHLActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLTitle}}" userInput="disabled" stepKey="grabDHLTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLTitleDisabled" stepKey="assertDHLTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccessId}}" userInput="disabled" stepKey="grabDHLAccessIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLAccessIdDisabled" stepKey="assertDHLAccessIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLPassword}}" userInput="disabled" stepKey="grabDHLPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLPasswordDisabled" stepKey="assertDHLPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccount}}" userInput="disabled" stepKey="grabDHLAccountDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLAccountDisabled" stepKey="assertDHLAccountDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLContentType}}" userInput="disabled" stepKey="grabDHLContentTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLContentTypeDisabled" stepKey="assertDHLContentTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingType}}" userInput="disabled" stepKey="grabDHLHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingTypeDisabled" stepKey="assertDHLHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingAction}}" userInput="disabled" stepKey="grabDHLHandlingDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingDisabled" stepKey="assertDHLHandlingDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLDivideOrderWeight}}" userInput="disabled" stepKey="grabDHLDivideOrderWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLDivideOrderWeightDisabled" stepKey="assertDHLDivideOrderWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLUnitOfMeasure}}" userInput="disabled" stepKey="grabDHLUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLUnitOfMeasureDisabled" stepKey="assertDHLUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSize}}" userInput="disabled" stepKey="grabDHLSizeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSizeDisabled" stepKey="assertDHLSizeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLNonDocAllowedMethod}}" userInput="disabled" stepKey="grabDHLNonDocAllowedMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLNonDocAllowedMethodDisabled" stepKey="assertDHLNonDocAllowedMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSmartPostHubId}}" userInput="disabled" stepKey="grabDHLSmartPostHubIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSmartPostHubIdDisabled" stepKey="assertDHLSmartPostHubIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSpecificErrMsg}}" userInput="disabled" stepKey="grabDHLSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSpecificErrMsgDisabled" stepKey="assertDHLSpecificErrMsgDisabled"/> + </test> +</tests> From 22c4ee1413212f4b55cff5014d48966c26582fe5 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Fri, 16 Aug 2019 09:34:55 -0500 Subject: [PATCH 0410/1172] MC-19152: Custom dropdown customer address attribute option id showing on guest checkout - Moving test to EE module --- .../web/js/model/address-converter.js | 1 + .../frontend/web/js/view/billing-address.js | 25 ++++++++++++++++- .../address-renderer/default.js | 27 ++++++++++++++++++- .../web/js/view/shipping-information/list.js | 3 ++- .../web/template/billing-address/details.html | 15 ++--------- .../address-renderer/default.html | 15 ++--------- 6 files changed, 57 insertions(+), 29 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js index 9b20a782c38d..d319ea501413 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js @@ -18,6 +18,7 @@ define([ return { /** * Convert address form data to Address object + * * @param {Object} formData * @returns {Object} */ diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js index 59d1daa75713..e728a5c0fcdd 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js @@ -159,7 +159,6 @@ function ( } addressData['save_in_address_book'] = this.saveInAddressBook() ? 1 : 0; newBillingAddress = createBillingAddress(addressData); - // New address must be selected as a billing address selectBillingAddress(newBillingAddress); checkoutData.setSelectedBillingAddress(newBillingAddress.getKey()); @@ -237,6 +236,30 @@ function ( */ getCode: function (parent) { return _.isFunction(parent.getCode) ? parent.getCode() : 'shared'; + }, + + /** + * Get customer attribute label + * + * @param {*} attribute + * @returns {*} + */ + getCustomAttributeLabel: function (attribute) { + var resultAttribute; + + if (typeof attribute === 'string') { + return attribute; + } + + if (attribute.label) { + return attribute.label; + } + + resultAttribute = _.findWhere(this.source.get('customAttributes')[attribute['attribute_code']], { + value: attribute.value + }); + + return resultAttribute && resultAttribute.label || attribute.value; } }); }); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js index acc9f1c2391d..009178cbb19b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js @@ -5,8 +5,9 @@ define([ 'uiComponent', + 'underscore', 'Magento_Customer/js/customer-data' -], function (Component, customerData) { +], function (Component, _, customerData) { 'use strict'; var countryData = customerData.get('directory-data'); @@ -22,6 +23,30 @@ define([ */ getCountryName: function (countryId) { return countryData()[countryId] != undefined ? countryData()[countryId].name : ''; //eslint-disable-line + }, + + /** + * Get customer attribute label + * + * @param {*} attribute + * @returns {*} + */ + getCustomAttributeLabel: function (attribute) { + var resultAttribute; + + if (typeof attribute === 'string') { + return attribute; + } + + if (attribute.label) { + return attribute.label; + } + + resultAttribute = _.findWhere(this.source.get('customAttributes')[attribute['attribute_code']], { + value: attribute.value + }); + + return resultAttribute && resultAttribute.label || attribute.value; } }); }); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js index 28eb83c8be3e..3bb2715c78a7 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js @@ -16,7 +16,8 @@ define([ var defaultRendererTemplate = { parent: '${ $.$data.parentName }', name: '${ $.$data.name }', - component: 'Magento_Checkout/js/view/shipping-information/address-renderer/default' + component: 'Magento_Checkout/js/view/shipping-information/address-renderer/default', + provider: 'checkoutProvider' }; return Component.extend({ diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index a0827d17d662..23bbce48fee2 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -13,19 +13,8 @@ <a if="currentBillingAddress().telephone" attr="'href': 'tel:' + currentBillingAddress().telephone" text="currentBillingAddress().telephone"></a><br/> <each args="data: currentBillingAddress().customAttributes, as: 'element'"> - <if args="typeof element === 'object'"> - <if args="element.label"> - <text args="element.label"/> - </if> - <ifnot args="element.label"> - <if args="element.value"> - <text args="element.value"/> - </if> - </ifnot> - </if> - <if args="typeof element === 'string'"> - <text args="element"/> - </if><br/> + <text args="$parent.getCustomAttributeLabel(element)"/> + <br/> </each> <button visible="!isAddressSameAsShipping()" diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 75e061426d81..26dd7742d1da 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -13,18 +13,7 @@ <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> <each args="data: address().customAttributes, as: 'element'"> - <if args="typeof element === 'object'"> - <if args="element.label"> - <text args="element.label"/> - </if> - <ifnot args="element.label"> - <if args="element.value"> - <text args="element.value"/> - </if> - </ifnot> - </if> - <if args="typeof element === 'string'"> - <text args="element"/> - </if><br/> + <text args="$parent.getCustomAttributeLabel(element)"/> + <br/> </each> </if> From e703cc8a5ad1721cf2293b5aff31e3ee60e484ba Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 3 Sep 2019 18:10:13 -0500 Subject: [PATCH 0411/1172] MC-19247: Broken translations with advanced bundling - Split mage/translate for adminhtml and frontend; --- .../Backend/view/adminhtml/layout/default.xml | 1 + .../view/adminhtml/requirejs-config.js | 3 +- .../view/adminhtml/web/js/translate.js | 54 +++++++++++++++++++ .../Block/Html/Head/Dictionary.php | 18 +++++++ .../view/base/templates/dictionary.phtml | 4 +- 5 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Backend/view/adminhtml/web/js/translate.js diff --git a/app/code/Magento/Backend/view/adminhtml/layout/default.xml b/app/code/Magento/Backend/view/adminhtml/layout/default.xml index b450102d7fc3..a7faab0bc467 100644 --- a/app/code/Magento/Backend/view/adminhtml/layout/default.xml +++ b/app/code/Magento/Backend/view/adminhtml/layout/default.xml @@ -77,6 +77,7 @@ <referenceContainer name="after.body.start"> <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/> <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> + <block class="Magento\Translation\Block\Js" name="translate" template="Magento_Translation::translate.phtml"/> <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Backend::page/js/components.phtml"/> <block class="Magento\Framework\View\Element\Html\Calendar" name="head.calendar" as="calendar" template="Magento_Backend::page/js/calendar.phtml"/> </referenceContainer> diff --git a/app/code/Magento/Backend/view/adminhtml/requirejs-config.js b/app/code/Magento/Backend/view/adminhtml/requirejs-config.js index ae0e84e2d27f..e886f28cd158 100644 --- a/app/code/Magento/Backend/view/adminhtml/requirejs-config.js +++ b/app/code/Magento/Backend/view/adminhtml/requirejs-config.js @@ -6,7 +6,8 @@ var config = { map: { '*': { - 'mediaUploader': 'Magento_Backend/js/media-uploader' + 'mediaUploader': 'Magento_Backend/js/media-uploader', + 'mage/translate': 'Magento_Backend/js/translate' } } }; diff --git a/app/code/Magento/Backend/view/adminhtml/web/js/translate.js b/app/code/Magento/Backend/view/adminhtml/web/js/translate.js new file mode 100644 index 000000000000..a9c30bf57791 --- /dev/null +++ b/app/code/Magento/Backend/view/adminhtml/web/js/translate.js @@ -0,0 +1,54 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/* eslint-disable strict */ +(function (factory) { + if (typeof define === 'function' && define.amd) { + define([ + 'jquery', + 'mage/mage' + ], factory); + } else { + factory(jQuery); + } +}(function ($) { + $.extend(true, $, { + mage: { + translate: (function () { + /** + * Key-value translations storage + * @type {Object} + * @private + */ + var _data = {}; + + /** + * Add new translation (two string parameters) or several translations (object) + */ + this.add = function () { + if (arguments.length > 1) { + _data[arguments[0]] = arguments[1]; + } else if (typeof arguments[0] === 'object') { + $.extend(_data, arguments[0]); + } + }; + + /** + * Make a translation with parsing (to handle case when _data represents tuple) + * @param {String} text + * @return {String} + */ + this.translate = function (text) { + return _data[text] ? _data[text] : text; + }; + + return this; + }()) + } + }); + $.mage.__ = $.proxy($.mage.translate.translate, $.mage.translate); + + return $.mage.__; +})); diff --git a/app/code/Magento/Translation/Block/Html/Head/Dictionary.php b/app/code/Magento/Translation/Block/Html/Head/Dictionary.php index ef7b6d0ac8bf..69e03f6b5e92 100644 --- a/app/code/Magento/Translation/Block/Html/Head/Dictionary.php +++ b/app/code/Magento/Translation/Block/Html/Head/Dictionary.php @@ -26,21 +26,29 @@ class Dictionary extends Template */ protected $pageConfig; + /** + * @var JsConfig + */ + private $config; + /** * @param Template\Context $context * @param PageConfig $pageConfig * @param FileManager $fileManager + * @param JsConfig $config * @param array $data */ public function __construct( Template\Context $context, PageConfig $pageConfig, FileManager $fileManager, + JsConfig $config, array $data = [] ) { parent::__construct($context, $data); $this->pageConfig = $pageConfig; $this->fileManager = $fileManager; + $this->config = $config; } /** @@ -55,4 +63,14 @@ public function getTranslationDictionaryFile(): string return $this->_assetRepo->getUrl($translateDictionaryConfigRelPath); } + + /** + * Is js translation set to dictionary mode + * + * @return bool + */ + public function dictionaryEnabled(): bool + { + return $this->config->dictionaryEnabled(); + } } diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 93b4a7c84def..385b898a5e52 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -6,7 +6,8 @@ /** @var \Magento\Translation\Block\Html\Head\Dictionary $block */ ?> -<link rel="preload" as="script" src="<?= $block->getTranslationDictionaryFile() ?>"> +<?php if ($block->dictionaryEnabled()) : ?> +<link rel="preload" as="script" href="<?= $block->getTranslationDictionaryFile() ?>"> <script> require.config({ map: { @@ -16,3 +17,4 @@ } }); </script> +<?php endif; ?> From 4d7d4a86bd1de4f57825ba53c6e8e65bd63f64e2 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Wed, 4 Sep 2019 10:23:10 +0300 Subject: [PATCH 0412/1172] graphQl-892: Improved strict typing in CartAddressInterface --- .../Magento/QuoteGraphQl/etc/schema.graphqls | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index c458b5e9dc05..13114ef97219 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -201,15 +201,15 @@ type Cart { } interface CartAddressInterface @typeResolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartAddressTypeResolver") { - firstname: String - lastname: String + firstname: String! + lastname: String! company: String - street: [String] - city: String + street: [String!]! + city: String! region: CartAddressRegion postcode: String - country: CartAddressCountry - telephone: String + country: CartAddressCountry! + telephone: String! customer_notes: String } @@ -229,13 +229,13 @@ type CartItemQuantity { } type CartAddressRegion { - code: String - label: String + code: String! + label: String! } type CartAddressCountry { - code: String - label: String + code: String! + label: String! } type SelectedShippingMethod { From 60ce6fad3d6ce5c32cfdd3b3b5cf711b7183b7f6 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 3 Sep 2019 14:26:10 +0300 Subject: [PATCH 0413/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MAGETWO-99376 --- .../Sales/Model/ResourceModel/OrderTest.php | 55 +++++++++++++++++++ .../Store/_files/store_with_long_name.php | 50 +++++++++++++++++ .../_files/store_with_long_name_rollback.php | 34 ++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php create mode 100644 dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php index d6fe86b6232d..9e102fab1d96 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php @@ -3,8 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Model\ResourceModel; +use Magento\Store\Api\StoreRepositoryInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\Event\ManagerInterface; + class OrderTest extends \PHPUnit\Framework\TestCase { /** @@ -22,13 +28,31 @@ class OrderTest extends \PHPUnit\Framework\TestCase */ protected $objectManager; + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var StoreRepositoryInterface + */ + private $storeRepository; + + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $this->resourceModel = $this->objectManager->create(\Magento\Sales\Model\ResourceModel\Order::class); $this->orderIncrementId = '100000001'; + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + $this->storeRepository = $this->objectManager->get(StoreRepositoryInterface::class); } + /** + * @inheritdoc + */ protected function tearDown() { $registry = $this->objectManager->get(\Magento\Framework\Registry::class); @@ -43,6 +67,9 @@ protected function tearDown() $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); + $defaultStore = $this->storeRepository->get('default'); + $this->storeManager->setCurrentStore($defaultStore->getId()); + parent::tearDown(); } @@ -108,4 +135,32 @@ public function testSaveOrder() $this->assertNotNull($order->getCreatedAt()); $this->assertNotNull($order->getUpdatedAt()); } + + /** + * Check that store name with length within 255 chars can be saved in table sales_order + * + * @magentoDataFixture Magento/Store/_files/store_with_long_name.php + * @return void + */ + public function testSaveStoreName() + { + $storeName = str_repeat('a', 220); + $store = $this->storeRepository->get('test_2'); + $this->storeManager->setCurrentStore($store->getId()); + $eventManager = $this->objectManager->get(ManagerInterface::class); + $eventManager->dispatch('store_add', ['store' => $store]); + $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); + $payment = $this->objectManager->create(\Magento\Sales\Model\Order\Payment::class); + $payment->setMethod('checkmo'); + $order->setStoreId($store->getId())->setPayment($payment); + $this->resourceModel->save($order); + $this->resourceModel->load($order, $storeName, 'store_name'); + $name = [ + 'Main Website', + 'Main Website Store', + $storeName, + ]; + $expectedStoreName = implode(PHP_EOL, $name); + $this->assertEquals($expectedStoreName, $order->getStoreName()); + } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php new file mode 100644 index 000000000000..c225519e2b2b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +/** @var $store \Magento\Store\Model\Store */ +$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); +$storeName = str_repeat('a', 220); +if (!$store->load('test', 'code')->getId()) { + $store->setData( + [ + 'code' => 'test_2', + 'website_id' => '1', + 'group_id' => '1', + 'name' => $storeName, + 'sort_order' => '10', + 'is_active' => '1', + ] + ); + $store->save(); +} else { + if ($store->getId()) { + /** @var \Magento\TestFramework\Helper\Bootstrap $registry */ + $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\Registry::class + ); + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', true); + + $store->delete(); + + $registry->unregister('isSecureArea'); + $registry->register('isSecureArea', false); + + $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); + $store->setData( + [ + 'code' => 'test_2', + 'website_id' => '1', + 'group_id' => '1', + 'name' => $storeName, + 'sort_order' => '10', + 'is_active' => '1', + ] + ); + $store->save(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name_rollback.php new file mode 100644 index 000000000000..5fe19e1e97df --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name_rollback.php @@ -0,0 +1,34 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Registry; +use Magento\Store\Model\Store; +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); + +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var Store $store */ +$store = $objectManager->get(Store::class); +$store->load('test_2', 'code'); +if ($store->getId()) { + $store->delete(); +} + +/** @var Store $store */ +$store = $objectManager->get(Store::class); +$store->load('test_2', 'code'); +if ($store->getId()) { + $store->delete(); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From bf3df0dec2729159a7c7ca4129c586ee9ede7163 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 4 Sep 2019 16:51:29 +0400 Subject: [PATCH 0414/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 519fecc313f7..c144d6f21b64 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -11,7 +11,7 @@ <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> <annotations> <features value="Config"/> - <stories value="App:config:dump doesn't lock all the settings in Magento backend"/> + <stories value="Disabling all the settings in Magento backend"/> <title value="Check that all input fields disabled after executing CLI app:config:dump"/> <description value="Check that all input fields disabled after executing CLI app:config:dump"/> <severity value="MAJOR"/> From 90a85ed358050f7cfeadbca4311da1670a31878f Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 4 Sep 2019 19:34:01 -0500 Subject: [PATCH 0415/1172] MC-19247: Broken translations with advanced bundling - Move block to view model; --- .../Html/Head => ViewModel}/Dictionary.php | 27 +++++-------------- .../Translation/view/base/layout/default.xml | 6 ++++- .../view/base/templates/dictionary.phtml | 23 ++++++++-------- 3 files changed, 23 insertions(+), 33 deletions(-) rename app/code/Magento/Translation/{Block/Html/Head => ViewModel}/Dictionary.php (57%) diff --git a/app/code/Magento/Translation/Block/Html/Head/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php similarity index 57% rename from app/code/Magento/Translation/Block/Html/Head/Dictionary.php rename to app/code/Magento/Translation/ViewModel/Dictionary.php index 69e03f6b5e92..c7bb972980e3 100644 --- a/app/code/Magento/Translation/Block/Html/Head/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -4,49 +4,35 @@ * See COPYING.txt for license details. */ -namespace Magento\Translation\Block\Html\Head; +namespace Magento\Translation\ViewModel; -use Magento\Framework\View\Element\Template; +use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\FileManager; -use Magento\Framework\View\Page\Config as PageConfig; use Magento\Translation\Model\Js\Config as JsConfig; /** - * Block responsible for getting translate dictionary file for the layout. + * View model responsible for getting translate dictionary file for the layout. */ -class Dictionary extends Template +class Dictionary implements ArgumentInterface { /** * @var FileManager */ private $fileManager; - /** - * @var PageConfig - */ - protected $pageConfig; - /** * @var JsConfig */ private $config; /** - * @param Template\Context $context - * @param PageConfig $pageConfig * @param FileManager $fileManager * @param JsConfig $config - * @param array $data */ public function __construct( - Template\Context $context, - PageConfig $pageConfig, FileManager $fileManager, - JsConfig $config, - array $data = [] + JsConfig $config ) { - parent::__construct($context, $data); - $this->pageConfig = $pageConfig; $this->fileManager = $fileManager; $this->config = $config; } @@ -59,9 +45,8 @@ public function __construct( public function getTranslationDictionaryFile(): string { $translateDictionaryConfig = $this->fileManager->createTranslateDictionaryConfigAsset(JsConfig::DICTIONARY_FILE_NAME); - $translateDictionaryConfigRelPath = $translateDictionaryConfig->getFilePath(); - return $this->_assetRepo->getUrl($translateDictionaryConfigRelPath); + return $translateDictionaryConfig->getUrl(); } /** diff --git a/app/code/Magento/Translation/view/base/layout/default.xml b/app/code/Magento/Translation/view/base/layout/default.xml index 76f93e625d1e..8e0408037386 100644 --- a/app/code/Magento/Translation/view/base/layout/default.xml +++ b/app/code/Magento/Translation/view/base/layout/default.xml @@ -8,7 +8,11 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="head.additional"> - <block class="Magento\Translation\Block\Html\Head\Dictionary" name="translation_dictionary" template="Magento_Translation::dictionary.phtml"/> + <block name="translation_dictionary" template="Magento_Translation::dictionary.phtml"> + <arguments> + <argument name="dictionary_view_model" xsi:type="object">Magento\Translation\ViewModel\Dictionary</argument> + </arguments> + </block> </referenceBlock> </body> </page> diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 385b898a5e52..f8d30149cf4f 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -4,17 +4,18 @@ * See COPYING.txt for license details. */ -/** @var \Magento\Translation\Block\Html\Head\Dictionary $block */ +/** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ +$viewModel = $block->getData('dictionary_view_model'); ?> -<?php if ($block->dictionaryEnabled()) : ?> -<link rel="preload" as="script" href="<?= $block->getTranslationDictionaryFile() ?>"> -<script> - require.config({ - map: { - '*': { - 'dictionary': '<?= $block->getTranslationDictionaryFile() ?>' +<?php if ($viewModel->dictionaryEnabled()) : ?> + <script type="application/json" src="<?= $viewModel->getTranslationDictionaryFile() ?>"></script> + <script> + require.config({ + map: { + '*': { + 'dictionary': '<?= $viewModel->getTranslationDictionaryFile() ?>' + } } - } - }); -</script> + }); + </script> <?php endif; ?> From b7d0657594e234d2f2b92335c6c48f769c5fdbe2 Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Fri, 30 Aug 2019 17:58:31 +0300 Subject: [PATCH 0416/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Implemented validation URL key during category creation --- .../CategoryUrlPathAutogeneratorObserver.php | 11 +++++++---- ...ategoryWithRestrictedUrlKeyNotCreatedTest.xml | 16 ++++++++-------- app/code/Magento/CatalogUrlRewrite/etc/di.xml | 11 +++++++++++ .../Magento/CatalogUrlRewrite/i18n/en_US.csv | 3 ++- .../Controller/Adminhtml/CategoryTest.php | 4 ++-- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php index 2fd45bf3c0bc..54ef7102fcc4 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryUrlPathAutogeneratorObserver.php @@ -24,9 +24,9 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface /** * Reserved endpoint names. * - * @var array + * @var string[] */ - private $invalidValues = ['admin', 'soap', 'rest', 'graphql']; + private $invalidValues = []; /** * @var \Magento\CatalogUrlRewrite\Model\CategoryUrlPathGenerator @@ -59,13 +59,15 @@ class CategoryUrlPathAutogeneratorObserver implements ObserverInterface * @param \Magento\CatalogUrlRewrite\Service\V1\StoreViewService $storeViewService * @param CategoryRepositoryInterface $categoryRepository * @param \Magento\Backend\App\Area\FrontNameResolver $frontNameResolver + * @param string[] $invalidValues */ public function __construct( CategoryUrlPathGenerator $categoryUrlPathGenerator, ChildrenCategoriesProvider $childrenCategoriesProvider, StoreViewService $storeViewService, CategoryRepositoryInterface $categoryRepository, - \Magento\Backend\App\Area\FrontNameResolver $frontNameResolver = null + \Magento\Backend\App\Area\FrontNameResolver $frontNameResolver = null, + array $invalidValues = [] ) { $this->categoryUrlPathGenerator = $categoryUrlPathGenerator; $this->childrenCategoriesProvider = $childrenCategoriesProvider; @@ -73,6 +75,7 @@ public function __construct( $this->categoryRepository = $categoryRepository; $this->frontNameResolver = $frontNameResolver ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Backend\App\Area\FrontNameResolver::class); + $this->invalidValues = $invalidValues; } /** @@ -116,7 +119,7 @@ private function updateUrlKey($category, $urlKey) if (in_array($urlKey, $this->getInvalidValues())) { throw new \Magento\Framework\Exception\LocalizedException( __( - 'URL key "%1" conflicts with reserved endpoint names: %2. Try another url key.', + 'URL key "%1" matches a reserved endpoint name (%2). Use another URL key.', $urlKey, implode(', ', $this->getInvalidValues()) ) diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index 1e71d8e15265..0212be38f426 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -45,12 +45,12 @@ <argument name="categoryName" value="admin"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "admin" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeAdminFirstErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeAdminFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminSecondCategoryForm"> <argument name="categoryName" value="{{SimpleSubCategory.name}}"/> <argument name="categoryUrlKey" value="admin"/> </actionGroup> - <see userInput='URL key "admin" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeAdminSecondErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeAdminSecondErrorMessage"/> <!--Create category with 'admin' name--> <comment userInput="Create category with 'admin' name" stepKey="commentAdminCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminThirdCategoryForm"> @@ -66,12 +66,12 @@ <argument name="categoryName" value="soap"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "soap" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeSoapFirstErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeSoapFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapSecondCategoryForm"> <argument name="categoryName" value="{{ApiCategory.name}}"/> <argument name="categoryUrlKey" value="soap"/> </actionGroup> - <see userInput='URL key "soap" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeSoapSecondErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeSoapSecondErrorMessage"/> <!--Create category with 'soap' name--> <comment userInput="Create category with 'soap' name" stepKey="commentSoapCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapThirdCategoryForm"> @@ -87,12 +87,12 @@ <argument name="categoryName" value="rest"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "rest" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeRestFirstErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeRestFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestSecondCategoryForm"> <argument name="categoryName" value="{{SubCategoryWithParent.name}}"/> <argument name="categoryUrlKey" value="rest"/> </actionGroup> - <see userInput='URL key "rest" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeRestSecondErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeRestSecondErrorMessage"/> <!--Create category with 'rest' name--> <comment userInput="Create category with 'rest' name" stepKey="commentRestCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestThirdCategoryForm"> @@ -108,12 +108,12 @@ <argument name="categoryName" value="graphql"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlFirstErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeGraphQlFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlSecondCategoryForm"> <argument name="categoryName" value="{{NewSubCategoryWithParent.name}}"/> <argument name="categoryUrlKey" value="graphql"/> </actionGroup> - <see userInput='URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlSecondErrorMessage"/> + <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlSecondErrorMessage"/> <!--Create category with 'graphql' name--> <comment userInput="Create category with 'graphql' name" stepKey="commentGraphQlCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlThirdCategoryForm"> diff --git a/app/code/Magento/CatalogUrlRewrite/etc/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/di.xml index e6fbcaefd076..2a74b5cd92b2 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/di.xml @@ -45,4 +45,15 @@ </argument> </arguments> </type> + <type name="Magento\CatalogUrlRewrite\Observer\CategoryUrlPathAutogeneratorObserver"> + <arguments> + <argument name="invalidValues" xsi:type="array"> + <item name="0" xsi:type="string">admin</item> + <item name="1" xsi:type="string">soap</item> + <item name="2" xsi:type="string">rest</item> + <item name="3" xsi:type="string">graphql</item> + <item name="4" xsi:type="string">standard</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/CatalogUrlRewrite/i18n/en_US.csv b/app/code/Magento/CatalogUrlRewrite/i18n/en_US.csv index b3335dc3523c..0f21e8ddf9fc 100644 --- a/app/code/Magento/CatalogUrlRewrite/i18n/en_US.csv +++ b/app/code/Magento/CatalogUrlRewrite/i18n/en_US.csv @@ -5,4 +5,5 @@ "Product URL Suffix","Product URL Suffix" "Use Categories Path for Product URLs","Use Categories Path for Product URLs" "Create Permanent Redirect for URLs if URL Key Changed","Create Permanent Redirect for URLs if URL Key Changed" -"Generate "category/product" URL Rewrites","Generate "category/product" URL Rewrites" \ No newline at end of file +"Generate "category/product" URL Rewrites","Generate "category/product" URL Rewrites" +"URL key ""%1"" matches a reserved endpoint name (%2). Use another URL key.","URL key ""%1"" matches a reserved endpoint name (%2). Use another URL key." diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index bfe02f2aa2e1..6340900404bd 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -592,8 +592,8 @@ public function testSaveWithCustomBackendNameAction() $this->assertSessionMessages( $this->equalTo( [ - 'URL key "backend" conflicts with reserved endpoint names: ' - . 'admin, soap, rest, graphql, backend. Try another url key.' + 'URL key "backend" matches a reserved endpoint name ' + . '(admin, soap, rest, graphql, standard, backend). Use another URL key.' ] ), MessageInterface::TYPE_ERROR From a6d39e805405cca7954d43cf8591652997953234 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Thu, 5 Sep 2019 12:31:41 +0400 Subject: [PATCH 0417/1172] MAGETWO-69825: [GITHUB #9891] Subcategory "liquid-hand-soap" is not opened in category "soap" - Updated automated test script --- .../AdminCategoryRestrictedUrlMessageData.xml | 17 +++++++++++ ...goryWithRestrictedUrlKeyNotCreatedTest.xml | 28 +++++++++---------- 2 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 app/code/Magento/CatalogUrlRewrite/Test/Mftf/Data/AdminCategoryRestrictedUrlMessageData.xml diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Data/AdminCategoryRestrictedUrlMessageData.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Data/AdminCategoryRestrictedUrlMessageData.xml new file mode 100644 index 000000000000..b463b0524d5f --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Data/AdminCategoryRestrictedUrlMessageData.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminCategoryRestrictedUrlErrorMessage"> + <data key="urlAdmin">URL key "admin" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.</data> + <data key="urlSoap">URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.</data> + <data key="urlRest">URL key "rest" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.</data> + <data key="urlGraphql">URL key "graphql" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.</data> + </entity> +</entities> diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml index 0212be38f426..6538ec6e935d 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml +++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminCategoryWithRestrictedUrlKeyNotCreatedTest.xml @@ -10,11 +10,11 @@ <test name="AdminCategoryWithRestrictedUrlKeyNotCreatedTest"> <annotations> <features value="CatalogUrlRewrite"/> - <stories value="Subcategory 'liquid-hand-soap' is not opened in category 'soap'"/> + <stories value="Url rewrites"/> <title value="Category with restricted Url Key cannot be created"/> <description value="Category with restricted Url Key cannot be created"/> <severity value="MAJOR"/> - <testCaseId value="MAGETWO-71221"/> + <testCaseId value="MC-17515"/> <useCaseId value="MAGETWO-69825"/> <group value="CatalogUrlRewrite"/> </annotations> @@ -45,19 +45,19 @@ <argument name="categoryName" value="admin"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeAdminFirstErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlAdmin}}' stepKey="seeAdminFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminSecondCategoryForm"> <argument name="categoryName" value="{{SimpleSubCategory.name}}"/> <argument name="categoryUrlKey" value="admin"/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeAdminSecondErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlAdmin}}' stepKey="seeAdminSecondErrorMessage"/> <!--Create category with 'admin' name--> <comment userInput="Create category with 'admin' name" stepKey="commentAdminCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillAdminThirdCategoryForm"> <argument name="categoryName" value="admin"/> <argument name="categoryUrlKey" value="{{SimpleSubCategory.name}}"/> </actionGroup> - <see userInput="You saved the category." stepKey="seeAdminSuccessMessage"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You saved the category." stepKey="seeAdminSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('admin')}}" stepKey="seeAdminCategoryInTree"/> <!--Check category creation with restricted url key 'soap'--> <comment userInput="Check category creation with restricted url key 'soap'" stepKey="commentCheckSoapCategoryCreation"/> @@ -66,19 +66,19 @@ <argument name="categoryName" value="soap"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeSoapFirstErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlSoap}}' stepKey="seeSoapFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapSecondCategoryForm"> <argument name="categoryName" value="{{ApiCategory.name}}"/> <argument name="categoryUrlKey" value="soap"/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeSoapSecondErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlSoap}}' stepKey="seeSoapSecondErrorMessage"/> <!--Create category with 'soap' name--> <comment userInput="Create category with 'soap' name" stepKey="commentSoapCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillSoapThirdCategoryForm"> <argument name="categoryName" value="soap"/> <argument name="categoryUrlKey" value="{{ApiCategory.name}}"/> </actionGroup> - <see userInput="You saved the category." stepKey="seeSoapSuccessMessage"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You saved the category." stepKey="seeSoapSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('soap')}}" stepKey="seeSoapCategoryInTree"/> <!--Check category creation with restricted url key 'rest'--> <comment userInput="Check category creation with restricted url key 'rest'" stepKey="commentCheckRestCategoryCreation"/> @@ -87,19 +87,19 @@ <argument name="categoryName" value="rest"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeRestFirstErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlRest}}' stepKey="seeRestFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestSecondCategoryForm"> <argument name="categoryName" value="{{SubCategoryWithParent.name}}"/> <argument name="categoryUrlKey" value="rest"/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeRestSecondErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlRest}}' stepKey="seeRestSecondErrorMessage"/> <!--Create category with 'rest' name--> <comment userInput="Create category with 'rest' name" stepKey="commentRestCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillRestThirdCategoryForm"> <argument name="categoryName" value="rest"/> <argument name="categoryUrlKey" value="{{SubCategoryWithParent.name}}"/> </actionGroup> - <see userInput="You saved the category." stepKey="seeRestSuccessMesdgssage"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You saved the category." stepKey="seeRestSuccessMesdgssage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('rest')}}" stepKey="seeRestCategoryInTree"/> <!--Check category creation with restricted url key 'graphql'--> <comment userInput="Check category creation with restricted url key 'graphql'" stepKey="commentCheckGraphQlCategoryCreation"/> @@ -108,19 +108,19 @@ <argument name="categoryName" value="graphql"/> <argument name="categoryUrlKey" value=""/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.' stepKey="seeGraphQlFirstErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlGraphql}}' stepKey="seeGraphQlFirstErrorMessage"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlSecondCategoryForm"> <argument name="categoryName" value="{{NewSubCategoryWithParent.name}}"/> <argument name="categoryUrlKey" value="graphql"/> </actionGroup> - <see userInput='URL key "soap" matches a reserved endpoint name (admin, soap, rest, graphql, standard). Use another URL key.URL key "graphql" conflicts with reserved endpoint names: admin, soap, rest, graphql. Try another url key.' stepKey="seeGraphQlSecondErrorMessage"/> + <see selector="{{AdminMessagesSection.errorMessage}}" userInput='{{AdminCategoryRestrictedUrlErrorMessage.urlGraphql}}' stepKey="seeGraphQlSecondErrorMessage"/> <!--Create category with 'graphql' name--> <comment userInput="Create category with 'graphql' name" stepKey="commentGraphQlCategoryCreation"/> <actionGroup ref="FillCategoryNameAndUrlKeyAndSave" stepKey="fillGraphQlThirdCategoryForm"> <argument name="categoryName" value="graphql"/> <argument name="categoryUrlKey" value="{{NewSubCategoryWithParent.name}}"/> </actionGroup> - <see userInput="You saved the category." stepKey="seeGraphQlSuccessMessage"/> + <see selector="{{AdminMessagesSection.successMessage}}" userInput="You saved the category." stepKey="seeGraphQlSuccessMessage"/> <seeElement selector="{{AdminCategorySidebarTreeSection.categoryByName('graphql')}}" stepKey="seeGraphQlCategoryInTree"/> </test> </tests> From 6276dca764d88fa9f5c880924b7a01fabc73a9cd Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Wed, 7 Aug 2019 15:17:14 +0300 Subject: [PATCH 0418/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup --- lib/web/mage/loader.js | 5 ++++- lib/web/mage/loader_old.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js index 83299efba422..29034f93e8ba 100644 --- a/lib/web/mage/loader.js +++ b/lib/web/mage/loader.js @@ -69,7 +69,10 @@ define([ show: function (e, ctx) { this._render(); this.loaderStarted++; - this.spinner.show(); + + if (this.loaderStarted === 1) { + this.spinner.show(); + } if (ctx) { this.spinner diff --git a/lib/web/mage/loader_old.js b/lib/web/mage/loader_old.js index f759758acd12..e008beb12d13 100644 --- a/lib/web/mage/loader_old.js +++ b/lib/web/mage/loader_old.js @@ -81,7 +81,10 @@ show: function (e, ctx) { this._render(); this.loaderStarted++; - this.spinner.show(); + + if (this.loaderStarted === 1) { + this.spinner.show(); + } if (ctx) { this.spinner From 7170855e27c6acd709740ba8183bad72ddb07def Mon Sep 17 00:00:00 2001 From: Lusine Papyan <lusine_papyan@epam.com> Date: Tue, 13 Aug 2019 11:20:04 +0300 Subject: [PATCH 0419/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup - Added automated test script --- .../AdminCMSBlockContentActionGroup.xml | 26 ++++++++ .../CmsNewBlockBlockActionsSection.xml | 14 +++++ ...lleryPopupUploadImagesWithoutErrorTest.xml | 62 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml create mode 100644 app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml new file mode 100644 index 000000000000..56fc28faa8d5 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AddImageToCMSBlockContent"> + <arguments> + <argument name="image" type="entity" defaultValue="MagentoLogo"/> + </arguments> + <click selector="{{BlockContentItemsSection.addImageButton}}" stepKey="clickAddImageButton"/> + <waitForElementVisible selector="{{BlockInsertOrEditImageSection.browseImage}}" stepKey="waitForBrowseImage"/> + <click selector="{{BlockInsertOrEditImageSection.browseImage}}" stepKey="clickBrowseImage"/> + <waitForElementVisible selector="{{BlockSelectImageSection.treeRoot}}" stepKey="waitForAttacheFiles"/> + <click selector="{{BlockSelectImageSection.treeRoot}}" stepKey="clickRoot"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <attachFile selector="{{BlockSelectImageSection.uploadFile}}" userInput="{{image.file}}" stepKey="attachLogo"/> + <waitForElementVisible selector="{{BlockSelectImageSection.addSelected}}" stepKey="waitForAddSelected"/> + <click selector="{{BlockSelectImageSection.addSelected}}" stepKey="clickAddSelected"/> + <waitForElementVisible selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="waitForOkButton"/> + <click selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="clickOk"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml index 2efa7f62fc4e..182254df2dc5 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml @@ -24,9 +24,23 @@ </section> <section name="BlockContentSection"> <element name="TextArea" type="input" selector="#cms_block_form_content"/> + <element name="image" type="file" selector="//*[contains(@class, 'mce-content-body')]//img"/> + <element name="contentIframe" type="iframe" selector="cms_block_form_content_ifr"/> </section> <section name="CmsBlockBlockActionSection"> <element name="deleteBlock" type="button" selector="#delete" timeout="30"/> <element name="deleteConfirm" type="button" selector=".action-primary.action-accept" timeout="60"/> </section> + <section name="BlockContentItemsSection"> + <element name="addImageButton" type="button" selector="//div[contains(@class, 'mce-widget')]//i[contains(@class, 'mce-i-image')]"/> + </section> + <section name="BlockInsertOrEditImageSection"> + <element name="browseImage" type="button" selector="//div[contains(@class, 'mce-floatpanel')]//i[contains(@class, 'mce-i-browse')]"/> + <element name="ok" type="button" selector="//div[contains(@class, 'mce-floatpanel')]//span[contains(text(), 'Ok')]"/> + </section> + <section name="BlockSelectImageSection"> + <element name="uploadFile" type="input" selector="input[name='image']"/> + <element name="addSelected" type="button" selector="#insert_files"/> + <element name="treeRoot" type="text" selector="//div[contains(@class, 'jstree')]//a[contains(text(), 'Storage Root')]"/> + </section> </sections> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml new file mode 100644 index 000000000000..bef967edcc68 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminMediaGalleryPopupUploadImagesWithoutErrorTest"> + <annotations> + <features value="Cms"/> + <stories value="WYSIWYG - Spinner is Always Displayed on Media Gallery popup"/> + <title value="Media Gallery popup upload images without error"/> + <description value="Media Gallery popup upload images without error"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-18962"/> + <useCaseId value="MC-18709"/> + <group value="Cms"/> + </annotations> + <before> + <!--Enable WYSIWYG options--> + <comment userInput="Enable WYSIWYG options" stepKey="commentEnableWYSIWYG"/> + <magentoCLI command="config:set cms/wysiwyg/enabled enabled" stepKey="enableWYSIWYGEditor"/> + <magentoCLI command="config:set cms/wysiwyg/editor 'TinyMCE 4'" stepKey="setValueWYSIWYGEditor"/> + <!--Create block--> + <comment userInput="Create block" stepKey="commentCreateBlock"/> + <createData entity="Sales25offBlock" stepKey="createBlock"/> + <actionGroup ref="LoginActionGroup" stepKey="login"/> + </before> + <after> + <!--Disable WYSIWYG options--> + <comment userInput="Disable WYSIWYG options" stepKey="commentDisableWYSIWYG"/> + <magentoCLI command="config:set cms/wysiwyg/enabled disabled" stepKey="disableWYSIWYG"/> + <deleteData createDataKey="createBlock" stepKey="deleteBlock" /> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Open created block page and add image--> + <comment userInput="Open create block page and add image" stepKey="commentOpenBlockPage"/> + <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage1"> + <argument name="CMSBlockPage" value="$$createBlock$$"/> + </actionGroup> + <actionGroup ref="AddImageToCMSBlockContent" stepKey="addImage"> + <argument name="image" value="TestImageNew"/> + </actionGroup> + <click selector="{{BlockWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtnFirstTime"/> + <click selector="{{BlockWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtnSecondTime"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!--Switch to content frame and click on image--> + <comment userInput="Switch to content frame and click on image" stepKey="commentSwitchToIframe"/> + <switchToIFrame selector="{{BlockContentSection.contentIframe}}" stepKey="switchToContentFrame"/> + <click selector="{{BlockContentSection.image}}" stepKey="clickImage"/> + <switchToIFrame stepKey="switchBack"/> + <!--Add image second time and assert--> + <comment userInput="Add image second time and assert" stepKey="commentAddImageAndAssert"/> + <actionGroup ref="AddImageToCMSBlockContent" stepKey="addImageSecondTime"> + <argument name="image" value="MagentoLogo"/> + </actionGroup> + <switchToIFrame selector="{{BlockContentSection.contentIframe}}" stepKey="switchToContentFrameSecondTime"/> + <seeElement selector="{{BlockContentSection.image}}" stepKey="seeImageElement"/> + </test> +</tests> From cc766ae751598d603157d17be25faeaac3567244 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <lusine_papyan@epam.com> Date: Wed, 4 Sep 2019 13:10:54 +0300 Subject: [PATCH 0420/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup - Updated automated test script --- .../Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml | 2 +- .../Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml | 2 +- .../AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml index 56fc28faa8d5..79bccbe705dc 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml @@ -7,7 +7,7 @@ --> <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="AddImageToCMSBlockContent"> + <actionGroup name="AdminAddImageToCMSBlockContent"> <arguments> <argument name="image" type="entity" defaultValue="MagentoLogo"/> </arguments> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml index 182254df2dc5..eac67ec9395b 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml @@ -39,7 +39,7 @@ <element name="ok" type="button" selector="//div[contains(@class, 'mce-floatpanel')]//span[contains(text(), 'Ok')]"/> </section> <section name="BlockSelectImageSection"> - <element name="uploadFile" type="input" selector="input[name='image']"/> + <element name="uploadFile" type="input" selector="input.fileupload"/> <element name="addSelected" type="button" selector="#insert_files"/> <element name="treeRoot" type="text" selector="//div[contains(@class, 'jstree')]//a[contains(text(), 'Storage Root')]"/> </section> diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml index bef967edcc68..bc1688c9d692 100644 --- a/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminMediaGalleryPopupUploadImagesWithoutErrorTest.xml @@ -10,7 +10,7 @@ <test name="AdminMediaGalleryPopupUploadImagesWithoutErrorTest"> <annotations> <features value="Cms"/> - <stories value="WYSIWYG - Spinner is Always Displayed on Media Gallery popup"/> + <stories value="Spinner is Always Displayed on Media Gallery popup"/> <title value="Media Gallery popup upload images without error"/> <description value="Media Gallery popup upload images without error"/> <severity value="CRITICAL"/> @@ -40,7 +40,7 @@ <actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage1"> <argument name="CMSBlockPage" value="$$createBlock$$"/> </actionGroup> - <actionGroup ref="AddImageToCMSBlockContent" stepKey="addImage"> + <actionGroup ref="AdminAddImageToCMSBlockContent" stepKey="addImage"> <argument name="image" value="TestImageNew"/> </actionGroup> <click selector="{{BlockWYSIWYGSection.ShowHideBtn}}" stepKey="clickShowHideBtnFirstTime"/> @@ -53,7 +53,7 @@ <switchToIFrame stepKey="switchBack"/> <!--Add image second time and assert--> <comment userInput="Add image second time and assert" stepKey="commentAddImageAndAssert"/> - <actionGroup ref="AddImageToCMSBlockContent" stepKey="addImageSecondTime"> + <actionGroup ref="AdminAddImageToCMSBlockContent" stepKey="addImageSecondTime"> <argument name="image" value="MagentoLogo"/> </actionGroup> <switchToIFrame selector="{{BlockContentSection.contentIframe}}" stepKey="switchToContentFrameSecondTime"/> From 6cce7520875f84313a74136d5fd3e3cf8e5bc65a Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 6 Sep 2019 14:12:38 +0400 Subject: [PATCH 0421/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../Test/Mftf/Suite/AppConfigDumpSuite.xml | 0 .../Section/AdminShippingMethodDHLSection.xml | 0 ...utFieldsDisabledAfterAppConfigDumpTest.xml | 47 +++++ .../AdminShippingMethodFedExSection.xml | 0 ...utFieldsDisabledAfterAppConfigDumpTest.xml | 53 ++++++ .../Section/AdminShippingMethodUPSSection.xml | 39 ---- ...utFieldsDisabledAfterAppConfigDumpTest.xml | 170 +----------------- .../AdminShippingMethodsUpsSection.xml | 25 +++ ...utFieldsDisabledAfterAppConfigDumpTest.xml | 67 +++++++ .../AdminShippingMethodUSPSSection.xml | 0 ...utFieldsDisabledAfterAppConfigDumpTest.xml | 55 ++++++ 11 files changed, 249 insertions(+), 207 deletions(-) rename app/code/Magento/{Shipping => Config}/Test/Mftf/Suite/AppConfigDumpSuite.xml (100%) rename app/code/Magento/{Shipping => Dhl}/Test/Mftf/Section/AdminShippingMethodDHLSection.xml (100%) create mode 100644 app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml rename app/code/Magento/{Shipping => Fedex}/Test/Mftf/Section/AdminShippingMethodFedExSection.xml (100%) create mode 100644 app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml delete mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml create mode 100644 app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml rename app/code/Magento/{Shipping => Usps}/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml (100%) create mode 100644 app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml diff --git a/app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml b/app/code/Magento/Config/Test/Mftf/Suite/AppConfigDumpSuite.xml similarity index 100% rename from app/code/Magento/Shipping/Test/Mftf/Suite/AppConfigDumpSuite.xml rename to app/code/Magento/Config/Test/Mftf/Suite/AppConfigDumpSuite.xml diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml b/app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml similarity index 100% rename from app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodDHLSection.xml rename to app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml diff --git a/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml new file mode 100644 index 000000000000..df6841cb718f --- /dev/null +++ b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> + <!--Assert configuration are disabled in DHL section--> + <comment userInput="Assert configuration are disabled in DHL section" stepKey="commentSeeDisabledDHLConfigs"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <conditionalClick selector="{{AdminShippingMethodDHLSection.carriersDHLTab}}" dependentSelector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" visible="false" stepKey="expandDHLTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" userInput="disabled" stepKey="grabDHLActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveDisabled" stepKey="assertDHLActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActiveRMA}}" userInput="disabled" stepKey="grabDHLActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveRMADisabled" stepKey="assertDHLActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLTitle}}" userInput="disabled" stepKey="grabDHLTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLTitleDisabled" stepKey="assertDHLTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccessId}}" userInput="disabled" stepKey="grabDHLAccessIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLAccessIdDisabled" stepKey="assertDHLAccessIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLPassword}}" userInput="disabled" stepKey="grabDHLPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLPasswordDisabled" stepKey="assertDHLPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccount}}" userInput="disabled" stepKey="grabDHLAccountDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLAccountDisabled" stepKey="assertDHLAccountDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLContentType}}" userInput="disabled" stepKey="grabDHLContentTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLContentTypeDisabled" stepKey="assertDHLContentTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingType}}" userInput="disabled" stepKey="grabDHLHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingTypeDisabled" stepKey="assertDHLHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingAction}}" userInput="disabled" stepKey="grabDHLHandlingDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingDisabled" stepKey="assertDHLHandlingDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLDivideOrderWeight}}" userInput="disabled" stepKey="grabDHLDivideOrderWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLDivideOrderWeightDisabled" stepKey="assertDHLDivideOrderWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLUnitOfMeasure}}" userInput="disabled" stepKey="grabDHLUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLUnitOfMeasureDisabled" stepKey="assertDHLUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSize}}" userInput="disabled" stepKey="grabDHLSizeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSizeDisabled" stepKey="assertDHLSizeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLNonDocAllowedMethod}}" userInput="disabled" stepKey="grabDHLNonDocAllowedMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLNonDocAllowedMethodDisabled" stepKey="assertDHLNonDocAllowedMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSmartPostHubId}}" userInput="disabled" stepKey="grabDHLSmartPostHubIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSmartPostHubIdDisabled" stepKey="assertDHLSmartPostHubIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSpecificErrMsg}}" userInput="disabled" stepKey="grabDHLSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabDHLSpecificErrMsgDisabled" stepKey="assertDHLSpecificErrMsgDisabled"/> + </test> +</tests> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml b/app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml similarity index 100% rename from app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodFedExSection.xml rename to app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml new file mode 100644 index 000000000000..c5cb75ae9975 --- /dev/null +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> + <!--Assert configuration are disabled in FedEx section--> + <comment userInput="Assert configuration are disabled in FedEx section" stepKey="commentSeeDisabledFedExConfigs"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <conditionalClick selector="{{AdminShippingMethodFedExSection.carriersFedExTab}}" dependentSelector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" visible="false" stepKey="expandFedExTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" userInput="disabled" stepKey="grabFedExActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveDisabled" stepKey="assertFedExActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActiveRMA}}" userInput="disabled" stepKey="grabFedExActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveRMADisabled" stepKey="assertFedExActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExTitle}}" userInput="disabled" stepKey="grabFedExTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExTitleDisabled" stepKey="assertFedExTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAccountId}}" userInput="disabled" stepKey="grabFedExAccountIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExAccountIdDisabled" stepKey="assertFedExAccountIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMeterNumber}}" userInput="disabled" stepKey="grabFedExMeterNumberDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExMeterNumberDisabled" stepKey="assertFedExMeterNumberDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExKey}}" userInput="disabled" stepKey="grabFedExKeyDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExKeyDisabled" stepKey="assertFedExKeyDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPassword}}" userInput="disabled" stepKey="grabFedExPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExPasswordDisabled" stepKey="assertFedExPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSandboxMode}}" userInput="disabled" stepKey="grabFedExSandboxDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSandboxDisabled" stepKey="assertFedExSandboxDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExShipmentRequestType}}" userInput="disabled" stepKey="grabFedExShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExShipmentRequestTypeDisabled" stepKey="assertFedExShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPackaging}}" userInput="disabled" stepKey="grabFedExPackagingDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExPackagingDisabled" stepKey="assertFedExPackagingDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExDropoff}}" userInput="disabled" stepKey="grabFedExDropoffDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExDropoffDisabled" stepKey="assertFedExDropoffDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExUnitOfMeasure}}" userInput="disabled" stepKey="grabFedExUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExUnitOfMeasureDisabled" stepKey="assertFedExUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMaxPackageWeight}}" userInput="disabled" stepKey="grabFedExMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExMaxPackageWeightDisabled" stepKey="assertFedExMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingType}}" userInput="disabled" stepKey="grabFedExHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingTypeDisabled" stepKey="assertFedExHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingAction}}" userInput="disabled" stepKey="grabFedExHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingActionDisabled" stepKey="assertFedExHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificErrMsg}}" userInput="disabled" stepKey="grabFedExSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificErrMsgDisabled" stepKey="assertFedExSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAllowSpecific}}" userInput="disabled" stepKey="grabFedExAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExAllowSpecificDisabled" stepKey="assertFedExAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificCountry}}" userInput="disabled" stepKey="grabFedExSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificCountryDisabled" stepKey="assertFedExSpecificCountryDisabled"/> + </test> +</tests> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml deleted file mode 100644 index 3eda77a31b42..000000000000 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUPSSection.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="AdminShippingMethodUPSSection"> - <element name="carriersUPSTab" type="button" selector="#carriers_ups-head"/> - <element name="carriersUPSActive" type="input" selector="#carriers_ups_active_inherit"/> - <element name="carriersUPSActiveRMA" type="select" selector="#carriers_ups_active_rma"/> - <element name="carriersUPSType" type="input" selector="#carriers_ups_type_inherit"/> - <element name="carriersUPSAccountLive" type="input" selector="#carriers_ups_is_account_live_inherit"/> - <element name="carriersUPSGatewayXMLUrl" type="input" selector="#carriers_ups_gateway_xml_url_inherit"/> - <element name="carriersUPSModeXML" type="input" selector="#carriers_ups_mode_xml_inherit"/> - <element name="carriersUPSOriginShipment" type="input" selector="#carriers_ups_origin_shipment_inherit"/> - <element name="carriersUPSTitle" type="input" selector="#carriers_ups_title_inherit"/> - <element name="carriersUPSNegotiatedActive" type="input" selector="#carriers_ups_negotiated_active_inherit"/> - <element name="carriersUPSIncludeTaxes" type="input" selector="#carriers_ups_include_taxes_inherit"/> - <element name="carriersUPSShipmentRequestType" type="input" selector="#carriers_ups_shipment_requesttype_inherit"/> - <element name="carriersUPSContainer" type="input" selector="#carriers_ups_container_inherit"/> - <element name="carriersUPSDestType" type="input" selector="#carriers_ups_dest_type_inherit"/> - <element name="carriersUPSTrackingXmlUrl" type="input" selector="#carriers_ups_tracking_xml_url_inherit"/> - <element name="carriersUPSUnitOfMeasure" type="input" selector="#carriers_ups_unit_of_measure_inherit"/> - <element name="carriersUPSMaxPackageWeight" type="input" selector="#carriers_ups_max_package_weight_inherit"/> - <element name="carriersUPSPickup" type="input" selector="#carriers_ups_pickup_inherit"/> - <element name="carriersUPSMinPackageWeight" type="input" selector="#carriers_ups_min_package_weight_inherit"/> - <element name="carriersUPSHandlingType" type="input" selector="#carriers_ups_handling_type_inherit"/> - <element name="carriersUPSHandlingAction" type="input" selector="#carriers_ups_handling_action_inherit"/> - <element name="carriersUPSAllowedMethods" type="input" selector="#carriers_ups_allowed_methods_inherit"/> - <element name="carriersUPSFreeMethod" type="input" selector="#carriers_ups_free_method_inherit"/> - <element name="carriersUPSSpecificErrMsg" type="input" selector="#carriers_ups_specificerrmsg_inherit"/> - <element name="carriersUPSAllowSpecific" type="input" selector="#carriers_ups_sallowspecific_inherit"/> - <element name="carriersUPSSpecificCountry" type="input" selector="#carriers_ups_specificcountry"/> - </section> -</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index c144d6f21b64..1739bcd01ec9 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -10,8 +10,8 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> <annotations> - <features value="Config"/> - <stories value="Disabling all the settings in Magento backend"/> + <features value="Configuration"/> + <stories value="Disable configuration inputs"/> <title value="Check that all input fields disabled after executing CLI app:config:dump"/> <description value="Check that all input fields disabled after executing CLI app:config:dump"/> <severity value="MAJOR"/> @@ -77,171 +77,5 @@ <assertEquals expected='true' expectedType="string" actual="$grabTableRateAllowSpecificDisabled" stepKey="assertTableRateAllowSpecificDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateSpecificCountry}}" userInput="disabled" stepKey="grabTableRateSpecificCountryDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabTableRateSpecificCountryDisabled" stepKey="assertTableRateSpecificCountryDisabled"/> - <!--Assert configuration are disabled in UPS section--> - <comment userInput="Assert configuration are disabled in UPS section" stepKey="commentSeeDisabledUPSConfigs"/> - <conditionalClick selector="{{AdminShippingMethodUPSSection.carriersUPSTab}}" dependentSelector="{{AdminShippingMethodUPSSection.carriersUPSActive}}" visible="false" stepKey="expandUPSTab"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSActive}}" userInput="disabled" stepKey="grabUPSActiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveDisabled" stepKey="assertUPSActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSActiveRMA}}" userInput="disabled" stepKey="grabUPSActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveRMADisabled" stepKey="assertUPSActiveRMADisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSType}}" userInput="disabled" stepKey="grabUPSTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSTypeDisabled" stepKey="assertUPSTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAccountLive}}" userInput="disabled" stepKey="grabUPSAccountLiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSAccountLiveDisabled" stepKey="assertUPSAccountLiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUPSGatewayXMLUrlDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSGatewayXMLUrlDisabled" stepKey="assertUPSGatewayXMLUrlDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSModeXML}}" userInput="disabled" stepKey="grabUPSModeXMLDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSModeXMLDisabled" stepKey="assertUPSModeXMLDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSOriginShipment}}" userInput="disabled" stepKey="grabUPSOriginShipmentDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSOriginShipmentDisabled" stepKey="assertUPSOriginShipmentDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSTitle}}" userInput="disabled" stepKey="grabUPSTitleDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSTitleDisabled" stepKey="assertUPSTitleDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSNegotiatedActive}}" userInput="disabled" stepKey="grabUPSNegotiatedActiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSNegotiatedActiveDisabled" stepKey="assertUPSNegotiatedActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSIncludeTaxes}}" userInput="disabled" stepKey="grabUPSIncludeTaxesDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSIncludeTaxesDisabled" stepKey="assertUPSIncludeTaxesDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSShipmentRequestType}}" userInput="disabled" stepKey="grabUPSShipmentRequestTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSShipmentRequestTypeDisabled" stepKey="assertUPSShipmentRequestTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSContainer}}" userInput="disabled" stepKey="grabUPSContainerDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSContainerDisabled" stepKey="assertUPSContainerDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSDestType}}" userInput="disabled" stepKey="grabUPSDestTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSDestTypeDisabled" stepKey="assertUPSDestTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSTrackingXmlUrl}}" userInput="disabled" stepKey="grabUPSTrackingXmlUrlDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSTrackingXmlUrlDisabled" stepKey="assertUPSTrackingXmlUrlDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSUnitOfMeasure}}" userInput="disabled" stepKey="grabUPSUnitOfMeasureDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSUnitOfMeasureDisabled" stepKey="assertUPSUnitOfMeasureDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUPSMaxPackageWeightDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSMaxPackageWeightDisabled" stepKey="assertUPSMaxPackageWeightDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSPickup}}" userInput="disabled" stepKey="grabUPSPickupDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSPickupDisabled" stepKey="assertUPSPickupDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSMinPackageWeight}}" userInput="disabled" stepKey="grabUPSMinPackageWeightDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSMinPackageWeightDisabled" stepKey="assertUPSMinPackageWeightDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSHandlingType}}" userInput="disabled" stepKey="grabUPSHandlingTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingTypeDisabled" stepKey="assertUPSHandlingTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSHandlingAction}}" userInput="disabled" stepKey="grabUPSHandlingActionDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingActionDisabled" stepKey="assertUPSHandlingActionDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAllowedMethods}}" userInput="disabled" stepKey="grabUPSAllowedMethodsDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowedMethodsDisabled" stepKey="assertUPSAllowedMethodsDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSFreeMethod}}" userInput="disabled" stepKey="grabUPSFreeMethodDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSFreeMethodDisabled" stepKey="assertUPSFreeMethodDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUPSSpecificErrMsgDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificErrMsgDisabled" stepKey="assertUPSSpecificErrMsgDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSAllowSpecific}}" userInput="disabled" stepKey="grabUPSAllowSpecificDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowSpecificDisabled" stepKey="assertUPSAllowSpecificDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUPSSection.carriersUPSSpecificCountry}}" userInput="disabled" stepKey="grabUPSSpecificCountryDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificCountryDisabled" stepKey="assertUPSSpecificCountryDisabled"/> - <!--Assert configuration are disabled in USPS section--> - <comment userInput="Assert configuration are disabled in USPS section" stepKey="commentSeeDisabledUSPSConfigs"/> - <conditionalClick selector="{{AdminShippingMethodUSPSSection.carriersUSPSTab}}" dependentSelector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" visible="false" stepKey="expandUSPSTab"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" userInput="disabled" stepKey="grabUSPSActiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSActiveDisabled" stepKey="assertUSPSActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUSPSGatewayXMLUrlDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewayXMLUrlDisabled" stepKey="assertUSPSGatewayXMLUrlDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewaySecureUrl}}" userInput="disabled" stepKey="grabUSPSGatewaySecureUrlDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewaySecureUrlDisabled" stepKey="assertUSPSGatewaySecureUrlDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSTitle}}" userInput="disabled" stepKey="grabUSPSTitleDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSTitleDisabled" stepKey="assertUSPSTitleDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSUserId}}" userInput="disabled" stepKey="grabUSPSUserIdDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSUserIdDisabled" stepKey="assertUSPSUserIdDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSPassword}}" userInput="disabled" stepKey="grabUSPSPasswordDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSPasswordDisabled" stepKey="assertUSPSPasswordDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSShipmentRequestType}}" userInput="disabled" stepKey="grabUSPSShipmentRequestTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSShipmentRequestTypeDisabled" stepKey="assertUSPSShipmentRequestTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSContainer}}" userInput="disabled" stepKey="grabUSPSContainerDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSContainerDisabled" stepKey="assertUSPSContainerDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSize}}" userInput="disabled" stepKey="grabUSPSSizeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSSizeDisabled" stepKey="assertUSPSSizeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSDestType}}" userInput="disabled" stepKey="grabUSPSDestTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSDestTypeDisabled" stepKey="assertUSPSDestTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMachinable}}" userInput="disabled" stepKey="grabUSPSMachinableDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSMachinableDisabled" stepKey="assertUSPSMachinableDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUSPSMaxPackageWeightDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSMaxPackageWeightDisabled" stepKey="assertUSPSMaxPackageWeightDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingType}}" userInput="disabled" stepKey="grabUSPSHandlingTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingTypeDisabled" stepKey="assertUSPSHandlingTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingAction}}" userInput="disabled" stepKey="grabUSPSHandlingActionDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingActionDisabled" stepKey="assertUSPSHandlingActionDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowedMethods}}" userInput="disabled" stepKey="grabUSPSAllowedMethodsDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowedMethodsDisabled" stepKey="assertUSPSAllowedMethodsDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSFreeMethod}}" userInput="disabled" stepKey="grabUSPSFreeMethodDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSFreeMethodDisabled" stepKey="assertUSPSFreeMethodDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUSPSSpecificErrMsgDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificErrMsgDisabled" stepKey="assertUSPSSpecificErrMsgDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowSpecific}}" userInput="disabled" stepKey="grabUSPSAllowSpecificDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowSpecificDisabled" stepKey="assertUSPSAllowSpecificDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificCountry}}" userInput="disabled" stepKey="grabUSPSSpecificCountryDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificCountryDisabled" stepKey="assertUSPSSpecificCountryDisabled"/> - <!--Assert configuration are disabled in FedEx section--> - <comment userInput="Assert configuration are disabled in FedEx section" stepKey="commentSeeDisabledFedExConfigs"/> - <conditionalClick selector="{{AdminShippingMethodFedExSection.carriersFedExTab}}" dependentSelector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" visible="false" stepKey="expandFedExTab"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" userInput="disabled" stepKey="grabFedExActiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveDisabled" stepKey="assertFedExActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActiveRMA}}" userInput="disabled" stepKey="grabFedExActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveRMADisabled" stepKey="assertFedExActiveRMADisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExTitle}}" userInput="disabled" stepKey="grabFedExTitleDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExTitleDisabled" stepKey="assertFedExTitleDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAccountId}}" userInput="disabled" stepKey="grabFedExAccountIdDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExAccountIdDisabled" stepKey="assertFedExAccountIdDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMeterNumber}}" userInput="disabled" stepKey="grabFedExMeterNumberDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExMeterNumberDisabled" stepKey="assertFedExMeterNumberDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExKey}}" userInput="disabled" stepKey="grabFedExKeyDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExKeyDisabled" stepKey="assertFedExKeyDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPassword}}" userInput="disabled" stepKey="grabFedExPasswordDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExPasswordDisabled" stepKey="assertFedExPasswordDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSandboxMode}}" userInput="disabled" stepKey="grabFedExSandboxDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExSandboxDisabled" stepKey="assertFedExSandboxDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExShipmentRequestType}}" userInput="disabled" stepKey="grabFedExShipmentRequestTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExShipmentRequestTypeDisabled" stepKey="assertFedExShipmentRequestTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExPackaging}}" userInput="disabled" stepKey="grabFedExPackagingDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExPackagingDisabled" stepKey="assertFedExPackagingDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExDropoff}}" userInput="disabled" stepKey="grabFedExDropoffDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExDropoffDisabled" stepKey="assertFedExDropoffDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExUnitOfMeasure}}" userInput="disabled" stepKey="grabFedExUnitOfMeasureDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExUnitOfMeasureDisabled" stepKey="assertFedExUnitOfMeasureDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExMaxPackageWeight}}" userInput="disabled" stepKey="grabFedExMaxPackageWeightDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExMaxPackageWeightDisabled" stepKey="assertFedExMaxPackageWeightDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingType}}" userInput="disabled" stepKey="grabFedExHandlingTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingTypeDisabled" stepKey="assertFedExHandlingTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExHandlingAction}}" userInput="disabled" stepKey="grabFedExHandlingActionDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExHandlingActionDisabled" stepKey="assertFedExHandlingActionDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificErrMsg}}" userInput="disabled" stepKey="grabFedExSpecificErrMsgDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificErrMsgDisabled" stepKey="assertFedExSpecificErrMsgDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAllowSpecific}}" userInput="disabled" stepKey="grabFedExAllowSpecificDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExAllowSpecificDisabled" stepKey="assertFedExAllowSpecificDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExSpecificCountry}}" userInput="disabled" stepKey="grabFedExSpecificCountryDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExSpecificCountryDisabled" stepKey="assertFedExSpecificCountryDisabled"/> - <!--Assert configuration are disabled in DHL section--> - <comment userInput="Assert configuration are disabled in DHL section" stepKey="commentSeeDisabledDHLConfigs"/> - <conditionalClick selector="{{AdminShippingMethodDHLSection.carriersDHLTab}}" dependentSelector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" visible="false" stepKey="expandDHLTab"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" userInput="disabled" stepKey="grabDHLActiveDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveDisabled" stepKey="assertDHLActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActiveRMA}}" userInput="disabled" stepKey="grabDHLActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveRMADisabled" stepKey="assertDHLActiveRMADisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLTitle}}" userInput="disabled" stepKey="grabDHLTitleDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLTitleDisabled" stepKey="assertDHLTitleDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccessId}}" userInput="disabled" stepKey="grabDHLAccessIdDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLAccessIdDisabled" stepKey="assertDHLAccessIdDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLPassword}}" userInput="disabled" stepKey="grabDHLPasswordDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLPasswordDisabled" stepKey="assertDHLPasswordDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccount}}" userInput="disabled" stepKey="grabDHLAccountDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLAccountDisabled" stepKey="assertDHLAccountDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLContentType}}" userInput="disabled" stepKey="grabDHLContentTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLContentTypeDisabled" stepKey="assertDHLContentTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingType}}" userInput="disabled" stepKey="grabDHLHandlingTypeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingTypeDisabled" stepKey="assertDHLHandlingTypeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLHandlingAction}}" userInput="disabled" stepKey="grabDHLHandlingDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLHandlingDisabled" stepKey="assertDHLHandlingDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLDivideOrderWeight}}" userInput="disabled" stepKey="grabDHLDivideOrderWeightDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLDivideOrderWeightDisabled" stepKey="assertDHLDivideOrderWeightDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLUnitOfMeasure}}" userInput="disabled" stepKey="grabDHLUnitOfMeasureDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLUnitOfMeasureDisabled" stepKey="assertDHLUnitOfMeasureDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSize}}" userInput="disabled" stepKey="grabDHLSizeDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLSizeDisabled" stepKey="assertDHLSizeDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLNonDocAllowedMethod}}" userInput="disabled" stepKey="grabDHLNonDocAllowedMethodDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLNonDocAllowedMethodDisabled" stepKey="assertDHLNonDocAllowedMethodDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSmartPostHubId}}" userInput="disabled" stepKey="grabDHLSmartPostHubIdDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLSmartPostHubIdDisabled" stepKey="assertDHLSmartPostHubIdDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLSpecificErrMsg}}" userInput="disabled" stepKey="grabDHLSpecificErrMsgDisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLSpecificErrMsgDisabled" stepKey="assertDHLSpecificErrMsgDisabled"/> </test> </tests> diff --git a/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml b/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml index 4107f17dbc18..d68b6a77add6 100644 --- a/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml +++ b/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml @@ -12,5 +12,30 @@ <element name="carriersUpsTab" type="button" selector="#carriers_ups-head"/> <element name="carriersUpsType" type="select" selector="#carriers_ups_type"/> <element name="selectedUpsType" type="text" selector="#carriers_ups_type option[selected]"/> + <element name="carriersUPSActive" type="input" selector="#carriers_ups_active_inherit"/> + <element name="carriersUPSActiveRMA" type="select" selector="#carriers_ups_active_rma"/> + <element name="carriersUPSTypeSystem" type="input" selector="#carriers_ups_type_inherit"/> + <element name="carriersUPSAccountLive" type="input" selector="#carriers_ups_is_account_live_inherit"/> + <element name="carriersUPSGatewayXMLUrl" type="input" selector="#carriers_ups_gateway_xml_url_inherit"/> + <element name="carriersUPSModeXML" type="input" selector="#carriers_ups_mode_xml_inherit"/> + <element name="carriersUPSOriginShipment" type="input" selector="#carriers_ups_origin_shipment_inherit"/> + <element name="carriersUPSTitle" type="input" selector="#carriers_ups_title_inherit"/> + <element name="carriersUPSNegotiatedActive" type="input" selector="#carriers_ups_negotiated_active_inherit"/> + <element name="carriersUPSIncludeTaxes" type="input" selector="#carriers_ups_include_taxes_inherit"/> + <element name="carriersUPSShipmentRequestType" type="input" selector="#carriers_ups_shipment_requesttype_inherit"/> + <element name="carriersUPSContainer" type="input" selector="#carriers_ups_container_inherit"/> + <element name="carriersUPSDestType" type="input" selector="#carriers_ups_dest_type_inherit"/> + <element name="carriersUPSTrackingXmlUrl" type="input" selector="#carriers_ups_tracking_xml_url_inherit"/> + <element name="carriersUPSUnitOfMeasure" type="input" selector="#carriers_ups_unit_of_measure_inherit"/> + <element name="carriersUPSMaxPackageWeight" type="input" selector="#carriers_ups_max_package_weight_inherit"/> + <element name="carriersUPSPickup" type="input" selector="#carriers_ups_pickup_inherit"/> + <element name="carriersUPSMinPackageWeight" type="input" selector="#carriers_ups_min_package_weight_inherit"/> + <element name="carriersUPSHandlingType" type="input" selector="#carriers_ups_handling_type_inherit"/> + <element name="carriersUPSHandlingAction" type="input" selector="#carriers_ups_handling_action_inherit"/> + <element name="carriersUPSAllowedMethods" type="input" selector="#carriers_ups_allowed_methods_inherit"/> + <element name="carriersUPSFreeMethod" type="input" selector="#carriers_ups_free_method_inherit"/> + <element name="carriersUPSSpecificErrMsg" type="input" selector="#carriers_ups_specificerrmsg_inherit"/> + <element name="carriersUPSAllowSpecific" type="input" selector="#carriers_ups_sallowspecific_inherit"/> + <element name="carriersUPSSpecificCountry" type="input" selector="#carriers_ups_specificcountry"/> </section> </sections> diff --git a/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml new file mode 100644 index 000000000000..9202476ef183 --- /dev/null +++ b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> + <!--Assert configuration are disabled in UPS section--> + <comment userInput="Assert configuration are disabled in UPS section" stepKey="commentSeeDisabledUPSConfigs"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <conditionalClick selector="{{AdminShippingMethodsUpsSection.carriersUpsTab}}" dependentSelector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" visible="false" stepKey="expandUPSTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" userInput="disabled" stepKey="grabUPSActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveDisabled" stepKey="assertUPSActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActiveRMA}}" userInput="disabled" stepKey="grabUPSActiveRMADisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveRMADisabled" stepKey="assertUPSActiveRMADisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSTypeSystem}}" userInput="disabled" stepKey="grabUPSTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTypeDisabled" stepKey="assertUPSTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSAccountLive}}" userInput="disabled" stepKey="grabUPSAccountLiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAccountLiveDisabled" stepKey="assertUPSAccountLiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUPSGatewayXMLUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSGatewayXMLUrlDisabled" stepKey="assertUPSGatewayXMLUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSModeXML}}" userInput="disabled" stepKey="grabUPSModeXMLDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSModeXMLDisabled" stepKey="assertUPSModeXMLDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSOriginShipment}}" userInput="disabled" stepKey="grabUPSOriginShipmentDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSOriginShipmentDisabled" stepKey="assertUPSOriginShipmentDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSTitle}}" userInput="disabled" stepKey="grabUPSTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTitleDisabled" stepKey="assertUPSTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSNegotiatedActive}}" userInput="disabled" stepKey="grabUPSNegotiatedActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSNegotiatedActiveDisabled" stepKey="assertUPSNegotiatedActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSIncludeTaxes}}" userInput="disabled" stepKey="grabUPSIncludeTaxesDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSIncludeTaxesDisabled" stepKey="assertUPSIncludeTaxesDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSShipmentRequestType}}" userInput="disabled" stepKey="grabUPSShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSShipmentRequestTypeDisabled" stepKey="assertUPSShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSContainer}}" userInput="disabled" stepKey="grabUPSContainerDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSContainerDisabled" stepKey="assertUPSContainerDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSDestType}}" userInput="disabled" stepKey="grabUPSDestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSDestTypeDisabled" stepKey="assertUPSDestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSTrackingXmlUrl}}" userInput="disabled" stepKey="grabUPSTrackingXmlUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSTrackingXmlUrlDisabled" stepKey="assertUPSTrackingXmlUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSUnitOfMeasure}}" userInput="disabled" stepKey="grabUPSUnitOfMeasureDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSUnitOfMeasureDisabled" stepKey="assertUPSUnitOfMeasureDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUPSMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSMaxPackageWeightDisabled" stepKey="assertUPSMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSPickup}}" userInput="disabled" stepKey="grabUPSPickupDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSPickupDisabled" stepKey="assertUPSPickupDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSMinPackageWeight}}" userInput="disabled" stepKey="grabUPSMinPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSMinPackageWeightDisabled" stepKey="assertUPSMinPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSHandlingType}}" userInput="disabled" stepKey="grabUPSHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingTypeDisabled" stepKey="assertUPSHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSHandlingAction}}" userInput="disabled" stepKey="grabUPSHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSHandlingActionDisabled" stepKey="assertUPSHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSAllowedMethods}}" userInput="disabled" stepKey="grabUPSAllowedMethodsDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowedMethodsDisabled" stepKey="assertUPSAllowedMethodsDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSFreeMethod}}" userInput="disabled" stepKey="grabUPSFreeMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSFreeMethodDisabled" stepKey="assertUPSFreeMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUPSSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificErrMsgDisabled" stepKey="assertUPSSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSAllowSpecific}}" userInput="disabled" stepKey="grabUPSAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSAllowSpecificDisabled" stepKey="assertUPSAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSSpecificCountry}}" userInput="disabled" stepKey="grabUPSSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUPSSpecificCountryDisabled" stepKey="assertUPSSpecificCountryDisabled"/> + </test> +</tests> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml b/app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml similarity index 100% rename from app/code/Magento/Shipping/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml rename to app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml diff --git a/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml new file mode 100644 index 000000000000..003ccb8c3ef8 --- /dev/null +++ b/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckInputFieldsDisabledAfterAppConfigDumpTest"> + <!--Assert configuration are disabled in USPS section--> + <comment userInput="Assert configuration are disabled in USPS section" stepKey="commentSeeDisabledUSPSConfigs"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <conditionalClick selector="{{AdminShippingMethodUSPSSection.carriersUSPSTab}}" dependentSelector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" visible="false" stepKey="expandUSPSTab"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" userInput="disabled" stepKey="grabUSPSActiveDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSActiveDisabled" stepKey="assertUSPSActiveDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUSPSGatewayXMLUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewayXMLUrlDisabled" stepKey="assertUSPSGatewayXMLUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewaySecureUrl}}" userInput="disabled" stepKey="grabUSPSGatewaySecureUrlDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSGatewaySecureUrlDisabled" stepKey="assertUSPSGatewaySecureUrlDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSTitle}}" userInput="disabled" stepKey="grabUSPSTitleDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSTitleDisabled" stepKey="assertUSPSTitleDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSUserId}}" userInput="disabled" stepKey="grabUSPSUserIdDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSUserIdDisabled" stepKey="assertUSPSUserIdDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSPassword}}" userInput="disabled" stepKey="grabUSPSPasswordDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSPasswordDisabled" stepKey="assertUSPSPasswordDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSShipmentRequestType}}" userInput="disabled" stepKey="grabUSPSShipmentRequestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSShipmentRequestTypeDisabled" stepKey="assertUSPSShipmentRequestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSContainer}}" userInput="disabled" stepKey="grabUSPSContainerDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSContainerDisabled" stepKey="assertUSPSContainerDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSize}}" userInput="disabled" stepKey="grabUSPSSizeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSizeDisabled" stepKey="assertUSPSSizeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSDestType}}" userInput="disabled" stepKey="grabUSPSDestTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSDestTypeDisabled" stepKey="assertUSPSDestTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMachinable}}" userInput="disabled" stepKey="grabUSPSMachinableDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSMachinableDisabled" stepKey="assertUSPSMachinableDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSMaxPackageWeight}}" userInput="disabled" stepKey="grabUSPSMaxPackageWeightDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSMaxPackageWeightDisabled" stepKey="assertUSPSMaxPackageWeightDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingType}}" userInput="disabled" stepKey="grabUSPSHandlingTypeDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingTypeDisabled" stepKey="assertUSPSHandlingTypeDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSHandlingAction}}" userInput="disabled" stepKey="grabUSPSHandlingActionDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSHandlingActionDisabled" stepKey="assertUSPSHandlingActionDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowedMethods}}" userInput="disabled" stepKey="grabUSPSAllowedMethodsDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowedMethodsDisabled" stepKey="assertUSPSAllowedMethodsDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSFreeMethod}}" userInput="disabled" stepKey="grabUSPSFreeMethodDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSFreeMethodDisabled" stepKey="assertUSPSFreeMethodDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificErrMsg}}" userInput="disabled" stepKey="grabUSPSSpecificErrMsgDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificErrMsgDisabled" stepKey="assertUSPSSpecificErrMsgDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSAllowSpecific}}" userInput="disabled" stepKey="grabUSPSAllowSpecificDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSAllowSpecificDisabled" stepKey="assertUSPSAllowSpecificDisabled"/> + <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSSpecificCountry}}" userInput="disabled" stepKey="grabUSPSSpecificCountryDisabled"/> + <assertEquals expected='true' expectedType="string" actual="$grabUSPSSpecificCountryDisabled" stepKey="assertUSPSSpecificCountryDisabled"/> + </test> +</tests> From ddcbb93cf8b897891f543a72ec709d34c2893df4 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 6 Sep 2019 09:41:10 -0500 Subject: [PATCH 0422/1172] MC-19247: Broken translations with advanced bundling - Fix embedded translation strategy; --- .../Magento/Translation/Model/FileManager.php | 20 ----------------- .../Translation/ViewModel/Dictionary.php | 22 +++++++++---------- .../view/base/templates/dictionary.phtml | 11 ++++++++++ .../view/base/templates/translate.phtml | 2 ++ 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/app/code/Magento/Translation/Model/FileManager.php b/app/code/Magento/Translation/Model/FileManager.php index 43bd357c5069..387173f6de0b 100644 --- a/app/code/Magento/Translation/Model/FileManager.php +++ b/app/code/Magento/Translation/Model/FileManager.php @@ -8,8 +8,6 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\App\ObjectManager; use Magento\Translation\Model\Inline\File as TranslationFile; -use Magento\Framework\View\Asset\File\FallbackContext as FileFallbackContext; -use Magento\Framework\View\Asset\File; /** * A service for handling Translation config files @@ -41,11 +39,6 @@ class FileManager */ private $translationFile; - /** - * @var FileFallbackContext - */ - private $staticContext; - /** * @param \Magento\Framework\View\Asset\Repository $assetRepo * @param \Magento\Framework\App\Filesystem\DirectoryList $directoryList @@ -62,7 +55,6 @@ public function __construct( $this->directoryList = $directoryList; $this->driverFile = $driverFile; $this->translationFile = $translationFile ?: ObjectManager::getInstance()->get(TranslationFile::class); - $this->staticContext = $assetRepo->getStaticViewFileContext(); } /** @@ -145,16 +137,4 @@ public function getTranslationFileVersion() return sha1($translationFileHash . $this->getTranslationFilePath()); } - - /** - * Create a view asset for translate dictionary config. - * - * @param string $fileName - * @return File - */ - public function createTranslateDictionaryConfigAsset(string $fileName): File - { - $relPath = $this->staticContext->getConfigPath() . '/' . $fileName; - return $this->assetRepo->createArbitrary($relPath, ''); - } } diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index c7bb972980e3..ced632fd7e6b 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -6,8 +6,8 @@ namespace Magento\Translation\ViewModel; +use Magento\Framework\View\Asset\Repository as AssetRepository; use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Translation\Model\FileManager; use Magento\Translation\Model\Js\Config as JsConfig; /** @@ -16,24 +16,24 @@ class Dictionary implements ArgumentInterface { /** - * @var FileManager + * @var JsConfig */ - private $fileManager; + private $config; /** - * @var JsConfig + * @var AssetRepository */ - private $config; + private $assetRepo; /** - * @param FileManager $fileManager + * @param AssetRepository $assetRepo * @param JsConfig $config */ public function __construct( - FileManager $fileManager, + AssetRepository $assetRepo, JsConfig $config ) { - $this->fileManager = $fileManager; + $this->assetRepo = $assetRepo; $this->config = $config; } @@ -44,13 +44,11 @@ public function __construct( */ public function getTranslationDictionaryFile(): string { - $translateDictionaryConfig = $this->fileManager->createTranslateDictionaryConfigAsset(JsConfig::DICTIONARY_FILE_NAME); - - return $translateDictionaryConfig->getUrl(); + return $this->assetRepo->getUrl(JsConfig::DICTIONARY_FILE_NAME); } /** - * Is js translation set to dictionary mode + * Is js translation set to dictionary mode. * * @return bool */ diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index f8d30149cf4f..87318ef43741 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -18,4 +18,15 @@ $viewModel = $block->getData('dictionary_view_model'); } }); </script> +<?php else: ?> +<!--work-around for embedded translation strategy--> + <script> + require.config({ + map: { + '*': { + 'dictionary': 'https://mage21.test/static/frontend/Magento/luma/en_US/js-translation.json' + } + } + }); + </script> <?php endif; ?> diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index 445c3e88830a..c4592e02eff8 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -6,6 +6,8 @@ /** @var \Magento\Translation\Block\Js $block */ ?> +<!--Now dictionary file is inserted into html head in Magento/Translation/view/base/templates/dictionary.phtml--> +<!--So now this script is redundant--> <?php if ($block->dictionaryEnabled()) : ?> <script> require.config({ From 79cb787f04fa7c27b036b0a6c54b2f99e9adcabd Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Wed, 4 Sep 2019 17:49:37 -0500 Subject: [PATCH 0423/1172] MC-19398: Changing Attribute Set while editing disabled Product makes it enabled - Fixing static issues and Unit tests --- .../Product/Form/Modifier/GeneralTest.php | 75 ++++++++++++++++--- .../Product/Form/Modifier/General.php | 57 +++++++------- 2 files changed, 94 insertions(+), 38 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php index a9d717db7b7f..16e3aa08c993 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php @@ -33,7 +33,7 @@ protected function setUp() parent::setUp(); $this->attributeRepositoryMock = $this->getMockBuilder(AttributeRepositoryInterface::class) - ->getMockForAbstractClass(); + ->getMockForAbstractClass(); $arrayManager = $this->objectManager->getObject(ArrayManager::class); @@ -52,10 +52,13 @@ protected function setUp() */ protected function createModel() { - return $this->objectManager->getObject(General::class, [ + return $this->objectManager->getObject( + General::class, + [ 'locator' => $this->locatorMock, 'arrayManager' => $this->arrayManagerMock, - ]); + ] + ); } public function testModifyMeta() @@ -63,8 +66,10 @@ public function testModifyMeta() $this->arrayManagerMock->expects($this->any()) ->method('merge') ->willReturnArgument(2); - $this->assertNotEmpty($this->getModel()->modifyMeta([ - 'first_panel_code' => [ + $this->assertNotEmpty( + $this->getModel()->modifyMeta( + [ + 'first_panel_code' => [ 'arguments' => [ 'data' => [ 'config' => [ @@ -72,15 +77,17 @@ public function testModifyMeta() ] ], ] - ] - ])); + ] + ] + ) + ); } /** - * @param array $data - * @param int $defaultStatusValue - * @param array $expectedResult - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @param array $data + * @param int $defaultStatusValue + * @param array $expectedResult + * @throws \Magento\Framework\Exception\NoSuchEntityException * @dataProvider modifyDataDataProvider */ public function testModifyDataNewProduct(array $data, int $defaultStatusValue, array $expectedResult) @@ -100,6 +107,52 @@ public function testModifyDataNewProduct(array $data, int $defaultStatusValue, a $this->assertSame($expectedResult, $this->generalModifier->modifyData($data)); } + /** + * Verify the product attribute status set owhen editing existing product + * + * @throws \Magento\Framework\Exception\NoSuchEntityException + */ + public function testModifyDataExistingProduct() + { + $data = []; + $modelId = 1; + $defaultStatusValue = 1; + $expectedResult = [ + 'enabledProductStatus' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 1, + ], + ], + 'disabledProductStatus' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 2, + ], + ], + ]; + $enabledProductStatus = 1; + $disabledProductStatus = 2; + $attributeMock = $this->getMockBuilder(AttributeInterface::class) + ->getMockForAbstractClass(); + $attributeMock + ->method('getDefaultValue') + ->willReturn($defaultStatusValue); + $this->attributeRepositoryMock + ->method('get') + ->with( + ProductAttributeInterface::ENTITY_TYPE_CODE, + ProductAttributeInterface::CODE_STATUS + ) + ->willReturn($attributeMock); + $this->productMock->expects($this->any()) + ->method('getId') + ->willReturn($modelId); + $this->productMock->expects($this->any()) + ->method('getStatus') + ->willReturnOnConsecutiveCalls($enabledProductStatus, $disabledProductStatus); + $this->assertSame($expectedResult['enabledProductStatus'], current($this->generalModifier->modifyData($data))); + $this->assertSame($expectedResult['disabledProductStatus'], current($this->generalModifier->modifyData($data))); + } + /** * @return array */ diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index 91c74a2da504..f4046b4a600d 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -21,13 +21,13 @@ class General extends AbstractModifier { /** - * @var LocatorInterface + * @var LocatorInterface * @since 101.0.0 */ protected $locator; /** - * @var ArrayManager + * @var ArrayManager * @since 101.0.0 */ protected $arrayManager; @@ -43,8 +43,8 @@ class General extends AbstractModifier private $attributeRepository; /** - * @param LocatorInterface $locator - * @param ArrayManager $arrayManager + * @param LocatorInterface $locator + * @param ArrayManager $arrayManager * @param AttributeRepositoryInterface|null $attributeRepository */ public function __construct( @@ -61,10 +61,10 @@ public function __construct( /** * Customize number fields for advanced price and weight fields. * - * @param array $data + * @param array $data * @return array * @throws \Magento\Framework\Exception\NoSuchEntityException - * @since 101.0.0 + * @since 101.0.0 */ public function modifyData(array $data) { @@ -72,7 +72,10 @@ public function modifyData(array $data) $data = $this->customizeAdvancedPriceFormat($data); $modelId = $this->locator->getProduct()->getId(); - if (!isset($data[$modelId][static::DATA_SOURCE_DEFAULT][ProductAttributeInterface::CODE_STATUS])) { + $productStatus = $this->locator->getProduct()->getStatus(); + if ((isset($productStatus) && !empty($productStatus)) && (isset($modelId)) && !empty($modelId)) { + $data[$modelId][static::DATA_SOURCE_DEFAULT][ProductAttributeInterface::CODE_STATUS] = $productStatus; + } elseif (!isset($data[$modelId][static::DATA_SOURCE_DEFAULT][ProductAttributeInterface::CODE_STATUS])) { $attributeStatus = $this->attributeRepository->get( ProductAttributeInterface::ENTITY_TYPE_CODE, ProductAttributeInterface::CODE_STATUS @@ -87,9 +90,9 @@ public function modifyData(array $data) /** * Customizing weight fields * - * @param array $data + * @param array $data * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeWeightFormat(array $data) { @@ -112,9 +115,9 @@ protected function customizeWeightFormat(array $data) /** * Customizing number fields for advanced price * - * @param array $data + * @param array $data * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeAdvancedPriceFormat(array $data) { @@ -136,9 +139,9 @@ protected function customizeAdvancedPriceFormat(array $data) /** * Customize product form fields. * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ public function modifyMeta(array $meta) { @@ -154,9 +157,9 @@ public function modifyMeta(array $meta) /** * Disable collapsible and set empty label * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function prepareFirstPanel(array $meta) { @@ -177,9 +180,9 @@ protected function prepareFirstPanel(array $meta) /** * Customize Status field * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeStatusField(array $meta) { @@ -203,9 +206,9 @@ protected function customizeStatusField(array $meta) /** * Customize Weight filed * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeWeightField(array $meta) { @@ -277,9 +280,9 @@ protected function customizeWeightField(array $meta) /** * Customize "Set Product as New" date fields * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeNewDateRangeField(array $meta) { @@ -335,9 +338,9 @@ protected function customizeNewDateRangeField(array $meta) /** * Add links for fields depends of product name * - * @param array $meta + * @param array $meta * @return array - * @since 101.0.0 + * @since 101.0.0 */ protected function customizeNameListeners(array $meta) { @@ -409,9 +412,9 @@ private function getLocaleCurrency() /** * Format price according to the locale of the currency * - * @param mixed $value + * @param mixed $value * @return string - * @since 101.0.0 + * @since 101.0.0 */ protected function formatPrice($value) { @@ -429,9 +432,9 @@ protected function formatPrice($value) /** * Format number according to the locale of the currency and precision of input * - * @param mixed $value + * @param mixed $value * @return string - * @since 101.0.0 + * @since 101.0.0 */ protected function formatNumber($value) { From c5319ae90944006fe86be53fac1a5fc3b87e60a8 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Wed, 4 Sep 2019 17:49:37 -0500 Subject: [PATCH 0424/1172] MC-19398: Changing Attribute Set while editing disabled Product makes it enabled - Fixing unit tests --- .../DisableProductLabelActionGroup.xml | 27 +++++ ...sableProductOnChangingAttributeSetTest.xml | 49 +++++++++ .../Product/Form/Modifier/GeneralTest.php | 101 +++++++++++++----- .../Product/Form/Modifier/General.php | 2 +- 4 files changed, 150 insertions(+), 29 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/ActionGroup/DisableProductLabelActionGroup.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminDisableProductOnChangingAttributeSetTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DisableProductLabelActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DisableProductLabelActionGroup.xml new file mode 100644 index 000000000000..a416957dabc2 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/DisableProductLabelActionGroup.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="DisableProductLabelActionGroup"> + <annotations> + <description>Disable Product Label and Change Attribute Set.</description> + </annotations> + <arguments> + <argument name="createAttributeSet"/> + </arguments> + + <checkOption selector="{{AdminProductFormSection.enableProductLabel}}" stepKey="disableProduct"/> + <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickSaveButton"/> + <waitForPageLoad time="30" stepKey="waitForChangeAttrSet"/> + <click selector="{{AdminProductFormSection.attributeSet}}" stepKey="startEditAttrSet"/> + <fillField selector="{{AdminProductFormSection.attributeSetFilter}}" userInput="{{createAttributeSet.attribute_set_name}}" stepKey="searchForAttrSet"/> + <click selector="{{AdminProductFormSection.attributeSetFilterResult}}" stepKey="selectAttrSet"/> + <dontSeeCheckboxIsChecked selector="{{AdminProductFormSection.productStatus}}" stepKey="dontSeeCheckboxEnableProductIsChecked"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDisableProductOnChangingAttributeSetTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDisableProductOnChangingAttributeSetTest.xml new file mode 100644 index 000000000000..dab1704d50bf --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDisableProductOnChangingAttributeSetTest.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminDisableProductOnChangingAttributeSetTest"> + <annotations> + <features value="Catalog"/> + <stories value="Disabled product is enabled when change attribute set"/> + <title value="Verify product status while changing attribute set"/> + <description value="Value set for enabled product has to be shown when attribute set is changed"/> + <severity value="MAJOR"/> + <testCaseId value="MC-19716"/> + <group value="catalog"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="CatalogAttributeSet" stepKey="createAttributeSet"/> + </before> + <after> + <deleteData createDataKey="createAttributeSet" stepKey="deleteAttributeSet"/> + <deleteData createDataKey="createSimpleProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="ClearProductsFilterActionGroup" stepKey="clearProductsFilter"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <amOnPage url="{{AdminProductAttributeSetEditPage.url}}/$$createAttributeSet.attribute_set_id$$/" stepKey="onAttributeSetEdit"/> + <actionGroup ref="SaveAttributeSet" stepKey="SaveAttributeSet"/> + <actionGroup ref="SearchForProductOnBackendActionGroup" stepKey="searchForSimpleProduct"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + + <actionGroup ref="OpenEditProductOnBackendActionGroup" stepKey="openEditProduct1"> + <argument name="product" value="$$createSimpleProduct$$"/> + </actionGroup> + <actionGroup ref="DisableProductLabelActionGroup" stepKey="disableWhileChangingAttributeSet" > + <argument name="createAttributeSet" value="$$createAttributeSet$$"/> + </actionGroup> + + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php index 16e3aa08c993..9d0e7fc57ffc 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/GeneralTest.php @@ -110,33 +110,26 @@ public function testModifyDataNewProduct(array $data, int $defaultStatusValue, a /** * Verify the product attribute status set owhen editing existing product * - * @throws \Magento\Framework\Exception\NoSuchEntityException + * @param array $data + * @param string $modelId + * @param int $defaultStatus + * @param int $statusAttributeValue + * @param array $expectedResult + * @throws \Magento\Framework\Exception\NoSuchEntityException + * @dataProvider modifyDataOfExistingProductDataProvider */ - public function testModifyDataExistingProduct() - { - $data = []; - $modelId = 1; - $defaultStatusValue = 1; - $expectedResult = [ - 'enabledProductStatus' => [ - General::DATA_SOURCE_DEFAULT => [ - ProductAttributeInterface::CODE_STATUS => 1, - ], - ], - 'disabledProductStatus' => [ - General::DATA_SOURCE_DEFAULT => [ - ProductAttributeInterface::CODE_STATUS => 2, - ], - ], - ]; - $enabledProductStatus = 1; - $disabledProductStatus = 2; - $attributeMock = $this->getMockBuilder(AttributeInterface::class) - ->getMockForAbstractClass(); - $attributeMock + public function testModifyDataOfExistingProduct( + array $data, + string $modelId, + int $defaultStatus, + int $statusAttributeValue, + array $expectedResult + ) { + $attributeMock = $this->getMockForAbstractClass(AttributeInterface::class); + $attributeMock->expects($this->any()) ->method('getDefaultValue') - ->willReturn($defaultStatusValue); - $this->attributeRepositoryMock + ->willReturn($defaultStatus); + $this->attributeRepositoryMock->expects($this->any()) ->method('get') ->with( ProductAttributeInterface::ENTITY_TYPE_CODE, @@ -148,9 +141,61 @@ public function testModifyDataExistingProduct() ->willReturn($modelId); $this->productMock->expects($this->any()) ->method('getStatus') - ->willReturnOnConsecutiveCalls($enabledProductStatus, $disabledProductStatus); - $this->assertSame($expectedResult['enabledProductStatus'], current($this->generalModifier->modifyData($data))); - $this->assertSame($expectedResult['disabledProductStatus'], current($this->generalModifier->modifyData($data))); + ->willReturn($statusAttributeValue); + $this->assertSame($expectedResult, current($this->generalModifier->modifyData($data))); + } + + /** + * @return array + */ + public function modifyDataOfExistingProductDataProvider(): array + { + return [ + 'With enable status value' => [ + 'data' => [], + 'modelId' => '1', + 'defaultStatus' => 1, + 'statusAttributeValue' => 1, + 'expectedResult' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 1, + ], + ], + ], + 'Without disable status value' => [ + 'data' => [], + 'modelId' => '1', + 'defaultStatus' => 1, + 'statusAttributeValue' => 2, + 'expectedResult' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 2, + ], + ], + ], + 'With enable status value with empty modelId' => [ + 'data' => [], + 'modelId' => '', + 'defaultStatus' => 1, + 'statusAttributeValue' => 1, + 'expectedResult' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 1, + ], + ], + ], + 'Without disable status value with empty modelId' => [ + 'data' => [], + 'modelId' => '', + 'defaultStatus' => 2, + 'statusAttributeValue' => 2, + 'expectedResult' => [ + General::DATA_SOURCE_DEFAULT => [ + ProductAttributeInterface::CODE_STATUS => 2, + ], + ], + ], + ]; } /** diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php index f4046b4a600d..7c42b881bad3 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/General.php @@ -73,7 +73,7 @@ public function modifyData(array $data) $modelId = $this->locator->getProduct()->getId(); $productStatus = $this->locator->getProduct()->getStatus(); - if ((isset($productStatus) && !empty($productStatus)) && (isset($modelId)) && !empty($modelId)) { + if (!empty($productStatus) && !empty($modelId)) { $data[$modelId][static::DATA_SOURCE_DEFAULT][ProductAttributeInterface::CODE_STATUS] = $productStatus; } elseif (!isset($data[$modelId][static::DATA_SOURCE_DEFAULT][ProductAttributeInterface::CODE_STATUS])) { $attributeStatus = $this->attributeRepository->get( From 529e19d3e5a25c28acfd5f37799cc9558617e624 Mon Sep 17 00:00:00 2001 From: "vishalverma.magento279" <vishalverma.magento279@webkul.com> Date: Sat, 7 Sep 2019 16:08:28 +0530 Subject: [PATCH 0425/1172] #14012 fixed --- .../Sales/Controller/Adminhtml/Order/Invoice/Save.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php index 67a0dc469163..b4fa6fed6cdf 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php @@ -89,13 +89,18 @@ public function __construct( protected function _prepareShipment($invoice) { $invoiceData = $this->getRequest()->getParam('invoice'); - + $itemArr = []; + if (!isset($invoiceData['items']) || empty($invoiceData['items'])) { + $orderItems = $invoice->getOrder()->getItems(); + foreach ($orderItems as $item) { + $itemArr[$item->getId()] = (int)$item->getQtyOrdered(); + } + } $shipment = $this->shipmentFactory->create( $invoice->getOrder(), - isset($invoiceData['items']) ? $invoiceData['items'] : [], + isset($invoiceData['items']) ? $invoiceData['items'] : $itemArr, $this->getRequest()->getPost('tracking') ); - if (!$shipment->getTotalQty()) { return false; } From 192971767b5a3e22af4299d7381e668a69d72bab Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 9 Sep 2019 11:45:33 +0400 Subject: [PATCH 0426/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Delete automation test for MC-11701 --- .../AdminForgotPasswordFormSection.xml | 2 - ...gRefreshCaptchaImageProductionModeTest.xml | 57 ------------------- 2 files changed, 59 deletions(-) delete mode 100644 app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml index fae3b768d445..efaca2212335 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminForgotPasswordFormSection.xml @@ -11,7 +11,5 @@ <section name="AdminForgotPasswordFormSection"> <element name="email" type="input" selector="#login-form input[name='email']"/> <element name="retrievePasswordButton" type="button" selector="#login-form button[type='submit']" timeout="30"/> - <element name="captchaImage" type="file" selector="#backend_forgotpassword"/> - <element name="captchaReload" type="button" selector="#captcha-reload"/> </section> </sections> diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml deleted file mode 100644 index e2c4e929741b..000000000000 --- a/app/code/Magento/Captcha/Test/Mftf/Test/AdminCheckingRefreshCaptchaImageProductionModeTest.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminCheckingRefreshCaptchaImageProductionModeTest"> - <annotations> - <features value="Captcha"/> - <stories value="Cannot refresh Captcha image in production mode"/> - <title value="Checking refresh Captcha image in production mode"/> - <description value="Checking refresh Captcha image in production mode"/> - <severity value="MAJOR"/> - <testCaseId value="MC-11701"/> - <useCaseId value="MAGETWO-96404"/> - <group value="captcha"/> - </annotations> - <before> - <!--Enable JavaScript setting--> - <comment userInput="Enable JavaScript setting" stepKey="commentEnableJSSettings"/> - <magentoCLI command="config:set dev/js/enable_js_bundling 1" stepKey="enableJSBundling"/> - <magentoCLI command="config:set dev/js/minify_files 1" stepKey="enableMinifyJSFiles"/> - <!--Enable admin captcha--> - <comment userInput="Enable admin captcha" stepKey="commentEnableAdminCaptcha"/> - <magentoCLI command="config:set admin/captcha/enable 1" stepKey="enableAdminCaptcha"/> - <!--Clean cache--> - <comment userInput="Clean cache" stepKey="commentCleanCache"/> - <magentoCLI command="cache:clean" stepKey="cleanCaches"/> - </before> - <after> - <!--Disable JavaScript setting--> - <comment userInput="Disable JavaScript setting" stepKey="commentDisableJSSettings"/> - <magentoCLI command="config:set dev/js/enable_js_bundling 0" stepKey="disableJSBundling"/> - <magentoCLI command="config:set dev/js/minify_files 0" stepKey="disableMinifyJSFiles"/> - </after> - <!--Go to forgot password--> - <comment userInput="Go to forgot password" stepKey="commentGoToForgotPassword"/> - <amOnPage url="{{AdminForgotPasswordPage.url}}" stepKey="navigateToForgotPasswordPagePage"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageBeforeRefresh"/> - <click selector="{{AdminForgotPasswordFormSection.captchaReload}}" stepKey="reloadCaptcha"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> - <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageAfterRefresh"/> - <assertNotEquals expected="$grabCaptchaImageBeforeRefresh" expectedType="variable" actual="$grabCaptchaImageAfterRefresh" actualType="variable" stepKey="assertCaptchaImagesNotEquals"/> - <amOnPage url="{{AdminForgotPasswordPage.url}}" stepKey="navigateToForgotPasswordPagePageProdMode"/> - <waitForPageLoad stepKey="waitForPageLoadProdMode"/> - <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageBeforeRefreshProdMode"/> - <click selector="{{AdminForgotPasswordFormSection.captchaReload}}" stepKey="reloadCaptchaProdMode"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskProdMode"/> - <grabAttributeFrom selector="{{AdminForgotPasswordFormSection.captchaImage}}" userInput="src" stepKey="grabCaptchaImageAfterRefreshProdMode"/> - <assertNotEquals expected="$grabCaptchaImageBeforeRefreshProdMode" expectedType="variable" actual="$grabCaptchaImageAfterRefreshProdMode" actualType="variable" stepKey="assertCaptchaImagesNotEqualsProdMode"/> - </test> -</tests> From 30d8cac72b4e2b64e2f8c8f20bf1d4e646167284 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 23 Aug 2019 15:49:14 +0300 Subject: [PATCH 0427/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6405 --- .../Customer/Test/Mftf/Data/AddressData.xml | 18 +++++ .../Customer/Test/Mftf/Data/CustomerData.xml | 13 ++++ .../Customer/Test/Mftf/Data/RegionData.xml | 5 ++ .../StorefrontShipmentActionGroup.xml | 18 +++++ ...splayTableRatesShippingMethodForAETest.xml | 76 +++++++++++++++++++ .../acceptance/tests/_data/tablerates.csv | 21 +++++ 6 files changed, 151 insertions(+) create mode 100644 app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml create mode 100644 dev/tests/acceptance/tests/_data/tablerates.csv diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 4d7a39b3246e..756574b76d4e 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -312,4 +312,22 @@ <data key="postcode">90230</data> <data key="telephone">555-55-555-55</data> </entity> + <entity name="US_Address_AFE" type="address"> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="company">Magento</data> + <array key="street"> + <item>7700 West Parmer Lane</item> + <item>113</item> + </array> + <data key="city">Los Angeles</data> + <data key="state">Armed Forces Europe</data> + <data key="country_id">US</data> + <data key="country">United States</data> + <data key="postcode">90001</data> + <data key="telephone">512-345-6789</data> + <data key="default_billing">Yes</data> + <data key="default_shipping">Yes</data> + <requiredEntity type="region">RegionAFE</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index c7a73b61dc48..f10732c55903 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -309,4 +309,17 @@ <data key="store_id">0</data> <data key="website_id">0</data> </entity> + <entity name="Simple_US_Customer_ArmedForcesEurope" type="customer"> + <data key="group_id">0</data> + <data key="default_billing">true</data> + <data key="default_shipping">true</data> + <data key="email" unique="prefix">John.Doe@example.com</data> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="fullname">John Doe</data> + <data key="password">pwdTest123!</data> + <data key="store_id">0</data> + <data key="website_id">0</data> + <requiredEntity type="address">US_Address_AFE</requiredEntity> + </entity> </entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml b/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml index 280bae7de411..1e6589057fa7 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml @@ -32,4 +32,9 @@ <data key="region_code">UT</data> <data key="region_id">58</data> </entity> + <entity name="RegionAFE" type="region"> + <data key="region">Armed Forces Europe</data> + <data key="region_code">AFE</data> + <data key="region_id">9</data> + </entity> </entities> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml new file mode 100644 index 000000000000..6e75ed921717 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="SetShippingMethodActionGroup"> + <arguments> + <argument name="shippingMethodName" type="string" defaultValue="Flat Rate"/> + </arguments> + <checkOption selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName(shippingMethodName)}}" stepKey="selectFlatRateShippingMethod"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskForNextButton"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml new file mode 100644 index 000000000000..5b6bcd1ebcd9 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontDisplayTableRatesShippingMethodForAETest"> + <annotations> + <features value="Shipping"/> + <stories value="Table Rates"/> + <title value="Displaying of Table Rates for Armed Forces Europe (AE)"/> + <description value="Displaying of Table Rates for Armed Forces Europe (AE)"/> + <severity value="MAJOR"/> + <testCaseId value="MC-6405"/> + <group value="shipping"/> + </annotations> + <before> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer_ArmedForcesEurope" stepKey="createCustomer"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <comment userInput="Rollback config" stepKey="rollbackConfigComment"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodSystemConfigPage"/> + <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="AdminSwitchStoreViewToMainWebsite"> + <argument name="website" value="_defaultWebsite"/> + </actionGroup> + <actionGroup ref="AdminChangeTableRatesShippingMethodStatusActionGroup" stepKey="disableTableRatesShippingMethod"> + <argument name="status" value="0"/> + </actionGroup> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveSystemConfig"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <comment userInput="Admin Configuration: enable Table Rates and import CSV file with the rates" stepKey="prepareAdminConfigurationComment"/> + <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> + <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="AdminSwitchStoreView"> + <argument name="website" value="_defaultWebsite"/> + </actionGroup> + <actionGroup ref="AdminChangeTableRatesShippingMethodStatusActionGroup" stepKey="enableTableRatesShippingMethod"/> + <attachFile selector="{{AdminShippingMethodTableRatesSection.importFile}}" userInput="tablerates.csv" stepKey="attachFileForImport"/> + <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> + <comment userInput="Login as created customer" stepKey="loginAsCustomerComment"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + <comment userInput="Add the created product to the shopping cart" stepKey="addProductToCartComment"/> + <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + </actionGroup> + <comment userInput="Proceed to Checkout from the mini cart" stepKey="proceedToCheckoutComment"/> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> + <comment userInput="Shipping Method: select table rate" stepKey="assertShippingMethodComment"/> + <actionGroup ref="AssertStoreFrontShippingMethodAvailableActionGroup" stepKey="assertShippingMethodAvailable"> + <argument name="shippingMethodName" value="Best Way"/> + </actionGroup> + <actionGroup ref="SetShippingMethodActionGroup" stepKey="setShippingMethodTableRate"> + <argument name="shippingMethodName" value="Best Way"/> + </actionGroup> + <comment userInput="Proceed to Review and Payments section" stepKey="proceedToReviewAndPaymentsComment"/> + <click selector="{{CheckoutShippingSection.next}}" stepKey="clickToSaveShippingInfo"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> + <waitForPageLoad stepKey="waitForReviewAndPaymentsPageIsLoaded"/> + <comment userInput="Place order and assert the message of success" stepKey="placeOrderComment"/> + <actionGroup ref="ClickPlaceOrderActionGroup" stepKey="clickOnPlaceOrder"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/_data/tablerates.csv b/dev/tests/acceptance/tests/_data/tablerates.csv new file mode 100644 index 000000000000..ddc591798e3c --- /dev/null +++ b/dev/tests/acceptance/tests/_data/tablerates.csv @@ -0,0 +1,21 @@ +Country,Region/State,Zip/Postal Code,Weight (and above),Shipping Price +ASM,*,*,0,9.95 +FSM,*,*,0,9.95 +GUM,*,*,0,9.95 +MHL,*,*,0,9.95 +MNP,*,*,0,9.95 +PLW,*,*,0,9.95 +USA,AA,*,0,9.95 +USA,AE,*,0,9.95 +USA,AK,*,0,9.95 +USA,AP,*,0,9.95 +USA,AS,*,0,9.95 +USA,FM,*,0,9.95 +USA,GU,*,0,9.95 +USA,HI,*,0,9.95 +USA,MH,*,0,9.95 +USA,MP,*,0,9.95 +USA,PR,*,0,9.95 +USA,PW,*,0,9.95 +USA,VI,*,0,9.95 +VIR,*,*,0,9.95 \ No newline at end of file From 91fed7b987878c3a79c43d3d3e597a62c4a6bc3e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 9 Sep 2019 14:33:39 +0300 Subject: [PATCH 0428/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup - Fix static tests. --- .../Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml | 2 ++ .../Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml index 79bccbe705dc..f350865fbf3d 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml @@ -19,8 +19,10 @@ <waitForPageLoad stepKey="waitForPageLoad"/> <attachFile selector="{{BlockSelectImageSection.uploadFile}}" userInput="{{image.file}}" stepKey="attachLogo"/> <waitForElementVisible selector="{{BlockSelectImageSection.addSelected}}" stepKey="waitForAddSelected"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear2"/> <click selector="{{BlockSelectImageSection.addSelected}}" stepKey="clickAddSelected"/> <waitForElementVisible selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="waitForOkButton"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> <click selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="clickOk"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml index eac67ec9395b..e7ad1b617ec4 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml @@ -41,6 +41,6 @@ <section name="BlockSelectImageSection"> <element name="uploadFile" type="input" selector="input.fileupload"/> <element name="addSelected" type="button" selector="#insert_files"/> - <element name="treeRoot" type="text" selector="//div[contains(@class, 'jstree')]//a[contains(text(), 'Storage Root')]"/> + <element name="treeRoot" type="text" selector="#root"/> </section> </sections> From 2bdab9af3c6bf0c7df63fb148ce1d396e97ab322 Mon Sep 17 00:00:00 2001 From: Krissy Hiserote <khiserote@magento.com> Date: Mon, 9 Sep 2019 11:56:03 -0500 Subject: [PATCH 0429/1172] MC-18532: Update Changelog based on delivered scope - remove reverts and fix minor issues --- CHANGELOG.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e445b043bf..59adb577b0cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * [#22527](https://github.com/magento/magento2/issues/22527) -- Wishlist and compare icon align issue in product listing page (fixed in [magento/magento2#22532](https://github.com/magento/magento2/pull/22532)) * [#628](https://github.com/magento/magento2/issues/628) -- Feature Request: Parent entities links in child entities grid. (fixed in [magento/graphql-ce#636](https://github.com/magento/graphql-ce/pull/636)) * [#640](https://github.com/magento/magento2/issues/640) -- [Insight] Files should not be executable (fixed in [magento/graphql-ce#648](https://github.com/magento/graphql-ce/pull/648)) - * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though 'I've read OSL licence' is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) + * [#603](https://github.com/magento/magento2/issues/603) -- 'Continue' button is disabled even though "I've read OSL licence" is checked (fixed in [magento/graphql-ce#653](https://github.com/magento/graphql-ce/pull/653)) * [#22406](https://github.com/magento/magento2/issues/22406) -- Store view specific labels cut in left navigation menu (fixed in [magento/magento2#22423](https://github.com/magento/magento2/pull/22423)) * [#19515](https://github.com/magento/magento2/issues/19515) -- Create new order from backend saves the credit card when it is told not to (fixed in [magento/magento2#19767](https://github.com/magento/magento2/pull/19767)) * [#21473](https://github.com/magento/magento2/issues/21473) -- Form element validation is not triggered when validation rules change (fixed in [magento/magento2#21992](https://github.com/magento/magento2/pull/21992)) @@ -93,7 +93,7 @@ * [#22004](https://github.com/magento/magento2/issues/22004) -- ce231 - can't update attribute for all product (fixed in [magento/magento2#22704](https://github.com/magento/magento2/pull/22704)) * [#22870](https://github.com/magento/magento2/issues/22870) -- ProductRepository fails to update an existing product with a changed SKU (fixed in [magento/magento2#22933](https://github.com/magento/magento2/pull/22933)) * [#22808](https://github.com/magento/magento2/issues/22808) -- php bin/magento catalog:image:resize error if image is missing (fixed in [magento/magento2#23005](https://github.com/magento/magento2/pull/23005)) - * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) + * [#674](https://github.com/magento/magento2/issues/674) -- Widgets in content pages. (fixed in [magento/graphql-ce#709](https://github.com/magento/graphql-ce/pull/709)) * [#683](https://github.com/magento/magento2/issues/683) -- CMS Router not routing correctly (fixed in [magento/graphql-ce#717](https://github.com/magento/graphql-ce/pull/717)) * [#9113](https://github.com/magento/magento2/issues/9113) -- [Bug or Feature?] url_path attribute value is not populated for any product (fixed in [magento/graphql-ce#721](https://github.com/magento/graphql-ce/pull/721)) * [#18337](https://github.com/magento/magento2/issues/18337) -- #search input is missing required attribute aria-expanded. (fixed in [magento/magento2#22942](https://github.com/magento/magento2/pull/22942)) @@ -137,8 +137,6 @@ * [#16234](https://github.com/magento/magento2/issues/16234) -- Unable to enter `+` character in widget content (fixed in [magento/magento2#23496](https://github.com/magento/magento2/pull/23496)) * [#9798](https://github.com/magento/magento2/issues/9798) -- Problem adding attribute options to configurable product via REST Api (fixed in [magento/magento2#23529](https://github.com/magento/magento2/pull/23529)) * [#6287](https://github.com/magento/magento2/issues/6287) -- Customer Admin Shopping Cart View Missing (fixed in [magento/magento2#20918](https://github.com/magento/magento2/pull/20918)) - * [#8258](https://github.com/magento/magento2/issues/8258) -- M2.1.3 : Form validation with identical field names does not work as expected. (fixed in [magento/magento2#15383](https://github.com/magento/magento2/pull/15383)) - * [#13561](https://github.com/magento/magento2/issues/13561) -- Magento 2 and SSL connection to MySQL (fixed in [magento/magento2#18075](https://github.com/magento/magento2/pull/18075)) * [#22545](https://github.com/magento/magento2/issues/22545) -- Status downloadable product stays pending after succesfull payment (fixed in [magento/magento2#22658](https://github.com/magento/magento2/pull/22658)) * [#23383](https://github.com/magento/magento2/issues/23383) -- Products which are not assigned to any store are automatically being force-assigned a store ID after being saved (fixed in [magento/magento2#23500](https://github.com/magento/magento2/pull/23500)) * [#22950](https://github.com/magento/magento2/issues/22950) -- Spacing issue for Gift message section in my account (fixed in [magento/magento2#23226](https://github.com/magento/magento2/pull/23226)) @@ -181,7 +179,7 @@ * [#23916](https://github.com/magento/magento2/issues/23916) -- Missing Validation at some Payment Method Settings (fixed in [magento/magento2#23917](https://github.com/magento/magento2/pull/23917)) * [#23932](https://github.com/magento/magento2/issues/23932) -- Decimal quantity is not displayed for wishlist items. (fixed in [magento/magento2#23933](https://github.com/magento/magento2/pull/23933)) * GitHub pull requests: - * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing… (by @cedarvinda) + * [magento/magento2#20135](https://github.com/magento/magento2/pull/20135) -- issue fixed #20124 Sort By label is hidden by Shop By Menu on listing (by @cedarvinda) * [magento/magento2#22020](https://github.com/magento/magento2/pull/22020) -- Non existing file, when adding image to gallery with move option. Fix for #21978 (by @dudzio12) * [magento/magento2#22260](https://github.com/magento/magento2/pull/22260) -- Disabling "Display on Product Details Page" the button is shown anyway. (by @Nazar65) * [magento/magento2#22287](https://github.com/magento/magento2/pull/22287) -- #222249 configurable product images wrong sorting fix (by @Wirson) @@ -295,7 +293,6 @@ * [magento/magento2#21876](https://github.com/magento/magento2/pull/21876) -- $product->getUrlInStore() does not allow to override the scope in backend context (by @Nazar65) * [magento/magento2#23007](https://github.com/magento/magento2/pull/23007) -- [Fixed] Reset feature does not clear the date (by @niravkrish) * [magento/magento2#23118](https://github.com/magento/magento2/pull/23118) -- #23053 : sendfriend verifies product visibility instead of status (by @Wirson) - * [magento/magento2#18748](https://github.com/magento/magento2/pull/18748) -- Add a module manager to the Magento Framework API (by @navarr) * [magento/magento2#22637](https://github.com/magento/magento2/pull/22637) -- Fixed #22484 Customer address States are duplicated in backend (by @shikhamis11) * [magento/magento2#23140](https://github.com/magento/magento2/pull/23140) -- magento/magento2#23138: Magento_Theme. Incorrect configuration file location (by @atwixfirster) * [magento/magento2#23179](https://github.com/magento/magento2/pull/23179) -- Fix for translation function (by @kkdg) @@ -361,8 +358,6 @@ * [magento/magento2#23529](https://github.com/magento/magento2/pull/23529) -- Feature/9798 updating configurable product options based on produc id and sku (by @lpouwelse) * [magento/magento2#20918](https://github.com/magento/magento2/pull/20918) -- Enabled 'Shopping Cart' tab for customer edit interface in admin (by @rav-redchamps) * [magento/magento2#22624](https://github.com/magento/magento2/pull/22624) -- Resolve Typo (by @prashantsharmacedcoss) - * [magento/magento2#15383](https://github.com/magento/magento2/pull/15383) -- issue fixed #8258 - assign indices for all array inputs so that validation works properly (by @jayankaghosh) - * [magento/magento2#18075](https://github.com/magento/magento2/pull/18075) -- Feature/issue 13561 2.3 (by @bnymn) * [magento/magento2#22658](https://github.com/magento/magento2/pull/22658) -- Fixed #22545 Status downloadable product stays pending after succesfu... (by @shikhamis11) * [magento/magento2#23500](https://github.com/magento/magento2/pull/23500) -- Fixed issue #23383 (by @manishgoswamij) * [magento/magento2#23226](https://github.com/magento/magento2/pull/23226) -- Spacing issue for Gift message section in my account (by @amjadm61) From 3a1c9ba4b88bfc4ca921ba84e88277ae4a1e7233 Mon Sep 17 00:00:00 2001 From: Ani <ani_tumanyn@epam.com> Date: Tue, 16 Jul 2019 14:30:43 +0300 Subject: [PATCH 0430/1172] MC-17493: Cart/catalog rules grid missing - Added automated test script --- .../ActionGroup/CatalogPriceRuleActionGroup.xml | 9 ++++++++- .../AdminCreateCartPriceRuleActionGroup.xml | 17 ++++++++++++++++- .../Section/AdminCartPriceRulesFormSection.xml | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index a7500858fc94..f2ee5dc30591 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -57,7 +57,14 @@ <scrollToTopOfPage stepKey="scrollToTop"/> <waitForPageLoad stepKey="waitForApplied"/> </actionGroup> - + <actionGroup name="CreateMultipleWebsiteCatalogPriceRule" extends="createCatalogPriceRule"> + <arguments> + <argument name="customerGroup" defaultValue="General" type="string"/> + </arguments> + <remove keyForRemoval="selectSite"/> + <selectOption selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="{{customerGroup}}" after="fillDiscountValue" stepKey="selectCustomerGroupMultiple"/> + <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" after="selectCustomerGroupMultiple" stepKey="selectWebsite"/> + </actionGroup> <actionGroup name="CreateCatalogPriceRuleViaTheUi"> <arguments> <argument name="catalogRule" defaultValue="_defaultCatalogRule"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index f9bc44a11cc4..16a19de670af 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -105,7 +105,22 @@ <waitForElementVisible selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="waitForCategoryVisible" after="openChooser"/> <checkOption selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="checkCategoryName" after="waitForCategoryVisible"/> </actionGroup> - + <actionGroup name="AdminMultiWebsiteCartPriceRuleActionGroup"> + <arguments> + <argument name="ruleName"/> + </arguments> + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> + <waitForPageLoad stepKey="waitForPriceList"/> + <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> + <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ruleName.name}}" stepKey="fillRuleName"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" parameterArray="[{{ruleName.customerGroups}}]" stepKey="selectCustomerGroup"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> + <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="{{ruleName.apply}}" stepKey="selectActionType"/> + <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="{{ruleName.discountAmount}}" stepKey="fillDiscountAmount"/> + <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> + <see selector="{{AdminCartPriceRulesFormSection.successMessage}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> + </actionGroup> <actionGroup name="CreateCartPriceRuleSecondWebsiteActionGroup"> <annotations> <description>Goes to the Admin Cart Price Rule grid page. Clicks on Add New Rule. Fills the provided Rule (Name). Selects 'Second Website' from the 'Websites' menu.</description> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml index 075584386124..3849d153be46 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/AdminCartPriceRulesFormSection.xml @@ -19,6 +19,7 @@ <element name="description" type="textarea" selector="//div[@class='admin__field-control']/textarea[@name='description']"/> <element name="active" type="checkbox" selector="//div[@class='admin__actions-switch']/input[@name='is_active']/../label"/> <element name="websites" type="multiselect" selector="select[name='website_ids']"/> + <element name="websitesOptions" type="select" selector="[name='website_ids'] option"/> <element name="customerGroups" type="multiselect" selector="select[name='customer_group_ids']"/> <element name="customerGroupsOptions" type="multiselect" selector="select[name='customer_group_ids'] option"/> <element name="coupon" type="select" selector="select[name='coupon_type']"/> From fa8f5662084dedc41ff54e68b0b166c5def03935 Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Tue, 10 Sep 2019 16:38:17 +0300 Subject: [PATCH 0431/1172] [Customer] Rename dob to date_of_birth #911 --- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 6 ++++-- .../Magento/GraphQl/Customer/UpdateCustomerTest.php | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index d27debdc39c6..73d33f5bf01d 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -61,7 +61,8 @@ input CustomerInput { lastname: String @doc(description: "The customer's family name") suffix: String @doc(description: "A value such as Sr., Jr., or III") email: String @doc(description: "The customer's email address. Required") - dob: String @doc(description: "The customer's date of birth") + dob: @deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") String @doc(description: "The customer's date of birth") + date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") gender: Int @doc(description: "The customer's gender(Male - 1, Female - 2)") password: String @doc(description: "The customer's password") @@ -87,7 +88,8 @@ type Customer @doc(description: "Customer defines the customer name and address email: String @doc(description: "The customer's email address. Required") default_billing: String @doc(description: "The ID assigned to the billing address") default_shipping: String @doc(description: "The ID assigned to the shipping address") - dob: String @doc(description: "The customer's date of birth") + dob: @deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") String @doc(description: "The customer's date of birth") + date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") id: Int @doc(description: "The ID assigned to the customer") is_subscribed: Boolean @doc(description: "Indicates whether the customer is subscribed to the company's newsletter") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\IsSubscribed") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index 178d10b3c35a..d1c6638e8d5f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -69,7 +69,7 @@ public function testUpdateCustomer() middlename: "{$newMiddlename}" lastname: "{$newLastname}" suffix: "{$newSuffix}" - dob: "{$newDob}" + date_of_birth: "{$newDob}" taxvat: "{$newTaxVat}" email: "{$newEmail}" password: "{$currentPassword}" @@ -82,7 +82,7 @@ public function testUpdateCustomer() middlename lastname suffix - dob + date_of_birth taxvat email gender @@ -102,7 +102,7 @@ public function testUpdateCustomer() $this->assertEquals($newMiddlename, $response['updateCustomer']['customer']['middlename']); $this->assertEquals($newLastname, $response['updateCustomer']['customer']['lastname']); $this->assertEquals($newSuffix, $response['updateCustomer']['customer']['suffix']); - $this->assertEquals($newDob, $response['updateCustomer']['customer']['dob']); + $this->assertEquals($newDob, $response['updateCustomer']['customer']['date_of_birth']); $this->assertEquals($newTaxVat, $response['updateCustomer']['customer']['taxvat']); $this->assertEquals($newEmail, $response['updateCustomer']['customer']['email']); $this->assertEquals($newGender, $response['updateCustomer']['customer']['gender']); From 0a9727ce03f89f5f5b42405ef7d9fe7372c50776 Mon Sep 17 00:00:00 2001 From: Ani Tumanyan <ani_tumanyan@epam.com> Date: Tue, 20 Aug 2019 19:50:14 +0400 Subject: [PATCH 0432/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Updated automated test script --- .../Test/Mftf/Page/CheckoutShippingPage.xml | 1 + .../Test/Mftf/Section/CheckoutPaymentSection.xml | 1 - .../Mftf/Section/CheckoutShippingSection.xml | 2 +- ...orefrontSelectShippingAddressPopupSection.xml | 16 ++++++++++++++++ .../Section/StorefrontCheckoutAddressSection.xml | 14 ++++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml create mode 100644 app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index c8641f7d8fbf..2ff10f8423b6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -12,5 +12,6 @@ <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> <section name="StorefrontCheckoutAddressPopupSection"/> + <section name="StorefrontCheckoutAddressSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 0ebe78e44e7a..903c21d7ec0c 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -60,6 +60,5 @@ <element name="billingAddressSelectShared" type="select" selector=".checkout-billing-address select[name='billing_address_id']"/> <element name="discount" type="block" selector="tr.totals.discount"/> <element name="discountPrice" type="text" selector=".discount .price"/> - <element name="changeAddressButton" type="button" selector="(//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 6c2615083292..7feef60238a4 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -44,6 +44,6 @@ <element name="addressFieldValidationError" type="text" selector="div.address div.field .field-error"/> <element name="textFieldAttrRequireMessage" type="text" selector="//input[@name='custom_attributes[{{attribute}}]']/ancestor::div[contains(@class, 'control')]/div/span" parameterized="true" timeout="30"/> <element name="textFieldAttribute" type="input" selector="[name*='custom_attributes[{{attribute}}]']" parameterized="true" timeout="30"/> - <element name="changeAddressButton" type="button" selector="//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')]"/> + <element name="changeAddressButton" type="button" selector=".change-address-popup button.action.action-additional"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml new file mode 100644 index 000000000000..e3c9b796ed1f --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontSelectBillingAddressPopupSection"> + <element name="shippingAddressSearch" type="input" selector="//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')]"/> + <element name="selectButton" type="button" selector="//button[contains(@class,'action-primary') and contains(@class, 'action-select-billing-item')]"/> + <element name="shippingAddressSearchParametrised" type="input" selector="(//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')])[{{index}}]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml b/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml new file mode 100644 index 000000000000..bd986c286258 --- /dev/null +++ b/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutAddressSection"> + <element name="changeAddressButton" type="button" selector="(//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> + </section> +</sections> \ No newline at end of file From ffcca867887d7e7917fe4805081642e062506657 Mon Sep 17 00:00:00 2001 From: Ani Tumanyan <ani_tumanyan@epam.com> Date: Mon, 9 Sep 2019 18:57:51 +0400 Subject: [PATCH 0433/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Updated automated test script --- .../Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml | 1 + .../StorefrontSelectShippingAddressPopupSection.xml | 7 +++---- .../Test/Mftf/Section/StorefrontCheckoutAddressSection.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 903c21d7ec0c..4ead6ea2109f 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -42,6 +42,7 @@ <element name="ProductOptionLinkActiveByProductItemName" type="text" selector="//div[@class='product-item-details']//strong[@class='product-item-name'][text()='{{var1}}']//ancestor::div[@class='product-item-details']//div[@class='product options active']//a[text() = '{{var2}}']" parameterized="true" /> <element name="shipToInformation" type="text" selector="//div[@class='ship-to']//div[@class='shipping-information-content']" /> <element name="shippingMethodInformation" type="text" selector="//div[@class='ship-via']//div[@class='shipping-information-content']" /> + <element name="shippingInformationSection" type="text" selector=".ship-to .shipping-information-content" /> <element name="paymentMethodTitle" type="text" selector=".payment-method-title span" /> <element name="productOptionsByProductItemPrice" type="text" selector="//div[@class='product-item-inner']//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options']" parameterized="true"/> <element name="productOptionsActiveByProductItemPrice" type="text" selector="//div[@class='subtotal']//span[@class='price'][contains(.,'{{price}}')]//ancestor::div[@class='product-item-details']//div[@class='product options active']" parameterized="true"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml index e3c9b796ed1f..1f2cd6648f88 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml @@ -8,9 +8,8 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontSelectBillingAddressPopupSection"> - <element name="shippingAddressSearch" type="input" selector="//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')]"/> - <element name="selectButton" type="button" selector="//button[contains(@class,'action-primary') and contains(@class, 'action-select-billing-item')]"/> - <element name="shippingAddressSearchParametrised" type="input" selector="(//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')])[{{index}}]" parameterized="true"/> + <section name="StorefrontSelectShippingAddressPopupSection"> + <element name="shippingAddressSearch" type="input" selector="aside[style*='z-index'] [placeholder*='Search for city']"/> + <element name="selectButton" type="button" selector=".action-primary.action-select-billing-item"/> </section> </sections> diff --git a/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml b/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml index bd986c286258..a2929c202092 100644 --- a/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml +++ b/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml @@ -9,6 +9,6 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontCheckoutAddressSection"> - <element name="changeAddressButton" type="button" selector="(//button[contains(@class,'action action-additional')][contains(@data-bind,'openAddressSelection')])[{{index}}]" parameterized="true"/> + <element name="changeAddressButton" type="button" selector=".checkout-billing-address .change-address-popup button.action-additional"/> </section> </sections> \ No newline at end of file From c1054d737f482731dfd483875bffd42f9c512042 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Tue, 10 Sep 2019 17:10:09 +0300 Subject: [PATCH 0434/1172] MC-10974: Return "Is Active" toggle to Catalog Price Rule Page - Change Is Active field - Add mftf test --- ...inCreateNewCatalogPriceRuleActionGroup.xml | 1 - .../AssertCatalogPriceRuleFormActionGroup.xml | 3 +- .../CatalogPriceRuleActionGroup.xml | 8 +++-- .../AdminCatalogPriceRuleStagingSection.xml | 1 + .../AdminNewCatalogPriceRuleSection.xml | 4 +++ .../AdminApplyCatalogRuleByCategoryTest.xml | 1 + ...dminCreateInactiveCatalogPriceRuleTest.xml | 1 + ...CatalogPriceRuleByProductAttributeTest.xml | 1 + .../StorefrontInactiveCatalogRuleTest.xml | 3 +- .../ui_component/catalog_rule_form.xml | 31 +++++++++---------- .../Section/CheckoutCartProductSection.xml | 1 + .../Mftf/Section/CheckoutPaymentSection.xml | 1 + .../Section/StorefrontMiniCartSection.xml | 2 ++ .../Promo/Catalog/Edit/PromoForm.xml | 2 +- .../AssertCatalogPriceRuleInGrid.php | 2 +- .../CreateCatalogPriceRuleEntityTest.xml | 10 +++--- .../UpdateCatalogPriceRuleEntityTest.xml | 4 +-- 17 files changed, 43 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminCreateNewCatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminCreateNewCatalogPriceRuleActionGroup.xml index 00dcb68089b7..209095e0b019 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminCreateNewCatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AdminCreateNewCatalogPriceRuleActionGroup.xml @@ -21,7 +21,6 @@ <waitForPageLoad stepKey="waitForPageToLoad"/> <fillField stepKey="fillName" selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}"/> <fillField stepKey="fillDescription" selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}"/> - <selectOption selector="{{AdminNewCatalogPriceRule.status}}" userInput="{{catalogRule.is_active}}" stepKey="selectStatus"/> <selectOption stepKey="selectWebSite" selector="{{AdminNewCatalogPriceRule.websites}}" userInput="{{catalogRule.website_ids[0]}}"/> <selectOption selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="{{customerGroup}}" stepKey="selectCustomerGroup"/> <scrollTo selector="{{AdminNewCatalogPriceRule.actionsTab}}" stepKey="scrollToActionTab"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AssertCatalogPriceRuleFormActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AssertCatalogPriceRuleFormActionGroup.xml index 77fe0f50653c..0a4b6366d11a 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AssertCatalogPriceRuleFormActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/AssertCatalogPriceRuleFormActionGroup.xml @@ -13,7 +13,7 @@ <description>Validates that the provided Catalog Rule, Status, Websites and Customer Group details are present and correct on a Admin Catalog Price Rule creation/edit page.</description> </annotations> <arguments> - <argument name="catalogRule" defaultValue="inactiveCatalogRule"/> + <argument name="catalogRule" defaultValue="inactiveCatalogRule" /> <argument name="status" type="string" defaultValue=""/> <argument name="websites" type="string"/> <argument name="customerGroup" type="string"/> @@ -21,7 +21,6 @@ <seeInField stepKey="fillName" selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}"/> <seeInField stepKey="fillDescription" selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}"/> - <seeOptionIsSelected selector="{{AdminNewCatalogPriceRule.status}}" userInput="{{status}}" stepKey="selectStatus"/> <see stepKey="seeWebSite" selector="{{AdminNewCatalogPriceRule.websites}}" userInput="{{websites}}"/> <seeOptionIsSelected selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="{{customerGroup}}" stepKey="selectCustomerGroup"/> <scrollTo selector="{{AdminNewCatalogPriceRule.actionsTab}}" stepKey="scrollToActionTab"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index a7500858fc94..dfe8268765b0 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -25,6 +25,7 @@ <!-- Fill the form according the attributes of the entity --> <fillField stepKey="fillName" selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}"/> <fillField stepKey="fillDescription" selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}"/> + <click stepKey="selectActive" selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}"/> <selectOption stepKey="selectSite" selector="{{AdminNewCatalogPriceRule.websites}}" userInput="{{catalogRule.website_ids[0]}}"/> <click stepKey="clickFromCalender" selector="{{AdminNewCatalogPriceRule.fromDateButton}}"/> <click stepKey="clickFromToday" selector="{{AdminNewCatalogPriceRule.todayDate}}"/> @@ -49,9 +50,10 @@ </arguments> <click stepKey="addNewRule" selector="{{AdminGridMainControls.add}}"/> - <fillField selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}" stepKey="fillName"/> - <fillField selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}" stepKey="fillDescription"/> - <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="{{catalogRule.website_ids}}" stepKey="selectSite"/> + <fillField selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}" stepKey="fillName" /> + <click stepKey="selectActive" selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}"/> + <fillField selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}" stepKey="fillDescription" /> + <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="{{catalogRule.website_ids}}" stepKey="selectSite" /> <click stepKey="openActionDropdown" selector="{{AdminNewCatalogPriceRule.actionsTab}}"/> <fillField stepKey="fillDiscountValue" selector="{{AdminNewCatalogPriceRuleActions.discountAmount}}" userInput="{{catalogRule.discount_amount}}"/> <scrollToTopOfPage stepKey="scrollToTop"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminCatalogPriceRuleStagingSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminCatalogPriceRuleStagingSection.xml index bab9842caaa4..7a92829e2371 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminCatalogPriceRuleStagingSection.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminCatalogPriceRuleStagingSection.xml @@ -10,5 +10,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCatalogPriceRuleStagingSection"> <element name="status" type="select" selector=".modal-component [data-index='is_active'] select"/> + <element name="isActive" type="select" selector=".modals-wrapper input[name='is_active']+label"/> </section> </sections> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml index ba0493d8e995..2d4ef3786d1c 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml @@ -20,8 +20,12 @@ <element name="ruleNameNew" type="input" selector="[name='staging[name]']"/> <element name="description" type="textarea" selector="[name='description']"/> <element name="status" type="select" selector="[name='is_active']"/> + <element name="isActive" type="select" selector="input[name='is_active']+label"/> <element name="websites" type="select" selector="[name='website_ids']"/> + <element name="active" type="checkbox" selector="//div[contains(@class, 'admin__actions-switch')]/input[@name='is_active']/../label"/> + <element name="activeIsEnabled" type="checkbox" selector="(//div[contains(@class, 'admin__actions-switch')])[1]/input[@value='1']"/> + <element name="activePosition" type="checkbox" selector="//fieldset[@class='admin__fieldset']//div[4]"/> <element name="websitesOptions" type="select" selector="[name='website_ids'] option"/> <element name="customerGroups" type="select" selector="[name='customer_group_ids']"/> <element name="customerGroupsOptions" type="select" selector="[name='customer_group_ids'] option"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml index 741da96179b8..ca534ec7f537 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml @@ -52,6 +52,7 @@ <waitForPageLoad stepKey="waitForIndividualRulePage"/> <fillField selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{_defaultCatalogRule.name}}" stepKey="fillName"/> <fillField selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{_defaultCatalogRule.description}}" stepKey="fillDescription"/> + <click stepKey="selectActive" selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}"/> <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" userInput="{{_defaultCatalogRule.website_ids[0]}}" stepKey="selectSite"/> <click selector="{{AdminNewCatalogPriceRule.fromDateButton}}" stepKey="clickFromCalender"/> <click selector="{{AdminNewCatalogPriceRule.todayDate}}" stepKey="clickFromToday"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateInactiveCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateInactiveCatalogPriceRuleTest.xml index 5223b18df4e4..83dff1ecdcab 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateInactiveCatalogPriceRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateInactiveCatalogPriceRuleTest.xml @@ -58,6 +58,7 @@ <argument name="websites" value="Main Website"/> <argument name="customerGroup" value="General"/> </actionGroup> + <dontSeeCheckboxIsChecked selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}" stepKey="verifyInactiveRule"/> <!-- Search Catalog Rule in Grid --> <actionGroup ref="AdminSearchCatalogRuleInGridActionGroup" stepKey="searchCreatedCatalogRule"> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml index b7a231df5045..dd54c0767e8e 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml @@ -195,6 +195,7 @@ Websites: Main Website Customer Groups: NOT LOGGED IN --> <fillField userInput="{{SimpleCatalogPriceRule.name}}" selector="{{AdminCartPriceRulesFormSection.ruleName}}" stepKey="fillRuleName"/> + <click stepKey="selectActive" selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}"/> <selectOption userInput="{{SimpleCatalogPriceRule.websites}}" selector="{{AdminCartPriceRulesFormSection.websites}}" stepKey="selectWebsite"/> <selectOption userInput="{{SimpleCatalogPriceRule.customerGroups}}" selector="{{AdminCartPriceRulesFormSection.customerGroups}}" stepKey="selectCustomerGroups"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml index b486654fe9ac..1a77dcbdfee6 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml @@ -26,7 +26,8 @@ </createData> <actionGroup stepKey="createNewPriceRule" ref="newCatalogPriceRuleByUI"/> <actionGroup stepKey="selectLoggedInCustomers" ref="selectNotLoggedInCustomerGroup"/> - <selectOption selector="{{AdminNewCatalogPriceRule.status}}" userInput="Inactive" stepKey="setInactive"/> + <scrollToTopOfPage stepKey="scrollToTop"/> + <click stepKey="setInactive" selector="{{AdminCategoryBasicFieldSection.enableCategoryLabel}}"/> <click selector="{{AdminNewCatalogPriceRule.saveAndApply}}" stepKey="saveAndApply"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the rule." stepKey="seeSuccess"/> </before> diff --git a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml index c114f6b1d77c..2af8bb0770b2 100644 --- a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml +++ b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml @@ -95,33 +95,30 @@ <dataScope>description</dataScope> </settings> </field> - <field name="is_active" formElement="select"> + <field name="is_active" formElement="checkbox"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="source" xsi:type="string">catalog_rule</item> + <item name="default" xsi:type="number">0</item> </item> </argument> <settings> - <dataType>number</dataType> - <label translate="true">Status</label> - <visible>true</visible> - <dataScope>is_active</dataScope> + <validation> + <rule name="required-entry" xsi:type="boolean">true</rule> + </validation> + <dataType>boolean</dataType> + <label translate="true">Active</label> </settings> <formElements> - <select> + <checkbox> <settings> - <options> - <option name="0" xsi:type="array"> - <item name="value" xsi:type="number">1</item> - <item name="label" xsi:type="string" translate="true">Active</item> - </option> - <option name="1" xsi:type="array"> - <item name="value" xsi:type="number">0</item> - <item name="label" xsi:type="string" translate="true">Inactive</item> - </option> - </options> + <valueMap> + <map name="false" xsi:type="number">0</map> + <map name="true" xsi:type="number">1</map> + </valueMap> + <prefer>toggle</prefer> </settings> - </select> + </checkbox> </formElements> </field> <field name="website_ids" formElement="multiselect"> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml index 3ab3fa5857b7..be195f564145 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml @@ -18,6 +18,7 @@ <element name="ProductRegularPriceByName" type="text" selector="//div[descendant::*[contains(text(), '{{var1}}')]]//*[contains(@class, 'subtotal')]" parameterized="true"/> + <element name="productFirstPriceByName" type="text" selector="(//tbody//a[@title='{{prodName}}']/../following-sibling::*//span[@class='price'])[1]" parameterized="true"/> <element name="ProductImageByName" type="text" selector="//main//table[@id='shopping-cart-table']//tbody//tr//img[contains(@class, 'product-image-photo') and @alt='{{var1}}']" parameterized="true"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 903c21d7ec0c..8e7b16c71057 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -51,6 +51,7 @@ <element name="orderSummaryTotalIncluding" type="text" selector="//tr[@class='grand totals incl']//span[@class='price']" /> <element name="orderSummaryTotalExcluding" type="text" selector="//tr[@class='grand totals excl']//span[@class='price']" /> <element name="shippingAndBillingAddressSame" type="input" selector="#billing-address-same-as-shipping-braintree_cc_vault"/> + <element name="myShippingAndBillingAddressSame" type="input" selector=".billing-address-same-as-shipping-block"/> <element name="addressAction" type="button" selector="//span[text()='{{action}}']" parameterized="true"/> <element name="addressBook" type="button" selector="//a[text()='Address Book']"/> <element name="noQuotes" type="text" selector=".no-quotes-block"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index 3e1de2b14ba6..443b4bf649eb 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -13,7 +13,9 @@ <element name="productCount" type="text" selector="//header//div[contains(@class, 'minicart-wrapper')]//a[contains(@class, 'showcart')]//span[@class='counter-number']"/> <element name="productLinkByName" type="button" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details']//a[contains(text(), '{{var1}}')]" parameterized="true"/> <element name="productPriceByName" type="text" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//span[@class='price']" parameterized="true"/> + <element name="productPriceByItsName" type="text" selector="//a[normalize-space()='{{prodName}}']/../following-sibling::*//*[@class='price']" parameterized="true"/> <element name="productImageByName" type="text" selector="//header//ol[@id='mini-cart']//span[@class='product-image-container']//img[@alt='{{var1}}']" parameterized="true"/> + <element name="productImageByItsName" type="text" selector="//img[@alt='{{prodName}}']" parameterized="true"/> <element name="productName" type="text" selector=".product-item-name"/> <element name="productOptionsDetailsByName" type="button" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//span[.='See Details']" parameterized="true"/> <element name="productOptionByNameAndAttribute" type="text" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//dt[@class='label' and .='{{var2}}']/following-sibling::dd[@class='values']//span" parameterized="true"/> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml index 0ff402daca07..4f74b7ff554d 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml @@ -12,7 +12,7 @@ <strategy>css selector</strategy> <fields> <is_active> - <input>select</input> + <input>switcher</input> </is_active> <website_ids> <selector>[name='website_ids']</selector> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php index 8ac13d407e43..695323990063 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php @@ -19,7 +19,7 @@ class AssertCatalogPriceRuleInGrid extends AbstractConstraint * Fields used to filter rows in the grid. * @var array */ - protected $fieldsToFilter = ['name', 'is_active']; + protected $fieldsToFilter = ['name']; /** * Assert that data in grid on Catalog Price Rules page according to fixture diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.xml index 49bf36b0325b..1f16e28c067d 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/CreateCatalogPriceRuleEntityTest.xml @@ -10,7 +10,7 @@ <variation name="CatalogRule_Create_Active_AdminOnly"> <data name="catalogPriceRule/data/name" xsi:type="string">CatalogPriceRule %isolation%</data> <data name="catalogPriceRule/data/description" xsi:type="string">Catalog Price Rule Description</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Active</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">Yes</data> <data name="catalogPriceRule/data/website_ids/option_0" xsi:type="string">Main Website</data> <data name="catalogPriceRule/data/customer_group_ids/option_0" xsi:type="string">Wholesale</data> <data name="catalogPriceRule/data/simple_action" xsi:type="string">Apply as percentage of original</data> @@ -24,7 +24,7 @@ <data name="tag" xsi:type="string">mftf_migrated:yes</data> <data name="catalogPriceRule/data/name" xsi:type="string">CatalogPriceRule %isolation%</data> <data name="catalogPriceRule/data/description" xsi:type="string">Catalog Price Rule Description</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Inactive</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">No</data> <data name="catalogPriceRule/data/website_ids/option_0" xsi:type="string">Main Website</data> <data name="catalogPriceRule/data/customer_group_ids/option_0" xsi:type="string">General</data> <data name="catalogPriceRule/data/condition" xsi:type="string">-</data> @@ -39,7 +39,7 @@ <variation name="CatalogRule_Create_ForGuestUsers_AdjustPriceToPercentage"> <data name="product" xsi:type="string">MAGETWO-23036</data> <data name="catalogPriceRule/data/name" xsi:type="string">rule_name%isolation%</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Active</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">Yes</data> <data name="catalogPriceRule/data/website_ids/option_0" xsi:type="string">Main Website</data> <data name="catalogPriceRule/data/customer_group_ids/option_0" xsi:type="string">NOT LOGGED IN</data> <data name="conditionEntity" xsi:type="string">category</data> @@ -54,7 +54,7 @@ <data name="customer/dataset" xsi:type="string">customer_with_new_customer_group</data> <data name="product" xsi:type="string">simple_10_dollar</data> <data name="catalogPriceRule/data/name" xsi:type="string">rule_name%isolation%</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Active</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">Yes</data> <data name="catalogPriceRule/data/website_ids/option_0" xsi:type="string">Main Website</data> <data name="conditionEntity" xsi:type="string">category</data> <data name="catalogPriceRule/data/conditions" xsi:type="string">[Category|is|%category_id%]</data> @@ -68,7 +68,7 @@ <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data> <data name="product" xsi:type="string">product_with_custom_color_attribute</data> <data name="catalogPriceRule/data/name" xsi:type="string">Catalog Price Rule %isolation%</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Active</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">Yes</data> <data name="catalogPriceRule/data/website_ids/option_0" xsi:type="string">Main Website</data> <data name="catalogPriceRule/data/customer_group_ids/option_0" xsi:type="string">NOT LOGGED IN</data> <data name="conditionEntity" xsi:type="string">attribute</data> diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.xml index 6c8e86b24ae6..e2916432c8eb 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/TestCase/UpdateCatalogPriceRuleEntityTest.xml @@ -10,7 +10,7 @@ <variation name="CatalogRule_Update_Name_Status"> <data name="catalogPriceRuleOriginal/dataset" xsi:type="string">active_catalog_price_rule_with_conditions</data> <data name="catalogPriceRule/data/name" xsi:type="string">New Catalog Price Rule Name %isolation%</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Inactive</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">No</data> <data name="saveAction" xsi:type="string">save</data> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleSuccessSaveMessage" /> <constraint name="Magento\CatalogRule\Test\Constraint\AssertCatalogPriceRuleNoticeMessage" /> @@ -24,7 +24,7 @@ <data name="catalogPriceRuleOriginal/dataset" xsi:type="string">active_catalog_price_rule_with_conditions</data> <data name="catalogPriceRule/data/name" xsi:type="string">New Catalog Price Rule Name %isolation%</data> <data name="catalogPriceRule/data/description" xsi:type="string">New Catalog Price Rule Description %isolation%</data> - <data name="catalogPriceRule/data/is_active" xsi:type="string">Active</data> + <data name="catalogPriceRule/data/is_active" xsi:type="string">Yes</data> <data name="catalogPriceRule/data/conditions" xsi:type="string">[Category|is|%category_1%]</data> <data name="catalogPriceRule/data/simple_action" xsi:type="string">Apply as fixed amount</data> <data name="catalogPriceRule/data/discount_amount" xsi:type="string">35</data> From babd3cb4b47549eace47b6e3b4cd955a63f150b1 Mon Sep 17 00:00:00 2001 From: utietze <u.tietze@neusta.de> Date: Tue, 10 Sep 2019 21:13:44 +0200 Subject: [PATCH 0435/1172] Require missing "doctrine/instantiator" dependency Yea, well. If you are gonna use code from "doctrine/instantiator", you may declare that in composer.json. --- lib/internal/Magento/Framework/MessageQueue/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/MessageQueue/composer.json b/lib/internal/Magento/Framework/MessageQueue/composer.json index 56644e428e5c..f1397fb91afe 100644 --- a/lib/internal/Magento/Framework/MessageQueue/composer.json +++ b/lib/internal/Magento/Framework/MessageQueue/composer.json @@ -11,7 +11,8 @@ ], "require": { "magento/framework": "*", - "php": "~7.1.3||~7.2.0||~7.3.0" + "php": "~7.1.3||~7.2.0||~7.3.0", + "doctrine/instantiator": "^1.0" }, "autoload": { "psr-4": { From e40e8ef76bca6c9c241d91208da47ff810022520 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 10 Sep 2019 16:10:48 -0500 Subject: [PATCH 0436/1172] MC-19247: Broken translations with advanced bundling - Return dictionary file content not url to html; --- .../Translation/ViewModel/Dictionary.php | 35 +++++++------------ .../view/base/templates/dictionary.phtml | 28 +++------------ lib/web/mage/translate.js | 5 ++- 3 files changed, 20 insertions(+), 48 deletions(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index ced632fd7e6b..20ecef1d0eed 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -6,20 +6,17 @@ namespace Magento\Translation\ViewModel; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\View\Asset\File\NotFoundException; use Magento\Framework\View\Asset\Repository as AssetRepository; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\Js\Config as JsConfig; /** - * View model responsible for getting translate dictionary file for the layout. + * View model responsible for getting translate dictionary file content for the layout. */ class Dictionary implements ArgumentInterface { - /** - * @var JsConfig - */ - private $config; - /** * @var AssetRepository */ @@ -27,33 +24,27 @@ class Dictionary implements ArgumentInterface /** * @param AssetRepository $assetRepo - * @param JsConfig $config */ public function __construct( - AssetRepository $assetRepo, - JsConfig $config + AssetRepository $assetRepo ) { $this->assetRepo = $assetRepo; - $this->config = $config; } /** - * Get translation dictionary file as an asset for the page. + * Get translation dictionary file content. * * @return string */ - public function getTranslationDictionaryFile(): string + public function getTranslationDictionary(): string { - return $this->assetRepo->getUrl(JsConfig::DICTIONARY_FILE_NAME); - } + try { + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + $content = $asset->getContent(); + } catch (LocalizedException | NotFoundException $e) { + $content = ''; + } - /** - * Is js translation set to dictionary mode. - * - * @return bool - */ - public function dictionaryEnabled(): bool - { - return $this->config->dictionaryEnabled(); + return $content; } } diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 87318ef43741..d2244ca31710 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -7,26 +7,8 @@ /** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ $viewModel = $block->getData('dictionary_view_model'); ?> -<?php if ($viewModel->dictionaryEnabled()) : ?> - <script type="application/json" src="<?= $viewModel->getTranslationDictionaryFile() ?>"></script> - <script> - require.config({ - map: { - '*': { - 'dictionary': '<?= $viewModel->getTranslationDictionaryFile() ?>' - } - } - }); - </script> -<?php else: ?> -<!--work-around for embedded translation strategy--> - <script> - require.config({ - map: { - '*': { - 'dictionary': 'https://mage21.test/static/frontend/Magento/luma/en_US/js-translation.json' - } - } - }); - </script> -<?php endif; ?> +<script> + define('dictionary', function () { + return <?= /* @noEscape */ $viewModel->getTranslationDictionaryFileContent() ?>; + }); +</script> diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index 261d680c9ffa..4a4a46e9a3e8 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -6,9 +6,8 @@ define([ 'jquery', 'mage/mage', - 'text!dictionary' -], function ($, mage, d) { - var dictionary = JSON.parse(d); + 'dictionary' +], function ($, mage, dictionary) { $.extend(true, $, { mage: { translate: (function () { From 57cf55a26da38edcf0dbd76b4d5b06242a321cd8 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 10 Sep 2019 16:38:44 -0500 Subject: [PATCH 0437/1172] MC-19247: Broken translations with advanced bundling --- .../Magento/Translation/view/base/templates/dictionary.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index d2244ca31710..8c517e3b3ea2 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -9,6 +9,6 @@ $viewModel = $block->getData('dictionary_view_model'); ?> <script> define('dictionary', function () { - return <?= /* @noEscape */ $viewModel->getTranslationDictionaryFileContent() ?>; + return <?= /* @noEscape */ $viewModel->getTranslationDictionary() ?>; }); </script> From bb4a4fe3b2b9cafc6af4830238241566567b7860 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 11 Sep 2019 11:20:05 +0300 Subject: [PATCH 0438/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Delete unnecessary file. --- .../SelectShippingAddressPopupSection.xml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml deleted file mode 100644 index 965ee4f4b10d..000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Section/SelectShippingAddressPopupSection.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="SelectBillingAddressPopupSection"> - <element name="shippingAddressSearch" type="input" selector="//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')]"/> - <element name="selectButton" type="button" selector="//button[contains(@class,'action-primary') and contains(@class, 'action-select-billing-item')]"/> - <element name="shippingAddressSearchParametrised" type="input" selector="(//input[contains(@class,'admin__control-text') and contains(@class, 'admin__action-multiselect-search')])[{{index}}]" parameterized="true"/> - </section> -</sections> From 34f7eafd372db51f9b49ad6e720cfb5bafce6734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 15:27:07 +0200 Subject: [PATCH 0439/1172] Allow use factories and OM for creating objects with variadic arguments in constructor --- .../Framework/Code/Reader/ClassReader.php | 16 +++++++++++++++- .../ObjectManager/Factory/AbstractFactory.php | 10 +++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/Code/Reader/ClassReader.php b/lib/internal/Magento/Framework/Code/Reader/ClassReader.php index fe96e9cc742a..25a7e8e2174c 100644 --- a/lib/internal/Magento/Framework/Code/Reader/ClassReader.php +++ b/lib/internal/Magento/Framework/Code/Reader/ClassReader.php @@ -28,7 +28,8 @@ public function getConstructor($className) $parameter->getName(), $parameter->getClass() !== null ? $parameter->getClass()->getName() : null, !$parameter->isOptional() && !$parameter->isDefaultValueAvailable(), - $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null, + $this->getReflectionParameterDefaultValue($parameter), + $parameter->isVariadic(), ]; } catch (\ReflectionException $e) { $message = $e->getMessage(); @@ -40,6 +41,19 @@ public function getConstructor($className) return $result; } + /** + * @param \ReflectionParameter $parameter + * @return array|mixed|null + */ + private function getReflectionParameterDefaultValue(\ReflectionParameter $parameter) + { + if ($parameter->isVariadic()) { + return []; + } + + return $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null; + } + /** * Retrieve parent relation information for type in a following format * array( diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 15c4cb098b84..261d9bc7834a 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -226,7 +226,7 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, { $resolvedArguments = []; foreach ($parameters as $parameter) { - list($paramName, $paramType, $paramRequired, $paramDefault) = $parameter; + list($paramName, $paramType, $paramRequired, $paramDefault, $isVariadic) = $parameter; $argument = null; if (!empty($arguments) && (isset($arguments[$paramName]) || array_key_exists($paramName, $arguments))) { $argument = $arguments[$paramName]; @@ -243,9 +243,13 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, $argument = $paramDefault; } - $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); + if ($isVariadic && is_array($argument)) { + $resolvedArguments = array_merge($resolvedArguments, $argument); + } else { + $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); + $resolvedArguments[] = $argument; + } - $resolvedArguments[] = $argument; } return $resolvedArguments; } From 47a32285ec3c5fb2032f56bdc1df8e11a8b5dece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 16:52:45 +0200 Subject: [PATCH 0440/1172] Fix Static Tests build --- .../Framework/Code/Reader/ClassReader.php | 11 +++++++--- .../ObjectManager/Factory/AbstractFactory.php | 21 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/internal/Magento/Framework/Code/Reader/ClassReader.php b/lib/internal/Magento/Framework/Code/Reader/ClassReader.php index 25a7e8e2174c..27e633c66068 100644 --- a/lib/internal/Magento/Framework/Code/Reader/ClassReader.php +++ b/lib/internal/Magento/Framework/Code/Reader/ClassReader.php @@ -5,12 +5,15 @@ */ namespace Magento\Framework\Code\Reader; +/** + * Class ClassReader + */ class ClassReader implements ClassReaderInterface { /** * Read class constructor signature * - * @param string $className + * @param string $className * @return array|null * @throws \ReflectionException */ @@ -42,7 +45,9 @@ public function getConstructor($className) } /** - * @param \ReflectionParameter $parameter + * Get reflection parameter default value + * + * @param \ReflectionParameter $parameter * @return array|mixed|null */ private function getReflectionParameterDefaultValue(\ReflectionParameter $parameter) @@ -63,7 +68,7 @@ private function getReflectionParameterDefaultValue(\ReflectionParameter $parame * ... * ) * - * @param string $className + * @param string $className * @return string[] */ public function getParents($className) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 261d9bc7834a..ed530b145593 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -11,6 +11,9 @@ use Psr\Log\LoggerInterface; use Magento\Framework\App\ObjectManager; +/** + * Class AbstractFactory + */ abstract class AbstractFactory implements \Magento\Framework\ObjectManager\FactoryInterface { /** @@ -49,10 +52,10 @@ abstract class AbstractFactory implements \Magento\Framework\ObjectManager\Facto protected $creationStack = []; /** - * @param \Magento\Framework\ObjectManager\ConfigInterface $config - * @param ObjectManagerInterface $objectManager + * @param \Magento\Framework\ObjectManager\ConfigInterface $config + * @param ObjectManagerInterface $objectManager * @param \Magento\Framework\ObjectManager\DefinitionInterface $definitions - * @param array $globalArguments + * @param array $globalArguments */ public function __construct( \Magento\Framework\ObjectManager\ConfigInterface $config, @@ -91,6 +94,8 @@ public function setArguments($arguments) } /** + * Get definitions + * * @return \Magento\Framework\ObjectManager\DefinitionInterface */ public function getDefinitions() @@ -105,7 +110,7 @@ public function getDefinitions() * Create object * * @param string $type - * @param array $args + * @param array $args * * @return object * @throws RuntimeException @@ -130,9 +135,9 @@ protected function createObject($type, $args) /** * Resolve an argument * - * @param array &$argument + * @param array &$argument * @param string $paramType - * @param mixed $paramDefault + * @param mixed $paramDefault * @param string $paramName * @param string $requestedType * @@ -214,8 +219,8 @@ protected function parseArray(&$array) * Resolve constructor arguments * * @param string $requestedType - * @param array $parameters - * @param array $arguments + * @param array $parameters + * @param array $arguments * * @return array * From cc70abdc388b62ca5ca58c3c41afa2b40e34ab0a Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Wed, 11 Sep 2019 18:36:09 +0300 Subject: [PATCH 0441/1172] MC-17493: Cart/catalog rules grid missing - Updated automated test script --- .../Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml | 6 +----- .../ActionGroup/AdminCreateCartPriceRuleActionGroup.xml | 3 --- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index f2ee5dc30591..e4aecfab549a 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -58,12 +58,8 @@ <waitForPageLoad stepKey="waitForApplied"/> </actionGroup> <actionGroup name="CreateMultipleWebsiteCatalogPriceRule" extends="createCatalogPriceRule"> - <arguments> - <argument name="customerGroup" defaultValue="General" type="string"/> - </arguments> <remove keyForRemoval="selectSite"/> - <selectOption selector="{{AdminNewCatalogPriceRule.customerGroups}}" userInput="{{customerGroup}}" after="fillDiscountValue" stepKey="selectCustomerGroupMultiple"/> - <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" after="selectCustomerGroupMultiple" stepKey="selectWebsite"/> + <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> </actionGroup> <actionGroup name="CreateCatalogPriceRuleViaTheUi"> <arguments> diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index 16a19de670af..8d71b8501a41 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -113,13 +113,10 @@ <waitForPageLoad stepKey="waitForPriceList"/> <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ruleName.name}}" stepKey="fillRuleName"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.customerGroups}}" parameterArray="[{{ruleName.customerGroups}}]" stepKey="selectCustomerGroup"/> <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="{{ruleName.apply}}" stepKey="selectActionType"/> <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="{{ruleName.discountAmount}}" stepKey="fillDiscountAmount"/> - <click selector="{{AdminCartPriceRulesFormSection.save}}" stepKey="clickSaveButton"/> - <see selector="{{AdminCartPriceRulesFormSection.successMessage}}" userInput="You saved the rule." stepKey="seeSuccessMessage"/> </actionGroup> <actionGroup name="CreateCartPriceRuleSecondWebsiteActionGroup"> <annotations> From 5d259e509c8b2a678bc9914a21578909fb481055 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 11 Sep 2019 10:46:38 -0500 Subject: [PATCH 0442/1172] MC-19247: Broken translations with advanced bundling - Test to find degradation; --- app/code/Magento/Translation/ViewModel/Dictionary.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 20ecef1d0eed..bb5244d50a7f 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -38,6 +38,7 @@ public function __construct( */ public function getTranslationDictionary(): string { + return '[]'; try { $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); $content = $asset->getContent(); From 67b3f6ea2325e495c99e0d70ce4cebc0e0080f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 17:53:28 +0200 Subject: [PATCH 0443/1172] Unit tests for variadic arguments in constructor --- .../Test/Unit/Factory/CompiledTest.php | 18 +++ .../Test/Unit/Factory/FactoryTest.php | 135 ++++++++++++++++-- .../Test/Unit/Factory/Fixture/Variadic.php | 35 +++++ 3 files changed, 177 insertions(+), 11 deletions(-) create mode 100644 lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/Variadic.php diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/CompiledTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/CompiledTest.php index 779a0d04ebc5..648a74b91495 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/CompiledTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/CompiledTest.php @@ -38,6 +38,9 @@ class CompiledTest extends \PHPUnit\Framework\TestCase /** @var ObjectManager */ private $objectManager; + /** + * Setup tests + */ protected function setUp() { $this->objectManager = new ObjectManager($this); @@ -57,6 +60,9 @@ protected function setUp() $this->objectManager->setBackwardCompatibleProperty($this->factory, 'definitions', $this->definitionsMock); } + /** + * Test create simple + */ public function testCreateSimple() { $expectedConfig = $this->getSimpleConfig(); @@ -106,6 +112,9 @@ public function testCreateSimple() $this->assertNull($result->getNullValue()); } + /** + * Test create simple configured arguments + */ public function testCreateSimpleConfiguredArguments() { $expectedConfig = $this->getSimpleNestedConfig(); @@ -170,6 +179,9 @@ public function testCreateSimpleConfiguredArguments() $this->assertNull($result->getNullValue()); } + /** + * Test create get arguments in runtime + */ public function testCreateGetArgumentsInRuntime() { // Stub OM to create test assets @@ -308,18 +320,21 @@ private function getRuntimeParameters() 1 => DependencyTesting::class, 2 => true, 3 => null, + 4 => false, ], 1 => [ 0 => 'sharedDependency', 1 => DependencySharedTesting::class, 2 => true, 3 => null, + 4 => false, ], 2 => [ 0 => 'value', 1 => null, 2 => false, 3 => 'value', + 4 => false, ], 3 => [ 0 => 'valueArray', @@ -329,18 +344,21 @@ private function getRuntimeParameters() 0 => 'default_value1', 1 => 'default_value2', ], + 4 => false, ], 4 => [ 0 => 'globalValue', 1 => null, 2 => false, 3 => '', + 4 => false, ], 5 => [ 0 => 'nullValue', 1 => null, 2 => false, 3 => null, + 4 => false, ], ]; } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php index 309bf48548ec..c062fcee2cde 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php @@ -10,6 +10,9 @@ use Magento\Framework\ObjectManager\Factory\Dynamic\Developer; use Magento\Framework\ObjectManager\ObjectManager; +/** + * Class FactoryTest + */ class FactoryTest extends \PHPUnit\Framework\TestCase { /** @@ -27,6 +30,9 @@ class FactoryTest extends \PHPUnit\Framework\TestCase */ private $objectManager; + /** + * Setup tests + */ protected function setUp() { $this->config = new Config(); @@ -35,6 +41,9 @@ protected function setUp() $this->factory->setObjectManager($this->objectManager); } + /** + * Test create without args + */ public function testCreateNoArgs() { $this->assertInstanceOf('StdClass', $this->factory->create(\StdClass::class)); @@ -55,7 +64,7 @@ public function testResolveArgumentsException() $definitionsMock = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); $definitionsMock->expects($this->once())->method('getParameters') ->will($this->returnValue([[ - 'firstParam', 'string', true, 'default_val', + 'firstParam', 'string', true, 'default_val', false ]])); $this->factory = new Developer( @@ -136,16 +145,16 @@ public function testCreateUsingReflection() $definitions = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); // should be more than defined in "switch" of create() method $definitions->expects($this->once())->method('getParameters')->with($type)->will($this->returnValue([ - ['one', null, false, null], - ['two', null, false, null], - ['three', null, false, null], - ['four', null, false, null], - ['five', null, false, null], - ['six', null, false, null], - ['seven', null, false, null], - ['eight', null, false, null], - ['nine', null, false, null], - ['ten', null, false, null], + ['one', null, false, null, false], + ['two', null, false, null, false], + ['three', null, false, null, false], + ['four', null, false, null, false], + ['five', null, false, null, false], + ['six', null, false, null, false], + ['seven', null, false, null, false], + ['eight', null, false, null, false], + ['nine', null, false, null, false], + ['ten', null, false, null, false], ])); $factory = new Developer($this->config, null, $definitions); $result = $factory->create( @@ -165,4 +174,108 @@ public function testCreateUsingReflection() ); $this->assertSame(10, $result->getArg(9)); } + + /** + * Test create objects with variadic argument in constructor + * + * @param $createArgs + * @param $expectedArg0 + * @param $expectedArg1 + * @dataProvider testCreateUsingVariadicDataProvider + */ + public function testCreateUsingVariadic( + $createArgs, + $expectedArg0, + $expectedArg1 + ) { + $type = \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic::class; + $definitions = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); + + $definitions->expects($this->once())->method('getParameters')->with($type)->will($this->returnValue([ + [ + 'oneScalars', + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class, + false, + [], + true + ], + ])); + $factory = new Developer($this->config, null, $definitions); + + + + /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic */ + $variadic = is_null($createArgs) + ? $factory->create($type) + : $factory->create($type, $createArgs); + + $this->assertSame($expectedArg0, $variadic->getOneScalarByKey(0)); + $this->assertSame($expectedArg1, $variadic->getOneScalarByKey(1)); + } + + /** + * @return array + */ + public function testCreateUsingVariadicDataProvider() { + $oneScalar1 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + $oneScalar2 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + + return [ + 'without_args' => [ + null, + null, + null, + ], + 'with_empty_args' => [ + [], + null, + null, + ], + 'with_empty_args_value' => [ + [ + 'oneScalars' => [] + ], + null, + null, + ], + 'with_args' => [ + [ + 'oneScalars' => [ + $oneScalar1, + $oneScalar2, + ] + ], + $oneScalar1, + $oneScalar2, + ], + ]; + } + + /** + * Test data can be injected into variadic arguments from di config + */ + public function testCreateVariadicFromDiConfig() + { + $oneScalar1 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + $oneScalar2 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + + // let's imitate that Variadic is configured by providing DI configuration for it + $this->config->extend( + [ + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic::class => [ + 'arguments' => [ + 'oneScalars' => [ + $oneScalar1, + $oneScalar2, + ] + ] + ], + ] + ); + /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic */ + $variadic = $this->factory->create(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic::class); + + $this->assertSame($oneScalar1, $variadic->getOneScalarByKey(0)); + $this->assertSame($oneScalar2, $variadic->getOneScalarByKey(1)); + } } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/Variadic.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/Variadic.php new file mode 100644 index 000000000000..af26f7456fdd --- /dev/null +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/Variadic.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture; + +/** + * Constructor with variadic argument in constructor + */ +class Variadic +{ + /** + * @var OneScalar[] + */ + private $oneScalars; + + /** + * Variadic constructor. + * @param OneScalar[] ...$oneScalars + */ + public function __construct(OneScalar ...$oneScalars) + { + $this->oneScalars = $oneScalars; + } + + /** + * @param string $key + * @return mixed + */ + public function getOneScalarByKey($key) + { + return $this->oneScalars[$key] ?? null; + } +} From 487edadf0fee63f4c1550e1f470920a0d6f64ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 18:56:28 +0200 Subject: [PATCH 0444/1172] Fix Static Tests build --- .../ObjectManager/Factory/AbstractFactory.php | 6 +- .../Test/Unit/Factory/FactoryTest.php | 110 ++++++++++++------ 2 files changed, 77 insertions(+), 39 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index ed530b145593..f3dc14a02c12 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -120,7 +120,9 @@ protected function createObject($type, $args) try { return new $type(...array_values($args)); } catch (\TypeError $exception) { - /** @var LoggerInterface $logger */ + /** + * @var LoggerInterface $logger + */ $logger = ObjectManager::getInstance()->get(LoggerInterface::class); $logger->critical( sprintf('Type Error occurred when creating object: %s, %s', $type, $exception->getMessage()) @@ -249,7 +251,7 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, } if ($isVariadic && is_array($argument)) { - $resolvedArguments = array_merge($resolvedArguments, $argument); + $resolvedArguments += $argument; } else { $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); $resolvedArguments[] = $argument; diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php index c062fcee2cde..dc49cc84e23d 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php @@ -50,22 +50,34 @@ public function testCreateNoArgs() } /** - * @expectedException \UnexpectedValueException + * @expectedException \UnexpectedValueException * @expectedExceptionMessage Invalid parameter configuration provided for $firstParam argument */ public function testResolveArgumentsException() { $configMock = $this->createMock(\Magento\Framework\ObjectManager\Config\Config::class); - $configMock->expects($this->once())->method('getArguments') - ->will($this->returnValue([ - 'firstParam' => 1, - ])); + $configMock->expects($this->once())->method('getArguments')->will( + $this->returnValue( + [ + 'firstParam' => 1, + ] + ) + ); $definitionsMock = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); - $definitionsMock->expects($this->once())->method('getParameters') - ->will($this->returnValue([[ - 'firstParam', 'string', true, 'default_val', false - ]])); + $definitionsMock->expects($this->once())->method('getParameters')->will( + $this->returnValue( + [ + [ + 'firstParam', + 'string', + true, + 'default_val', + false + ] + ] + ) + ); $this->factory = new Developer( $configMock, @@ -80,9 +92,14 @@ public function testResolveArgumentsException() ); } + /** + * Test create with one arg + */ public function testCreateOneArg() { - /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar $result */ + /** + * @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar $result + */ $result = $this->factory->create( \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class, ['foo' => 'bar'] @@ -91,6 +108,9 @@ public function testCreateOneArg() $this->assertEquals('bar', $result->getFoo()); } + /** + * Test create with injectable + */ public function testCreateWithInjectable() { // let's imitate that One is injectable by providing DI configuration for it @@ -101,7 +121,9 @@ public function testCreateWithInjectable() ], ] ); - /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Two $result */ + /** + * @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Two $result + */ $result = $this->factory->create(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Two::class); $this->assertInstanceOf(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Two::class, $result); $this->assertInstanceOf( @@ -113,8 +135,8 @@ public function testCreateWithInjectable() } /** - * @param string $startingClass - * @param string $terminationClass + * @param string $startingClass + * @param string $terminationClass * @dataProvider circularDataProvider */ public function testCircular($startingClass, $terminationClass) @@ -139,23 +161,30 @@ public function circularDataProvider() ]; } + /** + * Test create using reflection + */ public function testCreateUsingReflection() { $type = \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Polymorphous::class; $definitions = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); // should be more than defined in "switch" of create() method - $definitions->expects($this->once())->method('getParameters')->with($type)->will($this->returnValue([ - ['one', null, false, null, false], - ['two', null, false, null, false], - ['three', null, false, null, false], - ['four', null, false, null, false], - ['five', null, false, null, false], - ['six', null, false, null, false], - ['seven', null, false, null, false], - ['eight', null, false, null, false], - ['nine', null, false, null, false], - ['ten', null, false, null, false], - ])); + $definitions->expects($this->once())->method('getParameters')->with($type)->will( + $this->returnValue( + [ + ['one', null, false, null, false], + ['two', null, false, null, false], + ['three', null, false, null, false], + ['four', null, false, null, false], + ['five', null, false, null, false], + ['six', null, false, null, false], + ['seven', null, false, null, false], + ['eight', null, false, null, false], + ['nine', null, false, null, false], + ['ten', null, false, null, false], + ] + ) + ); $factory = new Developer($this->config, null, $definitions); $result = $factory->create( $type, @@ -178,9 +207,9 @@ public function testCreateUsingReflection() /** * Test create objects with variadic argument in constructor * - * @param $createArgs - * @param $expectedArg0 - * @param $expectedArg1 + * @param $createArgs + * @param $expectedArg0 + * @param $expectedArg1 * @dataProvider testCreateUsingVariadicDataProvider */ public function testCreateUsingVariadic( @@ -191,20 +220,24 @@ public function testCreateUsingVariadic( $type = \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic::class; $definitions = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); - $definitions->expects($this->once())->method('getParameters')->with($type)->will($this->returnValue([ - [ + $definitions->expects($this->once())->method('getParameters')->with($type)->will( + $this->returnValue( + [ + [ 'oneScalars', \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class, false, [], true - ], - ])); + ], + ] + ) + ); $factory = new Developer($this->config, null, $definitions); - - - /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic */ + /** + * @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic + */ $variadic = is_null($createArgs) ? $factory->create($type) : $factory->create($type, $createArgs); @@ -216,7 +249,8 @@ public function testCreateUsingVariadic( /** * @return array */ - public function testCreateUsingVariadicDataProvider() { + public function testCreateUsingVariadicDataProvider() + { $oneScalar1 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); $oneScalar2 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); @@ -272,7 +306,9 @@ public function testCreateVariadicFromDiConfig() ], ] ); - /** @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic */ + /** + * @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic $variadic + */ $variadic = $this->factory->create(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\Variadic::class); $this->assertSame($oneScalar1, $variadic->getOneScalarByKey(0)); From 5d3d6aa541c7200a76709420bab76c0f84433252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 19:22:59 +0200 Subject: [PATCH 0445/1172] Fix Static Tests build --- .../Magento/Framework/ObjectManager/Factory/AbstractFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index f3dc14a02c12..11fa0e5d8c7b 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -137,7 +137,7 @@ protected function createObject($type, $args) /** * Resolve an argument * - * @param array &$argument + * @param array $argument * @param string $paramType * @param mixed $paramDefault * @param string $paramName From 087023562a8f3b625e35059c8705747885090732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 19:47:44 +0200 Subject: [PATCH 0446/1172] Add tests for classes with non variadic and variadic arguments in constructor --- .../ObjectManager/Factory/AbstractFactory.php | 2 +- .../Test/Unit/Factory/FactoryTest.php | 127 ++++++++++++++++++ .../Unit/Factory/Fixture/SemiVariadic.php | 53 ++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 11fa0e5d8c7b..bb77fed4c447 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -251,7 +251,7 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, } if ($isVariadic && is_array($argument)) { - $resolvedArguments += $argument; + $resolvedArguments = array_merge($resolvedArguments, $argument); } else { $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); $resolvedArguments[] = $argument; diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php index dc49cc84e23d..d192bee2fbc6 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php @@ -314,4 +314,131 @@ public function testCreateVariadicFromDiConfig() $this->assertSame($oneScalar1, $variadic->getOneScalarByKey(0)); $this->assertSame($oneScalar2, $variadic->getOneScalarByKey(1)); } + + /** + * Test create objects with non variadic and variadic argument in constructor + * + * @param $createArgs + * @param $expectedFooValue + * @param $expectedArg0 + * @param $expectedArg1 + * @dataProvider testCreateUsingSemiVariadicDataProvider + */ + public function testCreateUsingSemiVariadic( + $createArgs, + $expectedFooValue, + $expectedArg0, + $expectedArg1 + ) { + $type = \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::class; + $definitions = $this->createMock(\Magento\Framework\ObjectManager\DefinitionInterface::class); + + $definitions->expects($this->once())->method('getParameters')->with($type)->will( + $this->returnValue( + [ + [ + 'foo', + null, + false, + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + false + ], + [ + 'oneScalars', + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class, + false, + [], + true + ], + ] + ) + ); + $factory = new Developer($this->config, null, $definitions); + + /** + * @var \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic $semiVariadic + */ + $semiVariadic = is_null($createArgs) + ? $factory->create($type) + : $factory->create($type, $createArgs); + + $this->assertSame($expectedFooValue, $semiVariadic->getFoo()); + $this->assertSame($expectedArg0, $semiVariadic->getOneScalarByKey(0)); + $this->assertSame($expectedArg1, $semiVariadic->getOneScalarByKey(1)); + } + + /** + * @return array + */ + public function testCreateUsingSemiVariadicDataProvider() + { + $oneScalar1 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + $oneScalar2 = $this->createMock(\Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\OneScalar::class); + + return [ + 'without_args' => [ + null, + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + null, + null, + ], + 'with_empty_args' => [ + [], + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + null, + null, + ], + 'only_with_foo_value' => [ + [ + 'foo' => 'baz' + ], + 'baz', + null, + null, + ], + 'only_with_oneScalars_empty_value' => [ + [ + 'oneScalars' => [] + ], + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + null, + null, + ], + 'only_with_oneScalars_full_value' => [ + [ + 'oneScalars' => [ + $oneScalar1, + $oneScalar2, + ] + ], + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + $oneScalar1, + $oneScalar2, + ], + 'with_all_values_defined_in_right_order' => [ + [ + 'foo' => 'baz', + 'oneScalars' => [ + $oneScalar1, + $oneScalar2, + ] + ], + 'baz', + $oneScalar1, + $oneScalar2, + ], + 'with_all_values_defined_in_reverse_order' => [ + [ + 'oneScalars' => [ + $oneScalar1, + $oneScalar2, + ], + 'foo' => 'baz', + ], + 'baz', + $oneScalar1, + $oneScalar2, + ], + ]; + } } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php new file mode 100644 index 000000000000..1074a96d31a0 --- /dev/null +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture; + +/** + * Constructor with non variadic and variadic argument in constructor + */ +class SemiVariadic +{ + const DEFAULT_FOO_VALUE = 'bar'; + /** + * @var OneScalar[] + */ + private $oneScalars; + + /** + * @var string + */ + private $foo; + + /** + * SemiVariadic constructor. + * @param string $foo + * @param OneScalar[] ...$oneScalars + */ + public function __construct( + string $foo = self::DEFAULT_FOO_VALUE, + OneScalar ...$oneScalars + ) { + $this->foo = $foo; + $this->oneScalars = $oneScalars; + } + + /** + * @param string $key + * @return mixed + */ + public function getOneScalarByKey($key) + { + return $this->oneScalars[$key] ?? null; + } + + /** + * @return string + */ + public function getFoo(): string + { + return $this->foo; + } +} From 8faaeb177fb0639f8696a4872c1fea2142dd281f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 19:49:10 +0200 Subject: [PATCH 0447/1172] Fix Static Tests build --- .../Test/Unit/Factory/Fixture/SemiVariadic.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php index 1074a96d31a0..8773dec1c48d 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/Fixture/SemiVariadic.php @@ -11,6 +11,7 @@ class SemiVariadic { const DEFAULT_FOO_VALUE = 'bar'; + /** * @var OneScalar[] */ @@ -23,7 +24,8 @@ class SemiVariadic /** * SemiVariadic constructor. - * @param string $foo + * + * @param string $foo * @param OneScalar[] ...$oneScalars */ public function __construct( @@ -35,7 +37,7 @@ public function __construct( } /** - * @param string $key + * @param mixed $key * @return mixed */ public function getOneScalarByKey($key) From 60ea1d7b4e1dcb4ad28b82980ef54fc5676634bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Wed, 11 Sep 2019 21:32:42 +0200 Subject: [PATCH 0448/1172] Avoid array_merge() in loop --- .../Framework/ObjectManager/Factory/AbstractFactory.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index bb77fed4c447..65a1b345c353 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -251,13 +251,14 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, } if ($isVariadic && is_array($argument)) { - $resolvedArguments = array_merge($resolvedArguments, $argument); + $resolvedArguments[] = $argument; } else { $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); - $resolvedArguments[] = $argument; + $resolvedArguments[] = [$argument]; } } - return $resolvedArguments; + + return empty($resolvedArguments) ? [] : array_merge(...$resolvedArguments); } } From d7f312a1dcc74d377e952c1ab86f5550bfbf503a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Thu, 12 Sep 2019 00:00:07 +0200 Subject: [PATCH 0449/1172] Resolve cyclomatic complexity, add support for simple parameter declaration --- .../ObjectManager/Factory/AbstractFactory.php | 54 +++++++++++-------- .../Test/Unit/Factory/FactoryTest.php | 17 +++++- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 65a1b345c353..9279e0b3edf4 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -233,32 +233,44 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, { $resolvedArguments = []; foreach ($parameters as $parameter) { - list($paramName, $paramType, $paramRequired, $paramDefault, $isVariadic) = $parameter; - $argument = null; - if (!empty($arguments) && (isset($arguments[$paramName]) || array_key_exists($paramName, $arguments))) { - $argument = $arguments[$paramName]; - } elseif ($paramRequired) { - if ($paramType) { - $argument = ['instance' => $paramType]; - } else { - $this->creationStack = []; - throw new \BadMethodCallException( - 'Missing required argument $' . $paramName . ' of ' . $requestedType . '.' - ); - } - } else { - $argument = $paramDefault; - } + $resolvedArguments[] = $this->getResolvedArgument((string)$requestedType, $parameter, $arguments); + } - if ($isVariadic && is_array($argument)) { - $resolvedArguments[] = $argument; + return empty($resolvedArguments) ? [] : array_merge(...$resolvedArguments); + } + + /** + * Get resolved argument from parameter + * + * @param string $requestedType + * @param array $parameter + * @param array $arguments + * @return array + */ + private function getResolvedArgument(string $requestedType, array $parameter, array $arguments): array + { + list($paramName, $paramType, $paramRequired, $paramDefault, $isVariadic) = $parameter; + $argument = null; + if (!empty($arguments) && (isset($arguments[$paramName]) || array_key_exists($paramName, $arguments))) { + $argument = $arguments[$paramName]; + } elseif ($paramRequired) { + if ($paramType) { + $argument = ['instance' => $paramType]; } else { - $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); - $resolvedArguments[] = [$argument]; + $this->creationStack = []; + throw new \BadMethodCallException( + 'Missing required argument $' . $paramName . ' of ' . $requestedType . '.' + ); } + } else { + $argument = $paramDefault; + } + if ($isVariadic) { + return is_array($argument) ? $argument : [$argument]; } - return empty($resolvedArguments) ? [] : array_merge(...$resolvedArguments); + $this->resolveArgument($argument, $paramType, $paramDefault, $paramName, $requestedType); + return [$argument]; } } diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php index d192bee2fbc6..cc86d794bd80 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Factory/FactoryTest.php @@ -272,7 +272,14 @@ public function testCreateUsingVariadicDataProvider() null, null, ], - 'with_args' => [ + 'with_single_arg' => [ + [ + 'oneScalars' => $oneScalar1 + ], + $oneScalar1, + null, + ], + 'with_full_args' => [ [ 'oneScalars' => [ $oneScalar1, @@ -404,6 +411,14 @@ public function testCreateUsingSemiVariadicDataProvider() null, null, ], + 'only_with_oneScalars_single_value' => [ + [ + 'oneScalars' => $oneScalar1 + ], + \Magento\Framework\ObjectManager\Test\Unit\Factory\Fixture\SemiVariadic::DEFAULT_FOO_VALUE, + $oneScalar1, + null, + ], 'only_with_oneScalars_full_value' => [ [ 'oneScalars' => [ From a2cbfa6a2fcb456c087ec7d96636eddec5e5945b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Mart=C3=ADnez?= <adrian.martinez@interactiv4.com> Date: Thu, 12 Sep 2019 00:05:46 +0200 Subject: [PATCH 0450/1172] Fix Static Tests build --- .../Framework/ObjectManager/Factory/AbstractFactory.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php index 9279e0b3edf4..7094b116ead3 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php +++ b/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php @@ -242,9 +242,9 @@ protected function resolveArgumentsInRuntime($requestedType, array $parameters, /** * Get resolved argument from parameter * - * @param string $requestedType - * @param array $parameter - * @param array $arguments + * @param string $requestedType + * @param array $parameter + * @param array $arguments * @return array */ private function getResolvedArgument(string $requestedType, array $parameter, array $arguments): array From f54db5e3636121e6e9785cab7529674e6f4e5046 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 11 Sep 2019 17:52:06 -0500 Subject: [PATCH 0451/1172] MC-19247: Broken translations with advanced bundling --- app/code/Magento/Translation/ViewModel/Dictionary.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index bb5244d50a7f..20ecef1d0eed 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -38,7 +38,6 @@ public function __construct( */ public function getTranslationDictionary(): string { - return '[]'; try { $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); $content = $asset->getContent(); From aaee0c8ae2322dae5c7626a8566865bf714e54a3 Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Thu, 12 Sep 2019 11:56:22 +0300 Subject: [PATCH 0452/1172] [Customer] Rename dob to date_of_birth #911 --- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index 73d33f5bf01d..c06c84a3bdd1 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -61,7 +61,7 @@ input CustomerInput { lastname: String @doc(description: "The customer's family name") suffix: String @doc(description: "A value such as Sr., Jr., or III") email: String @doc(description: "The customer's email address. Required") - dob: @deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") String @doc(description: "The customer's date of birth") + dob: String @doc(description: "The customer's date of birth") # deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") gender: Int @doc(description: "The customer's gender(Male - 1, Female - 2)") @@ -88,7 +88,7 @@ type Customer @doc(description: "Customer defines the customer name and address email: String @doc(description: "The customer's email address. Required") default_billing: String @doc(description: "The ID assigned to the billing address") default_shipping: String @doc(description: "The ID assigned to the shipping address") - dob: @deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") String @doc(description: "The customer's date of birth") + dob: String @doc(description: "The customer's date of birth") # deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") id: Int @doc(description: "The ID assigned to the customer") From 06095be6806ff6d542af4c0eb36279e626fdcff7 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Thu, 12 Sep 2019 16:30:57 +0300 Subject: [PATCH 0453/1172] MC-17653: Cannot schedule update for catalog price rule for date attribute --- .../CatalogPriceRuleActionGroup.xml | 19 ++++++++++++++++++- ...efrontVisibilityOfDuplicateProductTest.xml | 1 + .../Model/Condition/AbstractCondition.php | 16 +++++++++++++--- .../Model/Condition/AbstractConditionTest.php | 10 +++++----- .../Section/PriceRuleConditionsSection.xml | 2 ++ .../Unit/Model/Rule/Condition/ProductTest.php | 4 ++-- 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index a7500858fc94..06dda3722206 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -47,7 +47,6 @@ <arguments> <argument name="catalogRule" defaultValue="_defaultCatalogRule"/> </arguments> - <click stepKey="addNewRule" selector="{{AdminGridMainControls.add}}"/> <fillField selector="{{AdminNewCatalogPriceRule.ruleName}}" userInput="{{catalogRule.name}}" stepKey="fillName"/> <fillField selector="{{AdminNewCatalogPriceRule.description}}" userInput="{{catalogRule.description}}" stepKey="fillDescription"/> @@ -55,9 +54,27 @@ <click stepKey="openActionDropdown" selector="{{AdminNewCatalogPriceRule.actionsTab}}"/> <fillField stepKey="fillDiscountValue" selector="{{AdminNewCatalogPriceRuleActions.discountAmount}}" userInput="{{catalogRule.discount_amount}}"/> <scrollToTopOfPage stepKey="scrollToTop"/> + <click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/> <waitForPageLoad stepKey="waitForApplied"/> </actionGroup> + <actionGroup name="AdminCreateCatalogPriceRuleWithConditionActionGroup" extends="createCatalogPriceRule"> + <arguments> + <argument name="catalogRuleType" type="entity" defaultValue="PriceRuleWithCondition"/> + </arguments> + <waitForPageLoad stepKey="waitForPageLoad" after="addNewRule"/> + <click selector="{{AdminNewCatalogPriceRule.conditionsTab}}" stepKey="expandConditions" before="openActionDropdown"/> + <scrollTo selector="{{AdminNewCatalogPriceRule.conditionsTab}}" stepKey="scrollToConditionsTab" after="expandConditions"/> + <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule" after="scrollToConditionsTab"/> + <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule" after="waitForNewRule"/> + <selectOption selector="{{PriceRuleConditionsSection.conditionsDropdown}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="selectProductAttribute" after="clickNewRule"/> + <waitForPageLoad stepKey="waitForAttributeLoad" after="selectProductAttribute"/> + <!--Assert that attribute contains today date without time--> + <comment userInput="Assert that attribute contains today date without time" stepKey="assertDate" after="waitForAttributeLoad"/> + <generateDate date="now" format="Y-m-d" stepKey="today" after="assertDate"/> + <grabTextFrom selector="{{PriceRuleConditionsSection.firstProductAttributeSelected}}" stepKey="grabTextFromSelectedAttribute" after="today"/> + <assertEquals expected="$today" actual="$grabTextFromSelectedAttribute" stepKey="assertTodayDate" after="grabTextFromSelectedAttribute"/> + </actionGroup> <actionGroup name="CreateCatalogPriceRuleViaTheUi"> <arguments> <argument name="catalogRule" defaultValue="_defaultCatalogRule"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml index 749d1bee0661..c37b023317bf 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml @@ -11,6 +11,7 @@ <annotations> <stories value="Duplicate Product"/> <features value="ConfigurableProduct"/> + <stories value="Duplicate Product"/> <title value="Visibility of duplicate product on the Storefront"/> <description value="Check visibility of duplicate product on the Storefront"/> <severity value="AVERAGE"/> diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php index 6729fe722de5..d58af06da94c 100644 --- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php +++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Rule\Model\Condition; @@ -17,6 +18,7 @@ * @method setFormName() * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * phpcs:disable Magento2.Classes.AbstractApi * @api * @since 100.0.2 */ @@ -390,7 +392,7 @@ public function getValueParsed() $value = reset($value); } if (!is_array($value) && $this->isArrayOperatorType() && $value) { - $value = preg_split('#\s*[,;]\s*#', $value, null, PREG_SPLIT_NO_EMPTY); + $value = preg_split('#\s*[,;]\s*#', (string) $value, -1, PREG_SPLIT_NO_EMPTY); } $this->setValueParsed($value); } @@ -419,8 +421,11 @@ public function getValue() { if ($this->getInputType() == 'date' && !$this->getIsValueParsed()) { // date format intentionally hard-coded + $date = $this->getData('value'); + $date = (\is_numeric($date) ? '@' : '') . $date; $this->setValue( - (new \DateTime($this->getData('value')))->format('Y-m-d H:i:s') + (new \DateTime($date, new \DateTimeZone((string) $this->_localeDate->getConfigTimezone()))) + ->format('Y-m-d H:i:s') ); $this->setIsValueParsed(true); } @@ -432,6 +437,7 @@ public function getValue() * * @return array|string * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * phpcs:disable Generic.Metrics.NestingLevel */ public function getValueName() { @@ -469,6 +475,7 @@ public function getValueName() } return $value; } + //phpcs:enable Generic.Metrics.NestingLevel /** * Get inherited conditions selectors @@ -674,6 +681,9 @@ public function getValueElement() $elementParams['placeholder'] = \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT; $elementParams['autocomplete'] = 'off'; $elementParams['readonly'] = 'true'; + $elementParams['value_name'] = + (new \DateTime($elementParams['value'], new \DateTimeZone($this->_localeDate->getConfigTimezone()))) + ->format('Y-m-d'); } return $this->getForm()->addField( $this->getPrefix() . '__' . $this->getId() . '__value', @@ -879,7 +889,7 @@ protected function _compareValues($validatedValue, $value, $strict = true) return $validatedValue == $value; } - $validatePattern = preg_quote($validatedValue, '~'); + $validatePattern = preg_quote((string) $validatedValue, '~'); if ($strict) { $validatePattern = '^' . $validatePattern . '$'; } diff --git a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php index 52653197e398..0ba41af04a1b 100644 --- a/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php +++ b/app/code/Magento/Rule/Test/Unit/Model/Condition/AbstractConditionTest.php @@ -55,14 +55,14 @@ public function validateAttributeDataProvider() ['0', '==', 1, false], ['1', '==', 1, true], ['x', '==', 'x', true], - ['x', '==', 0, false], + ['x', '==', '0', false], [1, '!=', 1, false], [0, '!=', 1, true], ['0', '!=', 1, true], ['1', '!=', 1, false], ['x', '!=', 'x', false], - ['x', '!=', 0, true], + ['x', '!=', '0', true], [1, '==', [1], true], [1, '!=', [1], false], @@ -164,15 +164,15 @@ public function validateAttributeArrayInputTypeDataProvider() [[1, 2, 3], '{}', '1', true, 'grid'], [[1, 2, 3], '{}', '8', false, 'grid'], - [[1, 2, 3], '{}', 5, false, 'grid'], + [[1, 2, 3], '{}', '5', false, 'grid'], [[1, 2, 3], '{}', [2, 3, 4], true, 'grid'], [[1, 2, 3], '{}', [4], false, 'grid'], [[3], '{}', [], false, 'grid'], [1, '{}', 1, false, 'grid'], [1, '!{}', [1, 2, 3], false, 'grid'], [[1], '{}', null, false, 'grid'], - [null, '{}', null, true, 'input'], - [null, '!{}', null, false, 'input'], + ['null', '{}', 'null', true, 'input'], + ['null', '!{}', 'null', false, 'input'], [null, '{}', [1], false, 'input'], [[1, 2, 3], '()', 1, true, 'select'], diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml index 9a74ced2a2c1..7e0cd323f114 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml @@ -9,8 +9,10 @@ <element name="conditionsTab" type="text" selector="//div[@data-index='conditions']//span[contains(.,'Conditions')][1]"/> <element name="createNewRule" type="text" selector="span.rule-param.rule-param-new-child"/> <element name="rulesDropdown" type="select" selector="select[data-form-part='sales_rule_form'][data-ui-id='newchild-0-select-rule-conditions-1-new-child']"/> + <element name="conditionsDropdown" type="select" selector="select[data-form-part='catalog_rule_form'][data-ui-id='newchild-0-select-rule-conditions-1-new-child']"/> <element name="addProductAttributesButton" type="text" selector="#conditions__1--1__children>li>span>a"/> <element name="productAttributesDropdown" type="select" selector="#conditions__1--1__new_child"/> + <element name="firstProductAttributeSelected" type="select" selector="#conditions__1__children .rule-param:nth-of-type(2) a:nth-child(1)"/> <element name="changeCategoriesButton" type="text" selector="#conditions__1--1__children>li>span.rule-param:nth-of-type(2)>a"/> <element name="categoriesChooser" type="text" selector="#conditions__1--1__children>li>span.rule-param:nth-of-type(2)>span>label>a"/> <element name="treeRoot" type="text" selector=".x-tree-root-ct.x-tree-lines"/> diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php index 8ca6b20db3b5..da358372e089 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php @@ -247,10 +247,10 @@ public function testValidateCategoriesIgnoresVisibility(): void * @param boolean $isValid * @param string $conditionValue * @param string $operator - * @param double $productPrice + * @param string $productPrice * @dataProvider localisationProvider */ - public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = 2000.00) + public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = '2000.00') { $attr = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class) ->disableOriginalConstructor() From 72d25409ecb5e436522688b004626427ae2e3592 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 13 Sep 2019 11:50:01 +0300 Subject: [PATCH 0454/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Fix modularity for test. --- .../Test/Mftf/Page/CheckoutShippingPage.xml | 1 - .../Test/Mftf/Section/CheckoutShippingSection.xml | 1 - ...torefrontSelectShippingAddressPopupSection.xml | 15 --------------- .../Section/StorefrontCheckoutAddressSection.xml | 14 -------------- 4 files changed, 31 deletions(-) delete mode 100644 app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml delete mode 100644 app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml index 2ff10f8423b6..c8641f7d8fbf 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Page/CheckoutShippingPage.xml @@ -12,6 +12,5 @@ <section name="CheckoutShippingGuestInfoSection"/> <section name="CheckoutShippingSection"/> <section name="StorefrontCheckoutAddressPopupSection"/> - <section name="StorefrontCheckoutAddressSection"/> </page> </pages> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml index 7feef60238a4..59d46e8cca69 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml @@ -44,6 +44,5 @@ <element name="addressFieldValidationError" type="text" selector="div.address div.field .field-error"/> <element name="textFieldAttrRequireMessage" type="text" selector="//input[@name='custom_attributes[{{attribute}}]']/ancestor::div[contains(@class, 'control')]/div/span" parameterized="true" timeout="30"/> <element name="textFieldAttribute" type="input" selector="[name*='custom_attributes[{{attribute}}]']" parameterized="true" timeout="30"/> - <element name="changeAddressButton" type="button" selector=".change-address-popup button.action.action-additional"/> </section> </sections> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml deleted file mode 100644 index 1f2cd6648f88..000000000000 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontSelectShippingAddressPopupSection.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontSelectShippingAddressPopupSection"> - <element name="shippingAddressSearch" type="input" selector="aside[style*='z-index'] [placeholder*='Search for city']"/> - <element name="selectButton" type="button" selector=".action-primary.action-select-billing-item"/> - </section> -</sections> diff --git a/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml b/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml deleted file mode 100644 index a2929c202092..000000000000 --- a/app/code/Magento/OfflinePayments/Test/Mftf/Section/StorefrontCheckoutAddressSection.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> - <section name="StorefrontCheckoutAddressSection"> - <element name="changeAddressButton" type="button" selector=".checkout-billing-address .change-address-popup button.action-additional"/> - </section> -</sections> \ No newline at end of file From 55afca3410e919d03a16527c3af05ee6d47c3f93 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 13 Sep 2019 16:31:37 +0400 Subject: [PATCH 0455/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 1 + .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 1 + .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 3 +++ .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 1 + .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 1 + 5 files changed, 7 insertions(+) diff --git a/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index df6841cb718f..6322847ec1aa 100644 --- a/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -13,6 +13,7 @@ <comment userInput="Assert configuration are disabled in DHL section" stepKey="commentSeeDisabledDHLConfigs"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <conditionalClick selector="{{AdminShippingMethodDHLSection.carriersDHLTab}}" dependentSelector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" visible="false" stepKey="expandDHLTab"/> + <waitForElementVisible selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" stepKey="waitDHLTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" userInput="disabled" stepKey="grabDHLActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveDisabled" stepKey="assertDHLActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActiveRMA}}" userInput="disabled" stepKey="grabDHLActiveRMADisabled"/> diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index c5cb75ae9975..42139f65d081 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -13,6 +13,7 @@ <comment userInput="Assert configuration are disabled in FedEx section" stepKey="commentSeeDisabledFedExConfigs"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <conditionalClick selector="{{AdminShippingMethodFedExSection.carriersFedExTab}}" dependentSelector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" visible="false" stepKey="expandFedExTab"/> + <waitForElementVisible selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" stepKey="waitFedExTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" userInput="disabled" stepKey="grabFedExActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveDisabled" stepKey="assertFedExActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActiveRMA}}" userInput="disabled" stepKey="grabFedExActiveRMADisabled"/> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 1739bcd01ec9..0b7ddd0cfa78 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -29,6 +29,7 @@ <comment userInput="Assert configuration are disabled in Flat Rate section" stepKey="commentSeeDisabledFlatRateConfigs"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <conditionalClick selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateTab}}" dependentSelector="{{AdminShippingMethodFlatRateSection.carriersFlatRateActive}}" visible="false" stepKey="expandFlatRateTab"/> + <waitForElementVisible selector="{{AdminShippingMethodFlatRateSection.carriersEnableFlatRateActive}}" stepKey="waitForFlatRateTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersEnableFlatRateActive}}" userInput="disabled" stepKey="grabFlatRateActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabFlatRateActiveDisabled" stepKey="assertFlatRateActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodFlatRateSection.carriersFlatRateTitle}}" userInput="disabled" stepKey="grabFlatRateTitleDisabled"/> @@ -44,6 +45,7 @@ <!--Assert configuration are disabled in Free Shipping section--> <comment userInput="Assert configuration are disabled in Free Shipping section" stepKey="commentSeeDisabledFreeShippingConfigs"/> <conditionalClick selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingSectionHead}}" dependentSelector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingActive}}" visible="false" stepKey="expandFreeShippingTab"/> + <waitForElementVisible selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingActive}}" stepKey="waitForFreeShippingTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingActive}}" userInput="disabled" stepKey="grabFreeShippingActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabFreeShippingActiveDisabled" stepKey="assertFreeShippingActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodFreeShippingSection.carriersFreeShippingTitle}}" userInput="disabled" stepKey="grabFreeShippingTitleDisabled"/> @@ -59,6 +61,7 @@ <!--Assert configuration are disabled in Table Rates section--> <comment userInput="Assert configuration are disabled in Table Rates section" stepKey="commentSeeDisabledTableRatesConfigs"/> <conditionalClick selector="{{AdminShippingMethodTableRatesSection.carriersTableRateTab}}" dependentSelector="{{AdminShippingMethodTableRatesSection.carriersTableRateActive}}" visible="false" stepKey="expandTableRateTab"/> + <waitForElementVisible selector="{{AdminShippingMethodTableRatesSection.enabledUseSystemValue}}" stepKey="waitForTableRateTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.enabledUseSystemValue}}" userInput="disabled" stepKey="grabTableRateActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabTableRateActiveDisabled" stepKey="assertTableRateActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodTableRatesSection.carriersTableRateTitle}}" userInput="disabled" stepKey="grabTableRateTitleDisabled"/> diff --git a/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 9202476ef183..39272886d839 100644 --- a/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -13,6 +13,7 @@ <comment userInput="Assert configuration are disabled in UPS section" stepKey="commentSeeDisabledUPSConfigs"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <conditionalClick selector="{{AdminShippingMethodsUpsSection.carriersUpsTab}}" dependentSelector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" visible="false" stepKey="expandUPSTab"/> + <waitForElementVisible selector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" stepKey="waitUPSTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" userInput="disabled" stepKey="grabUPSActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveDisabled" stepKey="assertUPSActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActiveRMA}}" userInput="disabled" stepKey="grabUPSActiveRMADisabled"/> diff --git a/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 003ccb8c3ef8..cd77861fccd5 100644 --- a/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Usps/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -13,6 +13,7 @@ <comment userInput="Assert configuration are disabled in USPS section" stepKey="commentSeeDisabledUSPSConfigs"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <conditionalClick selector="{{AdminShippingMethodUSPSSection.carriersUSPSTab}}" dependentSelector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" visible="false" stepKey="expandUSPSTab"/> + <waitForElementVisible selector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" stepKey="waitUSPSTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSActive}}" userInput="disabled" stepKey="grabUSPSActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabUSPSActiveDisabled" stepKey="assertUSPSActiveDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodUSPSSection.carriersUSPSGatewayXMLUrl}}" userInput="disabled" stepKey="grabUSPSGatewayXMLUrlDisabled"/> From 1389445ed7e516baad6021695837f0df4f9e5fa8 Mon Sep 17 00:00:00 2001 From: Evgeny Petrov <evgeny_petrov@epam.com> Date: Thu, 27 Jun 2019 12:03:41 +0300 Subject: [PATCH 0456/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window --- .../Section/CheckoutCartSummarySection.xml | 2 +- .../Multishipping/Block/Checkout/Shipping.php | 38 +++-- .../Model/Cart/Controller/CartPlugin.php | 65 ++++++--- ...efrontMultishippingCheckoutActionGroup.xml | 28 ++++ .../Mftf/Section/MultishippingSection.xml | 8 ++ ...eckoutShippingMultipleAddressesSection.xml | 15 ++ ...utWhenCartPageIsOpenedInAnotherTabTest.xml | 130 ++++++++++++++++++ .../Mftf/Section/AdminOrdersGridSection.xml | 1 + 8 files changed, 256 insertions(+), 31 deletions(-) create mode 100644 app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index 477451ef003c..69a4ebdadf18 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -20,7 +20,7 @@ <element name="totalAmount" type="text" selector="//*[@id='cart-totals']//tr[@class='grand totals']//td//span[@class='price' and contains(text(), '{{amount}}')]" parameterized="true"/> <element name="proceedToCheckout" type="button" selector=".action.primary.checkout span" timeout="30"/> <element name="discountAmount" type="text" selector="td[data-th='Discount']"/> - <element name="shippingHeading" type="button" selector="#block-shipping-heading" timeout="60"/> + <element name="shippingHeading" type="button" selector="#block-shipping-heading" timeout="10"/> <element name="postcode" type="input" selector="input[name='postcode']" timeout="10"/> <element name="stateProvince" type="select" selector="select[name='region_id']" timeout="10"/> <element name="stateProvinceInput" type="input" selector="input[name='region']"/> diff --git a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php index 77981c736b9e..a3b10aea9b42 100644 --- a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php +++ b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php @@ -3,10 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Multishipping\Block\Checkout; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Quote\Model\Quote\Address; +use Magento\Store\Model\ScopeInterface; /** * Mustishipping checkout shipping @@ -67,7 +70,7 @@ public function getCheckout() } /** - * @return $this + * @inheritDoc */ protected function _prepareLayout() { @@ -78,6 +81,8 @@ protected function _prepareLayout() } /** + * Retrieves addresses + * * @return Address[] */ public function getAddresses() @@ -86,6 +91,8 @@ public function getAddresses() } /** + * Returns count of addresses + * * @return mixed */ public function getAddressCount() @@ -99,6 +106,8 @@ public function getAddressCount() } /** + * Retrieves the address items + * * @param Address $address * @return \Magento\Framework\DataObject[] */ @@ -106,7 +115,7 @@ public function getAddressItems($address) { $items = []; foreach ($address->getAllItems() as $item) { - if ($item->getParentItemId()) { + if ($item->getParentItemId() || !$item->getQuoteItemId()) { continue; } $item->setQuoteItem($this->getCheckout()->getQuote()->getItemById($item->getQuoteItemId())); @@ -118,6 +127,8 @@ public function getAddressItems($address) } /** + * Retrieves the address shipping method + * * @param Address $address * @return mixed */ @@ -127,6 +138,8 @@ public function getAddressShippingMethod($address) } /** + * Retrieves address shipping rates + * * @param Address $address * @return mixed */ @@ -137,22 +150,23 @@ public function getShippingRates($address) } /** + * Retrieves the carrier name by the code + * * @param string $carrierCode * @return string */ public function getCarrierName($carrierCode) { - if ($name = $this->_scopeConfig->getValue( - 'carriers/' . $carrierCode . '/title', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) - ) { + $name = $this->_scopeConfig->getValue('carriers/' . $carrierCode . '/title', ScopeInterface::SCOPE_STORE); + if ($name) { return $name; } return $carrierCode; } /** + * Retrieves the address edit url + * * @param Address $address * @return string */ @@ -162,6 +176,8 @@ public function getAddressEditUrl($address) } /** + * Retrieves the url for items edition + * * @return string */ public function getItemsEditUrl() @@ -170,6 +186,8 @@ public function getItemsEditUrl() } /** + * Retrieves the url for the post action + * * @return string */ public function getPostActionUrl() @@ -178,6 +196,8 @@ public function getPostActionUrl() } /** + * Retrieves the back url + * * @return string */ public function getBackUrl() @@ -186,6 +206,8 @@ public function getBackUrl() } /** + * Returns converted and formatted price + * * @param Address $address * @param float $price * @param bool $flag @@ -202,7 +224,7 @@ public function getShippingPrice($address, $price, $flag) } /** - * Retrieve text for items box + * Retrieves text for items box * * @param \Magento\Framework\DataObject $addressEntity * @return string diff --git a/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php index 4ef36a7c8b6f..40b6f0fa4d8f 100644 --- a/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php +++ b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php @@ -3,34 +3,48 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Multishipping\Model\Cart\Controller; +use Magento\Checkout\Controller\Cart; +use Magento\Checkout\Model\Session; +use Magento\Customer\Api\AddressRepositoryInterface; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Multishipping\Model\Checkout\Type\Multishipping\State; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Model\Quote; + +/** + * Cleans shipping addresses and item assignments after MultiShipping flow + */ class CartPlugin { /** - * @var \Magento\Quote\Api\CartRepositoryInterface + * @var CartRepositoryInterface */ private $cartRepository; /** - * @var \Magento\Checkout\Model\Session + * @var Session */ private $checkoutSession; /** - * @var \Magento\Customer\Api\AddressRepositoryInterface + * @var AddressRepositoryInterface */ private $addressRepository; /** - * @param \Magento\Quote\Api\CartRepositoryInterface $cartRepository - * @param \Magento\Checkout\Model\Session $checkoutSession - * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository + * @param CartRepositoryInterface $cartRepository + * @param Session $checkoutSession + * @param AddressRepositoryInterface $addressRepository */ public function __construct( - \Magento\Quote\Api\CartRepositoryInterface $cartRepository, - \Magento\Checkout\Model\Session $checkoutSession, - \Magento\Customer\Api\AddressRepositoryInterface $addressRepository + CartRepositoryInterface $cartRepository, + Session $checkoutSession, + AddressRepositoryInterface $addressRepository ) { $this->cartRepository = $cartRepository; $this->checkoutSession = $checkoutSession; @@ -38,20 +52,19 @@ public function __construct( } /** - * @param \Magento\Checkout\Controller\Cart $subject - * @param \Magento\Framework\App\RequestInterface $request + * Cleans shipping addresses and item assignments after MultiShipping flow + * + * @param Cart $subject + * @param RequestInterface $request * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @throws LocalizedException */ - public function beforeDispatch( - \Magento\Checkout\Controller\Cart $subject, - \Magento\Framework\App\RequestInterface $request - ) { - /** @var \Magento\Quote\Model\Quote $quote */ + public function beforeDispatch(Cart $subject, RequestInterface $request) + { + /** @var Quote $quote */ $quote = $this->checkoutSession->getQuote(); - - // Clear shipping addresses and item assignments after MultiShipping flow - if ($quote->isMultipleShippingAddresses()) { + if ($quote->isMultipleShippingAddresses() && $this->isCheckoutComplete()) { foreach ($quote->getAllShippingAddresses() as $address) { $quote->removeAddress($address->getId()); } @@ -59,12 +72,20 @@ public function beforeDispatch( $shippingAddress = $quote->getShippingAddress(); $defaultShipping = $quote->getCustomer()->getDefaultShipping(); if ($defaultShipping) { - $defaultCustomerAddress = $this->addressRepository->getById( - $defaultShipping - ); + $defaultCustomerAddress = $this->addressRepository->getById($defaultShipping); $shippingAddress->importCustomerAddressData($defaultCustomerAddress); } $this->cartRepository->save($quote); } } + + /** + * Checks whether the checkout flow is complete + * + * @return bool + */ + private function isCheckoutComplete() + { + return (bool) ($this->checkoutSession->getStepData(State::STEP_SHIPPING)['is_complete'] ?? true); + } } diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml new file mode 100644 index 000000000000..3ceb7c9a778e --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <actionGroup name="StorefrontCheckoutShippingSelectMultipleAddressesActionGroup"> + <arguments> + <argument name="firstAddress" type="string" defaultValue="{{CustomerAddressSimple.street[0]}}"/> + <argument name="secondAddress" type="string" defaultValue="{{CustomerAddressSimple.street[1]}}"/> + </arguments> + <selectOption selector="{{StorefrontCheckoutShippingMultipleAddressesSection.selectedMultipleShippingAddress('1')}}" userInput="{{firstAddress}}" stepKey="selectShippingAddressForTheFirstItem"/> + <selectOption selector="{{StorefrontCheckoutShippingMultipleAddressesSection.selectedMultipleShippingAddress('2')}}" userInput="{{secondAddress}}" stepKey="selectShippingAddressForTheSecondItem"/> + <click selector="{{StorefrontCheckoutShippingMultipleAddressesSection.goToShippingInformationButton}}" stepKey="clickToGoToInformationButton"/> + </actionGroup> + <actionGroup name="StorefrontGoCheckoutWithMultipleAddresses"> + <click selector="{{MultishippingSection.shippingMultipleCheckout}}" stepKey="clickToMultipleAddressShippingButton"/> + </actionGroup> + <actionGroup name="StorefrontGoToBillingInformationActionGroup"> + <click selector="{{StorefrontMultipleShippingMethodSection.continueToBillingInformationButton}}" stepKey="clickToContinueToBillingInformationButton"/> + <waitForPageLoad stepKey="waitForBillingPage"/> + </actionGroup> +</actionGroups> + diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index 45fafc3105c3..a3dfa9c53031 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -16,9 +16,17 @@ </section> <section name="MultishippingSection"> <element name="checkoutWithMultipleAddresses" type="button" selector="//span[text()='Check Out with Multiple Addresses']"/> + <element name="shippingMultipleCheckout" type="button" selector=".action.multicheckout"/> <element name="firstShippingAddressValue" type="select" selector="//table//tbody//tr[position()=1]//td[position()=3]//div//select//option[2]"/> <element name="firstShippingAddressOption" type="select" selector="//table//tbody//tr[position()=1]//td[position()=3]//div//select"/> <element name="secondShippingAddressValue" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select//option[1]"/> <element name="secondShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> </section> + <section name="StorefrontMultipleShippingMethodSection"> + <element name="orderId" type="text" selector="(//div[@class='order-id'])[{{rowNum}}]" parameterized="true"/> + <element name="placeOrderButton" type="button" selector="#review-button"/> + <element name="goToReviewYourOrderButton" type="button" selector="#payment-continue"/> + <element name="continueToBillingInformationButton" type="button" selector=".action.primary.continue"/> + <element name="successMessage" type="text" selector=".multicheckout.success"/> + </section> </sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml new file mode 100644 index 000000000000..75bc7f64b292 --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutShippingMultipleAddressesSection"> + <element name="selectedMultipleShippingAddress" type="select" selector=".table tr:nth-of-type({{selectNumber}}) select" parameterized="true"/> + <element name="goToShippingInformationButton" type="button" selector=".action.primary.continue"/> + </section> +</sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml new file mode 100644 index 000000000000..1ba03a01951b --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest"> + <annotations> + <features value="Multishipping"/> + <stories value="Multishipping"/> + <title value="Process multishipping checkout when Cart page is opened in another tab"/> + <description value="Process multishipping checkout when Cart page is opened in another tab"/> + <severity value="MAJOR"/> + <testCaseId value="MC-17871"/> + <useCaseId value="MC-17469"/> + <group value="multishipping"/> + </annotations> + <before> + <!-- Login as Admin --> + <comment userInput="Login as Admin" stepKey="commentLoginAsAdmin"/> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <!-- Set configurations --> + <comment userInput="Set configurations" stepKey="commentSetConfigurations"/> + <magentoCLI command="config:set multishipping/options/checkout_multiple 1" stepKey="allowShippingToMultipleAddresses"/> + <!-- Create two simple products --> + <comment userInput="Create two simple products" stepKey="commentCreateSimpleProducts"/> + <createData entity="ApiCategory" stepKey="createCategory"/> + <createData entity="_defaultProduct" stepKey="createFirstProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="_defaultProduct" stepKey="createSecondProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Simple_US_Customer_Multiple_Addresses" stepKey="createCustomerWithMultipleAddresses"/> + </before> + <after> + <!-- Delete created data --> + <comment userInput="Delete created data" stepKey="commentDeleteCreatedData"/> + <actionGroup ref="logout" stepKey="logout"/> + <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomerWithMultipleAddresses" stepKey="deleteCustomer"/> + </after> + <!-- Login to the Storefront as created customer --> + <comment userInput="Login to the Storefront as created customer" stepKey="commentLoginAsCustomer"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomerWithMultipleAddresses$$"/> + </actionGroup> + <!-- Add two products to the Shopping Cart --> + <comment userInput="Add two products to the Cart" stepKey="commentAddProductsToTheCart"/> + <amOnPage url="{{StorefrontProductPage.url($$createFirstProduct.name$$)}}" stepKey="amOnStorefrontProductFirstPage"/> + <waitForPageLoad stepKey="waitForTheFirstProduct"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCart"> + <argument name="product" value="$$createFirstProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <amOnPage url="{{StorefrontProductPage.url($$createSecondProduct.name$$)}}" stepKey="amOnStorefrontSecondProductPage"/> + <waitForPageLoad stepKey="waitForPageLoadForTheSecondProduct"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddSecondProductToCart"> + <argument name="product" value="$$createSecondProduct$$"/> + <argument name="productCount" value="2"/> + </actionGroup> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> + <!-- Click 'Check Out with Multiple Addresses' --> + <comment userInput="Click 'Check Out with Multiple Addresses'" stepKey="commentClickToCheckOutWithMultipleAddress"/> + <waitForPageLoad stepKey="waitForSecondPageLoad"/> + <actionGroup ref="StorefrontGoCheckoutWithMultipleAddresses" stepKey="goCheckoutWithMultipleAddresses"/> + <!-- Select different addresses and click 'Go to Shipping Information' --> + <comment userInput="Select different addresses and click 'Go to Shipping Information'" stepKey="commentClickOnGoToShippingInformation"/> + <actionGroup ref="StorefrontCheckoutShippingSelectMultipleAddressesActionGroup" stepKey="selectMultipleAddresses"> + <argument name="firstAddress" value="{{UK_Not_Default_Address.street[0]}}"/> + <argument name="secondAddress" value="{{US_Address_NY.street[1]}}"/> + </actionGroup> + <waitForPageLoad stepKey="waitPageLoad"/> + <!-- Open the Cart page in another browser window and go back --> + <comment userInput="Open the Cart page in another browser window and go back" stepKey="commentOpenCartPageInAnotherTab"/> + <openNewTab stepKey="openNewTab"/> + <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPageNewTab"/> + <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertFirstProductItemInCheckOutCart"> + <argument name="productName" value="$$createFirstProduct.name$$"/> + <argument name="productSku" value="$$createFirstProduct.sku$$"/> + <argument name="productPrice" value="$$createFirstProduct.price$$"/> + <argument name="subtotal" value="$$createFirstProduct.price$$" /> + <argument name="qty" value="1"/> + </actionGroup> + <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertSecondProductItemInCheckOutCart"> + <argument name="productName" value="$$createSecondProduct.name$$"/> + <argument name="productSku" value="$$createSecondProduct.sku$$"/> + <argument name="productPrice" value="$$createSecondProduct.price$$"/> + <argument name="subtotal" value="$$createSecondProduct.price$$" /> + <argument name="qty" value="1"/> + </actionGroup> + <switchToNextTab stepKey="switchToNextTab"/> + <!-- Click 'Continue to Billing Information' and 'Go to Review Your Order' --> + <comment userInput="Click 'Continue to Billing Information' > click 'Go to Review Your Order'" stepKey="commentGoToReviewYourOrder"/> + <actionGroup ref="StorefrontGoToBillingInformationActionGroup" stepKey="goToBillingInformation"/> + <see selector="{{ShipmentFormSection.shippingAddress}}" userInput="{{US_Address_NY.city}}" stepKey="seeBillingAddress"/> + <waitForElementVisible selector="{{StorefrontMultipleShippingMethodSection.goToReviewYourOrderButton}}" stepKey="waitForGoToReviewYourOrderVisible" /> + <click selector="{{StorefrontMultipleShippingMethodSection.goToReviewYourOrderButton}}" stepKey="clickToGoToReviewYourOrderButton"/> + <!-- Click 'Place Order' --> + <comment userInput="Click 'Place Order'" stepKey="commentPlaceOrder"/> + <actionGroup ref="PlaceOrderActionGroup" stepKey="placeOrder"/> + <see selector="{{StorefrontMultipleShippingMethodSection.successMessage}}" userInput="Successfully ordered" stepKey="seeSuccessMessage"/> + <grabTextFrom selector="{{StorefrontMultipleShippingMethodSection.orderId('1')}}" stepKey="grabFirstOrderId"/> + <grabTextFrom selector="{{StorefrontMultipleShippingMethodSection.orderId('2')}}" stepKey="grabSecondOrderId"/> + <!-- Go to My Account > My Orders --> + <comment userInput="Go to My Account > My Orders" stepKey="commentGoToMyOrders"/> + <amOnPage url="{{StorefrontCustomerOrdersHistoryPage.url}}" stepKey="goToMyOrdersPage"/> + <waitForPageLoad stepKey="waitForMyOrdersPageLoad"/> + <seeElement selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabFirstOrderId})}}" stepKey="seeFirstOrder"/> + <seeElement selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabSecondOrderId})}}" stepKey="seeSecondOrder"/> + <waitForPageLoad stepKey="waitForOrderPageLoad"/> + <!-- Go to Admin > Sales > Orders --> + <comment userInput="Go to Admin > Sales > Orders" stepKey="commentGoOrders"/> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> + <actionGroup ref="searchAdminDataGridByKeyword" stepKey="searchFirstOrder"> + <argument name="keyword" value="$grabFirstOrderId"/> + </actionGroup> + <see selector="{{AdminOrdersGridSection.firstLineOrderId}}" userInput="{$grabFirstOrderId}" stepKey="seeAdminFirstOrder"/> + <actionGroup ref="searchAdminDataGridByKeyword" stepKey="searchSecondOrder"> + <argument name="keyword" value="$grabSecondOrderId"/> + </actionGroup> + <see selector="{{AdminOrdersGridSection.firstLineOrderId}}" userInput="{$grabSecondOrderId}" stepKey="seeAdminSecondOrder"/> + </test> +</tests> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml index ace64cdaa103..ce777e5f9ca7 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml @@ -39,5 +39,6 @@ <element name="changeOrderStatus" type="button" selector="//div[contains(concat(' ',normalize-space(@class),' '),' row-gutter ')]//span[text()='{{status}}']" parameterized="true" timeout="30"/> <element name="viewLink" type="text" selector="//td/div[contains(.,'{{orderID}}')]/../..//a[@class='action-menu-item']" parameterized="true"/> <element name="selectOrderID" type="checkbox" selector="//td/div[text()='{{orderId}}']/../preceding-sibling::td//input" parameterized="true" timeout="60"/> + <element name="firstLineOrderId" type="text" selector=".data-grid td:nth-of-type(2)"/> </section> </sections> From 95d5d29392665d5b635bc0b42605c90309251496 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 13 Sep 2019 10:06:28 -0500 Subject: [PATCH 0457/1172] MC-19247: Broken translations with advanced bundling --- .../Translation/ViewModel/Dictionary.php | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 20ecef1d0eed..63f6f7f2c26c 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -6,11 +6,14 @@ namespace Magento\Translation\ViewModel; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem; use Magento\Framework\View\Asset\File\NotFoundException; use Magento\Framework\View\Asset\Repository as AssetRepository; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\Js\Config as JsConfig; +use Magento\Framework\App\State as AppState; /** * View model responsible for getting translate dictionary file content for the layout. @@ -22,13 +25,29 @@ class Dictionary implements ArgumentInterface */ private $assetRepo; + /** + * @var AppState + */ + private $appState; + + /** + * @var Filesystem + */ + private $filesystem; + /** * @param AssetRepository $assetRepo + * @param AppState $appState + * @param Filesystem $filesystem */ public function __construct( - AssetRepository $assetRepo + AssetRepository $assetRepo, + AppState $appState, + Filesystem $filesystem ) { $this->assetRepo = $assetRepo; + $this->appState = $appState; + $this->filesystem = $filesystem; } /** @@ -38,11 +57,23 @@ public function __construct( */ public function getTranslationDictionary(): string { - try { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - $content = $asset->getContent(); - } catch (LocalizedException | NotFoundException $e) { - $content = ''; + if ($this->appState->getMode() === AppState::MODE_PRODUCTION) { + try { + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + $staticViewFilePath = $this->filesystem->getDirectoryRead( + DirectoryList::STATIC_VIEW + )->getAbsolutePath(); + $content = file_get_contents($staticViewFilePath . $asset->getPath()); + } catch (LocalizedException $e) { + $content = ''; + } + } else { + try { + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + $content = $asset->getContent(); + } catch (LocalizedException | NotFoundException $e) { + $content = ''; + } } return $content; From 170dfa5ff8fec6ecbb5c4cc75e7f506f63ec2b44 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 13 Sep 2019 10:19:39 -0500 Subject: [PATCH 0458/1172] MC-19247: Broken translations with advanced bundling - Move translation module to theme require; --- app/code/Magento/Theme/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index 37802ee6c68f..f688d5b8863a 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -15,11 +15,11 @@ "magento/module-media-storage": "*", "magento/module-require-js": "*", "magento/module-store": "*", + "magento/module-translation": "*", "magento/module-ui": "*", "magento/module-widget": "*" }, "suggest": { - "magento/module-translation": "*", "magento/module-theme-sample-data": "*", "magento/module-deploy": "*", "magento/module-directory": "*" From 63349b3b23e1be8b65b91a536bcc0528c99b37d7 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Fri, 13 Sep 2019 19:00:48 -0500 Subject: [PATCH 0459/1172] MC-19247: Broken translations with advanced bundling - Fix MFTF test - Use strict mode for js; - File get contents with framework method; --- .../Mftf/Section/CheckoutPaymentSection.xml | 2 +- .../Translation/ViewModel/Dictionary.php | 16 ++++++-- app/code/Magento/Translation/etc/di.xml | 1 + .../view/base/templates/dictionary.phtml | 2 +- lib/web/mage/translate.js | 40 ++++++++++--------- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml index 903c21d7ec0c..7d280afe14ec 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml @@ -31,7 +31,7 @@ <element name="cartItemsAreaActive" type="textarea" selector="div.block.items-in-cart.active" timeout="30"/> <element name="checkMoneyOrderPayment" type="radio" selector="input#checkmo.radio" timeout="30"/> <element name="placeOrder" type="button" selector=".payment-method._active button.action.primary.checkout" timeout="30"/> - <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[text()='Payment Method']" /> + <element name="paymentSectionTitle" type="text" selector="//*[@id='checkout-payment-method-load']//div[@data-role='title']" /> <element name="orderSummarySubtotal" type="text" selector="//tr[@class='totals sub']//span[@class='price']" /> <element name="orderSummaryShippingTotal" type="text" selector="//tr[@class='totals shipping excl']//span[@class='price']" /> <element name="orderSummaryShippingMethod" type="text" selector="//tr[@class='totals shipping excl']//span[@class='value']" /> diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 63f6f7f2c26c..41a5faf097da 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -7,6 +7,7 @@ namespace Magento\Translation\ViewModel; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem; use Magento\Framework\View\Asset\File\NotFoundException; @@ -14,6 +15,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\Js\Config as JsConfig; use Magento\Framework\App\State as AppState; +use Magento\Framework\Filesystem\DriverInterface; /** * View model responsible for getting translate dictionary file content for the layout. @@ -35,19 +37,27 @@ class Dictionary implements ArgumentInterface */ private $filesystem; + /** + * @var DriverInterface + */ + private $filesystemDriver; + /** * @param AssetRepository $assetRepo * @param AppState $appState * @param Filesystem $filesystem + * @param DriverInterface $filesystemDriver */ public function __construct( AssetRepository $assetRepo, AppState $appState, - Filesystem $filesystem + Filesystem $filesystem, + DriverInterface $filesystemDriver ) { $this->assetRepo = $assetRepo; $this->appState = $appState; $this->filesystem = $filesystem; + $this->filesystemDriver = $filesystemDriver; } /** @@ -63,8 +73,8 @@ public function getTranslationDictionary(): string $staticViewFilePath = $this->filesystem->getDirectoryRead( DirectoryList::STATIC_VIEW )->getAbsolutePath(); - $content = file_get_contents($staticViewFilePath . $asset->getPath()); - } catch (LocalizedException $e) { + $content = $this->filesystemDriver->fileGetContents($staticViewFilePath . $asset->getPath()); + } catch (LocalizedException | FileSystemException $e) { $content = ''; } } else { diff --git a/app/code/Magento/Translation/etc/di.xml b/app/code/Magento/Translation/etc/di.xml index d17dac23933e..3ba249d60127 100644 --- a/app/code/Magento/Translation/etc/di.xml +++ b/app/code/Magento/Translation/etc/di.xml @@ -15,6 +15,7 @@ <preference for="Magento\Framework\Phrase\RendererInterface" type="Magento\Framework\Phrase\Renderer\Composite" /> <preference for="Magento\Translation\Model\Js\DataProviderInterface" type="Magento\Translation\Model\Js\DataProvider"/> <preference for="Magento\Framework\Translate\Js\Config" type="Magento\Translation\Model\Js\Config"/> + <preference for="Magento\Framework\Filesystem\DriverInterface" type="Magento\Framework\Filesystem\Driver\File"/> <type name="Magento\Framework\Translate\Inline"> <arguments> <argument name="templateFileName" xsi:type="string">Magento_Translation::translate_inline.phtml</argument> diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 8c517e3b3ea2..fb082439b1c3 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -/** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ +/** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ $viewModel = $block->getData('dictionary_view_model'); ?> <script> diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index 4a4a46e9a3e8..db341807364e 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -8,6 +8,8 @@ define([ 'mage/mage', 'dictionary' ], function ($, mage, dictionary) { + 'use strict'; + $.extend(true, $, { mage: { translate: (function () { @@ -18,27 +20,27 @@ define([ */ var _data = dictionary; - /** - * Add new translation (two string parameters) or several translations (object) - */ - this.add = function () { - if (arguments.length > 1) { - _data[arguments[0]] = arguments[1]; - } else if (typeof arguments[0] === 'object') { - $.extend(_data, arguments[0]); - } - }; + return { + /** + * Add new translation (two string parameters) or several translations (object) + */ + add: function () { + if (arguments.length > 1) { + _data[arguments[0]] = arguments[1]; + } else if (typeof arguments[0] === 'object') { + $.extend(_data, arguments[0]); + } + }, - /** - * Make a translation with parsing (to handle case when _data represents tuple) - * @param {String} text - * @return {String} - */ - this.translate = function (text) { - return _data[text] ? _data[text] : text; + /** + * Make a translation with parsing (to handle case when _data represents tuple) + * @param {String} text + * @return {String} + */ + translate: function (text) { + return _data[text] ? _data[text] : text; + } }; - - return this; }()) } }); From 1d284ef7a3ef63e0a68918c613b935833a8f3794 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Fri, 13 Sep 2019 22:31:47 -0700 Subject: [PATCH 0460/1172] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index e589c8595ce2..944710773123 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -101,7 +101,9 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) $scopeTz = new \DateTimeZone( $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) ); - $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); + $fromTime = $rule->getFromDate() + ? (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp() + : 0; $toTime = $rule->getToDate() ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 : 0; From 35f317b91afbe60c27c7a6a6331a3ae4ca7dcfc1 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Sat, 14 Sep 2019 06:45:26 +0000 Subject: [PATCH 0461/1172] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../Controller/Adminhtml/Promo/Catalog/Save.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 4f58293d5335..996fc4e8ef3d 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -12,6 +12,7 @@ use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\App\Request\DataPersistorInterface; +use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** * Save action for catalog rule @@ -25,19 +26,27 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog imple */ protected $dataPersistor; + /** + * @var TimezoneInterface + */ + private $localeDate; + /** * @param Context $context * @param Registry $coreRegistry * @param Date $dateFilter * @param DataPersistorInterface $dataPersistor + * @param TimezoneInterface $localeDate */ public function __construct( Context $context, Registry $coreRegistry, Date $dateFilter, - DataPersistorInterface $dataPersistor + DataPersistorInterface $dataPersistor, + TimezoneInterface $localeDate ) { $this->dataPersistor = $dataPersistor; + $this->localeDate = $localeDate; parent::__construct($context, $coreRegistry, $dateFilter); } @@ -66,6 +75,9 @@ public function execute() ); $data = $this->getRequest()->getPostValue(); + if (!$this->getRequest()->getParam('from_date')) { + $data['from_date'] = $this->localeDate->formatDate(); + } $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { $filterValues['to_date'] = $this->_dateFilter; From 6d7daa454c8f45669e13e17dddddc8ecbfbdd25d Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Sat, 14 Sep 2019 05:30:16 +0000 Subject: [PATCH 0462/1172] MC-19873: [Sample Data Function Test] Sample data test failed with Incorrect final price --- .../CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 996fc4e8ef3d..6d499b93e411 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -55,16 +55,15 @@ public function __construct( * * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { if ($this->getRequest()->getPostValue()) { - /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */ $ruleRepository = $this->_objectManager->get( \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class ); - /** @var \Magento\CatalogRule\Model\Rule $model */ $model = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class); @@ -74,7 +73,6 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); - if (!$this->getRequest()->getParam('from_date')) { $data['from_date'] = $this->localeDate->formatDate(); } From c18a2ed64af40909f8c38c5cfd5c55621b497a20 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 11:33:11 -0300 Subject: [PATCH 0463/1172] adding new validation for future dates to admin in customer DOB --- .../Customer/view/base/ui_component/customer_form.xml | 2 +- .../Ui/view/base/web/js/lib/validation/rules.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 5fb8b17dbb8c..9a9a79f49d14 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -264,7 +264,7 @@ </argument> <settings> <validation> - <rule name="validate-date" xsi:type="boolean">true</rule> + <rule name="validate-dob" xsi:type="boolean">true</rule> </validation> <dataType>text</dataType> <visible>true</visible> 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 3402d1d1df03..863b4a80f58c 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 @@ -1067,6 +1067,16 @@ define([ return new RegExp(param).test(value); }, $.mage.__('This link is not allowed.') + ], + 'validate-dob': [ + function (value, params, additionalParams) { + if(value === '') { + return true; + } + + return moment(value).isBefore(moment()); + }, + $.mage.__('The Date of Birth should not be greater than today') ] }, function (data) { return { From 5163a0518069e078e5b0920c57f5fa216b216272 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 11:44:11 -0300 Subject: [PATCH 0464/1172] the the date validation that was missing on last commit --- .../Magento/Customer/view/base/ui_component/customer_form.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 9a9a79f49d14..8692a4eafdb1 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -264,6 +264,7 @@ </argument> <settings> <validation> + <rule name="validate-date" xsi:type="boolean">true</rule> <rule name="validate-dob" xsi:type="boolean">true</rule> </validation> <dataType>text</dataType> From 8d9b2cb87066be1a3367d8604956bc12a4baab14 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 11:50:49 -0300 Subject: [PATCH 0465/1172] adding period (.) to end of line --- app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 863b4a80f58c..ca40cbfc168c 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 @@ -1076,7 +1076,7 @@ define([ return moment(value).isBefore(moment()); }, - $.mage.__('The Date of Birth should not be greater than today') + $.mage.__('The Date of Birth should not be greater than today.') ] }, function (data) { return { From 45158591b846982adda65c81c788f6039df54d6c Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 12:24:59 -0300 Subject: [PATCH 0466/1172] adding space after 'if' and removing unused arguments --- app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ca40cbfc168c..08f67955976c 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 @@ -1069,8 +1069,8 @@ define([ $.mage.__('This link is not allowed.') ], 'validate-dob': [ - function (value, params, additionalParams) { - if(value === '') { + function (value) { + if (value === '') { return true; } From c5d1aee471b44cc9bfc9e259645bb4ba9c82ae56 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 13:34:56 -0300 Subject: [PATCH 0467/1172] disabling the input of greater dates from datepicker. Validation still on field for manual inputs --- .../Magento/Customer/view/base/ui_component/customer_form.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 8692a4eafdb1..7eb1394f77a4 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -260,6 +260,9 @@ <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="source" xsi:type="string">customer</item> + <item name="options" xsi:type="array"> + <item name="maxDate" xsi:type="string">-1d</item> + </item> </item> </argument> <settings> From 849a26752d0838c98f66a2bd3a179f14fe68a17e Mon Sep 17 00:00:00 2001 From: Lucas Calazans <calazans95@hotmail.com> Date: Sat, 14 Sep 2019 14:55:00 -0300 Subject: [PATCH 0468/1172] Cleaning region after country change --- .../Checkout/view/frontend/web/js/region-updater.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index a9cbb1194cfd..175b6ca32068 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -224,8 +224,13 @@ define([ postcode.addClass('required-entry').closest('.field').addClass('required'); } - // Add defaultvalue attribute to state/province select element - regionList.attr('defaultvalue', this.options.defaultRegion); + if (!this.options.defaultRegion) { + regionList.val(''); + regionInput.val(''); + } else { + // Add defaultvalue attribute to state/province select element + regionList.attr('defaultvalue', this.options.defaultRegion); + } }, /** From 497462878f0a0bdec5becda7c92075e29a431346 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Sat, 14 Sep 2019 15:07:47 -0300 Subject: [PATCH 0469/1172] adding the validation for manual input on customer create, on frontend --- .../Magento/Customer/Block/Widget/Dob.php | 2 ++ .../view/frontend/templates/widget/dob.phtml | 8 ++++++++ .../view/frontend/web/js/validation.js | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 app/code/Magento/Customer/view/frontend/web/js/validation.js diff --git a/app/code/Magento/Customer/Block/Widget/Dob.php b/app/code/Magento/Customer/Block/Widget/Dob.php index d874729d9132..0a60c2d634cb 100644 --- a/app/code/Magento/Customer/Block/Widget/Dob.php +++ b/app/code/Magento/Customer/Block/Widget/Dob.php @@ -267,6 +267,8 @@ public function getHtmlExtraParams() $validators['validate-date'] = [ 'dateFormat' => $this->getDateFormat() ]; + $validators['validate-dob'] = true; + return 'data-validate="' . $this->_escaper->escapeHtml(json_encode($validators)) . '"'; } diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml index ac4b9f93e0c5..3c2f970faade 100644 --- a/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/widget/dob.phtml @@ -35,3 +35,11 @@ $fieldCssClass .= $block->isRequired() ? ' required' : ''; <?php endif; ?> </div> </div> + +<script type="text/x-magento-init"> + { + "*": { + "Magento_Customer/js/validation": {} + } + } + </script> diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js new file mode 100644 index 000000000000..840134d64422 --- /dev/null +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -0,0 +1,19 @@ +require([ + 'jquery', + 'moment', + 'jquery/ui', + 'jquery/validate', + 'mage/translate', +], function($, moment) { + 'use strict'; + $.validator.addMethod( + "validate-dob", + function (value) { + if (value === '') { + return true; + } + return moment(value).isBefore(moment()); + }, + $.mage.__('The Date of Birth should not be greater than today.') + ); +}); From 4122c40e193813e568b44953d6e12392cfed27cc Mon Sep 17 00:00:00 2001 From: Lucas Calazans <calazans95@hotmail.com> Date: Sat, 14 Sep 2019 15:16:25 -0300 Subject: [PATCH 0470/1172] Cleaning inputs value before the checks --- .../Checkout/view/frontend/web/js/region-updater.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 175b6ca32068..669e477770be 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -164,6 +164,7 @@ define([ // Populate state/province dropdown list if available or use input box if (this.options.regionJson[country]) { + $(regionList).find('option:selected').removeAttr("selected"); this._removeSelectOptions(regionList); $.each(this.options.regionJson[country], $.proxy(function (key, value) { this._renderSelectOption(regionList, key, value); @@ -198,6 +199,7 @@ define([ regionInput.hide(); label.attr('for', regionList.attr('id')); } else { + regionInput.val(''); this._removeSelectOptions(regionList); if (this.options.isRegionRequired) { @@ -224,13 +226,7 @@ define([ postcode.addClass('required-entry').closest('.field').addClass('required'); } - if (!this.options.defaultRegion) { - regionList.val(''); - regionInput.val(''); - } else { - // Add defaultvalue attribute to state/province select element - regionList.attr('defaultvalue', this.options.defaultRegion); - } + regionList.attr('defaultvalue', this.options.defaultRegion); }, /** From 140d59162047b25b9d413e3e597e383b41090616 Mon Sep 17 00:00:00 2001 From: Lucas Calazans <calazans95@hotmail.com> Date: Sat, 14 Sep 2019 16:25:36 -0300 Subject: [PATCH 0471/1172] Fixing static tests --- .../Magento/Checkout/view/frontend/web/js/region-updater.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 669e477770be..4f9b4c44db61 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -164,7 +164,7 @@ define([ // Populate state/province dropdown list if available or use input box if (this.options.regionJson[country]) { - $(regionList).find('option:selected').removeAttr("selected"); + $(regionList).find('option:selected').removeAttr('selected'); this._removeSelectOptions(regionList); $.each(this.options.regionJson[country], $.proxy(function (key, value) { this._renderSelectOption(regionList, key, value); From b97290e5ebba09eb9193b2bcc897aba983f6480a Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Mon, 16 Sep 2019 08:28:03 +0300 Subject: [PATCH 0472/1172] MC-20069: Fix Skipped MFTF Tests From MC-17140: MAGETWO-72277, MAGETWO-84682, MAGETWO-94854 --- .../Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml index a7ac9e38d4b0..9c961f9da751 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml @@ -16,9 +16,6 @@ <description value="Admin should be able to add widget to WYSIWYG Editor Newsletter"/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-84682"/> - <skip> - <issueId value="MC-17140"/> - </skip> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> From 9bddf12fbbe2138c1484e5ed3e095e7f6dd7f735 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 16 Sep 2019 10:54:17 +0300 Subject: [PATCH 0473/1172] MC-15507: Shipping address is dropped after zip code in new billing address form is filled - Fix for automation test. --- .../GuestCheckoutFillNewBillingAddressActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml index 6d92ca79000e..a1137308e8e6 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillNewBillingAddressActionGroup.xml @@ -24,7 +24,7 @@ <fillField selector="{{CheckoutPaymentSection.guestPostcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> <fillField selector="{{CheckoutPaymentSection.guestTelephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> </actionGroup> - <actionGroup name="CheckoutFillNewBillingAddressActionGroup" extends="GuestCheckoutFillNewBillingAddressActionGroup"> + <actionGroup name="StorefrontCheckoutFillNewBillingAddressActionGroup" extends="GuestCheckoutFillNewBillingAddressActionGroup"> <remove keyForRemoval="enterEmail"/> <remove keyForRemoval="waitForLoading3"/> </actionGroup> From 35e98f5fd33b4bdaa44dd4f3e982cbe7b30e3565 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Mon, 16 Sep 2019 11:40:17 +0300 Subject: [PATCH 0474/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../SaveQuoteAddressToCustomerAddressBook.php | 1 - .../Model/Cart/SetShippingAddressesOnCart.php | 20 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php index e9aa4ba745b9..543fe96ddec8 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php @@ -52,7 +52,6 @@ public function __construct( } /** - * * @param QuoteAddress $quoteAddress * @param int $customerId * diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index 1b735aadc110..f2e639f74cc2 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -78,6 +78,24 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } + $shippingAddress = $this->createShippingAddress($context, $customerAddressId, $addressInput); + + $this->assignShippingAddressToCart->execute($cart, $shippingAddress); + } + + /** + * @param ContextInterface $context + * @param int|null $customerAddressId + * @param array|null $addressInput + * + * @return \Magento\Quote\Model\Quote\Address + * @throws GraphQlAuthorizationException + */ + private function createShippingAddress( + ContextInterface $context, + ?int $customerAddressId, + ?array $addressInput + ) { $customerId = $context->getUserId(); if (null === $customerAddressId) { @@ -98,6 +116,6 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } - $this->assignShippingAddressToCart->execute($cart, $shippingAddress); + return $shippingAddress; } } From cbbf6127b68e3c5b68b0e06d81e4614e58f1210a Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 16 Sep 2019 15:42:13 +0400 Subject: [PATCH 0475/1172] MC-18821: Increase test coverage for Account functional area - Automation test for MC-11531 --- .../Test/Mftf/Section/StorefrontCategorySidebarSection.xml | 4 ++-- .../ActionGroup/AdminConfigurableProductActionGroup.xml | 4 ---- .../StorefrontImageColorWhenFilterByColorFilterTest.xml | 7 ++----- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml index 2c73941a92b4..136a8ceadb89 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontCategorySidebarSection.xml @@ -12,8 +12,8 @@ <element name="filterOptions" type="text" selector=".filter-options-content .items"/> <element name="filterOption" type="text" selector=".filter-options-content .item"/> <element name="optionQty" type="text" selector=".filter-options-content .item .count"/> - <element name="filterOptionByLabel" type="button" selector="//div[contains(@class, 'filter-options-item')]//div[contains(@class, 'swatch-option') and @option-label='{{optionLabel}}']" parameterized="true"/> - <element name="removeFilter" type="button" selector="//div[contains(@class, 'filter-current')]//a[contains(@class, 'remove')]"/> + <element name="filterOptionByLabel" type="button" selector=" div.filter-options-item div[option-label='{{optionLabel}}']" parameterized="true"/> + <element name="removeFilter" type="button" selector="div.filter-current .remove"/> </section> <section name="StorefrontCategorySidebarMobileSection"> <element name="shopByButton" type="button" selector="//div[contains(@class, 'filter-title')]/strong[contains(text(), 'Shop By')]"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml index 1561fa5e2702..a0a3a551c3d9 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/ActionGroup/AdminConfigurableProductActionGroup.xml @@ -220,10 +220,6 @@ <click selector="{{AdminCreateProductConfigurationsPanel.next}}" before="clickOnSaveButton2" stepKey="clickOnNextButton"/> <click selector="{{AdminCreateProductConfigurationsPanel.next}}" after="clickOnNextButton" stepKey="clickOnGenerateProductsButton"/> </actionGroup> - <actionGroup name="GenerateConfiguredProductAfterSettingOptions"> - <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton"/> - <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnGenerateProductsButton"/> - </actionGroup> <actionGroup name="addNewProductConfigurationAttribute"> <annotations> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml index 428915ab8ae6..033778635ddb 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontImageColorWhenFilterByColorFilterTest.xml @@ -21,7 +21,6 @@ </annotations> <before> <!--Create category and configurable product with two options--> - <comment userInput="Create category and configurable product" stepKey="commentCreateData"/> <createData entity="ApiCategory" stepKey="createCategory"/> <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> <requiredEntity createDataKey="createCategory"/> @@ -45,7 +44,6 @@ <amOnPage url="{{AdminProductEditPage.url($$createConfigProduct.id$$)}}" stepKey="navigateToConfigProductPage"/> <waitForPageLoad stepKey="waitForProductPageLoad"/> <!--Create visual swatch attribute--> - <comment userInput="Create visual swatch attribute" stepKey="commentCreateAttribute"/> <actionGroup ref="AddVisualSwatchWithProductWithStorefrontPreviewImageConfigActionGroup" stepKey="addSwatchToProduct"> <argument name="attribute" value="visualSwatchAttribute"/> <argument name="option1" value="visualSwatchOption1"/> @@ -56,7 +54,6 @@ <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton1"/> <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton2"/> <!--Add images to product attribute options--> - <comment userInput="Add images to product attribute options" stepKey="commentAddImageToOptions"/> <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionOne"> <argument name="image" value="MagentoLogo"/> <argument name="frontend_label" value="{{visualSwatchAttribute.default_label}}"/> @@ -67,10 +64,10 @@ <argument name="frontend_label" value="{{visualSwatchAttribute.default_label}}"/> <argument name="label" value="{{visualSwatchOption2.default_label}}"/> </actionGroup> - <actionGroup ref="GenerateConfiguredProductAfterSettingOptions" stepKey="generateConfigs"/> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnNextButton"/> + <click selector="{{AdminCreateProductConfigurationsPanel.next}}" stepKey="clickOnGenerateProductsButton"/> <actionGroup ref="saveProductForm" stepKey="saveProductForm"/> <!--Select any option in the Layered navigation and verify product image--> - <comment userInput="Select any option in the Layered navigation and verify product image" stepKey="commentVerifyImage"/> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="navigateToCategoryPage"/> <actionGroup ref="SelectStorefrontSideBarAttributeOption" stepKey="selectStorefrontProductAttributeOption"> <argument name="categoryName" value="$$createCategory.name$$"/> From f2627308caa7595d1e0da148f431dffcc132f120 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Mon, 16 Sep 2019 15:17:59 +0300 Subject: [PATCH 0476/1172] MC-20075: Fix Skipped MFTF Tests From MC-17140: MC-14536, MC-14538, MC-14720 --- ...yWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml index 09a5ce4c7037..a0aec77ad419 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml @@ -15,9 +15,6 @@ <testCaseId value="MC-14720"/> <severity value="CRITICAL"/> <group value="mtf_migrated"/> - <skip> - <issueId value="MC-17140"/> - </skip> </annotations> <before> From 5d440c5f5acb7092d6ca27212d249b313aa700ce Mon Sep 17 00:00:00 2001 From: Lucas Calazans <calazans95@hotmail.com> Date: Mon, 16 Sep 2019 09:23:26 -0300 Subject: [PATCH 0477/1172] Cleaning values before populate --- .../Magento/Checkout/view/frontend/web/js/region-updater.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 4f9b4c44db61..6a40e882a6bf 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -162,9 +162,11 @@ define([ this._clearError(); this._checkRegionRequired(country); + $(regionList).find('option:selected').removeAttr('selected'); + regionInput.val(''); + // Populate state/province dropdown list if available or use input box if (this.options.regionJson[country]) { - $(regionList).find('option:selected').removeAttr('selected'); this._removeSelectOptions(regionList); $.each(this.options.regionJson[country], $.proxy(function (key, value) { this._renderSelectOption(regionList, key, value); @@ -199,7 +201,6 @@ define([ regionInput.hide(); label.attr('for', regionList.attr('id')); } else { - regionInput.val(''); this._removeSelectOptions(regionList); if (this.options.isRegionRequired) { From f51fd0b5f105966aa8bed720581e89c9e140424d Mon Sep 17 00:00:00 2001 From: Lucas Calazans <calazans95@hotmail.com> Date: Mon, 16 Sep 2019 09:24:41 -0300 Subject: [PATCH 0478/1172] Reverting removed comment --- app/code/Magento/Checkout/view/frontend/web/js/region-updater.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js index 6a40e882a6bf..6d54f607484b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js @@ -227,6 +227,7 @@ define([ postcode.addClass('required-entry').closest('.field').addClass('required'); } + // Add defaultvalue attribute to state/province select element regionList.attr('defaultvalue', this.options.defaultRegion); }, From 966e4a071d97ebeac5266cd1cd735d2d7c3f0caf Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 16 Sep 2019 16:30:57 +0400 Subject: [PATCH 0479/1172] MC-18821: Increase test coverage for Catalog functional area - Automation test for MC-13641 --- .../Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml | 2 +- ...inSaveConfProductWithCustomProductAttributeTest.xml | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml b/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml index 750f7233342b..76dd6995c751 100644 --- a/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml +++ b/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml @@ -14,7 +14,7 @@ <magentoCLI command="deploy:mode:set production" stepKey="enableProductionMode"/> </after> <include> - <test name="AdminSaveConfProductWithCustomProductAttributeTest"/> + <group name="developer_mode_only"/> </include> </suite> </suites> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml index a7e1d5cad65e..084dceb004b4 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml @@ -11,18 +11,17 @@ <test name="AdminSaveConfProductWithCustomProductAttributeTest"> <annotations> <features value="Swatches"/> - <stories value="Configurable product with custom product images as swatches attribute"/> + <stories value="Configurable product with swatch attribute"/> <title value="Saving configurable product with custom product attribute (images as swatches)"/> <description value="Saving configurable product with custom product attribute (images as swatches)"/> <severity value="CRITICAL"/> <testCaseId value="MC-13641"/> <useCaseId value="MC-10968"/> - <group value="swatches"/> + <group value="developer_mode_only"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create configurable product--> - <comment userInput="Create configurable product" stepKey="commentCreateConfProduct"/> <createData entity="SimpleSubCategory" stepKey="createCategory"/> <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> <requiredEntity createDataKey="createCategory"/> @@ -30,7 +29,6 @@ </before> <after> <!--Delete created data--> - <comment userInput="Delete created data" stepKey="commentDeleteCreatedData"/> <deleteData createDataKey="createConfigProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToProductIndexPage"/> @@ -41,14 +39,12 @@ <actionGroup ref="logout" stepKey="logout"/> </after> <!--Create Visual swatch with preview image--> - <comment userInput="Create Visual swatch with preview image" stepKey="commentCreateAttribute"/> <amOnPage url="{{ProductAttributePage.url}}" stepKey="goToNewProductAttributePage"/> <actionGroup ref="AdminFillProductAttributePropertiesActionGroup" stepKey="fillProductAttributeProperties"> <argument name="attributeName" value="{{VisualSwatchProductAttribute.attribute_code}}"/> <argument name="attributeType" value="{{VisualSwatchProductAttribute.frontend_input}}"/> </actionGroup> <!--Add first option--> - <comment userInput="Add first option" stepKey="commentAddFirstOption"/> <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addFirstSwatchOptionAndFillFields"> <argument name="swatchOption" value="visualSwatchOption1"/> </actionGroup> @@ -60,7 +56,6 @@ <argument name="index" value="1"/> </actionGroup> <!--Add second option--> - <comment userInput="Add second option" stepKey="commentAddSecondOption"/> <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addSecondSwatchOptionAndFillFields"> <argument name="swatchOption" value="visualSwatchOption2"/> </actionGroup> @@ -76,7 +71,6 @@ <argument name="message" value="You saved the product attribute."/> </actionGroup> <!--Create configurations for product--> - <comment userInput="Create configurations for product" stepKey="commentCreateConfigsForProduct"/> <amOnPage url="{{AdminProductEditPage.url($$createConfigProduct.id$$)}}" stepKey="goToProductEditPage"/> <waitForPageLoad stepKey="waitForProductPageLoad"/> <actionGroup ref="StartCreateConfigurationsForAttribute" stepKey="createConfigurations"> From ebb48f81424e3cc414492e99bdde856e0a166db3 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <lusine_papyan@epam.com> Date: Mon, 16 Sep 2019 13:53:45 +0300 Subject: [PATCH 0480/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup - Updated automated test script --- .../AdminCMSBlockContentActionGroup.xml | 22 +++++++++---------- .../CmsNewBlockBlockActionsSection.xml | 14 +----------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml index f350865fbf3d..a7dc5ab96890 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml @@ -11,18 +11,16 @@ <arguments> <argument name="image" type="entity" defaultValue="MagentoLogo"/> </arguments> - <click selector="{{BlockContentItemsSection.addImageButton}}" stepKey="clickAddImageButton"/> - <waitForElementVisible selector="{{BlockInsertOrEditImageSection.browseImage}}" stepKey="waitForBrowseImage"/> - <click selector="{{BlockInsertOrEditImageSection.browseImage}}" stepKey="clickBrowseImage"/> - <waitForElementVisible selector="{{BlockSelectImageSection.treeRoot}}" stepKey="waitForAttacheFiles"/> - <click selector="{{BlockSelectImageSection.treeRoot}}" stepKey="clickRoot"/> + <click selector="{{TinyMCESection.InsertImage}}" stepKey="clickAddImageButton"/> + <waitForElementVisible selector="{{MediaGallerySection.Browse}}" stepKey="waitForBrowseImage"/> + <click selector="{{MediaGallerySection.Browse}}" stepKey="clickBrowseImage"/> + <waitForElementVisible selector="{{MediaGallerySection.StorageRootArrow}}" stepKey="waitForAttacheFiles"/> + <click selector="{{MediaGallerySection.StorageRootArrow}}" stepKey="clickRoot"/> <waitForPageLoad stepKey="waitForPageLoad"/> - <attachFile selector="{{BlockSelectImageSection.uploadFile}}" userInput="{{image.file}}" stepKey="attachLogo"/> - <waitForElementVisible selector="{{BlockSelectImageSection.addSelected}}" stepKey="waitForAddSelected"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear2"/> - <click selector="{{BlockSelectImageSection.addSelected}}" stepKey="clickAddSelected"/> - <waitForElementVisible selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="waitForOkButton"/> - <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear"/> - <click selector="{{BlockInsertOrEditImageSection.ok}}" stepKey="clickOk"/> + <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{image.file}}" stepKey="attachLogo"/> + <waitForElementVisible selector="{{MediaGallerySection.InsertFile}}" stepKey="waitForAddSelected"/> + <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickAddSelected"/> + <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkButton"/> + <click selector="{{MediaGallerySection.OkBtn}}" stepKey="clickOk"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml index e7ad1b617ec4..445279a8b140 100644 --- a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml +++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewBlockBlockActionsSection.xml @@ -24,23 +24,11 @@ </section> <section name="BlockContentSection"> <element name="TextArea" type="input" selector="#cms_block_form_content"/> - <element name="image" type="file" selector="//*[contains(@class, 'mce-content-body')]//img"/> + <element name="image" type="file" selector="#tinymce img"/> <element name="contentIframe" type="iframe" selector="cms_block_form_content_ifr"/> </section> <section name="CmsBlockBlockActionSection"> <element name="deleteBlock" type="button" selector="#delete" timeout="30"/> <element name="deleteConfirm" type="button" selector=".action-primary.action-accept" timeout="60"/> </section> - <section name="BlockContentItemsSection"> - <element name="addImageButton" type="button" selector="//div[contains(@class, 'mce-widget')]//i[contains(@class, 'mce-i-image')]"/> - </section> - <section name="BlockInsertOrEditImageSection"> - <element name="browseImage" type="button" selector="//div[contains(@class, 'mce-floatpanel')]//i[contains(@class, 'mce-i-browse')]"/> - <element name="ok" type="button" selector="//div[contains(@class, 'mce-floatpanel')]//span[contains(text(), 'Ok')]"/> - </section> - <section name="BlockSelectImageSection"> - <element name="uploadFile" type="input" selector="input.fileupload"/> - <element name="addSelected" type="button" selector="#insert_files"/> - <element name="treeRoot" type="text" selector="#root"/> - </section> </sections> From f97b59dfeb84c65ba22fab01e02299fc06dc8720 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Mon, 16 Sep 2019 15:59:57 +0300 Subject: [PATCH 0481/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup --- lib/web/mage/loader.js | 5 +---- lib/web/mage/loader_old.js | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js index 29034f93e8ba..83299efba422 100644 --- a/lib/web/mage/loader.js +++ b/lib/web/mage/loader.js @@ -69,10 +69,7 @@ define([ show: function (e, ctx) { this._render(); this.loaderStarted++; - - if (this.loaderStarted === 1) { - this.spinner.show(); - } + this.spinner.show(); if (ctx) { this.spinner diff --git a/lib/web/mage/loader_old.js b/lib/web/mage/loader_old.js index e008beb12d13..f759758acd12 100644 --- a/lib/web/mage/loader_old.js +++ b/lib/web/mage/loader_old.js @@ -81,10 +81,7 @@ show: function (e, ctx) { this._render(); this.loaderStarted++; - - if (this.loaderStarted === 1) { - this.spinner.show(); - } + this.spinner.show(); if (ctx) { this.spinner From d72ba99f208d593e1adc83f597e8fb09bba28bbd Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Mon, 16 Sep 2019 16:24:36 +0300 Subject: [PATCH 0482/1172] MC-17493: Cart/catalog rules grid missing - Fix for automation test. --- .../ActionGroup/CatalogPriceRuleActionGroup.xml | 2 +- .../AdminCreateCartPriceRuleActionGroup.xml | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index e4aecfab549a..39f509c68c6e 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -57,7 +57,7 @@ <scrollToTopOfPage stepKey="scrollToTop"/> <waitForPageLoad stepKey="waitForApplied"/> </actionGroup> - <actionGroup name="CreateMultipleWebsiteCatalogPriceRule" extends="createCatalogPriceRule"> + <actionGroup name="AdminCreateMultipleWebsiteCatalogPriceRule" extends="createCatalogPriceRule"> <remove keyForRemoval="selectSite"/> <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> </actionGroup> diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index 8d71b8501a41..537fc3fbc55e 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -105,18 +105,17 @@ <waitForElementVisible selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="waitForCategoryVisible" after="openChooser"/> <checkOption selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="checkCategoryName" after="waitForCategoryVisible"/> </actionGroup> - <actionGroup name="AdminMultiWebsiteCartPriceRuleActionGroup"> + <actionGroup name="AdminMultiWebsiteCartPriceRuleActionGroup" extends="AdminCreateCartPriceRuleActionGroup"> + <annotations> + <description>EXTENDS: AdminCreateCartPriceRuleActionGroup. Removes 'clickSaveButton' for the next data changing. Assign cart price rule to 2 websites instead of 1.</description> + </annotations> <arguments> <argument name="ruleName"/> </arguments> - <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="amOnCartPriceList"/> - <waitForPageLoad stepKey="waitForPriceList"/> - <click selector="{{AdminCartPriceRulesSection.addNewRuleButton}}" stepKey="clickAddNewRule"/> - <fillField selector="{{AdminCartPriceRulesFormSection.ruleName}}" userInput="{{ruleName.name}}" stepKey="fillRuleName"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> - <click selector="{{AdminCartPriceRulesFormSection.actionsHeader}}" stepKey="clickToExpandActions"/> - <selectOption selector="{{AdminCartPriceRulesFormSection.apply}}" userInput="{{ruleName.apply}}" stepKey="selectActionType"/> - <fillField selector="{{AdminCartPriceRulesFormSection.discountAmount}}" userInput="{{ruleName.discountAmount}}" stepKey="fillDiscountAmount"/> + <remove keyForRemoval="clickSaveButton"/> + <remove keyForRemoval="seeSuccessMessage"/> + <remove keyForRemoval="selectWebsites"/> + <selectOption selector="{{AdminCartPriceRulesFormSection.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsites" after="fillRuleName"/> </actionGroup> <actionGroup name="CreateCartPriceRuleSecondWebsiteActionGroup"> <annotations> From 232fd1d64d4d6168a3111d509f868f79ee020f67 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 16 Sep 2019 09:18:11 -0500 Subject: [PATCH 0483/1172] MC-19247: Broken translations with advanced bundling - Define dictionary as a text; --- .../Magento/Translation/view/base/templates/dictionary.phtml | 4 ++-- lib/web/mage/translate.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index fb082439b1c3..efd13e927cbd 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -8,7 +8,7 @@ $viewModel = $block->getData('dictionary_view_model'); ?> <script> - define('dictionary', function () { - return <?= /* @noEscape */ $viewModel->getTranslationDictionary() ?>; + define('text!dictionary', function () { + return "[]"; }); </script> diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index db341807364e..c4e7e53cea8a 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -6,7 +6,7 @@ define([ 'jquery', 'mage/mage', - 'dictionary' + 'text!dictionary' ], function ($, mage, dictionary) { 'use strict'; From 94f2c18f51554c6b2296012e0c294e1c890f82e3 Mon Sep 17 00:00:00 2001 From: utietze <ulf@tietze-digital.de> Date: Mon, 16 Sep 2019 16:40:15 +0200 Subject: [PATCH 0484/1172] Use InvalidArgumentException from plain PHP Update Patch --- .../Magento/Framework/MessageQueue/MessageValidator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php index a40bb9af1e0c..abb2918d459a 100644 --- a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php +++ b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php @@ -5,7 +5,7 @@ */ namespace Magento\Framework\MessageQueue; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Phrase; use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; @@ -58,6 +58,7 @@ protected function getTopicSchema($topic, $requestType) * @param bool $requestType * @return void * @throws InvalidArgumentException + * @throws LocalizedException */ public function validate($topic, $message, $requestType = true) { From 6fc366c5a743b08eb61f817ca35035cf37c9a9a5 Mon Sep 17 00:00:00 2001 From: utietze <ulf@tietze-digital.de> Date: Mon, 16 Sep 2019 16:43:48 +0200 Subject: [PATCH 0485/1172] No need for extra doctrine dependency --- lib/internal/Magento/Framework/MessageQueue/composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/MessageQueue/composer.json b/lib/internal/Magento/Framework/MessageQueue/composer.json index f1397fb91afe..56644e428e5c 100644 --- a/lib/internal/Magento/Framework/MessageQueue/composer.json +++ b/lib/internal/Magento/Framework/MessageQueue/composer.json @@ -11,8 +11,7 @@ ], "require": { "magento/framework": "*", - "php": "~7.1.3||~7.2.0||~7.3.0", - "doctrine/instantiator": "^1.0" + "php": "~7.1.3||~7.2.0||~7.3.0" }, "autoload": { "psr-4": { From 6b9f71a89ceef01050cbe9446891a15d3ab56d23 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 16 Sep 2019 10:08:46 -0500 Subject: [PATCH 0486/1172] MC-19247: Broken translations with advanced bundling - Update comment; --- .../Magento/Translation/view/base/templates/translate.phtml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index c4592e02eff8..844b16024f15 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -6,8 +6,7 @@ /** @var \Magento\Translation\Block\Js $block */ ?> -<!--Now dictionary file is inserted into html head in Magento/Translation/view/base/templates/dictionary.phtml--> -<!--So now this script is redundant--> +<!--Now dictionary file is inserted into html head for frontend in Magento/Translation/view/base/templates/dictionary.phtml--> <?php if ($block->dictionaryEnabled()) : ?> <script> require.config({ From a846ecc1a0e1c22f7f78b3ea5740bba721aac44b Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 16 Sep 2019 14:27:38 -0500 Subject: [PATCH 0487/1172] MC-19247: Broken translations with advanced bundling - Add fake dictionary for js unit tests; --- .../Translation/view/base/templates/dictionary.phtml | 4 ++-- dev/tests/js/jasmine/require.conf.js | 5 +++++ dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js | 8 ++++++++ dev/tests/js/jasmine/tests/lib/mage/translate.test.js | 8 ++++---- lib/web/mage/translate.js | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index efd13e927cbd..fb082439b1c3 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -8,7 +8,7 @@ $viewModel = $block->getData('dictionary_view_model'); ?> <script> - define('text!dictionary', function () { - return "[]"; + define('dictionary', function () { + return <?= /* @noEscape */ $viewModel->getTranslationDictionary() ?>; }); </script> diff --git a/dev/tests/js/jasmine/require.conf.js b/dev/tests/js/jasmine/require.conf.js index cd5d6fe836da..43ea596007f0 100644 --- a/dev/tests/js/jasmine/require.conf.js +++ b/dev/tests/js/jasmine/require.conf.js @@ -19,6 +19,11 @@ require.config({ 'tests': '../../../../../../dev/tests/js/jasmine', 'squire': '../../../../../../node_modules/squirejs/src/Squire' }, + map: { + '*': { + dictionary: '../../../../../../dev/tests/js/jasmine/tests/lib/mage/fake-dictionary' + } + }, shim: { squire: { exports: 'squire' diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js new file mode 100644 index 000000000000..a40bd15c77bd --- /dev/null +++ b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js @@ -0,0 +1,8 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +// Fake dictionary for js unit tests as real dictionary is defined is template and cannot be initialized by requirejs +define([], function () { + return {}; +}); diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js index c87cfa227c1a..22be0fbbaa32 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js @@ -14,6 +14,10 @@ define([ $.mage.translate.add('Hello World!'); expect('Hello World!').toEqual($.mage.translate.translate('Hello World!')); }); + it('works with translation alias __', function () { + $.mage.translate.add('Hello World!'); + expect('Hello World!').toEqual($.mage.__('Hello World!')); + }); it('works with one array as parameter', function () { $.mage.translate.add(['Hello World!', 'Bonjour tout le monde!']); expect('Hello World!').toEqual($.mage.translate.translate('Hello World!')); @@ -40,10 +44,6 @@ define([ $.mage.translate.add('Hello World!', 'Bonjour tout le monde!'); expect('Bonjour tout le monde!').toEqual($.mage.translate.translate('Hello World!')); }); - it('works with translation alias __', function () { - $.mage.translate.add('Hello World!'); - expect('Hello World!').toEqual($.mage.__('Hello World!')); - }); }); }); diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index c4e7e53cea8a..db341807364e 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -6,7 +6,7 @@ define([ 'jquery', 'mage/mage', - 'text!dictionary' + 'dictionary' ], function ($, mage, dictionary) { 'use strict'; From af587486d8aa30956c08eb99fdc09873fa7cbb17 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 16 Sep 2019 16:50:16 -0500 Subject: [PATCH 0488/1172] MC-19247: Broken translations with advanced bundling - Add strict type to js unit test; - Eliminate preference for file system driver; --- .../Translation/ViewModel/Dictionary.php | 25 +++++++------------ app/code/Magento/Translation/etc/di.xml | 6 ++++- .../jasmine/tests/lib/mage/fake-dictionary.js | 2 ++ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 41a5faf097da..011501fc219a 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -10,7 +10,6 @@ use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filesystem; -use Magento\Framework\View\Asset\File\NotFoundException; use Magento\Framework\View\Asset\Repository as AssetRepository; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\Js\Config as JsConfig; @@ -64,26 +63,20 @@ public function __construct( * Get translation dictionary file content. * * @return string + * @throws FileSystemException + * @throws LocalizedException */ public function getTranslationDictionary(): string { if ($this->appState->getMode() === AppState::MODE_PRODUCTION) { - try { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - $staticViewFilePath = $this->filesystem->getDirectoryRead( - DirectoryList::STATIC_VIEW - )->getAbsolutePath(); - $content = $this->filesystemDriver->fileGetContents($staticViewFilePath . $asset->getPath()); - } catch (LocalizedException | FileSystemException $e) { - $content = ''; - } + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + $staticViewFilePath = $this->filesystem->getDirectoryRead( + DirectoryList::STATIC_VIEW + )->getAbsolutePath(); + $content = $this->filesystemDriver->fileGetContents($staticViewFilePath . $asset->getPath()); } else { - try { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - $content = $asset->getContent(); - } catch (LocalizedException | NotFoundException $e) { - $content = ''; - } + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + $content = $asset->getContent(); } return $content; diff --git a/app/code/Magento/Translation/etc/di.xml b/app/code/Magento/Translation/etc/di.xml index 3ba249d60127..acb24bcd0a71 100644 --- a/app/code/Magento/Translation/etc/di.xml +++ b/app/code/Magento/Translation/etc/di.xml @@ -15,7 +15,11 @@ <preference for="Magento\Framework\Phrase\RendererInterface" type="Magento\Framework\Phrase\Renderer\Composite" /> <preference for="Magento\Translation\Model\Js\DataProviderInterface" type="Magento\Translation\Model\Js\DataProvider"/> <preference for="Magento\Framework\Translate\Js\Config" type="Magento\Translation\Model\Js\Config"/> - <preference for="Magento\Framework\Filesystem\DriverInterface" type="Magento\Framework\Filesystem\Driver\File"/> + <type name="Magento\Translation\ViewModel\Dictionary"> + <arguments> + <argument name="filesystemDriver" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument> + </arguments> + </type> <type name="Magento\Framework\Translate\Inline"> <arguments> <argument name="templateFileName" xsi:type="string">Magento_Translation::translate_inline.phtml</argument> diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js index a40bd15c77bd..bdaf66991a30 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js +++ b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js @@ -4,5 +4,7 @@ */ // Fake dictionary for js unit tests as real dictionary is defined is template and cannot be initialized by requirejs define([], function () { + 'use strict'; + return {}; }); From 8c2760f4b09ff63188c25ae131265c5dae60075b Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Mon, 16 Sep 2019 22:23:43 +0300 Subject: [PATCH 0489/1172] MAGETWO-99490: gift messaging options are not saved with multi-address checkout - Check gift massage ID in quote and quote items. - Added functional test. --- .../Message/Multishipping/Plugin/ItemsBox.php | 9 ++ .../Mftf/Section/AdminOrderGiftSection.xml | 15 +++ .../StorefrontCheckoutCartGiftSection.xml | 16 +++ .../Section/StorefrontOrderGiftSection.xml | 15 +++ ...eckingWithMultipleAddressesActionGroup.xml | 12 +++ .../SelectShippingInfoActionGroup.xml | 4 + .../Mftf/Section/MultishippingSection.xml | 2 + ...frontCheckoutWithMultipleAddressesTest.xml | 97 +++++++++++++++++++ 8 files changed, 170 insertions(+) create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/AdminOrderGiftSection.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftSection.xml create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml diff --git a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php index e02401c1a865..59ad900c491b 100644 --- a/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php +++ b/app/code/Magento/GiftMessage/Block/Message/Multishipping/Plugin/ItemsBox.php @@ -43,6 +43,15 @@ public function __construct(MessageHelper $helper) */ public function afterGetItemsBoxTextAfter(ShippingBlock $subject, $itemsBoxText, DataObject $addressEntity) { + if ($addressEntity->getGiftMessageId() === null) { + $addressEntity->setGiftMessageId($addressEntity->getQuote()->getGiftMessageId()); + } + foreach ($addressEntity->getAllItems() as $item) { + if ($item->getGiftMessageId() === null) { + $item->setGiftMessageId($item->getQuoteItem()->getGiftMessageId()); + } + } + return $itemsBoxText . $this->helper->getInline('multishipping_address', $addressEntity); } } diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/AdminOrderGiftSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/AdminOrderGiftSection.xml new file mode 100644 index 000000000000..dc6d0b79a836 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/AdminOrderGiftSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminOrderGiftSection"> + <element name="orderItemGiftOptionsLink" type="text" selector="//table[contains(@class, 'edit-order-table')]//tbody[contains(.,'{{productName}}')]//a[contains(@class, 'action-link')]" parameterized="true"/> + <element name="orderItemGiftMessage" type="textarea" selector="#current_item_giftmessage_message" /> + </section> +</sections> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftSection.xml new file mode 100644 index 000000000000..e39279de228f --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutCartGiftSection"> + <element name="cartItemGiftMessage" type="text" selector="//tbody[contains(.,'{{productName}}')]//div[@class='gift-message']//textarea" parameterized="true"/> + <element name="orderNumber" type="text" selector="(//div[contains(@class, 'orders-succeed')]//a)[{{blockNumber}}]" parameterized="true"/> + <element name="viewOrder" type="text" selector="//table[@id='my-orders-table']//tr[contains(.,'{{orderNumber}}')]//a[contains(@class, 'action view')]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml new file mode 100644 index 000000000000..301767561166 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontOrderGiftSection"> + <element name="giftMessageLink" type="button" selector="//div[contains(@class, 'table-wrapper order-items')]//a[contains(@id, 'order-item-gift-message-link')]"/> + <element name="giftMessage" type="text" selector=".order-gift-message .item-message" /> + </section> +</sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml index 333c2aec6c28..c5d04c6ab730 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml @@ -23,5 +23,17 @@ <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}" after="selectSecondShippingMethod" /> <waitForPageLoad stepKey="waitForShippingInformation" after="clickOnUpdateAddress" /> </actionGroup> + <actionGroup name="CheckingWithThreeDifferentAddressesActionGroup" extends="CheckingWithSingleAddressActionGroup"> + <grabTextFrom stepKey="firstShippingAddressValue" selector="{{MultishippingSection.firstShippingAddressValue}}" after="waitForMultipleAddressPageLoad" /> + <selectOption selector="{{MultishippingSection.firstShippingAddressOption}}" userInput="{$firstShippingAddressValue}" stepKey="selectFirstShippingMethod" after="firstShippingAddressValue" /> + <waitForPageLoad stepKey="waitForSecondShippingAddresses" after="selectFirstShippingMethod" /> + <grabTextFrom stepKey="secondShippingAddressValue" selector="{{MultishippingSection.secondShippingAddressValue}}" after="waitForSecondShippingAddresses" /> + <selectOption selector="{{MultishippingSection.secondShippingAddressOption}}" userInput="{$secondShippingAddressValue}" stepKey="selectSecondShippingMethod" after="secondShippingAddressValue" /> + <waitForPageLoad stepKey="waitForLastShippingAddressValue" after="selectSecondShippingMethod" /> + <grabTextFrom stepKey="lastShippingAddressValue" selector="{{MultishippingSection.lastShippingAddressValue}}" after="waitForLastShippingAddressValue"/> + <selectOption selector="{{MultishippingSection.lastShippingAddressOption}}" userInput="{$lastShippingAddressValue}" stepKey="selectLastShippingMethod" after="lastShippingAddressValue"/> + <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}" after="selectLastShippingMethod"/> + <waitForPageLoad stepKey="waitForShippingInformationAfterUpdated" after="clickOnUpdateAddress"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml index af0b2467862b..29d90c9083e8 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml @@ -29,5 +29,9 @@ <waitForPageLoad stepKey="waitForRadioOptions"/> <click stepKey="goToBillingInformation" selector="{{ShippingMethodSection.goToBillingInfo}}"/> </actionGroup> + <actionGroup name="defaultShippingInfoActionGroup"> + <waitForPageLoad stepKey="waitForShippingInfo"/> + <click stepKey="goToBillingInformation" selector="{{ShippingMethodSection.goToBillingInfo}}"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index 45fafc3105c3..e182cb3c68c0 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -20,5 +20,7 @@ <element name="firstShippingAddressOption" type="select" selector="//table//tbody//tr[position()=1]//td[position()=3]//div//select"/> <element name="secondShippingAddressValue" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select//option[1]"/> <element name="secondShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> + <element name="lastShippingAddressValue" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select//option[last()]"/> + <element name="lastShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> </section> </sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml new file mode 100644 index 000000000000..c45465598959 --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontCheckoutWithMultipleAddressesTest"> + <annotations> + <features value="Multishipping"/> + <stories value="Multiple Shipping"/> + <title value="Place an order with three different addresses"/> + <description value="Place an order with three different addresses"/> + <severity value="MAJOR"/> + <testCaseId value="MC-17461"/> + <useCaseId value="MAGETWO-99490"/> + <group value="Multishipment"/> + </annotations> + <before> + <!-- Login as Admin --> + <actionGroup ref="LoginAsAdmin" stepKey="login"/> + <!-- Set configurations --> + <magentoCLI command="config:set multishipping/options/checkout_multiple 1" stepKey="allowShippingToMultipleAddresses"/> + <!-- Create simple products --> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="firstProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="SimpleProduct" stepKey="secondProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="Customer_US_UK_DE" stepKey="createCustomerWithMultipleAddresses"/> + </before> + <after> + <!-- Delete created data --> + <actionGroup ref="logout" stepKey="logout"/> + <deleteData createDataKey="firstProduct" stepKey="deleteFirstProduct"/> + <deleteData createDataKey="secondProduct" stepKey="deleteSecondProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createCustomerWithMultipleAddresses" stepKey="deleteCustomer"/> + </after> + <!-- Login to the Storefront as created customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> + <argument name="Customer" value="$$createCustomerWithMultipleAddresses$$"/> + </actionGroup> + <!-- Open the first product page --> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="goToFirstProductPage"> + <argument name="productUrl" value="$$firstProduct.custom_attributes[url_key]$$"/> + </actionGroup> + <!-- Add the first product to the Shopping Cart --> + <actionGroup ref="AddProductWithQtyToCartFromStorefrontProductPage" stepKey="addFirstProductToCart"> + <argument name="productName" value="$$firstProduct.name$$"/> + <argument name="productQty" value="1"/> + </actionGroup> + <!-- Open the second product page --> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="goToSecondProductPage"> + <argument name="productUrl" value="$$secondProduct.custom_attributes[url_key]$$"/> + </actionGroup> + <!-- Add the second product to the Shopping Cart --> + <actionGroup ref="AddProductWithQtyToCartFromStorefrontProductPage" stepKey="addSecondProductToCart"> + <argument name="productName" value="$$secondProduct.name$$"/> + <argument name="productQty" value="1"/> + </actionGroup> + <!--Go to Cart --> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> + <!-- Select different addresses and click 'Go to Shipping Information' --> + <actionGroup ref="CheckingWithMultipleAddressesActionGroup" stepKey="checkoutWithMultipleAddresses"/> + <!-- Click 'Continue to Billing Information' --> + <actionGroup ref="defaultShippingInfoActionGroup" stepKey="useDefaultShippingMethod"/> + <!-- Click 'Go to Review Your Order' --> + <actionGroup ref="SelectBillingInfoActionGroup" stepKey="useDefaultBillingMethod"/> + <!-- Click 'Place Order' --> + <actionGroup ref="PlaceOrderActionGroup" stepKey="placeOrder"/> + <!-- Open the first product page --> + <actionGroup ref="StorefrontOpenProductPageActionGroup" stepKey="goToFirstProductPageSecondTime"> + <argument name="productUrl" value="$$firstProduct.custom_attributes[url_key]$$"/> + </actionGroup> + <!-- Add three identical products to the Shopping Cart --> + <actionGroup ref="AddProductWithQtyToCartFromStorefrontProductPage" stepKey="addIdenticalProductsToCart"> + <argument name="productName" value="$$firstProduct.name$$"/> + <argument name="productQty" value="3"/> + </actionGroup> + <!--Go to Cart --> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCartWithIdenticalProducts"/> + <!-- Select different addresses and click 'Go to Shipping Information' --> + <actionGroup ref="CheckingWithThreeDifferentAddressesActionGroup" stepKey="checkoutThreeDifferentAddresses"/> + <!-- Click 'Continue to Billing Information' --> + <actionGroup ref="defaultShippingInfoActionGroup" stepKey="useDefaultShippingMethodForIdenticalProducts"/> + <!-- Click 'Go to Review Your Order' --> + <actionGroup ref="SelectBillingInfoActionGroup" stepKey="UseDefaultBillingMethodForIdenticalProducts"/> + <!-- Click 'Place Order' --> + <actionGroup ref="PlaceOrderActionGroup" stepKey="placeOrderWithIdenticalProducts"/> + </test> +</tests> From 1024f53d39890aed965301807c7df4dac344b285 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Tue, 17 Sep 2019 08:17:55 +0300 Subject: [PATCH 0490/1172] MC-16333: Admin user with permission for 1 store can manage product quantity --- .../AdminAssertDisabledQtyActionGroup.xml | 19 ++++++++++++++ .../Form/Modifier/AdvancedInventory.php | 7 +++--- .../Product/Form/Modifier/ConfigurableQty.php | 25 ++++++++++++++++--- .../Block/Adminhtml/Product/ProductForm.xml | 2 +- 4 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 app/code/Magento/CatalogInventory/Test/Mftf/ActionGroup/AdminAssertDisabledQtyActionGroup.xml diff --git a/app/code/Magento/CatalogInventory/Test/Mftf/ActionGroup/AdminAssertDisabledQtyActionGroup.xml b/app/code/Magento/CatalogInventory/Test/Mftf/ActionGroup/AdminAssertDisabledQtyActionGroup.xml new file mode 100644 index 000000000000..27c4a93577a0 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Mftf/ActionGroup/AdminAssertDisabledQtyActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminAssertDisabledQtyActionGroup"> + <annotations> + <description>Goes to the 'Quantity' field and assert disabled attribute.</description> + </annotations> + + <seeElement selector="{{AdminProductFormSection.productQuantity}}" stepKey="assertProductQty"/> + <assertElementContainsAttribute selector="{{AdminProductFormSection.productQuantity}}" attribute="disabled" expectedValue="true" stepKey="checkIfQtyIsDisabled" /> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php index da465f5bdd3d..789befcfec8b 100644 --- a/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php +++ b/app/code/Magento/CatalogInventory/Ui/DataProvider/Product/Form/Modifier/AdvancedInventory.php @@ -1,11 +1,10 @@ <?php - -declare(strict_types=1); - /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\CatalogInventory\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter; @@ -238,7 +237,7 @@ private function prepareMeta() $this->meta = $this->arrayManager->merge( $fieldsetPath . '/children', $this->meta, - ['container_quantity_and_stock_status_qty' => $container] + ['quantity_and_stock_status_qty' => $container] ); } } diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableQty.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableQty.php index 7d337c57d7e7..055891ff79c6 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableQty.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/ConfigurableQty.php @@ -3,9 +3,12 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier; use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier; +use Magento\Catalog\Model\Locator\LocatorInterface; /** * Data provider for quantity in the Configurable products @@ -16,7 +19,22 @@ class ConfigurableQty extends AbstractModifier const CODE_QTY_CONTAINER = 'quantity_and_stock_status_qty'; /** - * {@inheritdoc} + * @var LocatorInterface + */ + private $locator; + + /** + * ConfigurableQty constructor + * + * @param LocatorInterface $locator + */ + public function __construct(LocatorInterface $locator) + { + $this->locator = $locator; + } + + /** + * @inheritdoc */ public function modifyData(array $data) { @@ -24,13 +42,14 @@ public function modifyData(array $data) } /** - * {@inheritdoc} + * @inheritdoc */ public function modifyMeta(array $meta) { if ($groupCode = $this->getGroupCodeByField($meta, self::CODE_QTY_CONTAINER)) { $parentChildren = &$meta[$groupCode]['children']; - if (!empty($parentChildren[self::CODE_QTY_CONTAINER])) { + $isConfigurable = $this->locator->getProduct()->getTypeId() === 'configurable'; + if (!empty($parentChildren[self::CODE_QTY_CONTAINER]) && $isConfigurable) { $parentChildren[self::CODE_QTY_CONTAINER] = array_replace_recursive( $parentChildren[self::CODE_QTY_CONTAINER], [ diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml index 525e6b47374a..028dfc6d109e 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml @@ -31,7 +31,7 @@ </category_ids> <quantity_and_stock_status composite="1"> <qty> - <selector>fieldset[data-index="container_quantity_and_stock_status_qty"] [name="product[quantity_and_stock_status][qty]"]</selector> + <selector>fieldset[data-index="quantity_and_stock_status_qty"] [name="product[quantity_and_stock_status][qty]"]</selector> </qty> <is_in_stock> <selector>[data-index="quantity_and_stock_status"] [name="product[quantity_and_stock_status][is_in_stock]"]</selector> From ebb71f8736c735b53157a5c368bf7625b7a6504e Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Tue, 17 Sep 2019 10:28:29 +0300 Subject: [PATCH 0491/1172] MC-17493: Cart/catalog rules grid missing - Fix actionGroup's name. --- .../Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml index 537fc3fbc55e..c840162f0d16 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminCreateCartPriceRuleActionGroup.xml @@ -105,7 +105,7 @@ <waitForElementVisible selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="waitForCategoryVisible" after="openChooser"/> <checkOption selector="{{AdminCartPriceRulesFormSection.categoryCheckbox(categoryName)}}" stepKey="checkCategoryName" after="waitForCategoryVisible"/> </actionGroup> - <actionGroup name="AdminMultiWebsiteCartPriceRuleActionGroup" extends="AdminCreateCartPriceRuleActionGroup"> + <actionGroup name="AdminCreateMultiWebsiteCartPriceRuleActionGroup" extends="AdminCreateCartPriceRuleActionGroup"> <annotations> <description>EXTENDS: AdminCreateCartPriceRuleActionGroup. Removes 'clickSaveButton' for the next data changing. Assign cart price rule to 2 websites instead of 1.</description> </annotations> From c25ce099be1473d211e19cfdab90886fc1244608 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 17 Sep 2019 11:55:17 +0300 Subject: [PATCH 0492/1172] MC-20075: Fix Skipped MFTF Tests From MC-17140: MC-14536, MC-14538, MC-14720 --- .../AssertStorefrontMiniCartItemsActionGroup.xml | 16 +++++++++++++++- ...AddedToTheCartThanDefaultDisplayLimitTest.xml | 6 ++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml index 176eebed142c..55ccf9539d43 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml @@ -18,7 +18,7 @@ <argument name="cartSubtotal" type="string"/> <argument name="qty" type="string"/> </arguments> - + <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="seeProductNameInMiniCart"/> <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productPrice}}" stepKey="seeProductPriceInMiniCart"/> <seeElement selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="seeCheckOutButtonInMiniCart"/> @@ -26,4 +26,18 @@ <seeElement selector="{{StorefrontMinicartSection.productImage}}" stepKey="seeProductImage"/> <see selector="{{StorefrontMinicartSection.productSubTotal}}" userInput="{{cartSubtotal}}" stepKey="seeSubTotal"/> </actionGroup> + + <actionGroup name="AssertStorefrontMiniCartProductDetailsAbsentActionGroup"> + <annotations> + <description>Validates that the provided Product details (Name, Price) are + not present in the Storefront Mini Shopping Cart.</description> + </annotations> + <arguments> + <argument name="productName" type="string"/> + <argument name="productPrice" type="string"/> + </arguments> + + <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="dontSeeProductNameInMiniCart"/> + <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productPrice}}" stepKey="dontSeeProductPriceInMiniCart"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml index a0aec77ad419..8b8aed3ac620 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCheckCartItemDisplayWhenMoreItemsAddedToTheCartThanDefaultDisplayLimitTest.xml @@ -277,7 +277,9 @@ </actionGroup> <!-- Verify Product11 is not displayed in Mini Cart --> - <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="$$simpleProduct11.name$$" stepKey="dontSeeProduct11NameInMiniCart"/> - <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="110" stepKey="dontSeeProduct11PriceInMiniCart"/> + <actionGroup ref="AssertStorefrontMiniCartProductDetailsAbsentActionGroup" stepKey="assertSimpleProduct11IsNotInMiniCart"> + <argument name="productName" value="$$simpleProduct11.name$$"/> + <argument name="productPrice" value="$110.00"/> + </actionGroup> </test> </tests> From 9cd6e22de237acb09cd1afaba5d2b95704ff0988 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Tue, 17 Sep 2019 13:35:04 +0400 Subject: [PATCH 0493/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6411 --- .../AdminOrderSelectShippingMethodActionGroup.xml | 8 ++++---- .../Section/AdminInvoicePaymentShippingSection.xml | 2 +- ...eOrderCustomStoreShippingMethodTableRatesTest.xml | 12 ++---------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml index 87f0c4d7e470..cfed144184e4 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml @@ -10,14 +10,14 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminOrderSelectShippingMethodActionGroup"> <arguments> - <argument name="methodTitle" type="string" defaultValue="Flat Rate"/> - <argument name="methodName" type="string" defaultValue="Fixed"/> + <argument name="methodTitle" type="string" defaultValue="flatrate"/> + <argument name="methodName" type="string" defaultValue="fixed"/> </arguments> <waitForElementVisible selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" stepKey="waitForShippingMethodsOpen"/> <click selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" stepKey="openShippingMethod"/> <conditionalClick selector="{{AdminInvoicePaymentShippingSection.getShippingMethod}}" dependentSelector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" visible="false" stepKey="openShippingMethodSecondTime"/> - <waitForElementVisible selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" stepKey="waitForShippingMethod"/> - <click selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodTitle, methodName)}}" stepKey="chooseShippingMethod"/> + <waitForElementVisible selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodName, methodTitle)}}" stepKey="waitForShippingMethod"/> + <click selector="{{AdminInvoicePaymentShippingSection.fixedPriceShippingMethod(methodName, methodTitle)}}" stepKey="chooseShippingMethod"/> <waitForPageLoad stepKey="waitForPageToLoad"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml index a0b93c66f3a5..32e987bea919 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoicePaymentShippingSection.xml @@ -17,7 +17,7 @@ <element name="CreateShipment" type="checkbox" selector=".order-shipping-address input[name='invoice[do_shipment]']"/> <element name="getShippingMethodAndRates" type="button" selector="//span[text()='Get shipping methods and rates']" timeout="60"/> <element name="shippingMethod" type="button" selector="//label[contains(text(), 'Fixed')]" timeout="60"/> - <element name="fixedPriceShippingMethod" type="button" selector="//*[contains(text(), '{{methodTitle}}')]/parent::dl//label[contains(text(), '{{methodName}}')]" parameterized="true"/> + <element name="fixedPriceShippingMethod" type="button" selector="#s_method_{{methodName}}_{{methodTitle}}" parameterized="true"/> <element name="getShippingMethod" type="button" selector="#order-shipping-method-summary a"/> </section> </sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml index bfb94c429313..67885ccfc99d 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -21,12 +21,10 @@ </annotations> <before> <!--Create product and customer--> - <comment userInput="Create product and customer" stepKey="commentCreateProductAndCustomer"/> <createData entity="SimpleProduct2" stepKey="createProduct"/> <createData entity="Simple_Customer_Without_Address" stepKey="createCustomer"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create website, store group and store view--> - <comment userInput="Create website, store group and store view" stepKey="commentCreateWebsiteStoreAndView"/> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> <argument name="newWebsiteName" value="{{customWebsite.name}}"/> <argument name="websiteCode" value="{{customWebsite.code}}"/> @@ -41,7 +39,6 @@ <argument name="customStore" value="customStore"/> </actionGroup> <!--Enable Table Rate method and import csv file--> - <comment userInput="Enable Table Rate method and import csv file" stepKey="commentEnableTableRates"/> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="switchDefaultWebsite"> <argument name="website" value="_defaultWebsite"/> @@ -64,7 +61,6 @@ </before> <after> <!--Delete created data--> - <comment userInput="Delete created data" stepKey="commetnDeleteCreatedData"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> <actionGroup ref="AdminDeleteCustomerActionGroup" stepKey="deleteSecondCreatedCustomer"> @@ -76,7 +72,6 @@ <actionGroup ref="logout" stepKey="logout"/> </after> <!--Assign product to custom website--> - <comment userInput="Assign product to custom website" stepKey="commentAssignProductToWebsite"/> <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="goToProductEditPage"/> <waitForPageLoad stepKey="waitForProductPageLoad"/> <actionGroup ref="unassignWebsiteFromProductActionGroup" stepKey="unassignWebsiteInProduct"> @@ -87,7 +82,6 @@ </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveProduct"/> <!--Assign customer to custom website--> - <comment userInput="Assign customer to custom website" stepKey="commentAssignCustomerToWebsite"/> <actionGroup ref="AdminOpenCustomerEditPageActionGroup" stepKey="openCustomerEditPage"> <argument name="customerId" value="$$createCustomer.id$$"/> </actionGroup> @@ -96,7 +90,6 @@ </actionGroup> <actionGroup ref="AdminSaveCustomerAndAssertSuccessMessage" stepKey="saveAndCheckSuccessMessage"/> <!--Create order--> - <comment userInput="Create order" stepKey="commentCreateOrder"/> <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> <argument name="customer" value="$$createCustomer$$"/> <argument name="storeView" value="customStore"/> @@ -109,10 +102,9 @@ <argument name="address" value="US_Address_TX"/> </actionGroup> <!--Choose Best Way shipping Method--> - <comment userInput="Choose Best Way shipping Method" stepKey="commentChooseShippingMethod"/> <actionGroup ref="AdminOrderSelectShippingMethodActionGroup" stepKey="chooseBestWayMethod"> - <argument name="methodTitle" value="Best Way"/> - <argument name="methodName" value="Table Rate"/> + <argument name="methodTitle" value="bestway"/> + <argument name="methodName" value="tablerate"/> </actionGroup> <actionGroup ref="AdminSubmitOrderActionGroup" stepKey="submitOrder"/> </test> From e9879d142bac70dbe5ffc9e90578a88152fccf5f Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Tue, 17 Sep 2019 12:49:29 +0300 Subject: [PATCH 0494/1172] [Customer] Rename dob to date_of_birth #911 --- .../testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index d1c6638e8d5f..c57b456cf9e3 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -102,7 +102,7 @@ public function testUpdateCustomer() $this->assertEquals($newMiddlename, $response['updateCustomer']['customer']['middlename']); $this->assertEquals($newLastname, $response['updateCustomer']['customer']['lastname']); $this->assertEquals($newSuffix, $response['updateCustomer']['customer']['suffix']); - $this->assertEquals($newDob, $response['updateCustomer']['customer']['date_of_birth']); + $this->assertEquals($newDob, $response['updateCustomer']['customer']['dob']); $this->assertEquals($newTaxVat, $response['updateCustomer']['customer']['taxvat']); $this->assertEquals($newEmail, $response['updateCustomer']['customer']['email']); $this->assertEquals($newGender, $response['updateCustomer']['customer']['gender']); From da62bd1da9804056882b08f3c3dcb2ae6d69dc3b Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Tue, 17 Sep 2019 14:05:56 +0300 Subject: [PATCH 0495/1172] [Customer] Rename dob to date_of_birth #911 --- .../testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index c57b456cf9e3..64f9afff81d1 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -82,7 +82,7 @@ public function testUpdateCustomer() middlename lastname suffix - date_of_birth + dob taxvat email gender From 80c2b7a16bdc47b88dc1512f28e9c7bbe15df1ad Mon Sep 17 00:00:00 2001 From: Evgeny Petrov <evgeny_petrov@epam.com> Date: Tue, 17 Sep 2019 14:24:57 +0300 Subject: [PATCH 0496/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window --- .../Magento/Multishipping/Model/Cart/Controller/CartPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php index 40b6f0fa4d8f..b450232395b8 100644 --- a/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php +++ b/app/code/Magento/Multishipping/Model/Cart/Controller/CartPlugin.php @@ -84,7 +84,7 @@ public function beforeDispatch(Cart $subject, RequestInterface $request) * * @return bool */ - private function isCheckoutComplete() + private function isCheckoutComplete() : bool { return (bool) ($this->checkoutSession->getStepData(State::STEP_SHIPPING)['is_complete'] ?? true); } From 6ddd1d10edbd542a88b526fe25b8010adb568bf9 Mon Sep 17 00:00:00 2001 From: Serhii Balko <serhii.balko@transoftgroup.com> Date: Tue, 17 Sep 2019 15:46:51 +0300 Subject: [PATCH 0497/1172] MC-20118: Arabic Date Selector shows date in incorrect format --- .../Magento/Customer/Block/Widget/Dob.php | 6 +++- .../Test/Unit/Block/Widget/DobTest.php | 31 ++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Customer/Block/Widget/Dob.php b/app/code/Magento/Customer/Block/Widget/Dob.php index d874729d9132..d822be853f18 100644 --- a/app/code/Magento/Customer/Block/Widget/Dob.php +++ b/app/code/Magento/Customer/Block/Widget/Dob.php @@ -277,7 +277,11 @@ public function getHtmlExtraParams() */ public function getDateFormat() { - return $this->_localeDate->getDateFormatWithLongYear(); + $dateFormat = $this->_localeDate->getDateFormatWithLongYear(); + /** Escape RTL characters which are present in some locales and corrupt formatting */ + $escapedDateFormat = preg_replace('/[^MmDdYy\/\.\-]/', '', $dateFormat); + + return $escapedDateFormat; } /** diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php index 8bfddac3cef8..2e8ee7af37ce 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php @@ -23,7 +23,7 @@ use Magento\Framework\View\Element\Html\Date; use Magento\Framework\View\Element\Template\Context; use PHPUnit\Framework\TestCase; -use PHPUnit_Framework_MockObject_MockObject; +use PHPUnit\Framework\MockObject\MockObject; use Zend_Cache_Backend_BlackHole; use Zend_Cache_Core; @@ -60,17 +60,17 @@ class DobTest extends TestCase const YEAR_HTML = '<div><label for="year"><span>yy</span></label><input type="text" id="year" name="Year" value="14"></div>'; - /** @var PHPUnit_Framework_MockObject_MockObject|AttributeMetadataInterface */ + /** @var MockObject|AttributeMetadataInterface */ protected $attribute; /** @var Dob */ protected $_block; - /** @var PHPUnit_Framework_MockObject_MockObject|CustomerMetadataInterface */ + /** @var MockObject|CustomerMetadataInterface */ protected $customerMetadata; /** - * @var FilterFactory|PHPUnit_Framework_MockObject_MockObject + * @var FilterFactory|MockObject */ protected $filterFactory; @@ -336,12 +336,27 @@ public function getYearDataProvider() } /** - * is used to derive the Locale that is used to determine the - * value of Dob::getDateFormat() for that Locale. + * Is used to derive the Locale that is used to determine the value of Dob::getDateFormat() for that Locale + * + * @param string $locale + * @param string $expectedFormat + * @dataProvider getDateFormatDataProvider */ - public function testGetDateFormat() + public function testGetDateFormat(string $locale, string $expectedFormat) { - $this->assertEquals(self::DATE_FORMAT, $this->_block->getDateFormat()); + $this->_locale = $locale; + $this->assertEquals($expectedFormat, $this->_block->getDateFormat()); + } + + /** + * @return array + */ + public function getDateFormatDataProvider(): array + { + return [ + ['ar_SA', 'd/M/y'], + [Resolver::DEFAULT_LOCALE, self::DATE_FORMAT], + ]; } /** From eabb8a3bdbaa62bf54a2e763d016e6212f84f55b Mon Sep 17 00:00:00 2001 From: Aliaksei_Manenak <Aliaksei_Manenak@epam.com> Date: Tue, 17 Sep 2019 16:31:54 +0300 Subject: [PATCH 0498/1172] MC-18819: Increase test coverage for Account functional area - Integration test for MC-11209 --- .../Cart/Item/Renderer/ConfigurableTest.php | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/ConfigurableTest.php diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/ConfigurableTest.php new file mode 100644 index 000000000000..aba813148512 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Cart/Item/Renderer/ConfigurableTest.php @@ -0,0 +1,68 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ConfigurableProduct\Block\Cart\Item\Renderer; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\ConfigurableProduct\Block\Cart\Item\Renderer\Configurable as ConfigurableRenderer; +use Magento\Framework\ObjectManagerInterface; +use Magento\Framework\View\LayoutInterface; + +/** + * Test \Magento\ConfigurableProduct\Block\Cart\Item\Renderer\Configurable block + * + * @magentoAppArea frontend + */ +class ConfigurableTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var ConfigurableRenderer + */ + private $block; + + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->block = $this->objectManager->get(LayoutInterface::class) + ->createBlock(ConfigurableRenderer::class); + } + + /** + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + * @magentoDataFixture Magento/ConfigurableProduct/_files/quote_with_configurable_product.php + */ + public function testGetProductPriceHtml() + { + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + $configurableProduct = $productRepository->getById(1); + + $layout = $this->objectManager->get(LayoutInterface::class); + $layout->createBlock( + \Magento\Framework\Pricing\Render::class, + 'product.price.render.default', + [ + 'data' => [ + 'price_render_handle' => 'catalog_product_prices', + 'use_link_for_as_low_as' => true + ] + ] + ); + + $this->block->setItem( + $this->block->getCheckoutSession()->getQuote()->getAllVisibleItems()[0] + ); + $html = $this->block->getProductPriceHtml($configurableProduct); + $this->assertContains('<span class="price">$10.00</span>', $html); + } +} From 3e890e6b38574383f45114097ec99d14169bebb4 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Tue, 17 Sep 2019 16:50:38 +0300 Subject: [PATCH 0499/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../Sales/Model/Order/ShipmentTest.php | 27 +++++++++++- .../testsuite/Magento/Sales/_files/order.php | 41 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index 9c0024480d16..5b5c2365bfac 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -173,7 +173,30 @@ public function testGetTracksCollection() $shipment->addTrack($track); $this->shipmentRepository->save($shipment); - $saved = $shipment->getTracksCollection(); - self::assertTrue(in_array($track->getId(), $saved->getColumnValues('id'))); + + $secondOrder = $this->getOrder('100000002'); + $secondOrderItems = []; + foreach ($secondOrder->getItems() as $item) { + $secondOrderItems[$item->getId()] = $item->getQtyOrdered(); + } + /** @var \Magento\Sales\Model\Order\Shipment $secondOrderShipment */ + $secondOrderShipment = $this->objectManager->get(ShipmentFactory::class) + ->create($secondOrder, $secondOrderItems); + + /** @var ShipmentTrackInterface $secondShipmentTrack */ + $secondShipmentTrack = $this->objectManager->create(ShipmentTrackInterface::class); + $secondShipmentTrack->setNumber('Test Number2') + ->setTitle('Test Title2') + ->setCarrierCode('Test CODE2'); + + $secondOrderShipment->addTrack($secondShipmentTrack); + $this->shipmentRepository->save($secondOrderShipment); + + self::assertEmpty( + array_intersect( + $shipment->getTracksCollection()->getColumnValues('id'), + $secondOrderShipment->getTracksCollection()->getColumnValues('id') + ) + ); } } diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order.php index 9ea85aae56cb..8d2132dadd69 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order.php @@ -68,3 +68,44 @@ /** @var OrderRepositoryInterface $orderRepository */ $orderRepository = $objectManager->create(OrderRepositoryInterface::class); $orderRepository->save($order); + +/** @var Payment $payment */ +$payment2 = $objectManager->create(Payment::class); +$payment2->setMethod('checkmo') + ->setAdditionalInformation('last_trans_id', '11122') + ->setAdditionalInformation( + 'metadata', + [ + 'type' => 'free', + 'fraudulent' => false, + ] + ); + +/** @var OrderItem $orderItem */ +$orderItem2 = $objectManager->create(OrderItem::class); +$orderItem2->setProductId($product->getId()) + ->setQtyOrdered(2) + ->setBasePrice($product->getPrice()) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType('simple') + ->setName($product->getName()) + ->setSku($product->getSku()); + +/** @var Order $order */ +$order2 = $objectManager->create(Order::class); +$order2->setIncrementId('100000002') + ->setState(Order::STATE_PROCESSING) + ->setStatus($order2->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) + ->setSubtotal(100) + ->setGrandTotal(100) + ->setBaseSubtotal(100) + ->setBaseGrandTotal(100) + ->setCustomerIsGuest(true) + ->setCustomerEmail('customer@null.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) + ->addItem($orderItem2) + ->setPayment($payment2); +$orderRepository->save($order2); From 3c5d4a716ec7f10ec1d06f656992aec1bb51f5ba Mon Sep 17 00:00:00 2001 From: Lusine Papyan <lusine_papyan@epam.com> Date: Tue, 17 Sep 2019 15:32:20 +0300 Subject: [PATCH 0500/1172] MC-18709: [WYSIWYG]Spinner is Always Displayed on Media Gallery popup - Updated automated test script --- .../Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml index a7dc5ab96890..711a8af38efe 100644 --- a/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml +++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/AdminCMSBlockContentActionGroup.xml @@ -15,12 +15,15 @@ <waitForElementVisible selector="{{MediaGallerySection.Browse}}" stepKey="waitForBrowseImage"/> <click selector="{{MediaGallerySection.Browse}}" stepKey="clickBrowseImage"/> <waitForElementVisible selector="{{MediaGallerySection.StorageRootArrow}}" stepKey="waitForAttacheFiles"/> + <waitForLoadingMaskToDisappear stepKey="waitForStorageRootLoadingMaskDisappear"/> <click selector="{{MediaGallerySection.StorageRootArrow}}" stepKey="clickRoot"/> <waitForPageLoad stepKey="waitForPageLoad"/> <attachFile selector="{{MediaGallerySection.BrowseUploadImage}}" userInput="{{image.file}}" stepKey="attachLogo"/> <waitForElementVisible selector="{{MediaGallerySection.InsertFile}}" stepKey="waitForAddSelected"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear"/> <click selector="{{MediaGallerySection.InsertFile}}" stepKey="clickAddSelected"/> <waitForElementVisible selector="{{MediaGallerySection.OkBtn}}" stepKey="waitForOkButton"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskToDisappear2"/> <click selector="{{MediaGallerySection.OkBtn}}" stepKey="clickOk"/> </actionGroup> </actionGroups> From 3c4607344e44dcebc864ca6e9dc0309f26b0b1ee Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Tue, 17 Sep 2019 18:09:27 +0400 Subject: [PATCH 0501/1172] MC-17653: Cannot schedule update for catalog price rule for date attribute - Updated automated test script. --- .../Catalog/Test/Mftf/Section/AdminProductFormSection.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml index 80b415916745..b2992a20814e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminProductFormSection.xml @@ -8,6 +8,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminProductFormSection"> + <element name="datepickerNewAttribute" type="input" selector="[data-index='{{attrName}}'] input" timeout="30" parameterized="true"/> <element name="attributeSet" type="select" selector="div[data-index='attribute_set_id'] .admin__field-control"/> <element name="attributeSetFilter" type="input" selector="div[data-index='attribute_set_id'] .admin__field-control input" timeout="30"/> <element name="attributeSetFilterResult" type="input" selector="div[data-index='attribute_set_id'] .action-menu-item._last" timeout="30"/> From 3aeaacffbcc043396f82af1dbffed47c20e256ef Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 17 Sep 2019 14:21:27 -0500 Subject: [PATCH 0502/1172] MC-19247: Broken translations with advanced bundling - Add json parse to dictionary file content in template; --- .../Magento/Translation/view/base/templates/dictionary.phtml | 5 ++++- dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index fb082439b1c3..2e1389abcffd 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -6,9 +6,12 @@ /** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ $viewModel = $block->getData('dictionary_view_model'); +$dictionary = json_encode($viewModel->getTranslationDictionary(), JSON_HEX_APOS | JSON_UNESCAPED_SLASHES); ?> <script> define('dictionary', function () { - return <?= /* @noEscape */ $viewModel->getTranslationDictionary() ?>; + var dict = <?= /* @noEscape */ $dictionary ?>; + // Use of JSON.parse is intentional as JSON is significantly faster to parse than JavaScript + return JSON.parse(dict); }); </script> diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js index bdaf66991a30..005a5817dfa1 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js +++ b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js @@ -2,7 +2,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -// Fake dictionary for js unit tests as real dictionary is defined is template and cannot be initialized by requirejs +// Fake dictionary for js unit tests as real dictionary is defined in template and cannot be initialized by requirejs define([], function () { 'use strict'; From 8f0c2252ecf8b43f725502c7badec1779e144576 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Tue, 17 Sep 2019 22:57:13 -0300 Subject: [PATCH 0503/1172] adding validation to unit test, line before return statement, and remove unused jquery/ui from validation --- .../Customer/Test/Unit/Block/Widget/DobTest.php | 12 ++++++------ .../view/base/ui_component/customer_form.xml | 12 +++++++++--- .../Customer/view/frontend/web/js/validation.js | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php index 8bfddac3cef8..da5e089f93ec 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php @@ -521,8 +521,8 @@ public function testGetHtmlExtraParamsWithoutRequiredOption() { $this->escaper->expects($this->any()) ->method('escapeHtml') - ->with('{"validate-date":{"dateFormat":"M\/d\/Y"}}') - ->will($this->returnValue('{"validate-date":{"dateFormat":"M\/d\/Y"}}')); + ->with('{"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}') + ->will($this->returnValue('{"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}')); $this->attribute->expects($this->once()) ->method("isRequired") @@ -530,7 +530,7 @@ public function testGetHtmlExtraParamsWithoutRequiredOption() $this->assertEquals( $this->_block->getHtmlExtraParams(), - 'data-validate="{"validate-date":{"dateFormat":"M\/d\/Y"}}"' + 'data-validate="{"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}"' ); } @@ -544,13 +544,13 @@ public function testGetHtmlExtraParamsWithRequiredOption() ->willReturn(true); $this->escaper->expects($this->any()) ->method('escapeHtml') - ->with('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"}}') - ->will($this->returnValue('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"}}')); + ->with('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}') + ->will($this->returnValue('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}')); $this->context->expects($this->any())->method('getEscaper')->will($this->returnValue($this->escaper)); $this->assertEquals( - 'data-validate="{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"}}"', + 'data-validate="{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}"', $this->_block->getHtmlExtraParams() ); } diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 7eb1394f77a4..954b44ec19bb 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -260,9 +260,6 @@ <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="source" xsi:type="string">customer</item> - <item name="options" xsi:type="array"> - <item name="maxDate" xsi:type="string">-1d</item> - </item> </item> </argument> <settings> @@ -273,6 +270,15 @@ <dataType>text</dataType> <visible>true</visible> </settings> + <formElements> + <date> + <settings> + <options> + <option name="maxDate" xsi:type="string">-1d</option> + </options> + </settings> + </date> + </formElements> </field> <field name="taxvat" formElement="input"> <argument name="data" xsi:type="array"> diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js index 840134d64422..14ae69b02080 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/validation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -1,7 +1,6 @@ require([ 'jquery', 'moment', - 'jquery/ui', 'jquery/validate', 'mage/translate', ], function($, moment) { @@ -12,6 +11,7 @@ require([ if (value === '') { return true; } + return moment(value).isBefore(moment()); }, $.mage.__('The Date of Birth should not be greater than today.') From f1a6a94842ea6ac28ec87ac99fdaab30c431f13a Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Wed, 18 Sep 2019 10:06:12 +0300 Subject: [PATCH 0504/1172] MC-19916: Attribute not showing on layered navigation if no value set for "All Store Views" --- .../Product/Indexer/Eav/Source.php | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index 7730d7cc9a7f..f0fe95467087 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -8,6 +8,8 @@ use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Framework\DB\Select; +use Magento\Framework\DB\Sql\UnionExpression; /** * Catalog Product Eav Select and Multiply Select Attributes Indexer resource model @@ -199,13 +201,48 @@ protected function _prepareSelectIndex($entityIds = null, $attributeId = null) 'dd.attribute_id', 's.store_id', 'value' => new \Zend_Db_Expr('COALESCE(ds.value, dd.value)'), - 'cpe.entity_id', + 'cpe.entity_id AS source_id', ] ); if ($entityIds !== null) { $ids = implode(',', array_map('intval', $entityIds)); + $selectWithoutDefaultStore = $connection->select()->from( + ['wd' => $this->getTable('catalog_product_entity_int')], + [ + $productIdField, + 'attribute_id', + 'store_id', + 'value', + $productIdField + ] + )->joinLeft( + ['d2d' => $this->getTable('catalog_product_entity_int')], + sprintf( + "d2d.store_id = 0 AND d2d.{$productIdField} = wd.{$productIdField} AND d2d.attribute_id = %s", + $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'status')->getId() + ), + [] + )->joinLeft( + ['d2s' => $this->getTable('catalog_product_entity_int')], + "d2s.store_id != 0 AND d2s.attribute_id = d2d.attribute_id AND " . + "d2s.{$productIdField} = d2d.{$productIdField}", + [] + ) + ->where((new \Zend_Db_Expr('COALESCE(d2s.value, d2d.value)')) . ' = ' . ProductStatus::STATUS_ENABLED) + ->where("wd.attribute_id IN({$attrIdsFlat})") + ->where('wd.value IS NOT NULL') + ->where('wd.store_id != 0') + ->where("wd.{$productIdField} IN({$ids})"); $select->where("cpe.entity_id IN({$ids})"); + $selects = new UnionExpression( + [$select, $selectWithoutDefaultStore], + Select::SQL_UNION, + '( %s )' + ); + + $select = $connection->select(); + $select->from(['u' => $selects]); } /** @@ -342,7 +379,7 @@ private function getMultiSelectAttributeWithSourceModels($attrIds) ProductAttributeInterface::ENTITY_TYPE_CODE, $criteria )->getItems(); - + $options = []; foreach ($attributes as $attribute) { $sourceModelOptions = $attribute->getOptions(); From edafb0a14d7ea5e6f9f65536d997acf9a71d34c5 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Tue, 17 Sep 2019 12:19:25 +0300 Subject: [PATCH 0505/1172] MC-18821: Increase test coverage for Catalog functional area - Fixes for MC-6328 test --- .../Magento/Catalog/Controller/Adminhtml/ProductTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php index 90b03510044d..3a28801b1ace 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -79,7 +79,7 @@ public function testSaveActionAndDuplicate() } /** - * Test saving and duplicate existing product after the script execution. + * Tests of saving and duplicating existing product after the script execution. * * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ From 33903f8a320f3d5e8695d497fe3df4b1b104341f Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Tue, 17 Sep 2019 11:59:46 +0300 Subject: [PATCH 0506/1172] MC-18821: Increase test coverage for Catalog functional area - Fixes for MC-6354 test --- .../Swatches/view/frontend/web/js/swatch-renderer.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js index b3172beec770..f7248f71d303 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js @@ -49,11 +49,11 @@ define([ html = $(widget._RenderSwatchOptions(attribute, 'option-label-control-id-1'))[0]; }); - it('check first conditional statement', function () { + it('check if swatch config has attribute id', function () { expect(widget.options.jsonSwatchConfig.hasOwnProperty(attribute.id)).toEqual(true); }); - it('check second conditional statement', function () { + it('check if option config has option id', function () { expect(optionConfig.hasOwnProperty(optionId)).toEqual(true); }); From 49cfa88c88462f946715b6f1d4065d0609729b72 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Wed, 18 Sep 2019 11:20:19 +0300 Subject: [PATCH 0507/1172] graphQl-892: fixed billing address return implementation --- .../Model/Resolver/BillingAddress.php | 8 ++++++- .../Magento/QuoteGraphQl/etc/schema.graphqls | 2 +- .../GetSpecifiedBillingAddressTest.php | 24 +------------------ .../Guest/GetSpecifiedBillingAddressTest.php | 23 +----------------- 4 files changed, 10 insertions(+), 47 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php index a6bb0b0d04df..c88a0d524c50 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/BillingAddress.php @@ -44,7 +44,13 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $cart = $value['model']; $billingAddress = $cart->getBillingAddress(); - if (null === $billingAddress) { + if (null === $billingAddress || + null === $billingAddress->getFirstname() || + null === $billingAddress->getLastname() || + null === $billingAddress->getCity() || + null === $billingAddress->getCountry() || + null === $billingAddress->getTelephone() || + null === $billingAddress->getStreet()) { return null; } diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 009b18e29c05..46ee6ee33525 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -194,7 +194,7 @@ type Cart { applied_coupon: AppliedCoupon @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\AppliedCoupon") email: String @resolver (class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartEmail") shipping_addresses: [ShippingCartAddress]! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\ShippingAddresses") - billing_address: BillingCartAddress! @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\BillingAddress") + billing_address: BillingCartAddress @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\BillingAddress") available_payment_methods: [AvailablePaymentMethod] @resolver(class: "Magento\\QuoteGraphQl\\Model\\Resolver\\AvailablePaymentMethods") @doc(description: "Available payment methods") selected_payment_method: SelectedPaymentMethod @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\SelectedPaymentMethod") prices: CartPrices @resolver(class: "\\Magento\\QuoteGraphQl\\Model\\Resolver\\CartPrices") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSpecifiedBillingAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSpecifiedBillingAddressTest.php index b6dde46871cb..e5353fc841c5 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSpecifiedBillingAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/GetSpecifiedBillingAddressTest.php @@ -91,29 +91,7 @@ public function testGetSpecifiedBillingAddressIfBillingAddressIsNotSet() $response = $this->graphQlQuery($query, [], '', $this->getHeaderMap()); self::assertArrayHasKey('cart', $response); self::assertArrayHasKey('billing_address', $response['cart']); - - $expectedBillingAddressData = [ - 'firstname' => null, - 'lastname' => null, - 'company' => null, - 'street' => [ - '' - ], - 'city' => null, - 'region' => [ - 'code' => null, - 'label' => null, - ], - 'postcode' => null, - 'country' => [ - 'code' => null, - 'label' => null, - ], - 'telephone' => null, - '__typename' => 'BillingCartAddress', - 'customer_notes' => null, - ]; - self::assertEquals($expectedBillingAddressData, $response['cart']['billing_address']); + self::assertNull($response['cart']['billing_address']); } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSpecifiedBillingAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSpecifiedBillingAddressTest.php index 8ddf1641ede8..cb1565879a81 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSpecifiedBillingAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetSpecifiedBillingAddressTest.php @@ -81,28 +81,7 @@ public function testGetSpecifiedBillingAddressIfBillingAddressIsNotSet() $response = $this->graphQlQuery($query); self::assertArrayHasKey('cart', $response); self::assertArrayHasKey('billing_address', $response['cart']); - - $expectedBillingAddressData = [ - 'firstname' => null, - 'lastname' => null, - 'company' => null, - 'street' => [ - '' - ], - 'city' => null, - 'region' => [ - 'code' => null, - 'label' => null, - ], - 'postcode' => null, - 'country' => [ - 'code' => null, - 'label' => null, - ], - 'telephone' => null, - '__typename' => 'BillingCartAddress', - ]; - self::assertEquals($expectedBillingAddressData, $response['cart']['billing_address']); + self::assertNull($response['cart']['billing_address']); } /** From 8de65673b5ca706875854e6b478ff42765585320 Mon Sep 17 00:00:00 2001 From: Viktor Sevch <svitja@ukr.net> Date: Wed, 18 Sep 2019 13:53:15 +0300 Subject: [PATCH 0508/1172] MC-20069: Fix Skipped MFTF Tests From MC-17140: MAGETWO-72277, MAGETWO-84682, MAGETWO-94854 --- .../Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml index 9c961f9da751..a123282bbcbc 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml @@ -23,13 +23,14 @@ <actionGroup ref="SwitchToVersion4ActionGroup" stepKey="switchToTinyMCE4" /> </before> <amOnPage url="{{NewsletterTemplateForm.url}}" stepKey="amOnNewsletterTemplatePage"/> - <waitForPageLoad stepKey="waitForPageLoad1"/> + <waitForElementVisible selector="{{BasicFieldNewsletterSection.templateName}}" stepKey="waitForTemplateName"/> <fillField selector="{{BasicFieldNewsletterSection.templateName}}" userInput="{{_defaultNewsletter.name}}" stepKey="fillTemplateName" /> <fillField selector="{{BasicFieldNewsletterSection.templateSubject}}" userInput="{{_defaultNewsletter.subject}}" stepKey="fillTemplateSubject" /> <fillField selector="{{BasicFieldNewsletterSection.senderName}}" userInput="{{_defaultNewsletter.senderName}}" stepKey="fillSenderName" /> <fillField selector="{{BasicFieldNewsletterSection.senderEmail}}" userInput="{{_defaultNewsletter.senderEmail}}" stepKey="fillSenderEmail" /> <conditionalClick selector="{{NewsletterWYSIWYGSection.ShowHideBtn}}" dependentSelector="{{NewsletterWYSIWYGSection.TinyMCE4}}" visible="false" stepKey="toggleEditorIfHidden"/> <waitForElementVisible selector="{{TinyMCESection.TinyMCE4}}" stepKey="waitForTinyMCE" /> + <waitForElementVisible selector="{{NewsletterWYSIWYGSection.InsertWidgetIcon}}" stepKey="waitForInsertWidgerIconButton"/> <click selector="{{NewsletterWYSIWYGSection.InsertWidgetIcon}}" stepKey="clickInsertWidgetIcon" /> <wait time="10" stepKey="waitForPageLoad" /> <see userInput="Inserting a widget does not create a widget instance." stepKey="seeMessage" /> From 984ef45dde306f67c13f3ea4ce39039e557a3837 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Wed, 18 Sep 2019 15:15:24 +0300 Subject: [PATCH 0509/1172] graphQl-912: optimized customer input schema --- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index d27debdc39c6..90d032be5b1e 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -60,10 +60,10 @@ input CustomerInput { middlename: String @doc(description: "The customer's middle name") lastname: String @doc(description: "The customer's family name") suffix: String @doc(description: "A value such as Sr., Jr., or III") - email: String @doc(description: "The customer's email address. Required") + email: String! @doc(description: "The customer's email address. Required") dob: String @doc(description: "The customer's date of birth") - taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") - gender: Int @doc(description: "The customer's gender(Male - 1, Female - 2)") + taxvat: String @doc(description: "The customer's Value-added tax (VAT) number (for corporate customers)") + gender: Int @doc(description: "The customer's gender (Male - 1, Female - 2)") password: String @doc(description: "The customer's password") is_subscribed: Boolean @doc(description: "Indicates whether the customer is subscribed to the company's newsletter") } @@ -88,11 +88,11 @@ type Customer @doc(description: "Customer defines the customer name and address default_billing: String @doc(description: "The ID assigned to the billing address") default_shipping: String @doc(description: "The ID assigned to the shipping address") dob: String @doc(description: "The customer's date of birth") - taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") + taxvat: String @doc(description: "The customer's Value-added tax (VAT) number (for corporate customers)") id: Int @doc(description: "The ID assigned to the customer") is_subscribed: Boolean @doc(description: "Indicates whether the customer is subscribed to the company's newsletter") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\IsSubscribed") addresses: [CustomerAddress] @doc(description: "An array containing the customer's shipping and billing addresses") @resolver(class: "\\Magento\\CustomerGraphQl\\Model\\Resolver\\CustomerAddresses") - gender: Int @doc(description: "The customer's gender(Male - 1, Female - 2)") + gender: Int @doc(description: "The customer's gender (Male - 1, Female - 2)") } type CustomerAddress @doc(description: "CustomerAddress contains detailed information about a customer's billing and shipping addresses"){ @@ -112,7 +112,7 @@ type CustomerAddress @doc(description: "CustomerAddress contains detailed inform middlename: String @doc(description: "The middle name of the person associated with the shipping/billing address") prefix: String @doc(description: "An honorific, such as Dr., Mr., or Mrs.") suffix: String @doc(description: "A value such as Sr., Jr., or III") - vat_id: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") + vat_id: String @doc(description: "The customer's Value-added tax (VAT) number (for corporate customers)") default_shipping: Boolean @doc(description: "Indicates whether the address is the default shipping address") default_billing: Boolean @doc(description: "Indicates whether the address is the default billing address") custom_attributes: [CustomerAddressAttribute] @doc(description: "Address custom attributes") From 944fa474707066d7147b63968e9219dedfa3ea73 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Wed, 18 Sep 2019 16:39:39 +0300 Subject: [PATCH 0510/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Cart/Address/SaveQuoteAddressToCustomerAddressBook.php | 2 ++ .../QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php | 4 +++- .../GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php | 1 - .../GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php | 4 ++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php index 543fe96ddec8..5c773d44e6a1 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/Address/SaveQuoteAddressToCustomerAddressBook.php @@ -52,6 +52,8 @@ public function __construct( } /** + * Save Address to Customer Address Book. + * * @param QuoteAddress $quoteAddress * @param int $customerId * diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index f2e639f74cc2..ccb35e884061 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -78,12 +78,14 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } - $shippingAddress = $this->createShippingAddress($context, $customerAddressId, $addressInput); + $shippingAddress = $this->createShippingAddress($context, $customerAddressId, $addressInput); $this->assignShippingAddressToCart->execute($cart, $shippingAddress); } /** + * Create shipping address. + * * @param ContextInterface $context * @param int|null $customerAddressId * @param array|null $addressInput diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php index 9a9c50c14057..40ec237c8b23 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php @@ -709,7 +709,6 @@ public function testSetBillingAddressWithLowerCaseCountry() $this->assertNewAddressFields($billingAddressResponse); } - /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php index a1afc0677429..95c8f4118adb 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php @@ -700,6 +700,7 @@ public function testSetNewShippingAddressWithSaveInAddressBook() telephone: "88776655" save_in_address_book: true } + customer_notes: "Test note" } ] } @@ -718,6 +719,7 @@ public function testSetNewShippingAddressWithSaveInAddressBook() label } __typename + customer_notes } } } @@ -769,6 +771,7 @@ public function testSetNewShippingAddressWithNotSaveInAddressBook() telephone: "88776655" save_in_address_book: false } + customer_notes: "Test note" } ] } @@ -787,6 +790,7 @@ public function testSetNewShippingAddressWithNotSaveInAddressBook() label } __typename + customer_notes } } } From 87fa1f3334390deeb16aa77559679e8c69051628 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Wed, 18 Sep 2019 10:31:51 -0500 Subject: [PATCH 0511/1172] enable elastic --- app/code/Magento/CatalogSearch/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/etc/config.xml b/app/code/Magento/CatalogSearch/etc/config.xml index 7ea15c6caa59..911d9da2fa5e 100644 --- a/app/code/Magento/CatalogSearch/etc/config.xml +++ b/app/code/Magento/CatalogSearch/etc/config.xml @@ -12,7 +12,7 @@ <search_terms>1</search_terms> </seo> <search> - <engine>mysql</engine> + <engine>elasticsearch6</engine> <min_query_length>3</min_query_length> <max_query_length>128</max_query_length> <max_count_cacheable_search_terms>100</max_count_cacheable_search_terms> From 06ebc664bb2351e7128f4f8e55e1014e5d548f4e Mon Sep 17 00:00:00 2001 From: Iryna Lagno <ilagno@adobe.com> Date: Wed, 18 Sep 2019 11:41:42 -0500 Subject: [PATCH 0512/1172] MC-20235: [2.3.3]Revert unapproved PR --- .../Adminhtml/Promo/Catalog/Save.php | 18 ++++-------------- .../Model/Indexer/ReindexRuleProduct.php | 4 +--- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php index 6d499b93e411..4f58293d5335 100644 --- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php +++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php @@ -12,7 +12,6 @@ use Magento\Framework\Registry; use Magento\Framework\Stdlib\DateTime\Filter\Date; use Magento\Framework\App\Request\DataPersistorInterface; -use Magento\Framework\Stdlib\DateTime\TimezoneInterface; /** * Save action for catalog rule @@ -26,27 +25,19 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog imple */ protected $dataPersistor; - /** - * @var TimezoneInterface - */ - private $localeDate; - /** * @param Context $context * @param Registry $coreRegistry * @param Date $dateFilter * @param DataPersistorInterface $dataPersistor - * @param TimezoneInterface $localeDate */ public function __construct( Context $context, Registry $coreRegistry, Date $dateFilter, - DataPersistorInterface $dataPersistor, - TimezoneInterface $localeDate + DataPersistorInterface $dataPersistor ) { $this->dataPersistor = $dataPersistor; - $this->localeDate = $localeDate; parent::__construct($context, $coreRegistry, $dateFilter); } @@ -55,15 +46,16 @@ public function __construct( * * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { if ($this->getRequest()->getPostValue()) { + /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */ $ruleRepository = $this->_objectManager->get( \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface::class ); + /** @var \Magento\CatalogRule\Model\Rule $model */ $model = $this->_objectManager->create(\Magento\CatalogRule\Model\Rule::class); @@ -73,9 +65,7 @@ public function execute() ['request' => $this->getRequest()] ); $data = $this->getRequest()->getPostValue(); - if (!$this->getRequest()->getParam('from_date')) { - $data['from_date'] = $this->localeDate->formatDate(); - } + $filterValues = ['from_date' => $this->_dateFilter]; if ($this->getRequest()->getParam('to_date')) { $filterValues['to_date'] = $this->_dateFilter; diff --git a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php index 944710773123..e589c8595ce2 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/ReindexRuleProduct.php @@ -101,9 +101,7 @@ public function execute(Rule $rule, $batchCount, $useAdditionalTable = false) $scopeTz = new \DateTimeZone( $this->localeDate->getConfigTimezone(ScopeInterface::SCOPE_WEBSITE, $websiteId) ); - $fromTime = $rule->getFromDate() - ? (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp() - : 0; + $fromTime = (new \DateTime($rule->getFromDate(), $scopeTz))->getTimestamp(); $toTime = $rule->getToDate() ? (new \DateTime($rule->getToDate(), $scopeTz))->getTimestamp() + IndexBuilder::SECONDS_IN_DAY - 1 : 0; From bacaf137b0fd15c20aad7395feb92b4b15b5ad96 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 18 Sep 2019 13:47:13 -0500 Subject: [PATCH 0513/1172] MC-19451: Adapt functional tests to Elasticsearch * Configuring Elasticsearch as default search engine --- app/code/Magento/CatalogSearch/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/etc/config.xml b/app/code/Magento/CatalogSearch/etc/config.xml index 7ea15c6caa59..911d9da2fa5e 100644 --- a/app/code/Magento/CatalogSearch/etc/config.xml +++ b/app/code/Magento/CatalogSearch/etc/config.xml @@ -12,7 +12,7 @@ <search_terms>1</search_terms> </seo> <search> - <engine>mysql</engine> + <engine>elasticsearch6</engine> <min_query_length>3</min_query_length> <max_query_length>128</max_query_length> <max_count_cacheable_search_terms>100</max_count_cacheable_search_terms> From 38c71b6e8aa77c0592d8f359e8e0aed80fd32356 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 18 Sep 2019 14:40:17 -0500 Subject: [PATCH 0514/1172] MC-18403: Pricing :: Product pricing schema --- .../Model/Resolver/Product/Price/Discount.php | 59 +++++++++ .../Model/Resolver/Product/Price/Prices.php | 121 +++++++++++++++++ .../Model/Resolver/Product/PriceRange.php | 125 ++++++++++++++++++ .../Resolver/Product/Price/DiscountTest.php | 57 ++++++++ .../CatalogGraphQl/etc/schema.graphqls | 36 +++-- 5 files changed, 389 insertions(+), 9 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php create mode 100644 app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php new file mode 100644 index 000000000000..c3f91daa72b9 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; + +/** + * Calculate price discount as value and percent + */ +class Discount +{ + /** + * Get formatted discount between two prices + * + * @param float $regularPrice + * @param float $finalPrice + * @return array + */ + public function getPriceDiscount(float $regularPrice, float $finalPrice) + { + return [ + 'amount_off' => $this->getPriceDifferenceAsValue($regularPrice, $finalPrice), + 'percent_off' => $this->getPriceDifferenceAsPercent($regularPrice, $finalPrice) + ]; + } + + /** + * Get value difference between two prices + * + * @param float $regularPrice + * @param float $finalPrice + * @return float + */ + private function getPriceDifferenceAsValue(float $regularPrice, float $finalPrice) + { + return round($regularPrice - $finalPrice, 2); + } + + /** + * Get percent difference between two prices + * + * @param float $regularPrice + * @param float $finalPrice + * @return float|int + */ + private function getPriceDifferenceAsPercent(float $regularPrice, float $finalPrice) + { + $difference = $this->getPriceDifferenceAsValue($regularPrice, $finalPrice); + + if ($difference === 0 || $regularPrice === 0) { + return 0; + } + + return round(($difference / $regularPrice) * 100, 2); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php new file mode 100644 index 000000000000..556ef46fceee --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; + +use Magento\Catalog\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; +use Magento\Framework\Pricing\PriceInfoInterface; +use Magento\Framework\Pricing\SaleableInterface; + +/** + * Provides product prices + */ +class Prices +{ + /** + * PriceInfo cache + * + * @var array + */ + private $productPrices = []; + + /** + * @var PriceInfoFactory + */ + private $priceInfoFactory; + + /** + * @param PriceInfoFactory $priceInfoFactory + */ + public function __construct( + PriceInfoFactory $priceInfoFactory + ) { + $this->priceInfoFactory = $priceInfoFactory; + } + + /** + * Get the product minimal final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); + return $finalPrice->getMinimalPrice(); + } + + /** + * Get the product minimal regular price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + $regularPrice = $priceInfo->getPrice(RegularPrice::PRICE_CODE); + return $regularPrice->getMinimalPrice(); + } + + /** + * Get the product maximum final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); + return $finalPrice->getMaximalPrice(); + } + + /** + * Get the product maximum final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + $regularPrice = $priceInfo->getPrice(RegularPrice::PRICE_CODE); + return $regularPrice->getMaximalPrice(); + } + + /** + * Get the product regular price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + } + + /** + * Get price info for product + * + * @param SaleableInterface $product + * @return PriceInfoInterface + */ + private function getProductPriceInfo($product) + { + if (!isset($this->productPrices[$product->getId()])) { + $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); + } + + return $this->productPrices[$product->getId()]; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php new file mode 100644 index 000000000000..78b76eddec46 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product; + +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Prices; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Catalog\Model\Product; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Pricing\SaleableInterface; +use Magento\Store\Api\Data\StoreInterface; + +/** + * Format product's pricing information for price_range field + */ +class PriceRange implements ResolverInterface +{ + /** + * @var Prices + */ + private $productPrices; + + /** + * @var Discount + */ + private $discount; + + /** + * @param Prices $productPrices + * @param Discount $discount + */ + public function __construct(Prices $productPrices, Discount $discount) + { + $this->productPrices = $productPrices; + $this->discount = $discount; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + /** @var StoreInterface $store */ + $store = $context->getExtensionAttributes()->getStore(); + + /** @var Product $product */ + $product = $value['model']; + $product->unsetData('minimal_price'); + + return [ + 'minimum_price' => $this->getMinimumProductPrice($product, $store), + 'maximum_price' => $this->getMaximumProductPrice($product, $store) + ]; + } + + /** + * Get formatted minimum product price + * + * @param SaleableInterface $product + * @param StoreInterface $store + * @return array + */ + private function getMinimumProductPrice(SaleableInterface $product, StoreInterface $store): array + { + $regularPrice = $this->productPrices->getMinimalRegularPrice($product)->getValue(); + $finalPrice = $this->productPrices->getMinimalFinalPrice($product)->getValue(); + + return $this->formatPrice($regularPrice, $finalPrice, $store); + } + + /** + * Get formatted maximum product price + * + * @param SaleableInterface $product + * @param StoreInterface $store + * @return array + */ + private function getMaximumProductPrice(SaleableInterface $product, StoreInterface $store): array + { + $regularPrice = $this->productPrices->getMaximalRegularPrice($product)->getValue(); + $finalPrice = $this->productPrices->getMaximalFinalPrice($product)->getValue(); + + return $this->formatPrice($regularPrice, $finalPrice, $store); + } + + /** + * Format price for GraphQl output + * + * @param float $regularPrice + * @param float $finalPrice + * @param StoreInterface $store + * @return array + */ + private function formatPrice(float $regularPrice, float $finalPrice, StoreInterface $store): array + { + return [ + 'regular_price' => [ + 'value' => $regularPrice, + 'currency' => $store->getCurrentCurrencyCode() + ], + 'final_price' => [ + 'value' => $finalPrice, + 'currency' => $store->getCurrentCurrencyCode() + ], + 'discount' => $this->discount->getPriceDiscount($regularPrice, $finalPrice), + ]; + } + + +} \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php new file mode 100644 index 000000000000..50d5b0ebd22c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Test\Unit\Model\Resolver\Product\Price; + +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; +use PHPUnit\Framework\TestCase; + +class DiscountTest extends TestCase +{ + /** + * @var Discount + */ + private $discount; + + protected function setUp() + { + $this->discount = new Discount(); + } + + /** + * @dataProvider priceDataProvider + * @param $regularPrice + * @param $finalPrice + * @param $expectedAmountOff + * @param $expectedPercentOff + */ + public function testGetPriceDiscount($regularPrice, $finalPrice, $expectedAmountOff, $expectedPercentOff) + { + $discountResult = $this->discount->getPriceDiscount($regularPrice, $finalPrice); + + $this->assertEquals($expectedAmountOff, $discountResult['amount_off']); + $this->assertEquals($expectedPercentOff, $discountResult['percent_off']); + } + + /** + * Price data provider + * + * [regularPrice, finalPrice, expectedAmountOff, expectedPercentOff] + * + * @return array + */ + public function priceDataProvider() + { + return [ + [100, 50, 50, 50], + [.1, .05, .05, 50], + [12.50, 10, 2.5, 20], + [99.99, 84.99, 15.0, 15], + [9999999999.01, 8999999999.11, 999999999.9, 10], + ]; + } +} diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 76a58857cebc..74350f81b9b0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -41,10 +41,26 @@ enum PriceTypeEnum @doc(description: "This enumeration the price type.") { DYNAMIC } -type ProductPrices @doc(description: "The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { - minimalPrice: Price @doc(description: "The lowest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the from value.") - maximalPrice: Price @doc(description: "The highest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the to value.") - regularPrice: Price @doc(description: "The base price of a product.") +type ProductPrices @deprecated(reason: "Use PriceRange instead.") @doc(description: "The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { + minimalPrice: Price @deprecated(reason: "Use PriceRange.minimum_price.") @doc(description: "The lowest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the from value.") + maximalPrice: Price @deprecated(reason: "Use PriceRange.maximum_price.") @doc(description: "The highest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the to value.") + regularPrice: Price @deprecated(reason: "Use PriceRange.minimum_price or PriceRange.minimum_price.") @doc(description: "The base price of a product.") +} + +type PriceRange @doc(description: "Price range for a product. If the product only has a single price minimum and maximum price will be the same."){ + minimum_price: ProductPrice! @doc(description: "The lowest possible final price for the product.") + maximum_price: ProductPrice @doc(description: "The highest possible final price for the product.") +} + +type ProductPrice @doc(description: "Represents a product price.") { + regular_price: Money! @doc(description: "The regular price of the product.") + final_price: Money! @doc(description: "The final price of the product after discounts applied.") + discount: ProductDiscount @doc(description: "The price discount. Represents the difference between the regular and final price.") +} + +type ProductDiscount @doc(description: "Price discount applied to a product.") { + percent_off: Float @doc(description: "The discount expressed a percent value.") + amount_off: Float @doc(description: "The discount expressed an absolute value.") } type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { @@ -61,8 +77,8 @@ interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\M type ProductTierPrices @doc(description: "The ProductTierPrices object defines a tier price, which is a quantity discount offered to a specific customer group.") { customer_group_id: String @doc(description: "The ID of the customer group.") qty: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") - value: Float @doc(description: "The price of the fixed price item.") - percentage_value: Float @doc(description: "The percentage discount of the item.") + value: Float @deprecated(reason: "Use final_price") @doc(description: "The price of the fixed price item.") + percentage_value: Float @decprected(reason: "Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") website_id: Float @doc(description: "The ID assigned to the website.") } @@ -84,7 +100,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ thumbnail: ProductImage @doc(description: "The relative path to the product's thumbnail image.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductImage") new_from_date: String @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") new_to_date: String @doc(description: "The end date for new product listings.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\NewFromTo") - tier_price: Float @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached.") + tier_price: Float @deprecated(reason: "Use price_tiers for product tier price information.") @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached.") options_container: String @doc(description: "If the product has multiple options, determines where they appear on the product page.") created_at: String @doc(description: "Timestamp indicating when the product was created.") updated_at: String @doc(description: "Timestamp indicating when the product was updated.") @@ -93,8 +109,10 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ websites: [Website] @doc(description: "An array of websites in which the product is available.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Websites") product_links: [ProductLinksInterface] @doc(description: "An array of ProductLinks objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\ProductLinks") media_gallery_entries: [MediaGalleryEntry] @deprecated(reason: "Use product's `media_gallery` instead") @doc(description: "An array of MediaGalleryEntry objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\MediaGalleryEntries") - tier_prices: [ProductTierPrices] @doc(description: "An array of ProductTierPrices objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") - price: ProductPrices @doc(description: "A ProductPrices object, indicating the price of an item.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") + tier_prices: [ProductTierPrices] @deprecated(reason: "Use price_tiers for product tier price information.") @doc(description: "An array of ProductTierPrices objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") + price: ProductPrices @deprecated(reason: "Use price_range for product price information.") @doc(description: "A ProductPrices object, indicating the price of an item.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") + price_range: PriceRange! @doc(description: "A PriceRange object, indicating the range of prices for the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\PriceRange") +#TODO price_tiers: [TierPrice] @doc(description: "An array of TierPrice objects.") gift_message_available: String @doc(description: "Indicates whether a gift message is available.") manufacturer: Int @doc(description: "A number representing the product's manufacturer.") categories: [CategoryInterface] @doc(description: "The categories assigned to a product.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentity") From 5af7a5d2fdf7cb26f71044847605a3e409b01488 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 18 Sep 2019 16:36:29 -0500 Subject: [PATCH 0515/1172] MC-18403: Pricing :: Product pricing schema --- .../CatalogGraphQl/etc/schema.graphqls | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 74350f81b9b0..973064c076c6 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -16,9 +16,9 @@ type Query { @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") } -type Price @doc(description: "The Price object defines the price of a product as well as any tax-related adjustments.") { - amount: Money @doc(description: "The price of a product plus a three-letter currency code.") - adjustments: [PriceAdjustment] @doc(description: "An array that provides information about tax, weee, or weee_tax adjustments.") +type Price @doc(description: "Price is deprecated, replaced by ProductPrice. The Price object defines the price of a product as well as any tax-related adjustments.") { + amount: Money @deprecated(reason: "Price is deprecated, use ProductPrice.") @doc(description: "The price of a product plus a three-letter currency code.") + adjustments: [PriceAdjustment] @deprecated(reason: "Price is deprecated, use ProductPrice.") @doc(description: "An array that provides information about tax, weee, or weee_tax adjustments.") } type PriceAdjustment @doc(description: "The PricedAdjustment object defines the amount of money to apply as an adjustment, the type of adjustment to apply, and whether the item is included or excluded from the adjustment.") { @@ -44,7 +44,7 @@ enum PriceTypeEnum @doc(description: "This enumeration the price type.") { type ProductPrices @deprecated(reason: "Use PriceRange instead.") @doc(description: "The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { minimalPrice: Price @deprecated(reason: "Use PriceRange.minimum_price.") @doc(description: "The lowest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the from value.") maximalPrice: Price @deprecated(reason: "Use PriceRange.maximum_price.") @doc(description: "The highest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the to value.") - regularPrice: Price @deprecated(reason: "Use PriceRange.minimum_price or PriceRange.minimum_price.") @doc(description: "The base price of a product.") + regularPrice: Price @deprecated(reason: "Use regular_price from PriceRange.minimum_price or PriceRange.minimum_price.") @doc(description: "The base price of a product.") } type PriceRange @doc(description: "Price range for a product. If the product only has a single price minimum and maximum price will be the same."){ @@ -63,6 +63,12 @@ type ProductDiscount @doc(description: "Price discount applied to a product.") { amount_off: Float @doc(description: "The discount expressed an absolute value.") } +type TierPrice @doc(description: "TierPrice defines a tier price, which is a price offered based on a particular quantity purchased.") { + final_price: Money @doc(desription: "The price of the product at this tier.") + quantity: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") + discount: ProductDiscount @doc(description: "The price discount that this tier represents.") +} + type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { } @@ -74,12 +80,12 @@ interface ProductLinksInterface @typeResolver(class: "Magento\\CatalogGraphQl\\M position: Int @doc(description: "The position within the list of product links.") } -type ProductTierPrices @doc(description: "The ProductTierPrices object defines a tier price, which is a quantity discount offered to a specific customer group.") { - customer_group_id: String @doc(description: "The ID of the customer group.") - qty: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") - value: Float @deprecated(reason: "Use final_price") @doc(description: "The price of the fixed price item.") - percentage_value: Float @decprected(reason: "Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") - website_id: Float @doc(description: "The ID assigned to the website.") +type ProductTierPrices @doc(description: "ProductTierPrices is deprecated and has been replaced by TierPrice. The ProductTierPrices object defines a tier price, which is a quantity discount offered to a specific customer group.") { + customer_group_id: String @deprecated(reason: "customer_group_id is not relevant for storefront.") @doc(description: "The ID of the customer group.") + qty: Float @deprecated(reason: "ProductTierPrices is deprecated, use TierPrice.quantity.") @doc(description: "The number of items that must be purchased to qualify for tier pricing.") + value: Float @deprecated(reason: "ProductTierPrices is deprecated. Use TierPrice.final_price") @doc(description: "The price of the fixed price item.") + percentage_value: Float @decprected(reason: "ProductTierPrices is deprecated. Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") + website_id: Float @deprecated(reason: "website_id is not relevant for storefront.") @doc(description: "The ID assigned to the website.") } interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "The ProductInterface contains attributes that are common to all types of products. Note that descriptions may not be available for custom and EAV attributes.") { @@ -112,7 +118,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ tier_prices: [ProductTierPrices] @deprecated(reason: "Use price_tiers for product tier price information.") @doc(description: "An array of ProductTierPrices objects.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\TierPrices") price: ProductPrices @deprecated(reason: "Use price_range for product price information.") @doc(description: "A ProductPrices object, indicating the price of an item.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Price") price_range: PriceRange! @doc(description: "A PriceRange object, indicating the range of prices for the product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\PriceRange") -#TODO price_tiers: [TierPrice] @doc(description: "An array of TierPrice objects.") + price_tiers: [TierPrice] @doc(description: "An array of TierPrice objects.") gift_message_available: String @doc(description: "Indicates whether a gift message is available.") manufacturer: Int @doc(description: "A number representing the product's manufacturer.") categories: [CategoryInterface] @doc(description: "The categories assigned to a product.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoriesIdentity") From bfbbe0ebf39617f0a2b75d032f339c1937e06866 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Wed, 18 Sep 2019 18:47:21 -0300 Subject: [PATCH 0516/1172] adjusting PHP CS for 120 lines and invalid quote at validation.js --- app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php | 4 +++- app/code/Magento/Customer/view/frontend/web/js/validation.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php index da5e089f93ec..f92545b0b767 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php @@ -545,7 +545,9 @@ public function testGetHtmlExtraParamsWithRequiredOption() $this->escaper->expects($this->any()) ->method('escapeHtml') ->with('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}') - ->will($this->returnValue('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}')); + ->will($this->returnValue( + '{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}' + )); $this->context->expects($this->any())->method('getEscaper')->will($this->returnValue($this->escaper)); diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js index 14ae69b02080..676fd18d2682 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/validation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -6,7 +6,7 @@ require([ ], function($, moment) { 'use strict'; $.validator.addMethod( - "validate-dob", + 'validate-dob', function (value) { if (value === '') { return true; From db5e65f5489ade4f4bfa024975ef6e78d1ae2c8a Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Wed, 18 Sep 2019 19:15:32 -0300 Subject: [PATCH 0517/1172] PHP CS fixing --- .../Magento/Customer/Test/Unit/Block/Widget/DobTest.php | 8 +++++--- .../Magento/Customer/view/frontend/web/js/validation.js | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php index f92545b0b767..9f49cbdce1f9 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php @@ -9,13 +9,13 @@ use Magento\Customer\Api\CustomerMetadataInterface; use Magento\Customer\Api\Data\AttributeMetadataInterface; use Magento\Customer\Api\Data\ValidationRuleInterface; +use Magento\Customer\Block\Widget\Dob; use Magento\Customer\Helper\Address; use Magento\Framework\App\CacheInterface; use Magento\Framework\Cache\FrontendInterface; use Magento\Framework\Data\Form\FilterFactory; use Magento\Framework\Escaper; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Customer\Block\Widget\Dob; use Magento\Framework\Locale\Resolver; use Magento\Framework\Locale\ResolverInterface; use Magento\Framework\Stdlib\DateTime\Timezone; @@ -545,9 +545,11 @@ public function testGetHtmlExtraParamsWithRequiredOption() $this->escaper->expects($this->any()) ->method('escapeHtml') ->with('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}') - ->will($this->returnValue( + ->will( + $this->returnValue( '{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}' - )); + ) + ); $this->context->expects($this->any())->method('getEscaper')->will($this->returnValue($this->escaper)); diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js index 676fd18d2682..a6c058236a10 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/validation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -5,6 +5,7 @@ require([ 'mage/translate', ], function($, moment) { 'use strict'; + $.validator.addMethod( 'validate-dob', function (value) { From b300c94f4dc39c60c3421db4531fdeb2fe277221 Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Wed, 18 Sep 2019 11:25:09 -0500 Subject: [PATCH 0518/1172] MC-19870: Update Regions list for China country - Add data patch for china regions --- .../Customer/Test/Mftf/Data/AddressData.xml | 15 +++ ...orefrontUpdateCustomerAddressChinaTest.xml | 51 ++++++++ .../Setup/Patch/Data/AddDataForChina.php | 117 ++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForChina.php diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 4d7a39b3246e..437eea10994d 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -239,6 +239,21 @@ <data key="state">Côtes-d'Armor</data> <data key="postcode">12345</data> </entity> + <entity name="updateCustomerChinaAddress" type="address"> + <data key="firstname">Xian</data> + <data key="lastname">Shai</data> + <data key="company">Hunan Fenmian</data> + <data key="telephone">+86 851 8410 4337</data> + <array key="street"> + <item>Nanyuan Rd, Wudang</item> + <item>Hunan Fenmian</item> + </array> + <data key="country_id">CN</data> + <data key="country">China</data> + <data key="city">Guiyang</data> + <data key="state">Guizhou Sheng</data> + <data key="postcode">550002</data> + </entity> <entity name="updateCustomerNoXSSInjection" type="address"> <data key="firstname">Jany</data> <data key="lastname">Doe</data> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml new file mode 100644 index 000000000000..285de8d777b4 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressChinaTest.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontUpdateCustomerAddressChinaTest"> + <annotations> + <stories value="Update Regions list for China country"/> + <title value="Update customer address on storefront with china address"/> + <description value="Update customer address on storefront with china address and verify you can select a region"/> + <testCaseId value="MC-20234"/> + <severity value="AVERAGE"/> + <group value="customer"/> + </annotations> + + <before> + <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="CustomerEntityOne"/> + </actionGroup> + </before> + <after> + <actionGroup ref="DeleteCustomerByEmailActionGroup" stepKey="deleteNewUser"> + <argument name="email" value="{{CustomerEntityOne.email}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Update customer address in storefront--> + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddress"> + <argument name="Address" value="updateCustomerChinaAddress"/> + </actionGroup> + <!--Verify customer address save success message--> + <see selector="{{AdminCustomerMessagesSection.successMessage}}" userInput="You saved the address." stepKey="seeAssertCustomerAddressSuccessSaveMessage"/> + + <!--Verify customer default billing address--> + <actionGroup ref="VerifyCustomerBillingAddressWithState" stepKey="verifyBillingAddress"> + <argument name="address" value="updateCustomerChinaAddress"/> + </actionGroup> + + <!--Verify customer default shipping address--> + <actionGroup ref="VerifyCustomerShippingAddressWithState" stepKey="verifyShippingAddress"> + <argument name="address" value="updateCustomerChinaAddress"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForChina.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForChina.php new file mode 100644 index 000000000000..0750f8056c4d --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForChina.php @@ -0,0 +1,117 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add China States + */ +class AddDataForChina implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var \Magento\Directory\Setup\DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * @param ModuleDataSetupInterface $moduleDataSetup + * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForChina() + ); + } + + /** + * China states data. + * + * @return array + */ + private function getDataForChina() + { + return [ + ['CN', 'CN-AH', 'Anhui Sheng'], + ['CN', 'CN-BJ', 'Beijing Shi'], + ['CN', 'CN-CQ', 'Chongqing Shi'], + ['CN', 'CN-FJ', 'Fujian Sheng'], + ['CN', 'CN-GS', 'Gansu Sheng'], + ['CN', 'CN-GD', 'Guangdong Sheng'], + ['CN', 'CN-GX', 'Guangxi Zhuangzu Zizhiqu'], + ['CN', 'CN-GZ', 'Guizhou Sheng'], + ['CN', 'CN-HI', 'Hainan Sheng'], + ['CN', 'CN-HE', 'Hebei Sheng'], + ['CN', 'CN-HL', 'Heilongjiang Sheng'], + ['CN', 'CN-HA', 'Henan Sheng'], + ['CN', 'CN-HK', 'Hong Kong SAR'], + ['CN', 'CN-HB', 'Hubei Sheng'], + ['CN', 'CN-HN', 'Hunan Sheng'], + ['CN', 'CN-JS', 'Jiangsu Sheng'], + ['CN', 'CN-JX', 'Jiangxi Sheng'], + ['CN', 'CN-JL', 'Jilin Sheng'], + ['CN', 'CN-LN', 'Liaoning Sheng'], + ['CN', 'CN-MO', 'Macao SAR'], + ['CN', 'CN-NM', 'Nei Mongol Zizhiqu'], + ['CN', 'CN-NX', 'Ningxia Huizi Zizhiqu'], + ['CN', 'CN-QH', 'Qinghai Sheng'], + ['CN', 'CN-SN', 'Shaanxi Sheng'], + ['CN', 'CN-SD', 'Shandong Sheng'], + ['CN', 'CN-SH', 'Shanghai Shi'], + ['CN', 'CN-SX', 'Shanxi Sheng'], + ['CN', 'CN-SC', 'Sichuan Sheng'], + ['CN', 'CN-TW', 'Taiwan Sheng'], + ['CN', 'CN-TJ', 'Tianjin Shi'], + ['CN', 'CN-XJ', 'Xinjiang Uygur Zizhiqu'], + ['CN', 'CN-XZ', 'Xizang Zizhiqu'], + ['CN', 'CN-YN', 'Yunnan Sheng'], + ['CN', 'CN-ZJ', 'Zhejiang Sheng'], + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} From 1de4b8cff4988e63f6e84b19004402426a7999b3 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Wed, 18 Sep 2019 19:38:51 -0300 Subject: [PATCH 0519/1172] fixing static check errors --- app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php | 2 +- app/code/Magento/Customer/view/frontend/web/js/validation.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php index 9f49cbdce1f9..11e828d18e57 100644 --- a/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php +++ b/app/code/Magento/Customer/Test/Unit/Block/Widget/DobTest.php @@ -547,7 +547,7 @@ public function testGetHtmlExtraParamsWithRequiredOption() ->with('{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}') ->will( $this->returnValue( - '{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}' + '{"required":true,"validate-date":{"dateFormat":"M\/d\/Y"},"validate-dob":true}' ) ); diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js index a6c058236a10..672681393015 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/validation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -3,7 +3,7 @@ require([ 'moment', 'jquery/validate', 'mage/translate', -], function($, moment) { +], function ($, moment) { 'use strict'; $.validator.addMethod( From 51c309292282a0988ebbaa0ca4187f48df026baa Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 18 Sep 2019 17:49:54 -0500 Subject: [PATCH 0520/1172] MC-18403: Pricing :: Product pricing schema --- .../Model/Resolver/Product/Price/Discount.php | 21 +++++++++++++------ .../Resolver/Product/Price/DiscountTest.php | 4 ++++ .../CatalogGraphQl/etc/schema.graphqls | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php index c3f91daa72b9..b7fb8dc2938c 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php @@ -12,6 +12,11 @@ */ class Discount { + /** + * @var float + */ + private $zeroThreshold = 0.0001; + /** * Get formatted discount between two prices * @@ -19,7 +24,7 @@ class Discount * @param float $finalPrice * @return array */ - public function getPriceDiscount(float $regularPrice, float $finalPrice) + public function getPriceDiscount(float $regularPrice, float $finalPrice): array { return [ 'amount_off' => $this->getPriceDifferenceAsValue($regularPrice, $finalPrice), @@ -34,9 +39,13 @@ public function getPriceDiscount(float $regularPrice, float $finalPrice) * @param float $finalPrice * @return float */ - private function getPriceDifferenceAsValue(float $regularPrice, float $finalPrice) + private function getPriceDifferenceAsValue(float $regularPrice, float $finalPrice): float { - return round($regularPrice - $finalPrice, 2); + $difference = $regularPrice - $finalPrice; + if ($difference <= $this->zeroThreshold) { + return 0; + } + return round($difference, 2); } /** @@ -44,13 +53,13 @@ private function getPriceDifferenceAsValue(float $regularPrice, float $finalPric * * @param float $regularPrice * @param float $finalPrice - * @return float|int + * @return float */ - private function getPriceDifferenceAsPercent(float $regularPrice, float $finalPrice) + private function getPriceDifferenceAsPercent(float $regularPrice, float $finalPrice): float { $difference = $this->getPriceDifferenceAsValue($regularPrice, $finalPrice); - if ($difference === 0 || $regularPrice === 0) { + if ($difference <= $this->zeroThreshold || $regularPrice <= $this->zeroThreshold) { return 0; } diff --git a/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php index 50d5b0ebd22c..ad688474c889 100644 --- a/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php +++ b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php @@ -52,6 +52,10 @@ public function priceDataProvider() [12.50, 10, 2.5, 20], [99.99, 84.99, 15.0, 15], [9999999999.01, 8999999999.11, 999999999.9, 10], + [0, 0, 0, 0], + [0, 10, 0, 0], + [9.95, 9.95, 0, 0], + [21.05, 0, 21.05, 100] ]; } } diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 973064c076c6..48d9db209b9c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -48,8 +48,8 @@ type ProductPrices @deprecated(reason: "Use PriceRange instead.") @doc(descripti } type PriceRange @doc(description: "Price range for a product. If the product only has a single price minimum and maximum price will be the same."){ - minimum_price: ProductPrice! @doc(description: "The lowest possible final price for the product.") - maximum_price: ProductPrice @doc(description: "The highest possible final price for the product.") + minimum_price: ProductPrice! @doc(description: "The lowest possible price for the product.") + maximum_price: ProductPrice @doc(description: "The highest possible price for the product.") } type ProductPrice @doc(description: "Represents a product price.") { From e481fe849332df380f9ab3833c41ca6c0d569209 Mon Sep 17 00:00:00 2001 From: Tiago <tiagooctp@gmail.com> Date: Wed, 18 Sep 2019 20:25:11 -0300 Subject: [PATCH 0521/1172] remove last comma --- app/code/Magento/Customer/view/frontend/web/js/validation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/view/frontend/web/js/validation.js b/app/code/Magento/Customer/view/frontend/web/js/validation.js index 672681393015..56b60c3a0810 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/validation.js +++ b/app/code/Magento/Customer/view/frontend/web/js/validation.js @@ -2,7 +2,7 @@ require([ 'jquery', 'moment', 'jquery/validate', - 'mage/translate', + 'mage/translate' ], function ($, moment) { 'use strict'; From 927f94070da8e13ec814da08deec47f02dbbd516 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Thu, 19 Sep 2019 10:14:51 +0300 Subject: [PATCH 0522/1172] MC-18215: Error message while creating shipping label - Revert echo url in location --- .../view/adminhtml/templates/order/packaging/popup.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml index cd25cb919adb..28322d953492 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/packaging/popup.phtml @@ -31,7 +31,7 @@ $girthEnabled = $block->isDisplayGirthValue() && $block->isGirthAllowed() ? 1 : packaging.sendCreateLabelRequest(); }); packaging.setLabelCreatedCallback(function(response){ - setLocation("<?php $block->escapeJs($block->escapeUrl($block->getUrl( + setLocation("<?= $block->escapeJs($block->escapeUrl($block->getUrl( 'sales/order/view', ['order_id' => $block->getShipment()->getOrderId()] ))); ?>"); From 8285e6a4ce6920835c5416d43cd8a2434793813d Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Wed, 11 Sep 2019 14:39:12 +0300 Subject: [PATCH 0523/1172] magento/magento2#: Replace deprecated message functions in the Magento_ProductAlert module. --- .../ProductAlert/Controller/Add/Price.php | 37 +++++++++++-------- .../ProductAlert/Controller/Add/Stock.php | 6 +-- .../Controller/Unsubscribe/Price.php | 21 ++++++++--- .../Controller/Unsubscribe/Stock.php | 6 +-- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/code/Magento/ProductAlert/Controller/Add/Price.php b/app/code/Magento/ProductAlert/Controller/Add/Price.php index 973db8c3bf5d..2dbcc27cd57d 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Price.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Price.php @@ -6,16 +6,17 @@ namespace Magento\ProductAlert\Controller\Add; -use Magento\Framework\App\Action\HttpGetActionInterface; -use Magento\ProductAlert\Controller\Add as AddController; -use Magento\Framework\App\Action\Context; -use Magento\Customer\Model\Session as CustomerSession; -use Magento\Store\Model\StoreManagerInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\UrlInterface; +use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Action\Context; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Controller\Result\Redirect; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\UrlInterface; +use Magento\ProductAlert\Controller\Add as AddController; +use Magento\Store\Model\StoreManagerInterface; /** * Controller for notifying about price. @@ -28,15 +29,17 @@ class Price extends AddController implements HttpGetActionInterface protected $storeManager; /** - * @var \Magento\Catalog\Api\ProductRepositoryInterface + * @var \Magento\Catalog\Api\ProductRepositoryInterface */ protected $productRepository; /** - * @param \Magento\Framework\App\Action\Context $context - * @param \Magento\Customer\Model\Session $customerSession - * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository + * Price constructor. + * + * @param Context $context + * @param CustomerSession $customerSession + * @param StoreManagerInterface $storeManager + * @param ProductRepositoryInterface $productRepository */ public function __construct( Context $context, @@ -54,6 +57,7 @@ public function __construct( * * @param string $url * @return bool + * @throws NoSuchEntityException */ protected function isInternal($url) { @@ -68,13 +72,14 @@ protected function isInternal($url) /** * Method for adding info about product alert price. * - * @return \Magento\Framework\Controller\Result\Redirect + * @return \Magento\Framework\Controller\ResultInterface + * @throws NoSuchEntityException */ public function execute() { $backUrl = $this->getRequest()->getParam(Action::PARAM_NAME_URL_ENCODED); $productId = (int)$this->getRequest()->getParam('product_id'); - /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ + /** @var Redirect $resultRedirect */ $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT); if (!$backUrl || !$productId) { $resultRedirect->setPath('/'); @@ -93,9 +98,9 @@ public function execute() ->setWebsiteId($store->getWebsiteId()) ->setStoreId($store->getId()); $model->save(); - $this->messageManager->addSuccess(__('You saved the alert subscription.')); + $this->messageManager->addSuccessMessage(__('You saved the alert subscription.')); } catch (NoSuchEntityException $noEntityException) { - $this->messageManager->addError(__('There are not enough parameters.')); + $this->messageManager->addErrorMessage(__('There are not enough parameters.')); if ($this->isInternal($backUrl)) { $resultRedirect->setUrl($backUrl); } else { @@ -103,7 +108,7 @@ public function execute() } return $resultRedirect; } catch (\Exception $e) { - $this->messageManager->addException( + $this->messageManager->addExceptionMessage( $e, __("The alert subscription couldn't update at this time. Please try again later.") ); diff --git a/app/code/Magento/ProductAlert/Controller/Add/Stock.php b/app/code/Magento/ProductAlert/Controller/Add/Stock.php index f36fdf5fb715..38b22d1efb85 100644 --- a/app/code/Magento/ProductAlert/Controller/Add/Stock.php +++ b/app/code/Magento/ProductAlert/Controller/Add/Stock.php @@ -76,13 +76,13 @@ public function execute() ->setWebsiteId($store->getWebsiteId()) ->setStoreId($store->getId()); $model->save(); - $this->messageManager->addSuccess(__('Alert subscription has been saved.')); + $this->messageManager->addSuccessMessage(__('Alert subscription has been saved.')); } catch (NoSuchEntityException $noEntityException) { - $this->messageManager->addError(__('There are not enough parameters.')); + $this->messageManager->addErrorMessage(__('There are not enough parameters.')); $resultRedirect->setUrl($backUrl); return $resultRedirect; } catch (\Exception $e) { - $this->messageManager->addException( + $this->messageManager->addExceptionMessage( $e, __("The alert subscription couldn't update at this time. Please try again later.") ); diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php index 2077b1ff2794..0aabf5d96e1e 100644 --- a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php +++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php @@ -6,6 +6,7 @@ namespace Magento\ProductAlert\Controller\Unsubscribe; +use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\ProductAlert\Controller\Unsubscribe as UnsubscribeController; use Magento\Framework\App\Action\Context; use Magento\Customer\Model\Session as CustomerSession; @@ -13,7 +14,10 @@ use Magento\Framework\Controller\ResultFactory; use Magento\Framework\Exception\NoSuchEntityException; -class Price extends UnsubscribeController +/** + * Class Price + */ +class Price extends UnsubscribeController implements HttpGetActionInterface { /** * @var \Magento\Catalog\Api\ProductRepositoryInterface @@ -35,6 +39,8 @@ public function __construct( } /** + * Unsubscribe action + * * @return \Magento\Framework\Controller\Result\Redirect */ public function execute() @@ -51,8 +57,13 @@ public function execute() /* @var $product \Magento\Catalog\Model\Product */ $product = $this->productRepository->getById($productId); if (!$product->isVisibleInCatalog()) { - throw new NoSuchEntityException(); + $this->messageManager->addErrorMessage( + __("The product wasn't found. Verify the product and try again.") + ); + $resultRedirect->setPath('customer/account/'); + return $resultRedirect; } + /** @var \Magento\ProductAlert\Model\Price $model */ $model = $this->_objectManager->create(\Magento\ProductAlert\Model\Price::class) ->setCustomerId($this->customerSession->getCustomerId()) @@ -67,13 +78,13 @@ public function execute() $model->delete(); } - $this->messageManager->addSuccess(__('You deleted the alert subscription.')); + $this->messageManager->addSuccessMessage(__('You deleted the alert subscription.')); } catch (NoSuchEntityException $noEntityException) { - $this->messageManager->addError(__("The product wasn't found. Verify the product and try again.")); + $this->messageManager->addErrorMessage(__("The product wasn't found. Verify the product and try again.")); $resultRedirect->setPath('customer/account/'); return $resultRedirect; } catch (\Exception $e) { - $this->messageManager->addException( + $this->messageManager->addExceptionMessage( $e, __("The alert subscription couldn't update at this time. Please try again later.") ); diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php index 1b729f988e4a..f8df6ae6af38 100644 --- a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php +++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php @@ -94,13 +94,13 @@ public function execute() if ($model->getId()) { $model->delete(); } - $this->messageManager->addSuccess(__('You will no longer receive stock alerts for this product.')); + $this->messageManager->addSuccessMessage(__('You will no longer receive stock alerts for this product.')); } catch (NoSuchEntityException $noEntityException) { - $this->messageManager->addError(__('The product was not found.')); + $this->messageManager->addErrorMessage(__('The product was not found.')); $resultRedirect->setPath('customer/account/'); return $resultRedirect; } catch (\Exception $e) { - $this->messageManager->addException( + $this->messageManager->addExceptionMessage( $e, __("The alert subscription couldn't update at this time. Please try again later.") ); From b34a586a690d5ba2697baada60d33bf3e78b2687 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Thu, 19 Sep 2019 17:01:33 +0400 Subject: [PATCH 0524/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window - Updated automated test script --- ...StorefrontCheckoutCartGiftMessageSection.xml | 12 ++++++++++++ ...orefrontMultishippingCheckoutActionGroup.xml | 2 +- .../Test/Mftf/Section/MultishippingSection.xml | 2 +- ...CheckoutShippingMultipleAddressesSection.xml | 1 - ...koutWhenCartPageIsOpenedInAnotherTabTest.xml | 17 ++--------------- .../Mftf/Section/AdminOrdersGridSection.xml | 2 +- 6 files changed, 17 insertions(+), 19 deletions(-) create mode 100644 app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftMessageSection.xml diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftMessageSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftMessageSection.xml new file mode 100644 index 000000000000..b1f6f35ba5d9 --- /dev/null +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontCheckoutCartGiftMessageSection.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontCheckoutCartGiftMessageSection"> + <element name="giftItemMessage" type="textarea" selector="tbody.cart:nth-of-type({{blockNumber}}) #gift-message-whole-message" parameterized="true"/> + </section> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml index 3ceb7c9a778e..c5dee010239d 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/StorefrontMultishippingCheckoutActionGroup.xml @@ -15,7 +15,7 @@ </arguments> <selectOption selector="{{StorefrontCheckoutShippingMultipleAddressesSection.selectedMultipleShippingAddress('1')}}" userInput="{{firstAddress}}" stepKey="selectShippingAddressForTheFirstItem"/> <selectOption selector="{{StorefrontCheckoutShippingMultipleAddressesSection.selectedMultipleShippingAddress('2')}}" userInput="{{secondAddress}}" stepKey="selectShippingAddressForTheSecondItem"/> - <click selector="{{StorefrontCheckoutShippingMultipleAddressesSection.goToShippingInformationButton}}" stepKey="clickToGoToInformationButton"/> + <click selector="{{CheckoutSuccessMainSection.continueShoppingButton}}" stepKey="clickToGoToInformationButton"/> </actionGroup> <actionGroup name="StorefrontGoCheckoutWithMultipleAddresses"> <click selector="{{MultishippingSection.shippingMultipleCheckout}}" stepKey="clickToMultipleAddressShippingButton"/> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index a3dfa9c53031..c6fc44922737 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -23,7 +23,7 @@ <element name="secondShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> </section> <section name="StorefrontMultipleShippingMethodSection"> - <element name="orderId" type="text" selector="(//div[@class='order-id'])[{{rowNum}}]" parameterized="true"/> + <element name="orderId" type="text" selector=".shipping-list:nth-child({{rowNum}}) .order-id" parameterized="true"/> <element name="placeOrderButton" type="button" selector="#review-button"/> <element name="goToReviewYourOrderButton" type="button" selector="#payment-continue"/> <element name="continueToBillingInformationButton" type="button" selector=".action.primary.continue"/> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml index 75bc7f64b292..34427bda9334 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/StorefrontCheckoutShippingMultipleAddressesSection.xml @@ -10,6 +10,5 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontCheckoutShippingMultipleAddressesSection"> <element name="selectedMultipleShippingAddress" type="select" selector=".table tr:nth-of-type({{selectNumber}}) select" parameterized="true"/> - <element name="goToShippingInformationButton" type="button" selector=".action.primary.continue"/> </section> </sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml index 1ba03a01951b..fd79d4d954cd 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontProcessMultishippingCheckoutWhenCartPageIsOpenedInAnotherTabTest.xml @@ -21,13 +21,10 @@ </annotations> <before> <!-- Login as Admin --> - <comment userInput="Login as Admin" stepKey="commentLoginAsAdmin"/> <actionGroup ref="LoginAsAdmin" stepKey="login"/> <!-- Set configurations --> - <comment userInput="Set configurations" stepKey="commentSetConfigurations"/> <magentoCLI command="config:set multishipping/options/checkout_multiple 1" stepKey="allowShippingToMultipleAddresses"/> <!-- Create two simple products --> - <comment userInput="Create two simple products" stepKey="commentCreateSimpleProducts"/> <createData entity="ApiCategory" stepKey="createCategory"/> <createData entity="_defaultProduct" stepKey="createFirstProduct"> <requiredEntity createDataKey="createCategory"/> @@ -39,7 +36,6 @@ </before> <after> <!-- Delete created data --> - <comment userInput="Delete created data" stepKey="commentDeleteCreatedData"/> <actionGroup ref="logout" stepKey="logout"/> <deleteData createDataKey="createFirstProduct" stepKey="deleteFirstProduct"/> <deleteData createDataKey="createSecondProduct" stepKey="deleteSecondProduct"/> @@ -47,12 +43,10 @@ <deleteData createDataKey="createCustomerWithMultipleAddresses" stepKey="deleteCustomer"/> </after> <!-- Login to the Storefront as created customer --> - <comment userInput="Login to the Storefront as created customer" stepKey="commentLoginAsCustomer"/> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> <argument name="Customer" value="$$createCustomerWithMultipleAddresses$$"/> </actionGroup> <!-- Add two products to the Shopping Cart --> - <comment userInput="Add two products to the Cart" stepKey="commentAddProductsToTheCart"/> <amOnPage url="{{StorefrontProductPage.url($$createFirstProduct.name$$)}}" stepKey="amOnStorefrontProductFirstPage"/> <waitForPageLoad stepKey="waitForTheFirstProduct"/> <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProductToCart"> @@ -67,18 +61,15 @@ </actionGroup> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPage"/> <!-- Click 'Check Out with Multiple Addresses' --> - <comment userInput="Click 'Check Out with Multiple Addresses'" stepKey="commentClickToCheckOutWithMultipleAddress"/> <waitForPageLoad stepKey="waitForSecondPageLoad"/> <actionGroup ref="StorefrontGoCheckoutWithMultipleAddresses" stepKey="goCheckoutWithMultipleAddresses"/> <!-- Select different addresses and click 'Go to Shipping Information' --> - <comment userInput="Select different addresses and click 'Go to Shipping Information'" stepKey="commentClickOnGoToShippingInformation"/> <actionGroup ref="StorefrontCheckoutShippingSelectMultipleAddressesActionGroup" stepKey="selectMultipleAddresses"> <argument name="firstAddress" value="{{UK_Not_Default_Address.street[0]}}"/> <argument name="secondAddress" value="{{US_Address_NY.street[1]}}"/> </actionGroup> <waitForPageLoad stepKey="waitPageLoad"/> <!-- Open the Cart page in another browser window and go back --> - <comment userInput="Open the Cart page in another browser window and go back" stepKey="commentOpenCartPageInAnotherTab"/> <openNewTab stepKey="openNewTab"/> <amOnPage url="{{CheckoutCartPage.url}}" stepKey="amOnShoppingCartPageNewTab"/> <actionGroup ref="AssertStorefrontCheckoutCartItemsActionGroup" stepKey="assertFirstProductItemInCheckOutCart"> @@ -97,34 +88,30 @@ </actionGroup> <switchToNextTab stepKey="switchToNextTab"/> <!-- Click 'Continue to Billing Information' and 'Go to Review Your Order' --> - <comment userInput="Click 'Continue to Billing Information' > click 'Go to Review Your Order'" stepKey="commentGoToReviewYourOrder"/> <actionGroup ref="StorefrontGoToBillingInformationActionGroup" stepKey="goToBillingInformation"/> <see selector="{{ShipmentFormSection.shippingAddress}}" userInput="{{US_Address_NY.city}}" stepKey="seeBillingAddress"/> <waitForElementVisible selector="{{StorefrontMultipleShippingMethodSection.goToReviewYourOrderButton}}" stepKey="waitForGoToReviewYourOrderVisible" /> <click selector="{{StorefrontMultipleShippingMethodSection.goToReviewYourOrderButton}}" stepKey="clickToGoToReviewYourOrderButton"/> <!-- Click 'Place Order' --> - <comment userInput="Click 'Place Order'" stepKey="commentPlaceOrder"/> <actionGroup ref="PlaceOrderActionGroup" stepKey="placeOrder"/> <see selector="{{StorefrontMultipleShippingMethodSection.successMessage}}" userInput="Successfully ordered" stepKey="seeSuccessMessage"/> <grabTextFrom selector="{{StorefrontMultipleShippingMethodSection.orderId('1')}}" stepKey="grabFirstOrderId"/> <grabTextFrom selector="{{StorefrontMultipleShippingMethodSection.orderId('2')}}" stepKey="grabSecondOrderId"/> <!-- Go to My Account > My Orders --> - <comment userInput="Go to My Account > My Orders" stepKey="commentGoToMyOrders"/> <amOnPage url="{{StorefrontCustomerOrdersHistoryPage.url}}" stepKey="goToMyOrdersPage"/> <waitForPageLoad stepKey="waitForMyOrdersPageLoad"/> <seeElement selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabFirstOrderId})}}" stepKey="seeFirstOrder"/> <seeElement selector="{{StorefrontCustomerOrdersGridSection.orderView({$grabSecondOrderId})}}" stepKey="seeSecondOrder"/> <waitForPageLoad stepKey="waitForOrderPageLoad"/> <!-- Go to Admin > Sales > Orders --> - <comment userInput="Go to Admin > Sales > Orders" stepKey="commentGoOrders"/> <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> <actionGroup ref="searchAdminDataGridByKeyword" stepKey="searchFirstOrder"> <argument name="keyword" value="$grabFirstOrderId"/> </actionGroup> - <see selector="{{AdminOrdersGridSection.firstLineOrderId}}" userInput="{$grabFirstOrderId}" stepKey="seeAdminFirstOrder"/> + <seeElement selector="{{AdminOrdersGridSection.orderId({$grabFirstOrderId})}}" stepKey="seeAdminFirstOrder"/> <actionGroup ref="searchAdminDataGridByKeyword" stepKey="searchSecondOrder"> <argument name="keyword" value="$grabSecondOrderId"/> </actionGroup> - <see selector="{{AdminOrdersGridSection.firstLineOrderId}}" userInput="{$grabSecondOrderId}" stepKey="seeAdminSecondOrder"/> + <seeElement selector="{{AdminOrdersGridSection.orderId({$grabSecondOrderId})}}" stepKey="seeAdminSecondOrder"/> </test> </tests> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml index ce777e5f9ca7..a18ca0c41556 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrdersGridSection.xml @@ -39,6 +39,6 @@ <element name="changeOrderStatus" type="button" selector="//div[contains(concat(' ',normalize-space(@class),' '),' row-gutter ')]//span[text()='{{status}}']" parameterized="true" timeout="30"/> <element name="viewLink" type="text" selector="//td/div[contains(.,'{{orderID}}')]/../..//a[@class='action-menu-item']" parameterized="true"/> <element name="selectOrderID" type="checkbox" selector="//td/div[text()='{{orderId}}']/../preceding-sibling::td//input" parameterized="true" timeout="60"/> - <element name="firstLineOrderId" type="text" selector=".data-grid td:nth-of-type(2)"/> + <element name="orderId" type="text" selector="//table[contains(@class, 'data-grid')]//div[contains(text(), '{{orderId}}')]" parameterized="true"/> </section> </sections> From 4dda5704fe996d92ae7e17772ea7baa76fa54ff9 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 19 Sep 2019 15:51:49 +0300 Subject: [PATCH 0525/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-11151 --- .../Adminhtml/Product/Set/SaveTest.php | 30 +++---------------- ...ttribute_set_based_on_default_rollback.php | 4 +-- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php index a3f9c542809a..80cc6c192324 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php @@ -172,7 +172,9 @@ public function testRemoveAttributeFromAttributeSet() $product->setAttributeSetId($attributeSet->getId()); $product = $this->productRepository->save($product); $this->dispatch('backend/catalog/product/edit/id/' . $product->getEntityId()); - $this->assertNotContains($message, $this->getSyslogContent()); + $syslogPath = $this->getSyslogPath(); + $syslogContent = file_exists($syslogPath) ? file_get_contents($syslogPath) : ''; + $this->assertNotContains($message, $syslogContent); } /** @@ -200,33 +202,9 @@ private function getSyslogPath() */ private function removeSyslog() { - $this->detachLogger(); + $this->syslogHandler->close(); if (file_exists($this->getSyslogPath())) { unlink($this->getSyslogPath()); } } - - /** - * Detach system log handler. - * - * @return void - */ - private function detachLogger() - { - $this->syslogHandler->close(); - } - - /** - * Retrieve content of system.log file - * - * @return bool|string - */ - private function getSyslogContent() - { - if (!file_exists($this->getSyslogPath())) { - return ''; - } - - return file_get_contents($this->getSyslogPath()); - } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php index 981aed5d0ca2..4cd18f6d23e8 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_based_on_default_rollback.php @@ -9,8 +9,8 @@ $entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product'); $attributeSetCollection = $objectManager->create( - \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection::class -); + \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory::class +)->create(); $attributeSetCollection->addFilter('attribute_set_name', 'new_attribute_set'); $attributeSetCollection->addFilter('entity_type_id', $entityType->getId()); $attributeSetCollection->setOrder('attribute_set_id'); From bff262dc6a13da40fadb86d6afc68e4002349bdd Mon Sep 17 00:00:00 2001 From: federeggiani <elfeffe@gmail.com> Date: Thu, 19 Sep 2019 15:43:08 +0200 Subject: [PATCH 0526/1172] Fix error in configurables Problem with configurables when the simple products that were associated did not have a value for the configurable attribute. Fix this issue https://github.com/magento/magento2/issues/14240 --- .../Model/Product/Type/VariationMatrix.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php index 979587dc500a..691f34ead9d6 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php @@ -40,7 +40,9 @@ public function getVariations($usedProductAttributes) for ($attributeIndex = $attributesCount; $attributeIndex--;) { $currentAttribute = $variationalAttributes[$attributeIndex]; $currentVariationValue = $currentVariation[$attributeIndex]; - $filledVariation[$currentAttribute['id']] = $currentAttribute['values'][$currentVariationValue]; + if(isset($currentAttribute['id']) && $currentAttribute['id']) { + $filledVariation[$currentAttribute['id']] = $currentAttribute['values'][$currentVariationValue]; + } } $variations[] = $filledVariation; From db7a3a1369d0c76422c56af179ab61f5b5d679e5 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Wed, 18 Sep 2019 17:06:04 -0500 Subject: [PATCH 0527/1172] MC-19894: Customer Address attribute code is displayed instead of attribute label during checkout - changes updated --- .../address-renderer/default.js | 27 ++++++++++++++++++- .../web/js/view/shipping-address/list.js | 3 ++- .../address-renderer/default.html | 17 ++---------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js index 54381ad96b0b..939a2af1a25a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js @@ -7,12 +7,13 @@ define([ 'jquery', 'ko', 'uiComponent', + 'underscore', 'Magento_Checkout/js/action/select-shipping-address', 'Magento_Checkout/js/model/quote', 'Magento_Checkout/js/model/shipping-address/form-popup-state', 'Magento_Checkout/js/checkout-data', 'Magento_Customer/js/customer-data' -], function ($, ko, Component, selectShippingAddressAction, quote, formPopUpState, checkoutData, customerData) { +], function ($, ko, Component, _, selectShippingAddressAction, quote, formPopUpState, checkoutData, customerData) { 'use strict'; var countryData = customerData.get('directory-data'); @@ -47,6 +48,30 @@ define([ return countryData()[countryId] != undefined ? countryData()[countryId].name : ''; //eslint-disable-line }, + /** + * Get customer attribute label + * + * @param {*} attribute + * @returns {*} + */ + getCustomAttributeLabel: function (attribute) { + var resultAttribute; + + if (typeof attribute === 'string') { + return attribute; + } + + if (attribute.label) { + return attribute.label; + } + + resultAttribute = _.findWhere(this.source.get('customAttributes')[attribute['attribute_code']], { + value: attribute.value + }); + + return resultAttribute && resultAttribute.label || attribute.value; + }, + /** Set selected customer shipping address */ selectAddress: function () { selectShippingAddressAction(this.address()); diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js index 4f4fc3de3e1a..2bdfd063cb6f 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js @@ -16,7 +16,8 @@ define([ var defaultRendererTemplate = { parent: '${ $.$data.parentName }', name: '${ $.$data.name }', - component: 'Magento_Checkout/js/view/shipping-address/address-renderer/default' + component: 'Magento_Checkout/js/view/shipping-address/address-renderer/default', + provider: 'checkoutProvider' }; return Component.extend({ diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index cf64c0140b95..b14f4da3f5f7 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -13,21 +13,8 @@ <a if="address().telephone" attr="'href': 'tel:' + address().telephone" text="address().telephone"></a><br/> <each args="data: address().customAttributes, as: 'element'"> - <each args="data: Object.keys(element), as: 'attribute'"> - <if args="typeof element[attribute] === 'object'"> - <if args="element[attribute].label"> - <text args="element[attribute].label"/> - </if> - <ifnot args="element[attribute].label"> - <if args="element[attribute].value"> - <text args="element[attribute].value"/> - </if> - </ifnot> - </if> - <if args="typeof element[attribute] === 'string'"> - <text args="element[attribute]"/> - </if><br/> - </each> + <text args="$parent.getCustomAttributeLabel(element)"/> + <br/> </each> <button visible="address().isEditable()" type="button" From e80c295edcdcd6bf91698b6a936b4b0f78f27a24 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Thu, 19 Sep 2019 16:55:56 +0300 Subject: [PATCH 0528/1172] MC-19916: Attribute not showing on layered navigation if no value set for "All Store Views" --- .../Product/Indexer/Eav/SourceTest.php | 41 ++++++++ ...pdown_attribute_without_all_store_view.php | 96 +++++++++++++++++++ ...ribute_without_all_store_view_rollback.php | 43 +++++++++ 3 files changed, 180 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php index 5cf6d00fe77e..78ae21b1441b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/SourceTest.php @@ -7,12 +7,17 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Eav\Api\Data\AttributeOptionInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\Catalog\_files\MultiselectSourceMock; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Api\Data\StoreInterface; /** * Class SourceTest * @magentoAppIsolation enabled + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class SourceTest extends \PHPUnit\Framework\TestCase { @@ -159,6 +164,42 @@ public function testReindexMultiselectAttribute() $this->assertCount(3, $result); } + /** + * Test for indexing product attribute without "all store view" value + * + * @magentoDataFixture Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view.php + * @magentoDbIsolation disabled + */ + public function testReindexSelectAttributeWithoutDefault() + { + $objectManager = Bootstrap::getObjectManager(); + /** @var StoreInterface $store */ + $store = $objectManager->get(StoreManagerInterface::class) + ->getStore(); + /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute **/ + $attribute = $objectManager->get(\Magento\Eav\Model\Config::class) + ->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); + /** @var AttributeOptionInterface $option */ + $option = $attribute->getOptions()[1]; + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + $product = $productRepository->get('test_attribute_dropdown_without_default', false, 1); + $expected = [ + 'entity_id' => $product->getId(), + 'attribute_id' => $attribute->getId(), + 'store_id' => $store->getId(), + 'value' => $option->getValue(), + 'source_id' => $product->getId(), + ]; + $connection = $this->productResource->getConnection(); + $select = $connection->select()->from($this->productResource->getTable('catalog_product_index_eav')) + ->where('entity_id = ?', $product->getId()) + ->where('attribute_id = ?', $attribute->getId()); + + $result = $connection->fetchRow($select); + $this->assertEquals($expected, $result); + } + /** * @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute_with_source_model.php * @magentoDbIsolation disabled diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view.php new file mode 100644 index 000000000000..7c872a66f60d --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view.php @@ -0,0 +1,96 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Eav\Api\AttributeRepositoryInterface; +use Magento\Eav\Model\Config as EavConfig; +use Magento\Catalog\Setup\CategorySetup; +use Magento\Catalog\Model\ResourceModel\Eav\Attribute as EavAttribute; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Model\Product\Type as ProductType; +use Magento\Catalog\Model\Product\Visibility; +use Magento\Catalog\Model\Product\Attribute\Source\Status; +use Magento\Eav\Api\AttributeOptionManagementInterface; +use Magento\Eav\Api\Data\AttributeOptionInterface; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Store\Api\Data\StoreInterface; + +$objectManager = Bootstrap::getObjectManager(); +$storeManager = $objectManager->get(StoreManagerInterface::class); +/** @var StoreInterface $store */ +$store = $storeManager->getStore(); +$eavConfig = $objectManager->get(EavConfig::class); +$eavConfig->clear(); +$attribute = $eavConfig->getAttribute(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); +/** @var CategorySetup $installer */ +$installer = $objectManager->get(CategorySetup::class); +$attributeSetId = $installer->getAttributeSetId(ProductAttributeInterface::ENTITY_TYPE_CODE, 'Default'); + +/** @var ProductInterface $product */ +$product = $objectManager->get(ProductInterface::class); +$product->setTypeId(ProductType::TYPE_SIMPLE) + ->setAttributeSetId($attributeSetId) + ->setName('Simple Product1') + ->setSku('test_attribute_dropdown_without_default') + ->setPrice(10) + ->setVisibility(Visibility::VISIBILITY_BOTH) + ->setStatus(Status::STATUS_ENABLED); +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +$product = $productRepository->save($product); + +if (!$attribute->getId()) { + /** @var $attribute */ + $attribute = $objectManager->get(EavAttribute::class); + /** @var AttributeRepositoryInterface $attributeRepository */ + $attributeRepository = $objectManager->get(AttributeRepositoryInterface::class); + $attribute->setData( + [ + 'attribute_code' => 'dropdown_without_default', + 'entity_type_id' => $installer->getEntityTypeId(ProductAttributeInterface::ENTITY_TYPE_CODE), + 'is_global' => 0, + 'is_user_defined' => 1, + 'frontend_input' => 'select', + 'is_unique' => 0, + 'is_required' => 0, + 'is_searchable' => 1, + 'is_visible_in_advanced_search' => 1, + 'is_comparable' => 1, + 'is_filterable' => 1, + 'is_filterable_in_search' => 1, + 'is_used_for_promo_rules' => 0, + 'is_html_allowed_on_front' => 1, + 'is_visible_on_front' => 1, + 'used_in_product_listing' => 1, + 'used_for_sort_by' => 1, + 'frontend_label' => ['Test Configurable'], + 'backend_type' => 'int', + 'option' => [ + 'value' => ['option_0' => ['Option 1'], 'option_1' => ['Option 2']], + 'order' => ['option_0' => 1, 'option_1' => 2], + ], + ] + ); + $attributeRepository->save($attribute); + /* Assign attribute to attribute set */ + $installer->addAttributeToGroup( + ProductAttributeInterface::ENTITY_TYPE_CODE, + 'Default', + 'General', + $attribute->getId() + ); +} +/** @var AttributeOptionManagementInterface $options */ +$attributeOption = $objectManager->get(AttributeOptionManagementInterface::class); +/* Getting the first nonempty option */ +/** @var AttributeOptionInterface $option */ +$option = $attributeOption->getItems($attribute->getEntityTypeId(), $attribute->getAttributeCode())[1]; +$product->setStoreId($store->getId()) + ->setData('dropdown_without_default', $option->getValue()); +$productRepository->save($product); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php new file mode 100644 index 000000000000..99e8a2e51120 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php @@ -0,0 +1,43 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\TestFramework\Helper\Bootstrap; +use Magento\Eav\Api\AttributeRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Eav\Model\Config as EavConfig; +use Magento\Eav\Api\Data\AttributeInterface; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Catalog\Model\Indexer\Product\Eav as ProductEav; +use Magento\Framework\Registry; + +$objectManager = Bootstrap::getObjectManager(); +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +$eavConfig = $objectManager->get(EavConfig::class); +$attributesToDelete = ['dropdown_without_default']; +/** @var AttributeRepositoryInterface $attributeRepository */ +$attributeRepository = $objectManager->get(AttributeRepositoryInterface::class); +/** @var AttributeInterface $attribute */ +$attribute = $attributeRepository->get(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); +$attributeRepository->delete($attribute); +$eavConfig->clear(); + +/** @var ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->get(ProductRepositoryInterface::class); +/** @var ProductInterface $product */ +$product = $productRepository->get('test_attribute_dropdown_without_default'); +if ($product->getId()) { + $productRepository->delete($product); +} +$objectManager->get(ProductEav::class)->executeRow($product->getId()); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); From 4b1b1dc7dee1832ba2ff3598c6c0afb766941bda Mon Sep 17 00:00:00 2001 From: "bruce.ayko" <bruce@ayko.com> Date: Thu, 19 Sep 2019 20:34:02 +0100 Subject: [PATCH 0529/1172] Price Indexer Performance Issue With Out of Stock Products - Relates to issue https://github.com/magento/magento2/issues/24414 - Made changes based on feedback on PR --- .../Model/Indexer/ProductPriceIndexFilter.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php index 8bcc5ea1dc2c..1033d56ac791 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php @@ -104,13 +104,7 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = $select->where('stock_item.use_config_manage_stock = 0 AND stock_item.manage_stock = 1'); } - if ($entityIds !== null) { - if (count($entityIds) > 1) { - $select->where('stock_item.product_id in (?)', $entityIds); - } else { - $select->where('stock_item.product_id = ?', $entityIds); - } - } + $select->where('stock_item.product_id in (?)', $entityIds); $select->group('stock_item.product_id'); $select->having('max_is_in_stock = 0'); From 2f47e164291f2cd32b6a3e2ce50746337cd0ef26 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 19 Sep 2019 23:12:32 -0500 Subject: [PATCH 0530/1172] MC-19247: Broken translations with advanced bundling - Load dictionary before js bundles; --- .../Translation/view/{base => frontend}/layout/default.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename app/code/Magento/Translation/view/{base => frontend}/layout/default.xml (93%) diff --git a/app/code/Magento/Translation/view/base/layout/default.xml b/app/code/Magento/Translation/view/frontend/layout/default.xml similarity index 93% rename from app/code/Magento/Translation/view/base/layout/default.xml rename to app/code/Magento/Translation/view/frontend/layout/default.xml index 8e0408037386..e58a249b0793 100644 --- a/app/code/Magento/Translation/view/base/layout/default.xml +++ b/app/code/Magento/Translation/view/frontend/layout/default.xml @@ -8,7 +8,7 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="head.additional"> - <block name="translation_dictionary" template="Magento_Translation::dictionary.phtml"> + <block name="translation_dictionary" template="Magento_Translation::dictionary.phtml" before="-"> <arguments> <argument name="dictionary_view_model" xsi:type="object">Magento\Translation\ViewModel\Dictionary</argument> </arguments> From d6e0fa7a8d0a808eb629c996448c5d4b9cb91645 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 20 Sep 2019 10:21:46 +0300 Subject: [PATCH 0531/1172] MC-19916: Attribute not showing on layered navigation if no value set for "All Store Views" --- .../Model/ResourceModel/Product/Indexer/Eav/Source.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php index f0fe95467087..e625e38b59f3 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Eav/Source.php @@ -210,12 +210,16 @@ protected function _prepareSelectIndex($entityIds = null, $attributeId = null) $selectWithoutDefaultStore = $connection->select()->from( ['wd' => $this->getTable('catalog_product_entity_int')], [ - $productIdField, + 'cpe.entity_id', 'attribute_id', 'store_id', 'value', - $productIdField + 'cpe.entity_id', ] + )->joinLeft( + ['cpe' => $this->getTable('catalog_product_entity')], + "cpe.{$productIdField} = wd.{$productIdField}", + [] )->joinLeft( ['d2d' => $this->getTable('catalog_product_entity_int')], sprintf( @@ -233,7 +237,7 @@ protected function _prepareSelectIndex($entityIds = null, $attributeId = null) ->where("wd.attribute_id IN({$attrIdsFlat})") ->where('wd.value IS NOT NULL') ->where('wd.store_id != 0') - ->where("wd.{$productIdField} IN({$ids})"); + ->where("cpe.entity_id IN({$ids})"); $select->where("cpe.entity_id IN({$ids})"); $selects = new UnionExpression( [$select, $selectWithoutDefaultStore], From ad23daf3d4c915e05f7e28fdef7e8aef1ebbb2a6 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 20 Sep 2019 13:30:12 +0400 Subject: [PATCH 0532/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6411 --- ...EditCustomerInformationFromActionGroup.xml | 7 ------ ...ustomStoreShippingMethodTableRatesTest.xml | 17 +++++++------- .../AdminWebsitePageActionGroup.xml | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml index fa8931bc5314..09033955ecc6 100644 --- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminEditCustomerInformationFromActionGroup.xml @@ -30,11 +30,4 @@ <waitForPageLoad stepKey="wait"/> <scrollToTopOfPage stepKey="scrollToTop"/> </actionGroup> - <actionGroup name="AdminAssociateCustomerToCustomWebsiteActionGroup"> - <arguments> - <argument name="websiteName" type="string" defaultValue="secondWebsite"/> - </arguments> - <conditionalClick selector="{{AdminCustomerAccountInformationSection.accountInformationTab}}" dependentSelector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" visible="false" stepKey="goToAccountInformation"/> - <selectOption selector="{{AdminCustomerAccountInformationSection.associateToWebsite}}" userInput="{{websiteName}}" stepKey="selectWebSite"/> - </actionGroup> </actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml index 67885ccfc99d..6f9327d68d45 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -22,7 +22,6 @@ <before> <!--Create product and customer--> <createData entity="SimpleProduct2" stepKey="createProduct"/> - <createData entity="Simple_Customer_Without_Address" stepKey="createCustomer"/> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> <!--Create website, store group and store view--> <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createWebsite"> @@ -38,6 +37,14 @@ <argument name="StoreGroup" value="customStoreGroup"/> <argument name="customStore" value="customStore"/> </actionGroup> + <!--Create customer associated to website--> + <actionGroup ref="AdminGoCreatedWebsitePageActionGroup" stepKey="DeleteWebsite"> + <argument name="websiteName" value="{{customWebsite.name}}"/> + </actionGroup> + <grabFromCurrentUrl regex="~/website_id/(\d+)/~" stepKey="grabWebsiteIdFromURL"/> + <createData entity="Simple_Customer_Without_Address" stepKey="createCustomer"> + <field key="website_id">$grabWebsiteIdFromURL</field> + </createData> <!--Enable Table Rate method and import csv file--> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="switchDefaultWebsite"> @@ -81,14 +88,6 @@ <argument name="website" value="{{customWebsite.name}}"/> </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveProduct"/> - <!--Assign customer to custom website--> - <actionGroup ref="AdminOpenCustomerEditPageActionGroup" stepKey="openCustomerEditPage"> - <argument name="customerId" value="$$createCustomer.id$$"/> - </actionGroup> - <actionGroup ref="AdminAssociateCustomerToCustomWebsiteActionGroup" stepKey="associateCustomerToWebsite"> - <argument name="websiteName" value="{{customWebsite.name}}"/> - </actionGroup> - <actionGroup ref="AdminSaveCustomerAndAssertSuccessMessage" stepKey="saveAndCheckSuccessMessage"/> <!--Create order--> <actionGroup ref="navigateToNewOrderPageExistingCustomer" stepKey="navigateToNewOrderWithExistingCustomer"> <argument name="customer" value="$$createCustomer$$"/> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml new file mode 100644 index 000000000000..fc54101c3a5f --- /dev/null +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminGoCreatedWebsitePageActionGroup"> + <arguments> + <argument name="websiteName" type="string" defaultValue="SecondWebsite"/> + </arguments> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <click selector="{{AdminStoresGridSection.resetButton}}" stepKey="resetSearchFilter"/> + <fillField userInput="{{websiteName}}" selector="{{AdminStoresGridSection.websiteFilterTextField}}" stepKey="fillSearchWebsiteField"/> + <click selector="{{AdminStoresGridSection.searchButton}}" stepKey="clickSearchButton"/> + <see userInput="{{websiteName}}" selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" stepKey="verifyThatCorrectWebsiteFound"/> + <click selector="{{AdminStoresGridSection.websiteNameInFirstRow}}" stepKey="clickEditExistingStoreRow"/> + <waitForPageLoad stepKey="waitForStoreToLoad"/> + </actionGroup> +</actionGroups> From b19b72b00364753f948cb0e28085763eea29e445 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Fri, 20 Sep 2019 12:35:42 +0300 Subject: [PATCH 0533/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../Sales/Model/Order/ShipmentTest.php | 2 + .../testsuite/Magento/Sales/_files/order.php | 41 ------- .../_files/two_orders_with_order_items.php | 111 ++++++++++++++++++ 3 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index 5b5c2365bfac..0c9728b71c82 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -150,6 +150,8 @@ private function getOrder(string $incrementId): OrderInterface /** * Check that getTracksCollection() returns only order related tracks. + * + * @magentoDataFixture Magento/Sales/_files/two_orders_with_order_items.php */ public function testGetTracksCollection() { diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order.php index 8d2132dadd69..9ea85aae56cb 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/order.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order.php @@ -68,44 +68,3 @@ /** @var OrderRepositoryInterface $orderRepository */ $orderRepository = $objectManager->create(OrderRepositoryInterface::class); $orderRepository->save($order); - -/** @var Payment $payment */ -$payment2 = $objectManager->create(Payment::class); -$payment2->setMethod('checkmo') - ->setAdditionalInformation('last_trans_id', '11122') - ->setAdditionalInformation( - 'metadata', - [ - 'type' => 'free', - 'fraudulent' => false, - ] - ); - -/** @var OrderItem $orderItem */ -$orderItem2 = $objectManager->create(OrderItem::class); -$orderItem2->setProductId($product->getId()) - ->setQtyOrdered(2) - ->setBasePrice($product->getPrice()) - ->setPrice($product->getPrice()) - ->setRowTotal($product->getPrice()) - ->setProductType('simple') - ->setName($product->getName()) - ->setSku($product->getSku()); - -/** @var Order $order */ -$order2 = $objectManager->create(Order::class); -$order2->setIncrementId('100000002') - ->setState(Order::STATE_PROCESSING) - ->setStatus($order2->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) - ->setSubtotal(100) - ->setGrandTotal(100) - ->setBaseSubtotal(100) - ->setBaseGrandTotal(100) - ->setCustomerIsGuest(true) - ->setCustomerEmail('customer@null.com') - ->setBillingAddress($billingAddress) - ->setShippingAddress($shippingAddress) - ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) - ->addItem($orderItem2) - ->setPayment($payment2); -$orderRepository->save($order2); diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php new file mode 100644 index 000000000000..8d2132dadd69 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php @@ -0,0 +1,111 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Sales\Api\OrderRepositoryInterface; +use Magento\Sales\Model\Order; +use Magento\Sales\Model\Order\Address as OrderAddress; +use Magento\Sales\Model\Order\Item as OrderItem; +use Magento\Sales\Model\Order\Payment; +use Magento\Store\Model\StoreManagerInterface; + +require 'default_rollback.php'; +require __DIR__ . '/../../../Magento/Catalog/_files/product_simple.php'; +/** @var \Magento\Catalog\Model\Product $product */ + +$addressData = include __DIR__ . '/address_data.php'; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$billingAddress = $objectManager->create(OrderAddress::class, ['data' => $addressData]); +$billingAddress->setAddressType('billing'); + +$shippingAddress = clone $billingAddress; +$shippingAddress->setId(null)->setAddressType('shipping'); + +/** @var Payment $payment */ +$payment = $objectManager->create(Payment::class); +$payment->setMethod('checkmo') + ->setAdditionalInformation('last_trans_id', '11122') + ->setAdditionalInformation( + 'metadata', + [ + 'type' => 'free', + 'fraudulent' => false, + ] + ); + +/** @var OrderItem $orderItem */ +$orderItem = $objectManager->create(OrderItem::class); +$orderItem->setProductId($product->getId()) + ->setQtyOrdered(2) + ->setBasePrice($product->getPrice()) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType('simple') + ->setName($product->getName()) + ->setSku($product->getSku()); + +/** @var Order $order */ +$order = $objectManager->create(Order::class); +$order->setIncrementId('100000001') + ->setState(Order::STATE_PROCESSING) + ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) + ->setSubtotal(100) + ->setGrandTotal(100) + ->setBaseSubtotal(100) + ->setBaseGrandTotal(100) + ->setCustomerIsGuest(true) + ->setCustomerEmail('customer@null.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) + ->addItem($orderItem) + ->setPayment($payment); + +/** @var OrderRepositoryInterface $orderRepository */ +$orderRepository = $objectManager->create(OrderRepositoryInterface::class); +$orderRepository->save($order); + +/** @var Payment $payment */ +$payment2 = $objectManager->create(Payment::class); +$payment2->setMethod('checkmo') + ->setAdditionalInformation('last_trans_id', '11122') + ->setAdditionalInformation( + 'metadata', + [ + 'type' => 'free', + 'fraudulent' => false, + ] + ); + +/** @var OrderItem $orderItem */ +$orderItem2 = $objectManager->create(OrderItem::class); +$orderItem2->setProductId($product->getId()) + ->setQtyOrdered(2) + ->setBasePrice($product->getPrice()) + ->setPrice($product->getPrice()) + ->setRowTotal($product->getPrice()) + ->setProductType('simple') + ->setName($product->getName()) + ->setSku($product->getSku()); + +/** @var Order $order */ +$order2 = $objectManager->create(Order::class); +$order2->setIncrementId('100000002') + ->setState(Order::STATE_PROCESSING) + ->setStatus($order2->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) + ->setSubtotal(100) + ->setGrandTotal(100) + ->setBaseSubtotal(100) + ->setBaseGrandTotal(100) + ->setCustomerIsGuest(true) + ->setCustomerEmail('customer@null.com') + ->setBillingAddress($billingAddress) + ->setShippingAddress($shippingAddress) + ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) + ->addItem($orderItem2) + ->setPayment($payment2); +$orderRepository->save($order2); From 9bfd3d480356448ed088d62893069265d3290ef8 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 20 Sep 2019 15:55:46 +0300 Subject: [PATCH 0534/1172] MC-19916: Attribute not showing on layered navigation if no value set for "All Store Views" --- ...ribute_without_all_store_view_rollback.php | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php index 99e8a2e51120..702ce6494aef 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php @@ -5,6 +5,7 @@ */ declare(strict_types=1); +use Magento\Framework\Exception\NoSuchEntityException; use Magento\TestFramework\Helper\Bootstrap; use Magento\Eav\Api\AttributeRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; @@ -22,20 +23,22 @@ $registry->register('isSecureArea', true); $eavConfig = $objectManager->get(EavConfig::class); -$attributesToDelete = ['dropdown_without_default']; +$eavConfig->clear(); /** @var AttributeRepositoryInterface $attributeRepository */ $attributeRepository = $objectManager->get(AttributeRepositoryInterface::class); -/** @var AttributeInterface $attribute */ -$attribute = $attributeRepository->get(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); -$attributeRepository->delete($attribute); -$eavConfig->clear(); - /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(ProductRepositoryInterface::class); -/** @var ProductInterface $product */ -$product = $productRepository->get('test_attribute_dropdown_without_default'); -if ($product->getId()) { +try { + /** @var AttributeInterface $attribute */ + $attribute = $attributeRepository->get(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); + $attributeRepository->delete($attribute); +} catch (NoSuchEntityException $e) { +} +try { + /** @var ProductInterface $product */ + $product = $productRepository->get('test_attribute_dropdown_without_default'); $productRepository->delete($product); +} catch (NoSuchEntityException $e) { } $objectManager->get(ProductEav::class)->executeRow($product->getId()); From 4032be0bf1b5fd35456eab1acff86f3747a117c1 Mon Sep 17 00:00:00 2001 From: "rostyslav.hymon" <rostyslav.hymon@transoftgroup.com> Date: Fri, 20 Sep 2019 15:57:45 +0300 Subject: [PATCH 0535/1172] MC-19916: Attribute not showing on layered navigation if no value set for "All Store Views" --- ..._with_dropdown_attribute_without_all_store_view_rollback.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php index 702ce6494aef..a60588c16ab6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_with_dropdown_attribute_without_all_store_view_rollback.php @@ -33,12 +33,14 @@ $attribute = $attributeRepository->get(ProductAttributeInterface::ENTITY_TYPE_CODE, 'dropdown_without_default'); $attributeRepository->delete($attribute); } catch (NoSuchEntityException $e) { + //Attribute already deleted } try { /** @var ProductInterface $product */ $product = $productRepository->get('test_attribute_dropdown_without_default'); $productRepository->delete($product); } catch (NoSuchEntityException $e) { + //Product already deleted } $objectManager->get(ProductEav::class)->executeRow($product->getId()); From c6693f7eab32d6d6209b204ac8cd58988faf46d2 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 20 Sep 2019 09:45:26 -0500 Subject: [PATCH 0536/1172] MC-18403: Pricing :: Product pricing schema - Support other product types - Refactoring --- .../Price/{Prices.php => Provider.php} | 10 +- .../Product/Price/ProviderInterface.php | 57 ++++++++ .../Model/Resolver/Product/Price/Type.php | 64 +++++++++ .../Model/Resolver/Product/PriceRange.php | 36 +++-- app/code/Magento/CatalogGraphQl/etc/di.xml | 9 ++ .../Model/Resolver/Product/Price/Provider.php | 103 ++++++++++++++ .../ConfigurableProductGraphQl/etc/di.xml | 16 +++ .../Model/Resolver/Product/Price/Provider.php | 133 ++++++++++++++++++ .../Magento/GroupedProductGraphQl/etc/di.xml | 8 ++ 9 files changed, 417 insertions(+), 19 deletions(-) rename app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/{Prices.php => Provider.php} (89%) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderInterface.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php create mode 100644 app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php create mode 100644 app/code/Magento/ConfigurableProductGraphQl/etc/di.xml create mode 100644 app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php similarity index 89% rename from app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php rename to app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php index 556ef46fceee..a3a3cbb46417 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Prices.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php @@ -17,7 +17,7 @@ /** * Provides product prices */ -class Prices +class Provider implements ProviderInterface { /** * PriceInfo cache @@ -61,9 +61,7 @@ public function getMinimalFinalPrice(SaleableInterface $product): AmountInterfac */ public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - $regularPrice = $priceInfo->getPrice(RegularPrice::PRICE_CODE); - return $regularPrice->getMinimalPrice(); + return $this->getRegularPrice($product); } /** @@ -87,9 +85,7 @@ public function getMaximalFinalPrice(SaleableInterface $product): AmountInterfac */ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - $regularPrice = $priceInfo->getPrice(RegularPrice::PRICE_CODE); - return $regularPrice->getMaximalPrice(); + return $this->getRegularPrice($product); } /** diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderInterface.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderInterface.php new file mode 100644 index 000000000000..99459daf045a --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderInterface.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; + +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\SaleableInterface; + +/** + * Provides product prices + */ +interface ProviderInterface +{ + /** + * Get the product minimal final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface; + + /** + * Get the product minimal regular price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface; + + /** + * Get the product maximum final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface; + + /** + * Get the product maximum final price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface; + + /** + * Get the product regular price + * + * @param SaleableInterface $product + * @return AmountInterface + */ + public function getRegularPrice(SaleableInterface $product): AmountInterface; +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php new file mode 100644 index 000000000000..01c3ea541e3a --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; + +use Magento\Framework\ObjectManagerInterface; + +/** + * Use to the retrieve correct price provider + */ +class Type +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * Store created provider objects + * + * @var array + */ + private $providers = []; + + /** + * @var array + */ + private $types = []; + + /** + * @param ObjectManagerInterface $objectManager + * @param array $types + */ + public function __construct(ObjectManagerInterface $objectManager, array $types) + { + $this->objectManager = $objectManager; + $this->types = array_merge($this->types, $types); + } + + /** + * Get appropriate price provider based on product type + * + * @param string $productType + * @return ProviderInterface + */ + public function getProviderByProductType(string $productType): ProviderInterface + { + $providerType = $this->types['default']; + + if (isset($this->types[$productType])) { + $providerType = $this->types[$productType]; + } + + if (!isset($this->providers[$providerType])) { + $this->providers[$providerType] = $this->objectManager->get($providerType); + } + + return $this->providers[$providerType]; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index 78b76eddec46..7c803815a16e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -8,7 +8,8 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; -use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Prices; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type as PriceProviderType; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -23,22 +24,22 @@ class PriceRange implements ResolverInterface { /** - * @var Prices + * @var Discount */ - private $productPrices; + private $discount; /** - * @var Discount + * @var PriceProviderType */ - private $discount; + private $priceProviderType; /** - * @param Prices $productPrices + * @param PriceProviderType $priceProviderType * @param Discount $discount */ - public function __construct(Prices $productPrices, Discount $discount) + public function __construct(PriceProviderType $priceProviderType, Discount $discount) { - $this->productPrices = $productPrices; + $this->priceProviderType = $priceProviderType; $this->discount = $discount; } @@ -77,8 +78,8 @@ public function resolve( */ private function getMinimumProductPrice(SaleableInterface $product, StoreInterface $store): array { - $regularPrice = $this->productPrices->getMinimalRegularPrice($product)->getValue(); - $finalPrice = $this->productPrices->getMinimalFinalPrice($product)->getValue(); + $regularPrice = $this->getPriceProvider($product)->getMinimalRegularPrice($product)->getValue(); + $finalPrice = $this->getPriceProvider($product)->getMinimalFinalPrice($product)->getValue(); return $this->formatPrice($regularPrice, $finalPrice, $store); } @@ -92,8 +93,8 @@ private function getMinimumProductPrice(SaleableInterface $product, StoreInterfa */ private function getMaximumProductPrice(SaleableInterface $product, StoreInterface $store): array { - $regularPrice = $this->productPrices->getMaximalRegularPrice($product)->getValue(); - $finalPrice = $this->productPrices->getMaximalFinalPrice($product)->getValue(); + $regularPrice = $this->getPriceProvider($product)->getMaximalRegularPrice($product)->getValue(); + $finalPrice = $this->getPriceProvider($product)->getMaximalFinalPrice($product)->getValue(); return $this->formatPrice($regularPrice, $finalPrice, $store); } @@ -121,5 +122,16 @@ private function formatPrice(float $regularPrice, float $finalPrice, StoreInterf ]; } + /** + * Get price provider object + * + * @param SaleableInterface $product + * @return ProviderInterface + */ + private function getPriceProvider(SaleableInterface $product): ProviderInterface + { + return $this->priceProviderType->getProviderByProductType($product->getTypeId()); + } + } \ No newline at end of file diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index 485ae792193e..ed404d35b47c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -69,4 +69,13 @@ <type name="Magento\Framework\Search\Request\Config\FilesystemReader"> <plugin name="productAttributesDynamicFields" type="Magento\CatalogGraphQl\Plugin\Search\Request\ConfigReader" /> </type> + + <preference type="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider" for="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface"/> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="default" xsi:type="string">\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php new file mode 100644 index 000000000000..24bc66fb199e --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -0,0 +1,103 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price; + +use Magento\Catalog\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; +use Magento\Framework\Pricing\PriceInfoInterface; +use Magento\Framework\Pricing\SaleableInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; + +/** + * Provides product prices for configurable products + */ +class Provider implements ProviderInterface +{ + /** + * PriceInfo cache + * + * @var array + */ + private $productPrices = []; + + /** + * @var PriceInfoFactory + */ + private $priceInfoFactory; + + /** + * @param PriceInfoFactory $priceInfoFactory + */ + public function __construct( + PriceInfoFactory $priceInfoFactory + ) { + $this->priceInfoFactory = $priceInfoFactory; + } + + /** + * @inheritdoc + */ + public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(FinalPrice::PRICE_CODE)->getMinimalPrice(); + } + + /** + * @inheritdoc + */ + public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getMinRegularAmount(); + } + + /** + * @inheritdoc + */ + public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(FinalPrice::PRICE_CODE)->getMaximalPrice(); + } + + /** + * @inheritdoc + */ + public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getMaxRegularAmount(); + } + + /** + * @inheritdoc + */ + public function getRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + } + + /** + * Get price info for product + * + * @param SaleableInterface $product + * @return PriceInfoInterface + */ + private function getProductPriceInfo($product) + { + if (!isset($this->productPrices[$product->getId()])) { + $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); + } + + return $this->productPrices[$product->getId()]; + } +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml new file mode 100644 index 000000000000..e16d9638003a --- /dev/null +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="configurable" xsi:type="string">\Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> +</config> diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php new file mode 100644 index 000000000000..b8c0d03250de --- /dev/null +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -0,0 +1,133 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GroupedProductGraphQl\Model\Resolver\Product\Price; + +use Magento\Catalog\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; +use Magento\Framework\Pricing\PriceInfoInterface; +use Magento\Framework\Pricing\SaleableInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; + +/** + * Provides product prices for configurable products + */ +class Provider implements ProviderInterface +{ + /** + * PriceInfo cache + * + * @var array + */ + private $productPrices = []; + + /** + * @var PriceInfoFactory + */ + private $priceInfoFactory; + + /** + * Cache product prices so only fetch once + * + * @var AmountInterface[] + */ + private $minimalProductAmounts; + + /** + * @param PriceInfoFactory $priceInfoFactory + */ + public function __construct( + PriceInfoFactory $priceInfoFactory + ) { + $this->priceInfoFactory = $priceInfoFactory; + } + + /** + * @inheritdoc + */ + public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface + { + return $this->getMinimalProductAmount($product, FinalPrice::PRICE_CODE); + } + + /** + * @inheritdoc + */ + public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface + { + return $this->getMinimalProductAmount($product, RegularPrice::PRICE_CODE); + } + + /** + * @inheritdoc + */ + public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface + { + //Use minimal for maximal since maximal price in infinite + return $this->getMinimalProductAmount($product, FinalPrice::PRICE_CODE); + } + + /** + * @inheritdoc + */ + public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface + { + //Use minimal for maximal since maximal price in infinite + return $this->getMinimalProductAmount($product, RegularPrice::PRICE_CODE); + } + + /** + * @inheritdoc + */ + public function getRegularPrice(SaleableInterface $product): AmountInterface + { + $priceInfo = $this->getProductPriceInfo($product); + return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + } + + /** + * Get minimal amount for cheapest product in group + * + * @param SaleableInterface $product + * @param string $priceType + * @return AmountInterface + */ + private function getMinimalProductAmount(SaleableInterface $product, string $priceType): AmountInterface + { + if (empty($this->minimalProductAmounts[$product->getId()][$priceType])) { + $products = $product->getTypeInstance()->getAssociatedProducts($product); + $minPrice = null; + foreach ($products as $item) { + $price = $this->getProductPriceInfo($item)->getPrice($priceType); + $priceValue = $price->getValue(); + if (($priceValue !== false) && ($priceValue <= ($minPrice === null ? $priceValue : $minPrice))) { + $minPrice = $price->getValue(); + $this->minimalProductAmounts[$product->getId()][$priceType] = $price->getAmount(); + } + } + } + + return $this->minimalProductAmounts[$product->getId()][$priceType]; + } + + /** + * Get price info for product + * + * @param SaleableInterface $product + * @return PriceInfoInterface + */ + private function getProductPriceInfo($product) + { + if (!isset($this->productPrices[$product->getId()])) { + $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); + } + + return $this->productPrices[$product->getId()]; + } +} diff --git a/app/code/Magento/GroupedProductGraphQl/etc/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/di.xml index 35b63370baf2..56780b4dd9b1 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/di.xml @@ -13,4 +13,12 @@ </argument> </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <arguments> + <argument name="types" xsi:type="array"> + <item name="grouped" xsi:type="string">\Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> </config> From 6677a497fead97540d12befc39fa702b4f318631 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Fri, 20 Sep 2019 10:54:12 -0500 Subject: [PATCH 0537/1172] Added check for empty array --- .../Model/Indexer/ProductPriceIndexFilter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php index 1033d56ac791..d1fbe4f98858 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php @@ -104,7 +104,9 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = $select->where('stock_item.use_config_manage_stock = 0 AND stock_item.manage_stock = 1'); } - $select->where('stock_item.product_id in (?)', $entityIds); + if (!empty($entityIds)) { + $select->where('stock_item.product_id in (?)', $entityIds); + } $select->group('stock_item.product_id'); $select->having('max_is_in_stock = 0'); From 2c4adbf63b0c108cd45be7df2c335b0dbad8adff Mon Sep 17 00:00:00 2001 From: Lena Orobei <oorobei@magento.com> Date: Fri, 20 Sep 2019 12:47:00 -0500 Subject: [PATCH 0538/1172] magento/graphql-ce#911: [Customer] Rename dob to date_of_birth --- app/code/Magento/CustomerGraphQl/etc/schema.graphqls | 4 ++-- .../testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index c06c84a3bdd1..360b7f14f38e 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -61,7 +61,7 @@ input CustomerInput { lastname: String @doc(description: "The customer's family name") suffix: String @doc(description: "A value such as Sr., Jr., or III") email: String @doc(description: "The customer's email address. Required") - dob: String @doc(description: "The customer's date of birth") # deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") + dob: String @doc(description: "Deprecated: Use `date_of_birth` instead") date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") gender: Int @doc(description: "The customer's gender(Male - 1, Female - 2)") @@ -88,7 +88,7 @@ type Customer @doc(description: "Customer defines the customer name and address email: String @doc(description: "The customer's email address. Required") default_billing: String @doc(description: "The ID assigned to the billing address") default_shipping: String @doc(description: "The ID assigned to the shipping address") - dob: String @doc(description: "The customer's date of birth") # deprecated(reason: "The `dob` is deprecated. Use `date_of_birth` instead.") + dob: String @doc(description: "The customer's date of birth") @deprecated(reason: "Use `date_of_birth` instead") date_of_birth: String @doc(description: "The customer's date of birth") taxvat: String @doc(description: "The customer's Tax/VAT number (for corporate customers)") id: Int @doc(description: "The ID assigned to the customer") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php index 64f9afff81d1..d1c6638e8d5f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerTest.php @@ -82,7 +82,7 @@ public function testUpdateCustomer() middlename lastname suffix - dob + date_of_birth taxvat email gender @@ -102,7 +102,7 @@ public function testUpdateCustomer() $this->assertEquals($newMiddlename, $response['updateCustomer']['customer']['middlename']); $this->assertEquals($newLastname, $response['updateCustomer']['customer']['lastname']); $this->assertEquals($newSuffix, $response['updateCustomer']['customer']['suffix']); - $this->assertEquals($newDob, $response['updateCustomer']['customer']['dob']); + $this->assertEquals($newDob, $response['updateCustomer']['customer']['date_of_birth']); $this->assertEquals($newTaxVat, $response['updateCustomer']['customer']['taxvat']); $this->assertEquals($newEmail, $response['updateCustomer']['customer']['email']); $this->assertEquals($newGender, $response['updateCustomer']['customer']['gender']); From ad369f8980e1111631c8cc57a4623d74a0b353e8 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 20 Sep 2019 14:54:41 -0500 Subject: [PATCH 0539/1172] MC-18403: Pricing :: Product pricing schema --- .../Model/Resolver/Product/Price/Type.php | 64 ------------------- .../Model/Resolver/Product/PriceRange.php | 16 +++-- .../AttributeProcessor.php | 25 +++++++- app/code/Magento/CatalogGraphQl/etc/di.xml | 6 +- .../Model/Resolver/Product/Price/Provider.php | 49 ++++++++++++-- .../ConfigurableProductGraphQl/etc/di.xml | 6 +- .../Magento/GroupedProductGraphQl/etc/di.xml | 6 +- .../_files/product_configurable_12345.php | 2 +- 8 files changed, 86 insertions(+), 88 deletions(-) delete mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php deleted file mode 100644 index 01c3ea541e3a..000000000000 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Type.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; - -use Magento\Framework\ObjectManagerInterface; - -/** - * Use to the retrieve correct price provider - */ -class Type -{ - /** - * @var ObjectManagerInterface - */ - private $objectManager; - - /** - * Store created provider objects - * - * @var array - */ - private $providers = []; - - /** - * @var array - */ - private $types = []; - - /** - * @param ObjectManagerInterface $objectManager - * @param array $types - */ - public function __construct(ObjectManagerInterface $objectManager, array $types) - { - $this->objectManager = $objectManager; - $this->types = array_merge($this->types, $types); - } - - /** - * Get appropriate price provider based on product type - * - * @param string $productType - * @return ProviderInterface - */ - public function getProviderByProductType(string $productType): ProviderInterface - { - $providerType = $this->types['default']; - - if (isset($this->types[$productType])) { - $providerType = $this->types[$productType]; - } - - if (!isset($this->providers[$providerType])) { - $this->providers[$providerType] = $this->objectManager->get($providerType); - } - - return $this->providers[$providerType]; - } -} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index 7c803815a16e..bfa932c51a91 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -9,7 +9,6 @@ use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; -use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type as PriceProviderType; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -29,17 +28,17 @@ class PriceRange implements ResolverInterface private $discount; /** - * @var PriceProviderType + * @var array */ - private $priceProviderType; + private $priceProviders; /** - * @param PriceProviderType $priceProviderType + * @param array $priceProviders * @param Discount $discount */ - public function __construct(PriceProviderType $priceProviderType, Discount $discount) + public function __construct(array $priceProviders, Discount $discount) { - $this->priceProviderType = $priceProviderType; + $this->priceProviders = $priceProviders; $this->discount = $discount; } @@ -130,7 +129,10 @@ private function formatPrice(float $regularPrice, float $finalPrice, StoreInterf */ private function getPriceProvider(SaleableInterface $product): ProviderInterface { - return $this->priceProviderType->getProviderByProductType($product->getTypeId()); + if (isset($this->priceProviders[$product->getTypeId()])) { + return $this->priceProviders[$product->getTypeId()]; + } + return $this->priceProviders['default']; } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php index f4cefeb3f363..824551f31ac5 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php @@ -19,7 +19,24 @@ class AttributeProcessor implements CollectionProcessorInterface { /** - * {@inheritdoc} + * Map GraphQl input fields to product attributes + * + * @var array + */ + private $fieldToAttributeMap = [ + 'price_range' => 'price' + ]; + + /** + * @param array $fieldToAttributeMap + */ + public function __construct($fieldToAttributeMap = []) + { + $this->fieldToAttributeMap = array_merge($this->fieldToAttributeMap, $fieldToAttributeMap); + } + + /** + * @inheritdoc */ public function process( Collection $collection, @@ -27,7 +44,11 @@ public function process( array $attributeNames ): Collection { foreach ($attributeNames as $name) { - $collection->addAttributeToSelect($name); + $attributeName = $name; + if (isset($this->fieldToAttributeMap[$name])) { + $attributeName = $this->fieldToAttributeMap[$name]; + } + $collection->addAttributeToSelect($attributeName); } return $collection; diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index ed404d35b47c..eceaafb479f8 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -71,10 +71,10 @@ </type> <preference type="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider" for="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface"/> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> <arguments> - <argument name="types" xsi:type="array"> - <item name="default" xsi:type="string">\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> + <argument name="priceProviders" xsi:type="array"> + <item name="default" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> </type> diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php index 24bc66fb199e..986247e5759a 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -14,6 +14,7 @@ use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\Pricing\SaleableInterface; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; +use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface; /** * Provides product prices for configurable products @@ -32,13 +33,31 @@ class Provider implements ProviderInterface */ private $priceInfoFactory; + /** + * @var ConfigurableOptionsProviderInterface + */ + private $optionsProvider; + + /** + * @var array + */ + private $minimumFinalAmounts = []; + + /** + * @var array + */ + private $maximumFinalAmounts = []; + /** * @param PriceInfoFactory $priceInfoFactory + * @param ConfigurableOptionsProviderInterface $optionsProvider */ public function __construct( - PriceInfoFactory $priceInfoFactory + PriceInfoFactory $priceInfoFactory, + ConfigurableOptionsProviderInterface $optionsProvider ) { $this->priceInfoFactory = $priceInfoFactory; + $this->optionsProvider = $optionsProvider; } /** @@ -46,8 +65,18 @@ public function __construct( */ public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(FinalPrice::PRICE_CODE)->getMinimalPrice(); + if (!isset($this->minimumFinalAmounts[$product->getId()])) { + $minimumAmount = null; + foreach ($this->optionsProvider->getProducts($product) as $variant) { + $variantAmount = $this->getProductPriceInfo($variant)->getPrice(FinalPrice::PRICE_CODE)->getAmount(); + if (!$minimumAmount || ($variantAmount->getValue() < $minimumAmount->getValue())) { + $minimumAmount = $variantAmount; + $this->minimumFinalAmounts[$product->getId()] = $variantAmount; + } + } + } + + return $this->minimumFinalAmounts[$product->getId()]; } /** @@ -64,8 +93,18 @@ public function getMinimalRegularPrice(SaleableInterface $product): AmountInterf */ public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(FinalPrice::PRICE_CODE)->getMaximalPrice(); + if (!isset($this->maximumFinalAmounts[$product->getId()])) { + $maximumAmount = null; + foreach ($this->optionsProvider->getProducts($product) as $variant) { + $variantAmount = $this->getProductPriceInfo($variant)->getPrice(FinalPrice::PRICE_CODE)->getAmount(); + if (!$maximumAmount || ($variantAmount->getValue() > $maximumAmount->getValue())) { + $maximumAmount = $variantAmount; + $this->maximumFinalAmounts[$product->getId()] = $variantAmount; + } + } + } + + return $this->maximumFinalAmounts[$product->getId()]; } /** diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml index e16d9638003a..323390d9eb27 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml @@ -6,10 +6,10 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> <arguments> - <argument name="types" xsi:type="array"> - <item name="configurable" xsi:type="string">\Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> + <argument name="priceProviders" xsi:type="array"> + <item name="configurable" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> </type> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/di.xml index 56780b4dd9b1..c0e6d0742a19 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/di.xml @@ -14,10 +14,10 @@ </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\Type"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> <arguments> - <argument name="types" xsi:type="array"> - <item name="grouped" xsi:type="string">\Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> + <argument name="priceProviders" xsi:type="array"> + <item name="grouped" xsi:type="object">Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> </type> diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php index 9a2f5c49ac29..70aa7c07ed53 100644 --- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable_12345.php @@ -121,7 +121,7 @@ $registry->register('isSecureArea', false); $product->setTypeId(Configurable::TYPE_CODE) - ->setId(11) + ->setId(111) ->setAttributeSetId($attributeSetId) ->setWebsiteIds([1]) ->setName('Configurable Product 12345') From 1429078243783e6e278bbdeb6f440c6f579a2a8a Mon Sep 17 00:00:00 2001 From: Raul E Watson <diazwatson@gmail.com> Date: Sat, 21 Sep 2019 01:16:40 +0100 Subject: [PATCH 0540/1172] Update Magento_BraintreeGraphQl module ReadMe --- app/code/Magento/BraintreeGraphQl/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/BraintreeGraphQl/README.md b/app/code/Magento/BraintreeGraphQl/README.md index f6740e4d250e..78b527b76360 100644 --- a/app/code/Magento/BraintreeGraphQl/README.md +++ b/app/code/Magento/BraintreeGraphQl/README.md @@ -1,4 +1,9 @@ -# BraintreeGraphQl +# Magento_BraintreeGraphQl module -**BraintreeGraphQl** provides type and resolver for method additional -information. \ No newline at end of file +The Magento_BraintreeGraphQl module provides type and resolver for method additional information. + +## Extensibility + +Extension developers can interact with the Magento_BraintreeGraphQl module. For more information about the Magento extension mechanism, see [Magento plug-ins](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html). + +[The Magento dependency injection mechanism](https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html) enables you to override the functionality of the Magento_BraintreeGraphQl module. From eaa5f74a7cc4488450494ad5bb618913e13a08eb Mon Sep 17 00:00:00 2001 From: "bruce.ayko" <bruce@ayko.com> Date: Sat, 21 Sep 2019 09:38:48 +0100 Subject: [PATCH 0541/1172] Price Indexer Performance Issue With Out of Stock Products - Relates to issue https://github.com/magento/magento2/issues/24414 - Made changes based on feedback on PR - Resolving whitespace issue https://testing-service.magento-community.engineering/reports/magento/magento2/pull/24415/56e6453d1da3a1546212c6c35f78d77d/Statics/allure-report-ce/index.html#categories/479362f77c9377ec388bccba15830ad3/997602107dd59e40/ --- .../CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php index 1033d56ac791..35e741d12783 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php @@ -105,7 +105,6 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = } $select->where('stock_item.product_id in (?)', $entityIds); - $select->group('stock_item.product_id'); $select->having('max_is_in_stock = 0'); From 127e8aca29874e08f96582a19e2c6dd83a4d9232 Mon Sep 17 00:00:00 2001 From: "bruce.ayko" <bruce@ayko.com> Date: Sat, 21 Sep 2019 09:47:10 +0100 Subject: [PATCH 0542/1172] Price Indexer Performance Issue With Out of Stock Products - Relates to issue https://github.com/magento/magento2/issues/24414 - Resolving whitespace issue https://testing-service.magento-community.engineering/reports/magento/magento2/pull/24415/56e6453d1da3a1546212c6c35f78d77d/Statics/allure-report-ce/index.html#categories/479362f77c9377ec388bccba15830ad3/997602107dd59e40/ --- .../CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php index d1fbe4f98858..35231b8460b1 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/ProductPriceIndexFilter.php @@ -105,7 +105,7 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds = } if (!empty($entityIds)) { - $select->where('stock_item.product_id in (?)', $entityIds); + $select->where('stock_item.product_id in (?)', $entityIds); } $select->group('stock_item.product_id'); From dbf518eb6ccb1ed0881453714fbc6cf462b2a778 Mon Sep 17 00:00:00 2001 From: Kaushik Chavda <chavda@team23.de> Date: Sat, 21 Sep 2019 12:16:24 +0200 Subject: [PATCH 0543/1172] #24581 Added unique key on eav_attribute_label table --- app/code/Magento/Eav/etc/db_schema.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index b6c42d725e5e..bce3c7be2aa3 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -481,11 +481,11 @@ referenceColumn="attribute_id" onDelete="CASCADE"/> <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID" table="eav_attribute_label" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> - <index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID_UNIQUE"> <column name="store_id"/> - </index> - <index referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> <column name="attribute_id"/> + </constraint> + <index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> </table> From 4dbf01c8aaf6c13e24f9862ca801ec07ba3f08b5 Mon Sep 17 00:00:00 2001 From: Kaushik Chavda <chavda@team23.de> Date: Sat, 21 Sep 2019 13:24:24 +0200 Subject: [PATCH 0544/1172] #24581 Added unique key on eav_attribute_label table - Fixed pipeline issue. --- app/code/Magento/Eav/etc/db_schema.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index bce3c7be2aa3..ece2857aae61 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -488,6 +488,10 @@ <index referenceId="EAV_ATTRIBUTE_LABEL_STORE_ID" indexType="btree"> <column name="store_id"/> </index> + <index referenceId="EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_STORE_ID" indexType="btree"> + <column name="attribute_id"/> + <column name="store_id"/> + </index> </table> <table name="eav_form_type" resource="default" engine="innodb" comment="Eav Form Type"> <column xsi:type="smallint" name="type_id" padding="5" unsigned="true" nullable="false" identity="true" From d16dd4cacae81fac4ead4629e32ad85c829c31c0 Mon Sep 17 00:00:00 2001 From: federeggiani <elfeffe@gmail.com> Date: Sat, 21 Sep 2019 14:34:53 +0200 Subject: [PATCH 0545/1172] Improve code, a bit --- .../ConfigurableProduct/Model/Product/Type/VariationMatrix.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php index 691f34ead9d6..e7da5ccd6cdf 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/VariationMatrix.php @@ -40,7 +40,7 @@ public function getVariations($usedProductAttributes) for ($attributeIndex = $attributesCount; $attributeIndex--;) { $currentAttribute = $variationalAttributes[$attributeIndex]; $currentVariationValue = $currentVariation[$attributeIndex]; - if(isset($currentAttribute['id']) && $currentAttribute['id']) { + if(!empty($currentAttribute['id'])) { $filledVariation[$currentAttribute['id']] = $currentAttribute['values'][$currentVariationValue]; } } From 9d54005fc99c1a0aeddb228563ee913ccb7a9e6f Mon Sep 17 00:00:00 2001 From: Patrick McLain <pat@pmclain.com> Date: Sat, 21 Sep 2019 13:49:53 -0400 Subject: [PATCH 0546/1172] Fix test `base_amount` is always returned as null https://github.com/magento/graphql-ce/blob/4013a390348bf15ae48ddcaeecadae402351cf33/app/code/Magento/QuoteGraphQl/Model/Resolver/ShippingAddress/AvailableShippingMethods.php#L100 --- .../GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php index 13c63929adca..0d64d73965d2 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/GetAvailableShippingMethodsTest.php @@ -67,6 +67,7 @@ public function testGetAvailableShippingMethods() 'value' => 10, 'currency' => 'USD', ], + 'base_amount' => null, ]; self::assertEquals( $expectedAddressData, From d562df9da428dd249d80bfc38e86c5e9c3decfbc Mon Sep 17 00:00:00 2001 From: Andrey Legayev <andrey@ven.com> Date: Sat, 21 Sep 2019 21:48:05 +0300 Subject: [PATCH 0547/1172] Static Content Deploy - Optimize files scanning performance According to XDebug profiling Magento2 calls preg_match() and preg_quote() unreasonable amount of times during static content deploy. I've debugged it and found root cause. This is current algorithm: 1. Get list of all modules 2. Get array of all files in all modules 3. Now try to guess which file belongs to which module by using dynamic regex: preg_quote(), preg_match() I've refactored it to avoid mixing all files in one array and then splitting again. Quite simple fix. --- .../Magento/Framework/App/Utility/Files.php | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index 3460faf854ba..8c95ede7f2e5 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -925,14 +925,12 @@ public function getStaticPreProcessingFiles($filePattern = '*') $area = '*'; $locale = '*'; $result = []; - $moduleWebPath = []; $moduleLocalePath = []; foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleDir) { - $moduleWebPath[] = $moduleDir . "/view/{$area}/web"; $moduleLocalePath[] = $moduleDir . "/view/{$area}/web/i18n/{$locale}"; } - $this->_accumulateFilesByPatterns($moduleWebPath, $filePattern, $result, '_parseModuleStatic'); + $this->_accumulateStaticFiles($area, $filePattern, $result); $this->_accumulateFilesByPatterns($moduleLocalePath, $filePattern, $result, '_parseModuleLocaleStatic'); $this->accumulateThemeStaticFiles($area, $locale, $filePattern, $result); self::$_cache[$key] = $result; @@ -1041,25 +1039,26 @@ protected function _accumulateFilesByPatterns(array $patterns, $filePattern, arr } /** - * Parse meta-info of a static file in module + * Search static files from all modules by the specified pattern and accumulate meta-info * - * @param string $file - * @return array + * @param string $area + * @param string $filePattern + * @param array $result + * @return void */ - protected function _parseModuleStatic($file) + protected function _accumulateStaticFiles($area, $filePattern, array &$result) { - foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { - if (preg_match( - '/^' . preg_quote("{$modulePath}/", '/') . 'view\/([a-z]+)\/web\/(.+)$/i', - $file, - $matches - ) === 1 - ) { - list(, $area, $filePath) = $matches; - return [$area, '', '', $moduleName, $filePath, $file]; + foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { + $moduleWebPath = $moduleDir . "/view/{$area}/web"; + + foreach (self::getFiles([$moduleWebPath], $filePattern) as $absolutePath) { + $localPath = substr($absolutePath, strlen($moduleDir) + 1); + if (preg_match('/^view\/([a-z]+)\/web\/(.+)$/i', $localPath, $matches) === 1) { + list(, $parsedArea, $parsedPath) = $matches; + $result[] = [$parsedArea, '', '', $moduleName, $parsedPath, $absolutePath]; + } } } - return []; } /** From 0402368c5b663288a612b1b6464b628c44e9f71d Mon Sep 17 00:00:00 2001 From: Oleksandr Kravchuk <swnsma@gmail.com> Date: Sun, 22 Sep 2019 16:03:59 +0300 Subject: [PATCH 0548/1172] Add extension point for Quote Address. --- .../Model/Cart/GetShippingAddress.php | 66 +++++++++++++++++++ .../Model/Cart/SetShippingAddressesOnCart.php | 34 +++------- 2 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php new file mode 100644 index 000000000000..eeb33972f2c0 --- /dev/null +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\QuoteGraphQl\Model\Cart; + +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\GraphQl\Model\Query\ContextInterface; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; +use Magento\Quote\Model\Quote\Address; + +/** + * Get shipping address + */ +class GetShippingAddress +{ + /** + * @var QuoteAddressFactory + */ + private $quoteAddressFactory; + + /** + * @param QuoteAddressFactory $quoteAddressFactory + */ + public function __construct(QuoteAddressFactory $quoteAddressFactory) + { + $this->quoteAddressFactory = $quoteAddressFactory; + } + + /** + * @param ContextInterface $context + * @param array $shippingAddressInput + * @return Address + * @throws GraphQlAuthorizationException + * @throws GraphQlInputException + * @throws GraphQlNoSuchEntityException + */ + public function execute(ContextInterface $context, array $shippingAddressInput) + { + $customerAddressId = $shippingAddressInput['customer_address_id'] ?? null; + + $addressInput = $shippingAddressInput['address']; + if ($addressInput) { + $addressInput['customer_notes'] = $shippingAddressInput['customer_notes'] ?? ''; + } + + if (null === $customerAddressId) { + $shippingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); + } else { + if (false === $context->getExtensionAttributes()->getIsCustomer()) { + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); + } + + $shippingAddress = $this->quoteAddressFactory->createBasedOnCustomerAddress( + (int)$customerAddressId, + $context->getUserId() + ); + } + + return $shippingAddress; + } +} diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index 260f1343556f..9fa4f3462b51 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -17,26 +17,25 @@ */ class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface { - /** - * @var QuoteAddressFactory - */ - private $quoteAddressFactory; - /** * @var AssignShippingAddressToCart */ private $assignShippingAddressToCart; + /** + * @var GetShippingAddress + */ + private $getShippingAddress; /** - * @param QuoteAddressFactory $quoteAddressFactory * @param AssignShippingAddressToCart $assignShippingAddressToCart + * @param GetShippingAddress $getShippingAddress */ public function __construct( - QuoteAddressFactory $quoteAddressFactory, - AssignShippingAddressToCart $assignShippingAddressToCart + AssignShippingAddressToCart $assignShippingAddressToCart, + GetShippingAddress $getShippingAddress ) { - $this->quoteAddressFactory = $quoteAddressFactory; $this->assignShippingAddressToCart = $assignShippingAddressToCart; + $this->getShippingAddress = $getShippingAddress; } /** @@ -53,10 +52,6 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s $customerAddressId = $shippingAddressInput['customer_address_id'] ?? null; $addressInput = $shippingAddressInput['address'] ?? null; - if ($addressInput) { - $addressInput['customer_notes'] = $shippingAddressInput['customer_notes'] ?? ''; - } - if (null === $customerAddressId && null === $addressInput) { throw new GraphQlInputException( __('The shipping address must contain either "customer_address_id" or "address".') @@ -69,18 +64,7 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } - if (null === $customerAddressId) { - $shippingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); - } else { - if (false === $context->getExtensionAttributes()->getIsCustomer()) { - throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); - } - - $shippingAddress = $this->quoteAddressFactory->createBasedOnCustomerAddress( - (int)$customerAddressId, - $context->getUserId() - ); - } + $shippingAddress = $this->getShippingAddress->execute($context, $shippingAddressInput); $this->assignShippingAddressToCart->execute($cart, $shippingAddress); } From be027d80f164614a2951ee544170679959556048 Mon Sep 17 00:00:00 2001 From: Oleksandr Kravchuk <swnsma@gmail.com> Date: Sun, 22 Sep 2019 16:37:10 +0300 Subject: [PATCH 0549/1172] Add extension point for Quote Address. Move logic related to Shipping Address to the GetShippingAddress service. --- .../Model/Cart/GetShippingAddress.php | 18 ++++++++++++++++-- .../Model/Cart/SetShippingAddressesOnCart.php | 14 -------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php index eeb33972f2c0..6e35091aecd7 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php @@ -32,6 +32,8 @@ public function __construct(QuoteAddressFactory $quoteAddressFactory) } /** + * Get Shipping Address based on the input. + * * @param ContextInterface $context * @param array $shippingAddressInput * @return Address @@ -39,15 +41,27 @@ public function __construct(QuoteAddressFactory $quoteAddressFactory) * @throws GraphQlInputException * @throws GraphQlNoSuchEntityException */ - public function execute(ContextInterface $context, array $shippingAddressInput) + public function execute(ContextInterface $context, array $shippingAddressInput): Address { $customerAddressId = $shippingAddressInput['customer_address_id'] ?? null; + $addressInput = $shippingAddressInput['address'] ?? null; - $addressInput = $shippingAddressInput['address']; if ($addressInput) { $addressInput['customer_notes'] = $shippingAddressInput['customer_notes'] ?? ''; } + if (null === $customerAddressId && null === $addressInput) { + throw new GraphQlInputException( + __('The shipping address must contain either "customer_address_id" or "address".') + ); + } + + if ($customerAddressId && $addressInput) { + throw new GraphQlInputException( + __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') + ); + } + if (null === $customerAddressId) { $shippingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); } else { diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index 9fa4f3462b51..d4f2853467b3 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -49,20 +49,6 @@ public function execute(ContextInterface $context, CartInterface $cart, array $s ); } $shippingAddressInput = current($shippingAddressesInput); - $customerAddressId = $shippingAddressInput['customer_address_id'] ?? null; - $addressInput = $shippingAddressInput['address'] ?? null; - - if (null === $customerAddressId && null === $addressInput) { - throw new GraphQlInputException( - __('The shipping address must contain either "customer_address_id" or "address".') - ); - } - - if ($customerAddressId && $addressInput) { - throw new GraphQlInputException( - __('The shipping address cannot contain "customer_address_id" and "address" at the same time.') - ); - } $shippingAddress = $this->getShippingAddress->execute($context, $shippingAddressInput); From ab4e73654bb2b9eceb010e6adc3368435e696326 Mon Sep 17 00:00:00 2001 From: Sergey Dovbenko <sdovbenko@magecom.us> Date: Sun, 22 Sep 2019 16:09:20 +0000 Subject: [PATCH 0550/1172] Covered with api-functional Tests --- ...mpleProductWithCustomOptionsToCartTest.php | 58 +++++++++++++++++++ .../GetCustomOptionsValuesForQueryBySku.php | 7 ++- .../GetEmptyOptionsValuesForQueryBySku.php | 53 +++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetEmptyOptionsValuesForQueryBySku.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php index b0b116b0cdda..272c0df29e04 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php @@ -31,6 +31,11 @@ class AddSimpleProductWithCustomOptionsToCartTest extends GraphQlAbstract */ private $getCustomOptionsValuesForQueryBySku; + /** + * @var GetEmptyOptionsValuesForQueryBySku + */ + private $getEmptyOptionsValuesForQueryBySku; + /** * @inheritdoc */ @@ -40,6 +45,7 @@ protected function setUp() $this->getMaskedQuoteIdByReservedOrderId = $objectManager->get(GetMaskedQuoteIdByReservedOrderId::class); $this->productCustomOptionsRepository = $objectManager->get(ProductCustomOptionRepositoryInterface::class); $this->getCustomOptionsValuesForQueryBySku = $objectManager->get(GetCustomOptionsValuesForQueryBySku::class); + $this->getEmptyOptionsValuesForQueryBySku = $objectManager->get(GetEmptyOptionsValuesForQueryBySku::class); } /** @@ -99,6 +105,58 @@ public function testAddSimpleProductWithMissedRequiredOptionsSet() $this->graphQlMutation($query); } + /** + * Test adding a simple product to the shopping cart with Date customizable option assigned + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_option_date.php + * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php + */ + public function testAddSimpleProductWithDateOption() + { + $sku = 'simple-product-1'; + $quantity = 1; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1'); + + $customOptionsValues = $this->getCustomOptionsValuesForQueryBySku->execute($sku); + $queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; + $query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions); + + $response = $this->graphQlMutation($query); + + self::assertArrayHasKey('items', $response['addSimpleProductsToCart']['cart']); + self::assertCount(1, $response['addSimpleProductsToCart']['cart']); + + $customizableOptionOutput = $response['addSimpleProductsToCart']['cart']['items'][0]['customizable_options'][0]['values'][0]['value']; + $expectedValue = date("M d, Y", strtotime($customOptionsValues[0]['value_string'])); + + self::assertEquals($expectedValue, $customizableOptionOutput); + } + + /** + * Test adding a simple product with empty values for date option + * + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_with_option_date.php + * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php + */ + public function testAddSimpleProductWithMissedDateOptionsSet() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_order_1'); + $sku = 'simple-product-1'; + $quantity = 1; + + $customOptionsValues = $this->getEmptyOptionsValuesForQueryBySku->execute($sku); + $queryCustomizableOptionValues = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', json_encode($customOptionsValues)); + $customizableOptions = "customizable_options: {$queryCustomizableOptionValues}"; + $query = $this->getQuery($maskedQuoteId, $sku, $quantity, $customizableOptions); + + self::expectExceptionMessage( + 'Invalid format provided. Please use \'Y-m-d H:i:s\' format.' + ); + + $this->graphQlMutation($query); + } + /** * @param string $maskedQuoteId * @param string $sku diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php index 7514eb1c4e1d..8bc17cba0bf7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetCustomOptionsValuesForQueryBySku.php @@ -40,7 +40,12 @@ public function execute(string $sku): array foreach ($customOptions as $customOption) { $optionType = $customOption->getType(); - if ($optionType == 'field' || $optionType == 'area') { + if ($optionType == 'date') { + $customOptionsValues[] = [ + 'id' => (int)$customOption->getOptionId(), + 'value_string' => '2012-12-12 00:00:00' + ]; + } elseif ($optionType == 'field' || $optionType == 'area') { $customOptionsValues[] = [ 'id' => (int)$customOption->getOptionId(), 'value_string' => 'test' diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetEmptyOptionsValuesForQueryBySku.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetEmptyOptionsValuesForQueryBySku.php new file mode 100644 index 000000000000..b6c0fecf0f1c --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/GetEmptyOptionsValuesForQueryBySku.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Quote; + +use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface; + +/** + * Generate an array with test values for customizable options based on the option type + */ +class GetEmptyOptionsValuesForQueryBySku +{ + /** + * @var ProductCustomOptionRepositoryInterface + */ + private $productCustomOptionRepository; + + /** + * @param ProductCustomOptionRepositoryInterface $productCustomOptionRepository + */ + public function __construct(ProductCustomOptionRepositoryInterface $productCustomOptionRepository) + { + $this->productCustomOptionRepository = $productCustomOptionRepository; + } + + /** + * Returns array of empty options for the product + * + * @param string $sku + * @return array + */ + public function execute(string $sku): array + { + $customOptions = $this->productCustomOptionRepository->getList($sku); + $customOptionsValues = []; + + foreach ($customOptions as $customOption) { + $optionType = $customOption->getType(); + if ($optionType == 'date') { + $customOptionsValues[] = [ + 'id' => (int)$customOption->getOptionId(), + 'value_string' => '' + ]; + } + } + + return $customOptionsValues; + } +} From f1e225d81bbb4dbb2b155531445cfc3e880db81d Mon Sep 17 00:00:00 2001 From: Daniel Filipek <d.filipek@global4net.com> Date: Sun, 22 Sep 2019 19:31:09 +0200 Subject: [PATCH 0551/1172] #23880 [Magento_Paypal][fix] - M2.3.2 - fix - Node <payment><payflow_advanced><user> is declared twice in Paypal module --- app/code/Magento/Paypal/etc/config.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Paypal/etc/config.xml b/app/code/Magento/Paypal/etc/config.xml index 4619fc853944..6c0601f80137 100644 --- a/app/code/Magento/Paypal/etc/config.xml +++ b/app/code/Magento/Paypal/etc/config.xml @@ -164,7 +164,6 @@ <title>Credit Card (Payflow Advanced) PayPal PayPal - PayPal 1 1 GET From 6a648202b3bf6d93f357901f31f51292982fe1d7 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi Date: Fri, 20 Sep 2019 10:40:57 -0500 Subject: [PATCH 0552/1172] MC-17518: Cart Rest API not showing all shipping assignments for multi-shipping --- .../Controller/Checkout/Plugin.php | 22 ++- .../MultishippingQuoteRepositoryPlugin.php | 159 ++++++++++++++++++ .../Plugin/ResetShippingAssigmentPlugin.php | 52 ++++++ .../Unit/Controller/Checkout/PluginTest.php | 63 +++++-- app/code/Magento/Multishipping/etc/di.xml | 3 + .../Magento/Multishipping/etc/frontend/di.xml | 3 + .../Magento/Quote/Api/CartRepositoryTest.php | 79 ++++++++- 7 files changed, 354 insertions(+), 27 deletions(-) create mode 100644 app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php create mode 100644 app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php b/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php index f88cdfc26fa9..f60feb2b834b 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php @@ -7,36 +7,44 @@ namespace Magento\Multishipping\Controller\Checkout; +use Magento\Checkout\Model\Cart; +use Magento\Framework\App\Action\Action; + /** * Turns Off Multishipping mode for Quote. */ class Plugin { /** - * @var \Magento\Checkout\Model\Cart + * @var Cart */ - protected $cart; + private $cart; /** - * @param \Magento\Checkout\Model\Cart $cart + * @param Cart $cart */ - public function __construct(\Magento\Checkout\Model\Cart $cart) - { + public function __construct( + Cart $cart + ) { $this->cart = $cart; } /** * Disable multishipping * - * @param \Magento\Framework\App\Action\Action $subject + * @param Action $subject * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function beforeExecute(\Magento\Framework\App\Action\Action $subject) + public function beforeExecute(Action $subject) { $quote = $this->cart->getQuote(); if ($quote->getIsMultiShipping()) { $quote->setIsMultiShipping(0); + $extensionAttributes = $quote->getExtensionAttributes(); + if ($extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $extensionAttributes->setShippingAssignments([]); + } $this->cart->saveQuote(); } } diff --git a/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php b/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php new file mode 100644 index 000000000000..db972cf9bd7c --- /dev/null +++ b/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php @@ -0,0 +1,159 @@ +shippingAssignmentFactory = $shippingAssignmentFactory; + $this->shippingProcessor = $shippingProcessor; + } + + /** + * Process multishipping quote for get. + * + * @param CartRepositoryInterface $subject + * @param CartInterface $result + * @return CartInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGet( + CartRepositoryInterface $subject, + CartInterface $result + ) { + return $this->processQuote($result); + } + + /** + * Process multishipping quote for get list. + * + * @param CartRepositoryInterface $subject + * @param SearchResultsInterface $result + * + * @return SearchResultsInterface + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterGetList( + CartRepositoryInterface $subject, + SearchResultsInterface $result + ) { + $items = []; + foreach ($result->getItems() as $item) { + $items[] = $this->processQuote($item); + } + $result->setItems($items); + + return $result; + } + + /** + * Remove shipping assignments for multishipping quote. + * + * @param CartRepositoryInterface $subject + * @param CartInterface $quote + * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function beforeSave(CartRepositoryInterface $subject, CartInterface $quote) + { + $extensionAttributes = $quote->getExtensionAttributes(); + if ($quote->getIsMultiShipping() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $quote->getExtensionAttributes()->setShippingAssignments([]); + } + + return [$quote]; + } + + /** + * Set shipping assignments for multishipping quote according to customer selection. + * + * @param CartInterface $quote + * @return CartInterface + */ + private function processQuote(CartInterface $quote): CartInterface + { + if (!$quote->getIsMultiShipping() || !$quote instanceof Quote) { + return $quote; + } + + if ($quote->getExtensionAttributes() && $quote->getExtensionAttributes()->getShippingAssignments()) { + $shippingAssignments = []; + $addresses = $quote->getAllAddresses(); + + foreach ($addresses as $address) { + $quoteItems = $this->getQuoteItems($quote, $address); + if (!empty($quoteItems)) { + $shippingAssignment = $this->shippingAssignmentFactory->create(); + $shippingAssignment->setItems($quoteItems); + $shippingAssignment->setShipping($this->shippingProcessor->create($address)); + $shippingAssignments[] = $shippingAssignment; + } + } + + if (!empty($shippingAssignments)) { + $quote->getExtensionAttributes()->setShippingAssignments($shippingAssignments); + } + } + + return $quote; + } + + /** + * Returns quote items assigned to address. + * + * @param Quote $quote + * @param Quote\Address $address + * @return Quote\Item[] + */ + private function getQuoteItems(Quote $quote, Quote\Address $address): array + { + $quoteItems = []; + foreach ($address->getItemsCollection() as $addressItem) { + $quoteItem = $quote->getItemById($addressItem->getQuoteItemId()); + if ($quoteItem) { + $multishippingQuoteItem = clone $quoteItem; + $qty = $addressItem->getQty(); + $sku = $multishippingQuoteItem->getSku(); + if (isset($quoteItems[$sku])) { + $qty += $quoteItems[$sku]->getQty(); + } + $multishippingQuoteItem->setQty($qty); + $quoteItems[$sku] = $multishippingQuoteItem; + } + } + + return array_values($quoteItems); + } +} diff --git a/app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php b/app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php new file mode 100644 index 000000000000..376dbf723b88 --- /dev/null +++ b/app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php @@ -0,0 +1,52 @@ +shippingAssignmentProcessor = $shippingAssignmentProcessor; + } + + /** + * Resets quote shipping assignments when item is removed from multishipping quote. + * + * @param Quote $subject + * @param mixed $itemId + * + * @return array + */ + public function beforeRemoveItem(Quote $subject, $itemId): array + { + if ($subject->getIsMultiShipping()) { + $extensionAttributes = $subject->getExtensionAttributes(); + if ($extensionAttributes && $extensionAttributes->getShippingAssignments()) { + $shippingAssignment = $this->shippingAssignmentProcessor->create($subject); + $extensionAttributes->setShippingAssignments([$shippingAssignment]); + } + } + + return [$itemId]; + } +} diff --git a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php index a26f2661ebab..bbcd6d85c501 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php @@ -4,53 +4,90 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); namespace Magento\Multishipping\Test\Unit\Controller\Checkout; +use Magento\Checkout\Controller\Index\Index; +use Magento\Checkout\Model\Cart; use Magento\Multishipping\Controller\Checkout\Plugin; +use Magento\Quote\Api\Data\CartExtensionInterface; +use Magento\Quote\Api\Data\ShippingAssignmentInterface; +use Magento\Quote\Model\Quote; +/** + * Class PluginTest + */ class PluginTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $cartMock; + private $cartMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $quoteMock; + private $quoteMock; /** * @var Plugin */ - protected $object; + private $object; + /** + * @inheritdoc + */ protected function setUp() { - $this->cartMock = $this->createMock(\Magento\Checkout\Model\Cart::class); + $this->cartMock = $this->createMock(Cart::class); $this->quoteMock = $this->createPartialMock( - \Magento\Quote\Model\Quote::class, - ['__wakeUp', 'setIsMultiShipping', 'getIsMultiShipping'] + Quote::class, + ['__wakeUp', 'setIsMultiShipping', 'getIsMultiShipping', 'getExtensionAttributes'] ); - $this->cartMock->expects($this->once())->method('getQuote')->will($this->returnValue($this->quoteMock)); + $this->cartMock->expects($this->once()) + ->method('getQuote') + ->will($this->returnValue($this->quoteMock)); $this->object = new \Magento\Multishipping\Controller\Checkout\Plugin($this->cartMock); } + /** + * Tests turn off multishipping on multishipping quote. + * + * @return void + */ public function testExecuteTurnsOffMultishippingModeOnMultishippingQuote(): void { - $subject = $this->createMock(\Magento\Checkout\Controller\Index\Index::class); - $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(1); - $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(0); - $this->cartMock->expects($this->once())->method('saveQuote'); + $subject = $this->createMock(Index::class); + $extensionAttributes = $this->createMock(CartExtensionInterface::class); + $extensionAttributes->method('getShippingAssignments') + ->willReturn( + $this->createMock(ShippingAssignmentInterface::class) + ); + $extensionAttributes->expects($this->once()) + ->method('setShippingAssignments') + ->with([]); + $this->quoteMock->method('getExtensionAttributes') + ->willReturn($extensionAttributes); + $this->quoteMock->expects($this->once()) + ->method('getIsMultiShipping')->willReturn(1); + $this->quoteMock->expects($this->once()) + ->method('setIsMultiShipping') + ->with(0); + $this->cartMock->expects($this->once()) + ->method('saveQuote'); + $this->object->beforeExecute($subject); } + /** + * Tests turn off multishipping on non-multishipping quote. + * + * @return void + */ public function testExecuteTurnsOffMultishippingModeOnNotMultishippingQuote(): void { - $subject = $this->createMock(\Magento\Checkout\Controller\Index\Index::class); + $subject = $this->createMock(Index::class); $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(0); $this->quoteMock->expects($this->never())->method('setIsMultiShipping'); $this->cartMock->expects($this->never())->method('saveQuote'); diff --git a/app/code/Magento/Multishipping/etc/di.xml b/app/code/Magento/Multishipping/etc/di.xml index 3bccf0b74bcd..993376da8378 100644 --- a/app/code/Magento/Multishipping/etc/di.xml +++ b/app/code/Magento/Multishipping/etc/di.xml @@ -9,4 +9,7 @@ + + + diff --git a/app/code/Magento/Multishipping/etc/frontend/di.xml b/app/code/Magento/Multishipping/etc/frontend/di.xml index 0c2daaf45043..3d85f4c8a447 100644 --- a/app/code/Magento/Multishipping/etc/frontend/di.xml +++ b/app/code/Magento/Multishipping/etc/frontend/di.xml @@ -45,4 +45,7 @@ + + + diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php index 8cb82f5c8f20..7ffc4311e40e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php @@ -42,6 +42,9 @@ class CartRepositoryTest extends WebapiAbstract */ private $filterBuilder; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -59,8 +62,12 @@ protected function setUp() protected function tearDown() { try { + /** @var CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class); $cart = $this->getCart('test01'); - $cart->delete(); + $quoteRepository->delete($cart); + $cart = $this->getCart('multishipping_quote_id'); + $quoteRepository->delete($cart); } catch (\InvalidArgumentException $e) { // Do nothing if cart fixture was not used } @@ -74,18 +81,27 @@ protected function tearDown() * @return \Magento\Quote\Model\Quote * @throws \InvalidArgumentException */ - protected function getCart($reservedOrderId) + private function getCart($reservedOrderId) { - /** @var $cart \Magento\Quote\Model\Quote */ - $cart = $this->objectManager->get(\Magento\Quote\Model\Quote::class); - $cart->load($reservedOrderId, 'reserved_order_id'); - if (!$cart->getId()) { + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); + $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId) + ->create(); + + /** @var CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class); + $items = $quoteRepository->getList($searchCriteria)->getItems(); + + if (empty($items)) { throw new \InvalidArgumentException('There is no quote with provided reserved order ID.'); } - return $cart; + + return array_pop($items); } /** + * Tests successfull get cart web-api call. + * * @magentoApiDataFixture Magento/Sales/_files/quote.php */ public function testGetCart() @@ -130,6 +146,52 @@ public function testGetCart() } /** + * Tests that multishipping quote contains all addresses in shipping assignments. + * + * @magentoApiDataFixture Magento/Multishipping/Fixtures/quote_with_split_items.php + */ + public function testGetMultishippingCart() + { + $cart = $this->getCart('multishipping_quote_id'); + $cartId = $cart->getId(); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/carts/' . $cartId, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => 'quoteCartRepositoryV1', + 'serviceVersion' => 'V1', + 'operation' => 'quoteCartRepositoryV1Get', + ], + ]; + + $requestData = ['cartId' => $cartId]; + $cartData = $this->_webApiCall($serviceInfo, $requestData); + + $shippingAssignments = $cart->getExtensionAttributes()->getShippingAssignments(); + foreach ($shippingAssignments as $key => $shippingAssignment) { + $address = $shippingAssignment->getShipping()->getAddress(); + $cartItem = $shippingAssignment->getItems()[0]; + $this->assertEquals( + $address->getId(), + $cartData['extension_attributes']['shipping_assignments'][$key]['shipping']['address']['id'] + ); + $this->assertEquals( + $cartItem->getSku(), + $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['sku'] + ); + $this->assertEquals( + $cartItem->getQty(), + $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['qty'] + ); + } + } + + /** + * Tests exception when cartId is not provided. + * * @expectedException \Exception * @expectedExceptionMessage No such entity with */ @@ -154,6 +216,8 @@ public function testGetCartThrowsExceptionIfThereIsNoCartWithProvidedId() } /** + * Tests carts search. + * * @magentoApiDataFixture Magento/Sales/_files/quote.php */ public function testGetList() @@ -184,6 +248,7 @@ public function testGetList() $this->searchCriteriaBuilder->addFilters([$grandTotalFilter, $subtotalFilter]); $this->searchCriteriaBuilder->addFilters([$minCreatedAtFilter]); $this->searchCriteriaBuilder->addFilters([$maxCreatedAtFilter]); + $this->searchCriteriaBuilder->addFilter('reserved_order_id', 'test01'); /** @var SortOrder $sortOrder */ $sortOrder = $this->sortOrderBuilder->setField('subtotal')->setDirection(SortOrder::SORT_ASC)->create(); $this->searchCriteriaBuilder->setSortOrders([$sortOrder]); From ffe156b4c79e2b91a61fcf622a2f106428098462 Mon Sep 17 00:00:00 2001 From: George Babarus Date: Sun, 22 Sep 2019 17:50:34 +0300 Subject: [PATCH 0553/1172] refactor deployment config reader, change inconsistent load method to constructor structure --- .../Framework/App/DeploymentConfig/Reader.php | 12 +++---- .../Test/Unit/DeploymentConfig/ReaderTest.php | 35 ++++++++----------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php b/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php index ff7077213c5c..9c5cd2fe1232 100644 --- a/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php +++ b/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php @@ -16,7 +16,6 @@ /** * Deployment configuration reader. * Loads the merged configuration from config files. - * * @see FileReader The reader for specific configuration file */ class Reader @@ -107,11 +106,9 @@ public function load($fileKey = null) } } } else { - $configFiles = $this->configFilePool->getPaths(); - $allFilesData = []; - $result = []; - foreach (array_keys($configFiles) as $fileKey) { - $configFile = $path . '/' . $this->configFilePool->getPath($fileKey); + $configFiles = $this->getFiles(); + foreach ($configFiles as $file) { + $configFile = $path . DIRECTORY_SEPARATOR . $file; if ($fileDriver->isExists($configFile)) { $fileData = include $configFile; if (!is_array($fileData)) { @@ -120,7 +117,6 @@ public function load($fileKey = null) } else { continue; } - $allFilesData[$configFile] = $fileData; if ($fileData) { $result = array_replace_recursive($result, $fileData); } @@ -136,6 +132,8 @@ public function load($fileKey = null) * @param string $pathConfig The path config * @param bool $ignoreInitialConfigFiles Whether ignore custom pools * @return array + * @throws FileSystemException + * @throws RuntimeException * @deprecated 100.2.0 Magento does not support custom config file pools since 2.2.0 version * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ diff --git a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfig/ReaderTest.php b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfig/ReaderTest.php index 8f8399263384..8a8bebb4d2f8 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfig/ReaderTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfig/ReaderTest.php @@ -43,17 +43,18 @@ protected function setUp() ->willReturn(__DIR__ . '/_files'); $this->fileDriver = $this->createMock(File::class); $this->fileDriver - ->expects($this->any()) ->method('isExists') - ->will($this->returnValueMap([ - [__DIR__ . '/_files/config.php', true], - [__DIR__ . '/_files/custom.php', true], - [__DIR__ . '/_files/duplicateConfig.php', true], - [__DIR__ . '/_files/env.php', true], - [__DIR__ . '/_files/mergeOne.php', true], - [__DIR__ . '/_files/mergeTwo.php', true], - [__DIR__ . '/_files/nonexistent.php', false] - ])); + ->willReturnMap( + [ + [__DIR__.'/_files/config.php', true], + [__DIR__.'/_files/custom.php', true], + [__DIR__.'/_files/duplicateConfig.php', true], + [__DIR__.'/_files/env.php', true], + [__DIR__.'/_files/mergeOne.php', true], + [__DIR__.'/_files/mergeTwo.php', true], + [__DIR__.'/_files/nonexistent.php', false] + ] + ); $this->driverPool = $this->createMock(DriverPool::class); $this->driverPool ->expects($this->any()) @@ -152,8 +153,9 @@ public function testLoadInvalidConfigurationFileWithFileKey() * @expectedException \Magento\Framework\Exception\RuntimeException * @expectedExceptionMessageRegExp /Invalid configuration file: \'.*\/\_files\/emptyConfig\.php\'/ * @return void + * @throws \Magento\Framework\Exception\FileSystemException */ - public function testLoadInvalidConfigurationFile() + public function testLoadInvalidConfigurationFile(): void { $fileDriver = $this->getMockBuilder(File::class) ->disableOriginalConstructor() @@ -173,7 +175,7 @@ public function testLoadInvalidConfigurationFile() $configFilePool = $this->getMockBuilder(ConfigFilePool::class) ->disableOriginalConstructor() ->getMock(); - $configFilePool->expects($this->exactly(2)) + $configFilePool->expects($this->once()) ->method('getPaths') ->willReturn( [ @@ -181,15 +183,6 @@ public function testLoadInvalidConfigurationFile() 'testConfig' => 'emptyConfig.php' ] ); - $configFilePool->expects($this->exactly(2)) - ->method('getPath') - ->withConsecutive( - [$this->identicalTo('configKeyOne')], - [$this->identicalTo('testConfig')] - )->willReturnOnConsecutiveCalls( - 'config.php', - 'emptyConfig.php' - ); $object = new Reader($this->dirList, $driverPool, $configFilePool); $object->load(); } From 6ac41538732dd5c7f748963361624555eeb76081 Mon Sep 17 00:00:00 2001 From: Andrey Legayev Date: Mon, 23 Sep 2019 12:02:35 +0300 Subject: [PATCH 0554/1172] Rollback removal of _parseModuleStatic() --- .../Magento/Framework/App/Utility/Files.php | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index 8c95ede7f2e5..a55010769ee3 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -1038,6 +1038,30 @@ protected function _accumulateFilesByPatterns(array $patterns, $filePattern, arr } } + /** + * Parse meta-info of a static file in module + * + * @deprecated Replaced with method _accumulateStaticFiles() + * + * @param string $file + * @return array + */ + protected function _parseModuleStatic($file) + { + foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { + if (preg_match( + '/^' . preg_quote("{$modulePath}/", '/') . 'view\/([a-z]+)\/web\/(.+)$/i', + $file, + $matches + ) === 1 + ) { + list(, $area, $filePath) = $matches; + return [$area, '', '', $moduleName, $filePath, $file]; + } + } + return []; + } + /** * Search static files from all modules by the specified pattern and accumulate meta-info * @@ -1046,7 +1070,7 @@ protected function _accumulateFilesByPatterns(array $patterns, $filePattern, arr * @param array $result * @return void */ - protected function _accumulateStaticFiles($area, $filePattern, array &$result) + private function _accumulateStaticFiles($area, $filePattern, array &$result) { foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { $moduleWebPath = $moduleDir . "/view/{$area}/web"; From 2b3319675ea917db6bae4e889bbb23d860baf964 Mon Sep 17 00:00:00 2001 From: Andrey Legayev Date: Mon, 23 Sep 2019 12:06:08 +0300 Subject: [PATCH 0555/1172] Keep original formatting in _parseModuleStatic() --- lib/internal/Magento/Framework/App/Utility/Files.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index a55010769ee3..c5f2053ec407 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -1050,10 +1050,10 @@ protected function _parseModuleStatic($file) { foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $modulePath) { if (preg_match( - '/^' . preg_quote("{$modulePath}/", '/') . 'view\/([a-z]+)\/web\/(.+)$/i', - $file, - $matches - ) === 1 + '/^' . preg_quote("{$modulePath}/", '/') . 'view\/([a-z]+)\/web\/(.+)$/i', + $file, + $matches + ) === 1 ) { list(, $area, $filePath) = $matches; return [$area, '', '', $moduleName, $filePath, $file]; From ada23e3d7896ef030b71f850389a994e9b695a4f Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina Date: Fri, 20 Sep 2019 16:03:30 +0300 Subject: [PATCH 0556/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MAGETWO-99376 --- .../Sales/Model/ResourceModel/OrderTest.php | 27 ++++++++++--------- .../Store/_files/store_with_long_name.php | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php index 9e102fab1d96..25f759e7b1b9 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/OrderTest.php @@ -10,7 +10,11 @@ use Magento\Store\Api\StoreRepositoryInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\Event\ManagerInterface; +use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollectionFactory; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class OrderTest extends \PHPUnit\Framework\TestCase { /** @@ -59,10 +63,10 @@ protected function tearDown() $registry->unregister('isSecureArea'); $registry->register('isSecureArea', true); - /** @var \Magento\Sales\Model\Order $order */ - $order = $this->objectManager->create(\Magento\Sales\Model\Order::class); - $order->loadByIncrementId($this->orderIncrementId); - $order->delete(); + $orderCollection = $this->objectManager->create(OrderCollectionFactory::class)->create(); + foreach ($orderCollection as $order) { + $order->delete(); + } $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); @@ -140,11 +144,11 @@ public function testSaveOrder() * Check that store name with length within 255 chars can be saved in table sales_order * * @magentoDataFixture Magento/Store/_files/store_with_long_name.php + * @magentoDbIsolation disabled * @return void */ public function testSaveStoreName() { - $storeName = str_repeat('a', 220); $store = $this->storeRepository->get('test_2'); $this->storeManager->setCurrentStore($store->getId()); $eventManager = $this->objectManager->get(ManagerInterface::class); @@ -154,13 +158,10 @@ public function testSaveStoreName() $payment->setMethod('checkmo'); $order->setStoreId($store->getId())->setPayment($payment); $this->resourceModel->save($order); - $this->resourceModel->load($order, $storeName, 'store_name'); - $name = [ - 'Main Website', - 'Main Website Store', - $storeName, - ]; - $expectedStoreName = implode(PHP_EOL, $name); - $this->assertEquals($expectedStoreName, $order->getStoreName()); + $orderRepository = $this->objectManager->create(\Magento\Sales\Api\OrderRepositoryInterface::class); + $order = $orderRepository->get($order->getId()); + $this->assertEquals(255, strlen($order->getStoreName())); + $this->assertContains($store->getWebsite()->getName(), $order->getStoreName()); + $this->assertContains($store->getGroup()->getName(), $order->getStoreName()); } } diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php index c225519e2b2b..f1beaee683b8 100644 --- a/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php +++ b/dev/tests/integration/testsuite/Magento/Store/_files/store_with_long_name.php @@ -7,7 +7,7 @@ /** @var $store \Magento\Store\Model\Store */ $store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Store\Model\Store::class); -$storeName = str_repeat('a', 220); +$storeName = str_repeat('a', 255); if (!$store->load('test', 'code')->getId()) { $store->setData( [ From 17fa6d9dad005ad38d69b1a1107f9bc220a77835 Mon Sep 17 00:00:00 2001 From: RomanKis Date: Mon, 23 Sep 2019 13:02:50 +0300 Subject: [PATCH 0557/1172] graphQl-914: [Customer] Improve consistency of country field in customer address --- .../Address/CreateCustomerAddress.php | 3 + .../Address/UpdateCustomerAddress.php | 3 + .../CustomerGraphQl/etc/schema.graphqls | 6 +- .../Customer/CreateCustomerAddressTest.php | 99 +++++++++++++++ .../Customer/UpdateCustomerAddressTest.php | 120 ++++++++++++++++++ 5 files changed, 229 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php index 388b6dc2ea94..474bd99a8f13 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php @@ -67,6 +67,9 @@ public function __construct( */ public function execute(int $customerId, array $data): AddressInterface { + if (isset($data['country_code'])) { + $data['country_id'] = $data['country_code']; + } $this->validateData($data); /** @var AddressInterface $address */ diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/UpdateCustomerAddress.php b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/UpdateCustomerAddress.php index 65745a20bc8e..26e53c7c3a0a 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/UpdateCustomerAddress.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/UpdateCustomerAddress.php @@ -66,6 +66,9 @@ public function __construct( */ public function execute(AddressInterface $address, array $data): void { + if (isset($data['country_code'])) { + $data['country_id'] = $data['country_code']; + } $this->validateData($data); $filteredData = array_diff_key($data, array_flip($this->restrictedKeys)); diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index d27debdc39c6..fa50ebeed09c 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -28,7 +28,8 @@ input CustomerAddressInput { city: String @doc(description: "The city or town") region: CustomerAddressRegionInput @doc(description: "An object containing the region name, region code, and region ID") postcode: String @doc(description: "The customer's ZIP or postal code") - country_id: CountryCodeEnum @doc(description: "The customer's country") + country_id: CountryCodeEnum @doc(description: "The customer's country") @deprecated(reason: "Use country_code instead.") + country_code: CountryCodeEnum @doc(description: "The customer's country") default_shipping: Boolean @doc(description: "Indicates whether the address is the default shipping address") default_billing: Boolean @doc(description: "Indicates whether the address is the default billing address") fax: String @doc(description: "The fax number") @@ -100,7 +101,8 @@ type CustomerAddress @doc(description: "CustomerAddress contains detailed inform customer_id: Int @doc(description: "The customer ID") region: CustomerAddressRegion @doc(description: "An object containing the region name, region code, and region ID") region_id: Int @doc(description: "A number that uniquely identifies the state, province, or other area") - country_id: String @doc(description: "The customer's country") + country_id: String @doc(description: "The customer's country") @deprecated(reason: "Use country_code instead.") + country_code: CountryCodeEnum @doc(description: "The customer's country") street: [String] @doc(description: "An array of strings that define the street number and name") company: String @doc(description: "The customer's company") telephone: String @doc(description: "The telephone number") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php index 203e9b5cb42e..a065ab3f26e7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php @@ -133,6 +133,105 @@ public function testCreateCustomerAddress() $this->assertCustomerAddressesFields($address, $newAddress); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer_without_addresses.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testCreateCustomerAddressWithCountryCode() + { + $customerId = 1; + $newAddress = [ + 'region' => [ + 'region' => 'Arizona', + 'region_id' => 4, + 'region_code' => 'AZ' + ], + 'country_code' => 'US', + 'street' => ['Line 1 Street', 'Line 2'], + 'company' => 'Company name', + 'telephone' => '123456789', + 'fax' => '123123123', + 'postcode' => '7777', + 'city' => 'City Name', + 'firstname' => 'Adam', + 'lastname' => 'Phillis', + 'middlename' => 'A', + 'prefix' => 'Mr.', + 'suffix' => 'Jr.', + 'vat_id' => '1', + 'default_shipping' => true, + 'default_billing' => false + ]; + + $mutation + = <<graphQlMutation($mutation, [], '', $this->getCustomerAuthHeaders($userName, $password)); + $this->assertArrayHasKey('createCustomerAddress', $response); + $this->assertArrayHasKey('customer_id', $response['createCustomerAddress']); + $this->assertEquals($customerId, $response['createCustomerAddress']['customer_id']); + $this->assertArrayHasKey('id', $response['createCustomerAddress']); + + $address = $this->addressRepository->getById($response['createCustomerAddress']['id']); + $this->assertEquals($address->getId(), $response['createCustomerAddress']['id']); + + $newAddress['country_id'] = $newAddress['country_code']; + unset($newAddress['country_code']); + $this->assertCustomerAddressesFields($address, $response['createCustomerAddress']); + $this->assertCustomerAddressesFields($address, $newAddress); + } + /** * @expectedException Exception * @expectedExceptionMessage The current customer isn't authorized. diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php index 9840236dc989..b83649061c33 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php @@ -77,6 +77,34 @@ public function testUpdateCustomerAddress() $this->assertCustomerAddressesFields($address, $updateAddress); } + /** + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/Customer/_files/customer_address.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testUpdateCustomerAddressWithCountryCode() + { + $userName = 'customer@example.com'; + $password = 'password'; + $customerId = 1; + $addressId = 1; + + $mutation = $this->getMutationWithCountryCode($addressId); + + $response = $this->graphQlMutation($mutation, [], '', $this->getCustomerAuthHeaders($userName, $password)); + $this->assertArrayHasKey('updateCustomerAddress', $response); + $this->assertArrayHasKey('customer_id', $response['updateCustomerAddress']); + $this->assertEquals($customerId, $response['updateCustomerAddress']['customer_id']); + $this->assertArrayHasKey('id', $response['updateCustomerAddress']); + + $address = $this->addressRepository->getById($addressId); + $this->assertEquals($address->getId(), $response['updateCustomerAddress']['id']); + $this->assertCustomerAddressesFields($address, $response['updateCustomerAddress']); + + $updateAddress = $this->getAddressDataCanadaCountry(); + $this->assertCustomerAddressesFields($address, $updateAddress); + } + /** * @expectedException Exception * @expectedExceptionMessage The current customer isn't authorized. @@ -405,6 +433,35 @@ private function getAddressData(): array ]; } + /** + * @return array + */ + private function getAddressDataCanadaCountry(): array + { + return [ + 'region' => [ + 'region' => 'Alberta', + 'region_id' => 66, + 'region_code' => 'AB' + ], + 'country_id' => 'CA', + 'street' => ['Line 1 Street', 'Line 2'], + 'company' => 'Company Name', + 'telephone' => '123456789', + 'fax' => '123123123', + 'postcode' => '7777', + 'city' => 'City Name', + 'firstname' => 'Adam', + 'lastname' => 'Phillis', + 'middlename' => 'A', + 'prefix' => 'Mr.', + 'suffix' => 'Jr.', + 'vat_id' => '1', + 'default_shipping' => true, + 'default_billing' => true + ]; + } + /** * @param int $addressId * @return string @@ -464,6 +521,69 @@ private function getMutation(int $addressId): string default_billing } } +MUTATION; + return $mutation; + } + + /** + * @param int $addressId + * @return string + */ + private function getMutationWithCountryCode(int $addressId): string + { + $updateAddress = $this->getAddressDataCanadaCountry(); + $defaultShippingText = $updateAddress['default_shipping'] ? "true" : "false"; + $defaultBillingText = $updateAddress['default_billing'] ? "true" : "false"; + + $mutation + = << Date: Mon, 23 Sep 2019 14:06:25 +0300 Subject: [PATCH 0558/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Model/Cart/SetBillingAddressOnCart.php | 4 ++ .../Model/Cart/SetShippingAddressesOnCart.php | 4 ++ .../Customer/SetBillingAddressOnCartTest.php | 49 ++++++++++++++++++ .../Customer/SetShippingAddressOnCartTest.php | 50 +++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php index 22dff2d5550b..e4457f274110 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php @@ -116,6 +116,10 @@ private function createBillingAddress( if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { $this->saveQuoteAddressToCustomerAddressBook->execute($billingAddress, $customerId); } + + if (0 === $customerId) { + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); + } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index ccb35e884061..fbb6d0e5a652 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -107,6 +107,10 @@ private function createShippingAddress( if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { $this->saveQuoteAddressToCustomerAddressBook->execute($shippingAddress, $customerId); } + + if (0 === $customerId) { + throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); + } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php index 40ec237c8b23..00188014f26e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php @@ -651,6 +651,55 @@ public function testSetNewBillingAddressWithRedundantStreetLine() $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetBillingAddressToGuestCartWithoutAddressId() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<expectExceptionMessage( + 'The current customer isn\'t authorized.' + ); + + $this->graphQlMutation($query, [], ''); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php index 95c8f4118adb..57d428822799 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php @@ -619,6 +619,56 @@ public function testSetShippingAddressToGuestCart() $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } + /** + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + */ + public function testSetShippingAddressToGuestCartWithoutAddressId() + { + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); + + $query = <<expectExceptionMessage( + 'The current customer isn\'t authorized.' + ); + + $this->graphQlMutation($query, [], ''); + } + /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php From 493d6f9cdf94beb40642c25e6cb6a4990365fc75 Mon Sep 17 00:00:00 2001 From: Viktor Sevch Date: Mon, 23 Sep 2019 14:25:41 +0300 Subject: [PATCH 0559/1172] MC-20069: Fix Skipped MFTF Tests From MC-17140: MAGETWO-72277, MAGETWO-84682, MAGETWO-94854 --- .../Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml index a123282bbcbc..273a39a31213 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminAddWidgetToWYSIWYGNewsletterTest.xml @@ -15,7 +15,7 @@ <description value="Admin should be able to add widget to WYSIWYG Editor Newsletter"/> <severity value="CRITICAL"/> - <testCaseId value="MAGETWO-84682"/> + <testCaseId value="MC-6070"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="login"/> From 6b47b8e9806ecb6d3df2dcfe63b6d7bfd299b1ca Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 23 Sep 2019 15:58:06 +0400 Subject: [PATCH 0560/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml | 1 - .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 2 -- .../Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml | 1 - .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 2 -- .../Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml | 1 - .../AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml | 2 -- 6 files changed, 9 deletions(-) diff --git a/app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml b/app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml index de603d281153..1256bb5443e0 100644 --- a/app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml +++ b/app/code/Magento/Dhl/Test/Mftf/Section/AdminShippingMethodDHLSection.xml @@ -11,7 +11,6 @@ <section name="AdminShippingMethodDHLSection"> <element name="carriersDHLTab" type="button" selector="#carriers_dhl-head"/> <element name="carriersDHLActive" type="input" selector="#carriers_dhl_active_inherit"/> - <element name="carriersDHLActiveRMA" type="select" selector="#carriers_dhl_active_rma"/> <element name="carriersDHLTitle" type="input" selector="#carriers_dhl_title_inherit"/> <element name="carriersDHLAccessId" type="input" selector="#carriers_dhl_id"/> <element name="carriersDHLPassword" type="input" selector="#carriers_dhl_password"/> diff --git a/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 6322847ec1aa..f5e1e8ef0c8e 100644 --- a/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Dhl/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -16,8 +16,6 @@ <waitForElementVisible selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" stepKey="waitDHLTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActive}}" userInput="disabled" stepKey="grabDHLActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveDisabled" stepKey="assertDHLActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLActiveRMA}}" userInput="disabled" stepKey="grabDHLActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabDHLActiveRMADisabled" stepKey="assertDHLActiveRMADisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLTitle}}" userInput="disabled" stepKey="grabDHLTitleDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabDHLTitleDisabled" stepKey="assertDHLTitleDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodDHLSection.carriersDHLAccessId}}" userInput="disabled" stepKey="grabDHLAccessIdDisabled"/> diff --git a/app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml b/app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml index 61902a96030b..0f75d475d6b1 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Section/AdminShippingMethodFedExSection.xml @@ -11,7 +11,6 @@ <section name="AdminShippingMethodFedExSection"> <element name="carriersFedExTab" type="button" selector="#carriers_fedex-head"/> <element name="carriersFedExActive" type="input" selector="#carriers_fedex_active_inherit"/> - <element name="carriersFedExActiveRMA" type="select" selector="#carriers_fedex_active_rma"/> <element name="carriersFedExTitle" type="input" selector="#carriers_fedex_title_inherit"/> <element name="carriersFedExAccountId" type="input" selector="#carriers_fedex_account"/> <element name="carriersFedExMeterNumber" type="input" selector="#carriers_fedex_meter_number"/> diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 42139f65d081..f599d7ca223a 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -16,8 +16,6 @@ <waitForElementVisible selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" stepKey="waitFedExTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActive}}" userInput="disabled" stepKey="grabFedExActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveDisabled" stepKey="assertFedExActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExActiveRMA}}" userInput="disabled" stepKey="grabFedExActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabFedExActiveRMADisabled" stepKey="assertFedExActiveRMADisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExTitle}}" userInput="disabled" stepKey="grabFedExTitleDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabFedExTitleDisabled" stepKey="assertFedExTitleDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodFedExSection.carriersFedExAccountId}}" userInput="disabled" stepKey="grabFedExAccountIdDisabled"/> diff --git a/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml b/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml index d68b6a77add6..f330695867e7 100644 --- a/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml +++ b/app/code/Magento/Ups/Test/Mftf/Section/AdminShippingMethodsUpsSection.xml @@ -13,7 +13,6 @@ <element name="carriersUpsType" type="select" selector="#carriers_ups_type"/> <element name="selectedUpsType" type="text" selector="#carriers_ups_type option[selected]"/> <element name="carriersUPSActive" type="input" selector="#carriers_ups_active_inherit"/> - <element name="carriersUPSActiveRMA" type="select" selector="#carriers_ups_active_rma"/> <element name="carriersUPSTypeSystem" type="input" selector="#carriers_ups_type_inherit"/> <element name="carriersUPSAccountLive" type="input" selector="#carriers_ups_is_account_live_inherit"/> <element name="carriersUPSGatewayXMLUrl" type="input" selector="#carriers_ups_gateway_xml_url_inherit"/> diff --git a/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml index 39272886d839..126586669afd 100644 --- a/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml +++ b/app/code/Magento/Ups/Test/Mftf/Test/AdminCheckInputFieldsDisabledAfterAppConfigDumpTest.xml @@ -16,8 +16,6 @@ <waitForElementVisible selector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" stepKey="waitUPSTabOpen"/> <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActive}}" userInput="disabled" stepKey="grabUPSActiveDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveDisabled" stepKey="assertUPSActiveDisabled"/> - <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSActiveRMA}}" userInput="disabled" stepKey="grabUPSActiveRMADisabled"/> - <assertEquals expected='true' expectedType="string" actual="$grabUPSActiveRMADisabled" stepKey="assertUPSActiveRMADisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSTypeSystem}}" userInput="disabled" stepKey="grabUPSTypeDisabled"/> <assertEquals expected='true' expectedType="string" actual="$grabUPSTypeDisabled" stepKey="assertUPSTypeDisabled"/> <grabAttributeFrom selector="{{AdminShippingMethodsUpsSection.carriersUPSAccountLive}}" userInput="disabled" stepKey="grabUPSAccountLiveDisabled"/> From 0ac490dff4b9d7dc6a1b0bac0f72708b9f961a2e Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 23 Sep 2019 16:14:13 +0400 Subject: [PATCH 0561/1172] MC-18823: Increase test coverage for Framework and Performance functional areas - Automation test for MC-11158 --- .../Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml b/app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml index c85883fcd887..9226c40e1316 100644 --- a/app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml +++ b/app/code/Magento/Usps/Test/Mftf/Section/AdminShippingMethodUSPSSection.xml @@ -11,7 +11,6 @@ <section name="AdminShippingMethodUSPSSection"> <element name="carriersUSPSTab" type="button" selector="#carriers_usps-head"/> <element name="carriersUSPSActive" type="input" selector="#carriers_usps_active_inherit"/> - <element name="carriersUSPSActiveRMA" type="select" selector="#carriers_usps_active_rma"/> <element name="carriersUSPSGatewayXMLUrl" type="input" selector="#carriers_usps_gateway_url_inherit"/> <element name="carriersUSPSGatewaySecureUrl" type="input" selector="#carriers_usps_gateway_secure_url_inherit"/> <element name="carriersUSPSTitle" type="input" selector="#carriers_usps_title_inherit"/> From e720b6864fb8b91cf99403c9b6bffe13d0d627bc Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Mon, 23 Sep 2019 16:31:24 +0300 Subject: [PATCH 0562/1172] magento/magento2#24686: Static Content Deploy - Optimize files scanning performance - Fix static test failures - Ignore using array_merge in loop for now --- .../Magento/Framework/App/Utility/Files.php | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index c5f2053ec407..10b14f749005 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -24,44 +24,20 @@ */ class Files { - /** - * Include app code - */ const INCLUDE_APP_CODE = 1; - /** - * Include tests - */ const INCLUDE_TESTS = 2; - /** - * Include dev tools - */ const INCLUDE_DEV_TOOLS = 4; - /** - * Include templates - */ const INCLUDE_TEMPLATES = 8; - /** - * Include lib files - */ const INCLUDE_LIBS = 16; - /** - * Include pub code - */ const INCLUDE_PUB_CODE = 32; - /** - * Include non classes - */ const INCLUDE_NON_CLASSES = 64; - /** - * Include setup - */ const INCLUDE_SETUP = 128; /** @@ -397,6 +373,7 @@ public function getMainConfigFiles($asDataSet = true) $configXmlPaths = array_merge($globPaths, $configXmlPaths); $files = []; foreach ($configXmlPaths as $xmlPath) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $files = array_merge($files, glob($xmlPath, GLOB_NOSORT)); } self::$_cache[$cacheKey] = $files; @@ -679,6 +656,7 @@ private function collectModuleLayoutFiles(array $params, $location) } } } else { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $files = array_merge($files, $moduleFiles); } } @@ -713,8 +691,10 @@ private function collectThemeLayoutFiles(array $params, $location) ); if ($params['with_metainfo']) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $files = array_merge($this->parseThemeFiles($themeFiles, $currentThemePath, $theme)); } else { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $files = array_merge($files, $themeFiles); } } From 1cc75d452dd58f4d7a551058bb4bff2d01f18d66 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Mon, 23 Sep 2019 16:37:11 +0300 Subject: [PATCH 0563/1172] magento/magento2#24686: Static Content Deploy - Optimize files scanning performance Fix one using array_merge in loop issue --- lib/internal/Magento/Framework/App/Utility/Files.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index 10b14f749005..65794e4f79da 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -371,12 +371,11 @@ public function getMainConfigFiles($asDataSet = true) } $globPaths = [BP . '/app/etc/config.xml', BP . '/app/etc/*/config.xml']; $configXmlPaths = array_merge($globPaths, $configXmlPaths); - $files = []; + $files = [[]]; foreach ($configXmlPaths as $xmlPath) { - // phpcs:ignore Magento2.Performance.ForeachArrayMerge - $files = array_merge($files, glob($xmlPath, GLOB_NOSORT)); + $files[] = glob($xmlPath, GLOB_NOSORT); } - self::$_cache[$cacheKey] = $files; + self::$_cache[$cacheKey] = array_merge(...$files); } if ($asDataSet) { return self::composeDataSets(self::$_cache[$cacheKey]); From 3e8b90c054e98671f48b29960b28a48eceb355d7 Mon Sep 17 00:00:00 2001 From: Ihor Sviziev <ihor-sviziev@users.noreply.github.com> Date: Mon, 23 Sep 2019 16:42:26 +0300 Subject: [PATCH 0564/1172] magento/magento2#24686: Static Content Deploy - Optimize files scanning performance Remove underscore from new method name --- lib/internal/Magento/Framework/App/Utility/Files.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php index 65794e4f79da..d329a7db029e 100644 --- a/lib/internal/Magento/Framework/App/Utility/Files.php +++ b/lib/internal/Magento/Framework/App/Utility/Files.php @@ -909,7 +909,7 @@ public function getStaticPreProcessingFiles($filePattern = '*') $moduleLocalePath[] = $moduleDir . "/view/{$area}/web/i18n/{$locale}"; } - $this->_accumulateStaticFiles($area, $filePattern, $result); + $this->accumulateStaticFiles($area, $filePattern, $result); $this->_accumulateFilesByPatterns($moduleLocalePath, $filePattern, $result, '_parseModuleLocaleStatic'); $this->accumulateThemeStaticFiles($area, $locale, $filePattern, $result); self::$_cache[$key] = $result; @@ -1020,7 +1020,7 @@ protected function _accumulateFilesByPatterns(array $patterns, $filePattern, arr /** * Parse meta-info of a static file in module * - * @deprecated Replaced with method _accumulateStaticFiles() + * @deprecated Replaced with method accumulateStaticFiles() * * @param string $file * @return array @@ -1049,7 +1049,7 @@ protected function _parseModuleStatic($file) * @param array $result * @return void */ - private function _accumulateStaticFiles($area, $filePattern, array &$result) + private function accumulateStaticFiles($area, $filePattern, array &$result) { foreach ($this->componentRegistrar->getPaths(ComponentRegistrar::MODULE) as $moduleName => $moduleDir) { $moduleWebPath = $moduleDir . "/view/{$area}/web"; From 2f3b81c333c32c9123262f702d5777ed1d7866f5 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 23 Sep 2019 11:02:05 -0500 Subject: [PATCH 0565/1172] MC-18403: Pricing :: Product pricing schema - adding functional tests --- .../GraphQl/Catalog/ProductPriceTest.php | 389 ++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php new file mode 100644 index 000000000000..393063be9d97 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php @@ -0,0 +1,389 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +class ProductPriceTest extends GraphQlAbstract +{ + + /** + * @magentoApiDataFixture Magento/Catalog/_files/products.php + */ + public function testProductWithSinglePrice() + { + $skus = ['simple']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 10 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 10 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ] + ]; + + $this->assertPrices($expectedPriceRange, $product['price_range']); + } + + /** + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable_12345.php + * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped_with_simple.php + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_duplicated.php + */ + public function testMultipleProductTypes() + { + $skus = ["simple-1", "12345", "grouped"]; + + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(3, $result['products']['items']); + + $expected = [ + "simple-1" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 10 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 10 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ] + ], + "12345" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 30 + ], + "final_price" => [ + "value" => 30 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 40 + ], + "final_price" => [ + "value" => 40 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ] + ], + "grouped" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 100 + ], + "final_price" => [ + "value" => 100 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 100 + ], + "final_price" => [ + "value" => 100 + ], + "discount" => [ + "amount_off" => 0, + "percent_off" => 0 + ] + ] + ] + ]; + + foreach ($result['products']['items'] as $product) { + $this->assertNotEmpty($product['price_range']); + $this->assertPrices($expected[$product['sku']], $product['price_range']); + } + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php + */ + public function testProductWithSpecialPrice() + { + $skus = ["simple1", "simple2"]; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(2, $result['products']['items']); + + $expected = [ + "simple1" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 5.99 + ], + "discount" => [ + "amount_off" => 4.01, + "percent_off" => 40.1 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 5.99 + ], + "discount" => [ + "amount_off" => 4.01, + "percent_off" => 40.1 + ] + ] + ], + "simple2" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 20 + ], + "final_price" => [ + "value" => 15.99 + ], + "discount" => [ + "amount_off" => 4.01, + "percent_off" => 20.05 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 20 + ], + "final_price" => [ + "value" => 15.99 + ], + "discount" => [ + "amount_off" => 4.01, + "percent_off" => 20.05 + ] + ] + ] + ]; + + foreach ($result['products']['items'] as $product) { + $this->assertNotEmpty($product['price_range']); + $this->assertPrices($expected[$product['sku']], $product['price_range']); + } + } + + /** + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php + * @magentoApiDataFixture Magento/CatalogRule/_files/catalog_rule_10_off_not_logged.php + */ + public function testProductWithCatalogDiscount() + { + $skus = ["virtual-product", "configurable"]; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(2, $result['products']['items']); + + $expected = [ + "virtual-product" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 9 + ], + "discount" => [ + "amount_off" => 1, + "percent_off" => 10 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 9 + ], + "discount" => [ + "amount_off" => 1, + "percent_off" => 10 + ] + ] + ], + "configurable" => [ + "minimum_price" => [ + "regular_price" => [ + "value" => 10 + ], + "final_price" => [ + "value" => 9 + ], + "discount" => [ + "amount_off" => 1, + "percent_off" => 10 + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => 20 + ], + "final_price" => [ + "value" => 18 + ], + "discount" => [ + "amount_off" => 2, + "percent_off" => 10 + ] + ] + ] + ]; + + foreach ($result['products']['items'] as $product) { + $this->assertNotEmpty($product['price_range']); + $this->assertPrices($expected[$product['sku']], $product['price_range']); + } + } + + /** + * Get GraphQl query to fetch products by sku + * + * @param array $skus + * @return string + */ + private function getProductQuery(array $skus): string + { + $stringSkus = '"' . implode('","', $skus) . '"'; + return <<<QUERY +{ + products(filter: {sku: {in: [$stringSkus]}}, sort: {name: ASC}) { + items { + name + sku + price_range { + minimum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + maximum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + } + } + } +} +QUERY; + } + + /** + * Check prices from graphql response + * + * @param $expectedPrices + * @param $actualPrices + * @param string $currency + */ + private function assertPrices($expectedPrices, $actualPrices, $currency = 'USD') + { + $priceTypes = ['minimum_price', 'maximum_price']; + + foreach ($priceTypes as $priceType) { + $expected = $expectedPrices[$priceType]; + $actual = $actualPrices[$priceType]; + $this->assertEquals($expected['regular_price']['value'], $actual['regular_price']['value']); + $this->assertEquals( + $expected['regular_price']['currency'] ?? $currency, + $actual['regular_price']['currency'] + ); + $this->assertEquals($expected['final_price']['value'], $actual['final_price']['value']); + $this->assertEquals( + $expected['final_price']['currency'] ?? $currency, + $actual['final_price']['currency'] + ); + $this->assertEquals($expected['discount']['amount_off'], $actual['discount']['amount_off']); + $this->assertEquals($expected['discount']['percent_off'], $actual['discount']['percent_off']); + } + } +} From 2d86f3971dab3ddce51a65060417a378f4904ef6 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Mon, 23 Sep 2019 11:45:19 -0500 Subject: [PATCH 0566/1172] MC-17518: Cart Rest API not showing all shipping assignments for multi-shipping --- .../Test/Unit/Controller/Checkout/PluginTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php index bbcd6d85c501..5397317ca299 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php @@ -59,7 +59,10 @@ protected function setUp() public function testExecuteTurnsOffMultishippingModeOnMultishippingQuote(): void { $subject = $this->createMock(Index::class); - $extensionAttributes = $this->createMock(CartExtensionInterface::class); + $extensionAttributes = $this->createPartialMock( + CartExtensionInterface::class, + ['setShippingAssignments', 'getShippingAssignments'] + ); $extensionAttributes->method('getShippingAssignments') ->willReturn( $this->createMock(ShippingAssignmentInterface::class) From b2a4ec972baac842250471320d28d3cc1823f227 Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Fri, 20 Sep 2019 17:40:55 -0500 Subject: [PATCH 0567/1172] MC-20225: Low performance in getting configurable product attribute options functionality - Fix performance issue related to AbstractAttribute::getOptions due to the expansive cost of the function AbstractAttribute::convertToObjects - Fix performance issue related to loading options multiple times --- .../DataProvider/Product/Form/Modifier/Eav.php | 5 +++++ .../Edit/Tab/Variations/Config/Matrix.php | 12 +++++++----- .../Form/Modifier/Data/AssociatedProducts.php | 17 +++++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 5d1e853cef3d..4039ff862f6f 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -46,6 +46,7 @@ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @since 101.0.0 */ class Eav extends AbstractModifier @@ -1048,6 +1049,10 @@ private function isScopeGlobal($attribute) */ private function getAttributeModel($attribute) { + // The statement below solves performance issue related to loading same attribute options on different models + if ($attribute instanceof EavAttribute) { + return $attribute; + } $attributeId = $attribute->getAttributeId(); if (!array_key_exists($attributeId, $this->attributesCache)) { diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php index 4874dc8ea03a..11384263b59a 100644 --- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php +++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config/Matrix.php @@ -197,6 +197,7 @@ protected function getAttributes() foreach ($attributes as $key => $attribute) { if (isset($configurableData[$key])) { $attributes[$key] = array_replace_recursive($attribute, $configurableData[$key]); + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $attributes[$key]['values'] = array_merge( isset($attribute['values']) ? $attribute['values'] : [], isset($configurableData[$key]['values']) @@ -412,14 +413,15 @@ private function prepareAttributes( 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], ]; - foreach ($attribute->getOptions() as $option) { - if (!empty($option->getValue())) { + $options = $attribute->usesSource() ? $attribute->getSource()->getAllOptions() : []; + foreach ($options as $option) { + if (!empty($option['value'])) { $attributes[$attribute->getAttributeId()]['options'][] = [ 'attribute_code' => $attribute->getAttributeCode(), 'attribute_label' => $attribute->getStoreLabel(0), - 'id' => $option->getValue(), - 'label' => $option->getLabel(), - 'value' => $option->getValue(), + 'id' => $option['value'], + 'label' => $option['label'], + 'value' => $option['value'], '__disableTmpl' => true, ]; } diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php index c474acbec509..4bde97fa8022 100644 --- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php +++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php @@ -21,6 +21,8 @@ use Magento\Framework\Escaper; /** + * Associated products helper + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AssociatedProducts @@ -231,6 +233,8 @@ public function getConfigurableAttributesData() * * @return void * @throws \Zend_Currency_Exception + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * phpcs:disable Generic.Metrics.NestingLevel */ protected function prepareVariations() { @@ -262,14 +266,15 @@ protected function prepareVariations() 'position' => $configurableAttributes[$attribute->getAttributeId()]['position'], 'chosen' => [], ]; - foreach ($attribute->getOptions() as $option) { - if (!empty($option->getValue())) { - $attributes[$attribute->getAttributeId()]['options'][$option->getValue()] = [ + $options = $attribute->usesSource() ? $attribute->getSource()->getAllOptions() : []; + foreach ($options as $option) { + if (!empty($option['value'])) { + $attributes[$attribute->getAttributeId()]['options'][$option['value']] = [ 'attribute_code' => $attribute->getAttributeCode(), 'attribute_label' => $attribute->getStoreLabel(0), - 'id' => $option->getValue(), - 'label' => $option->getLabel(), - 'value' => $option->getValue(), + 'id' => $option['value'], + 'label' => $option['label'], + 'value' => $option['value'], ]; } } From f1a187eba85b2eaeca4c619c1482ca8916fdb284 Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 12 Jan 2018 16:42:22 +0200 Subject: [PATCH 0568/1172] magento/magento2#13126: 2.2.2 - Duplicating Bundle Product Removes Bundle Options From Original Product (cherry picked from commit b57eb03b2f6491d271221d08b185e2ff37bfcd4c) --- .../Model/Product/CopyConstructor/Bundle.php | 11 +- .../Product/CopyConstructor/BundleTest.php | 38 ++- .../Controller/Adminhtml/ProductTest.php | 235 ++++++++++++++++++ 3 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php diff --git a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php index 61559df4d2cf..221a7431714d 100644 --- a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php +++ b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php @@ -27,7 +27,16 @@ public function build(Product $product, Product $duplicate) $bundleOptions = $product->getExtensionAttributes()->getBundleProductOptions() ?: []; $duplicatedBundleOptions = []; foreach ($bundleOptions as $key => $bundleOption) { - $duplicatedBundleOptions[$key] = clone $bundleOption; + $duplicatedBundleOption = clone $bundleOption; + /** + * Set option and selection ids to 'null' in order to create new option(selection) for duplicated product, + * but not modifying existing one, which led to lost of option(selection) in original product. + */ + foreach ($duplicatedBundleOption->getProductLinks() as $productLink) { + $productLink->setSelectionId(null); + } + $duplicatedBundleOption->setOptionId(null); + $duplicatedBundleOptions[$key] = $duplicatedBundleOption; } $duplicate->getExtensionAttributes()->setBundleProductOptions($duplicatedBundleOptions); } diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/CopyConstructor/BundleTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/CopyConstructor/BundleTest.php index 831098cc44c3..4df60d07d98e 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/Product/CopyConstructor/BundleTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/CopyConstructor/BundleTest.php @@ -6,6 +6,7 @@ namespace Magento\Bundle\Test\Unit\Model\Product\CopyConstructor; use Magento\Bundle\Api\Data\BundleOptionInterface; +use Magento\Bundle\Model\Link; use Magento\Bundle\Model\Product\CopyConstructor\Bundle; use Magento\Catalog\Api\Data\ProductExtensionInterface; use Magento\Catalog\Model\Product; @@ -45,6 +46,7 @@ public function testBuildNegative() */ public function testBuildPositive() { + /** @var Product|\PHPUnit_Framework_MockObject_MockObject $product */ $product = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->getMock(); @@ -60,18 +62,42 @@ public function testBuildPositive() ->method('getExtensionAttributes') ->willReturn($extensionAttributesProduct); + $productLink = $this->getMockBuilder(Link::class) + ->setMethods(['setSelectionId']) + ->disableOriginalConstructor() + ->getMock(); + $productLink->expects($this->exactly(2)) + ->method('setSelectionId') + ->with($this->identicalTo(null)); + $firstOption = $this->getMockBuilder(BundleOptionInterface::class) + ->setMethods(['getProductLinks']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $firstOption->expects($this->once()) + ->method('getProductLinks') + ->willReturn([$productLink]); + $firstOption->expects($this->once()) + ->method('setOptionId') + ->with($this->identicalTo(null)); + $secondOption = $this->getMockBuilder(BundleOptionInterface::class) + ->setMethods(['getProductLinks']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $secondOption->expects($this->once()) + ->method('getProductLinks') + ->willReturn([$productLink]); + $secondOption->expects($this->once()) + ->method('setOptionId') + ->with($this->identicalTo(null)); $bundleOptions = [ - $this->getMockBuilder(BundleOptionInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass(), - $this->getMockBuilder(BundleOptionInterface::class) - ->disableOriginalConstructor() - ->getMockForAbstractClass() + $firstOption, + $secondOption ]; $extensionAttributesProduct->expects($this->once()) ->method('getBundleProductOptions') ->willReturn($bundleOptions); + /** @var Product|\PHPUnit_Framework_MockObject_MockObject $duplicate */ $duplicate = $this->getMockBuilder(Product::class) ->disableOriginalConstructor() ->getMock(); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php new file mode 100644 index 000000000000..f48f2019dd52 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php @@ -0,0 +1,235 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Bundle\Controller\Adminhtml; + +use Magento\Bundle\Api\Data\OptionInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Type; +use Magento\Framework\Data\Form\FormKey; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\AbstractBackendController; + +/** + * Provide tests for product admin controllers. + * @magentoAppArea adminhtml + */ +class ProductTest extends AbstractBackendController +{ + /** + * Test bundle product duplicate won't remove bundle options from original product. + * + * @magentoDataFixture Magento/Catalog/_files/products_new.php + * @return void + */ + public function testDuplicateProduct() + { + $params = $this->getRequestParamsForDuplicate(); + $this->getRequest()->setParams(['type' => Type::TYPE_BUNDLE]); + $this->getRequest()->setPostValue($params); + $this->dispatch('backend/catalog/product/save'); + $this->assertSessionMessages( + $this->equalTo( + [ + 'You saved the product.', + 'You duplicated the product.', + ] + ), + MessageInterface::TYPE_SUCCESS + ); + $this->assertOptions(); + } + + /** + * Get necessary request post params for creating and duplicating bundle product. + * + * @return array + */ + private function getRequestParamsForDuplicate() + { + $product = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class)->get('simple'); + return [ + 'product' => + [ + 'attribute_set_id' => '4', + 'gift_message_available' => '0', + 'use_config_gift_message_available' => '1', + 'stock_data' => + [ + 'min_qty_allowed_in_shopping_cart' => + [ + [ + 'record_id' => '0', + 'customer_group_id' => '32000', + 'min_sale_qty' => '', + ], + ], + 'min_qty' => '0', + 'max_sale_qty' => '10000', + 'notify_stock_qty' => '1', + 'min_sale_qty' => '1', + 'qty_increments' => '1', + 'use_config_manage_stock' => '1', + 'manage_stock' => '1', + 'use_config_min_qty' => '1', + 'use_config_max_sale_qty' => '1', + 'use_config_backorders' => '1', + 'backorders' => '0', + 'use_config_notify_stock_qty' => '1', + 'use_config_enable_qty_inc' => '1', + 'enable_qty_increments' => '0', + 'use_config_qty_increments' => '1', + 'use_config_min_sale_qty' => '1', + 'is_qty_decimal' => '0', + 'is_decimal_divided' => '0', + ], + 'status' => '1', + 'affect_product_custom_options' => '1', + 'name' => 'b1', + 'price' => '', + 'weight' => '', + 'url_key' => '', + 'special_price' => '', + 'quantity_and_stock_status' => + [ + 'qty' => '', + 'is_in_stock' => '1', + ], + 'sku_type' => '0', + 'price_type' => '0', + 'weight_type' => '0', + 'website_ids' => + [ + 1 => '1', + ], + 'sku' => 'b1', + 'meta_title' => 'b1', + 'meta_keyword' => 'b1', + 'meta_description' => 'b1 ', + 'tax_class_id' => '2', + 'product_has_weight' => '1', + 'visibility' => '4', + 'country_of_manufacture' => '', + 'page_layout' => '', + 'options_container' => 'container2', + 'custom_design' => '', + 'custom_layout' => '', + 'price_view' => '0', + 'shipment_type' => '0', + 'news_from_date' => '', + 'news_to_date' => '', + 'custom_design_from' => '', + 'custom_design_to' => '', + 'special_from_date' => '', + 'special_to_date' => '', + 'description' => '', + 'short_description' => '', + 'custom_layout_update' => '', + 'image' => '', + 'small_image' => '', + 'thumbnail' => '', + ], + 'bundle_options' => + [ + 'bundle_options' => + [ + [ + 'record_id' => '0', + 'type' => 'select', + 'required' => '1', + 'title' => 'test option title', + 'position' => '1', + 'option_id' => '', + 'delete' => '', + 'bundle_selections' => + [ + [ + 'product_id' => $product->getId(), + 'name' => $product->getName(), + 'sku' => $product->getSku(), + 'price' => $product->getPrice(), + 'delete' => '', + 'selection_can_change_qty' => '', + 'selection_id' => '', + 'selection_price_type' => '0', + 'selection_price_value' => '', + 'selection_qty' => '1', + 'position' => '1', + 'option_id' => '', + 'record_id' => '1', + 'is_default' => '0', + ], + ], + 'bundle_button_proxy' => + [ + [ + 'entity_id' => '1', + ], + ], + ], + ], + ], + 'affect_bundle_product_selections' => '1', + 'back' => 'duplicate', + 'form_key' => Bootstrap::getObjectManager()->get(FormKey::class)->getFormKey(), + ]; + } + + /** + * Check options in created and duplicated products. + * + * @return void + */ + private function assertOptions() + { + $createdOptions = $this->getProductOptions('b1'); + $createdOption = array_shift($createdOptions); + $duplicatedOptions = $this->getProductOptions('b1-1'); + $duplicatedOption = array_shift($duplicatedOptions); + $this->assertNotEmpty($createdOption); + $this->assertNotEmpty($duplicatedOption); + $optionFields = ['type', 'title', 'position', 'required', 'default_title']; + foreach ($optionFields as $field) { + $this->assertSame($createdOption->getData($field), $duplicatedOption->getData($field)); + } + $createdLinks = $createdOption->getProductLinks(); + $createdLink = array_shift($createdLinks); + $duplicatedLinks = $duplicatedOption->getProductLinks(); + $duplicatedLink = array_shift($duplicatedLinks); + $this->assertNotEmpty($createdLink); + $this->assertNotEmpty($duplicatedLink); + $linkFields = [ + 'entity_id', + 'sku', + 'position', + 'is_default', + 'price', + 'qty', + 'selection_can_change_quantity', + 'price_type', + ]; + foreach ($linkFields as $field) { + $this->assertSame($createdLink->getData($field), $duplicatedLink->getData($field)); + } + } + + /** + * Get options for given product. + * + * @param string $sku + * @return OptionInterface[] + */ + private function getProductOptions(string $sku) + { + $product = Bootstrap::getObjectManager()->create(Product::class); + $productId = $product->getResource()->getIdBySku($sku); + $product->load($productId); + + return $product->getExtensionAttributes()->getBundleProductOptions(); + } +} From bf36defe362496ecb6f6b7693600a9054fbd801b Mon Sep 17 00:00:00 2001 From: nmalevanec <mikola.malevanec@transoftgroup.com> Date: Fri, 12 Jan 2018 16:48:44 +0200 Subject: [PATCH 0569/1172] magento/magento2#13126: 2.2.2 - Duplicating Bundle Product Removes Bundle Options From Original Product (cherry picked from commit d8bd657c94175392eca5ad462932bc2e86c51257) --- .../Magento/Bundle/Model/Product/CopyConstructor/Bundle.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php index 221a7431714d..20e4828835d0 100644 --- a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php +++ b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php @@ -32,7 +32,8 @@ public function build(Product $product, Product $duplicate) * Set option and selection ids to 'null' in order to create new option(selection) for duplicated product, * but not modifying existing one, which led to lost of option(selection) in original product. */ - foreach ($duplicatedBundleOption->getProductLinks() as $productLink) { + $productLinks = $duplicatedBundleOption->getProductLinks() ?: []; + foreach ($productLinks as $productLink) { $productLink->setSelectionId(null); } $duplicatedBundleOption->setOptionId(null); From 851d9c5d076926c71ba32d2bdac9be2f848fd9da Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Mon, 23 Sep 2019 14:02:28 -0500 Subject: [PATCH 0570/1172] MC-18403: Pricing :: Product pricing schema --- .../Model/Resolver/Product/Price/Provider.php | 60 +++++++++++++++ app/code/Magento/BundleGraphQl/etc/di.xml | 8 ++ .../Model/Resolver/Product/Price/Provider.php | 74 +++---------------- .../Model/Resolver/Product/PriceRange.php | 4 +- .../Model/Resolver/Product/Price/Provider.php | 50 +++---------- .../Model/Resolver/Product/Price/Provider.php | 43 +---------- 6 files changed, 91 insertions(+), 148 deletions(-) create mode 100644 app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php new file mode 100644 index 000000000000..b6515c98c078 --- /dev/null +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php @@ -0,0 +1,60 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\BundleGraphQl\Model\Resolver\Product\Price; + +use Magento\Bundle\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; +use Magento\Framework\Pricing\Amount\AmountInterface; +use Magento\Framework\Pricing\SaleableInterface; + +/** + * Provides pricing information for Bundle products + */ +class Provider implements ProviderInterface +{ + /** + * @inheritdoc + */ + public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface + { + return $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getMinimalPrice(); + } + + /** + * @inheritdoc + */ + public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface + { + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getMinimalPrice(); + } + + /** + * @inheritdoc + */ + public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface + { + return $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getMaximalPrice(); + } + + /** + * @inheritdoc + */ + public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface + { + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getMaximalPrice(); + } + + /** + * @inheritdoc + */ + public function getRegularPrice(SaleableInterface $product): AmountInterface + { + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + } +} diff --git a/app/code/Magento/BundleGraphQl/etc/di.xml b/app/code/Magento/BundleGraphQl/etc/di.xml index 4f41f3cb8dc8..edcaa34b527f 100644 --- a/app/code/Magento/BundleGraphQl/etc/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/di.xml @@ -16,4 +16,12 @@ </argument> </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> + <arguments> + <argument name="priceProviders" xsi:type="array"> + <item name="bundle" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php index a3a3cbb46417..67dbcf861170 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Provider.php @@ -10,8 +10,6 @@ use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\Framework\Pricing\Amount\AmountInterface; -use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; -use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\Pricing\SaleableInterface; /** @@ -20,44 +18,17 @@ class Provider implements ProviderInterface { /** - * PriceInfo cache - * - * @var array - */ - private $productPrices = []; - - /** - * @var PriceInfoFactory - */ - private $priceInfoFactory; - - /** - * @param PriceInfoFactory $priceInfoFactory - */ - public function __construct( - PriceInfoFactory $priceInfoFactory - ) { - $this->priceInfoFactory = $priceInfoFactory; - } - - /** - * Get the product minimal final price - * - * @param SaleableInterface $product - * @return AmountInterface + * @inheritdoc */ public function getMinimalFinalPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); + /** @var FinalPrice $finalPrice */ + $finalPrice = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE); return $finalPrice->getMinimalPrice(); } /** - * Get the product minimal regular price - * - * @param SaleableInterface $product - * @return AmountInterface + * @inheritdoc */ public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface { @@ -65,23 +36,17 @@ public function getMinimalRegularPrice(SaleableInterface $product): AmountInterf } /** - * Get the product maximum final price - * - * @param SaleableInterface $product - * @return AmountInterface + * @inheritdoc */ public function getMaximalFinalPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - $finalPrice = $priceInfo->getPrice(FinalPrice::PRICE_CODE); + /** @var FinalPrice $finalPrice */ + $finalPrice = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE); return $finalPrice->getMaximalPrice(); } /** - * Get the product maximum final price - * - * @param SaleableInterface $product - * @return AmountInterface + * @inheritdoc */ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface { @@ -89,29 +54,10 @@ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterf } /** - * Get the product regular price - * - * @param SaleableInterface $product - * @return AmountInterface + * @inheritdoc */ public function getRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); - } - - /** - * Get price info for product - * - * @param SaleableInterface $product - * @return PriceInfoInterface - */ - private function getProductPriceInfo($product) - { - if (!isset($this->productPrices[$product->getId()])) { - $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); - } - - return $this->productPrices[$product->getId()]; + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getAmount(); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index bfa932c51a91..a80f6be289e0 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -134,6 +134,4 @@ private function getPriceProvider(SaleableInterface $product): ProviderInterface } return $this->priceProviders['default']; } - - -} \ No newline at end of file +} diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php index 986247e5759a..4dfa09d77cec 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -9,9 +9,8 @@ use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\ConfigurableProduct\Pricing\Price\ConfigurableRegularPrice; use Magento\Framework\Pricing\Amount\AmountInterface; -use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; -use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\Pricing\SaleableInterface; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; use Magento\ConfigurableProduct\Pricing\Price\ConfigurableOptionsProviderInterface; @@ -21,18 +20,6 @@ */ class Provider implements ProviderInterface { - /** - * PriceInfo cache - * - * @var array - */ - private $productPrices = []; - - /** - * @var PriceInfoFactory - */ - private $priceInfoFactory; - /** * @var ConfigurableOptionsProviderInterface */ @@ -49,14 +36,11 @@ class Provider implements ProviderInterface private $maximumFinalAmounts = []; /** - * @param PriceInfoFactory $priceInfoFactory * @param ConfigurableOptionsProviderInterface $optionsProvider */ public function __construct( - PriceInfoFactory $priceInfoFactory, ConfigurableOptionsProviderInterface $optionsProvider ) { - $this->priceInfoFactory = $priceInfoFactory; $this->optionsProvider = $optionsProvider; } @@ -68,7 +52,7 @@ public function getMinimalFinalPrice(SaleableInterface $product): AmountInterfac if (!isset($this->minimumFinalAmounts[$product->getId()])) { $minimumAmount = null; foreach ($this->optionsProvider->getProducts($product) as $variant) { - $variantAmount = $this->getProductPriceInfo($variant)->getPrice(FinalPrice::PRICE_CODE)->getAmount(); + $variantAmount = $variant->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getAmount(); if (!$minimumAmount || ($variantAmount->getValue() < $minimumAmount->getValue())) { $minimumAmount = $variantAmount; $this->minimumFinalAmounts[$product->getId()] = $variantAmount; @@ -84,8 +68,9 @@ public function getMinimalFinalPrice(SaleableInterface $product): AmountInterfac */ public function getMinimalRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getMinRegularAmount(); + /** @var ConfigurableRegularPrice $regularPrice */ + $regularPrice = $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE); + return $regularPrice->getMinRegularAmount(); } /** @@ -96,7 +81,7 @@ public function getMaximalFinalPrice(SaleableInterface $product): AmountInterfac if (!isset($this->maximumFinalAmounts[$product->getId()])) { $maximumAmount = null; foreach ($this->optionsProvider->getProducts($product) as $variant) { - $variantAmount = $this->getProductPriceInfo($variant)->getPrice(FinalPrice::PRICE_CODE)->getAmount(); + $variantAmount = $variant->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getAmount(); if (!$maximumAmount || ($variantAmount->getValue() > $maximumAmount->getValue())) { $maximumAmount = $variantAmount; $this->maximumFinalAmounts[$product->getId()] = $variantAmount; @@ -112,8 +97,9 @@ public function getMaximalFinalPrice(SaleableInterface $product): AmountInterfac */ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getMaxRegularAmount(); + /** @var ConfigurableRegularPrice $regularPrice */ + $regularPrice = $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE); + return $regularPrice->getMaxRegularAmount(); } /** @@ -121,22 +107,6 @@ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterf */ public function getRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); - } - - /** - * Get price info for product - * - * @param SaleableInterface $product - * @return PriceInfoInterface - */ - private function getProductPriceInfo($product) - { - if (!isset($this->productPrices[$product->getId()])) { - $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); - } - - return $this->productPrices[$product->getId()]; + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getAmount(); } } diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php index b8c0d03250de..a876824d99fe 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -10,8 +10,6 @@ use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\Framework\Pricing\Amount\AmountInterface; -use Magento\Framework\Pricing\PriceInfo\Factory as PriceInfoFactory; -use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\Pricing\SaleableInterface; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; @@ -20,18 +18,6 @@ */ class Provider implements ProviderInterface { - /** - * PriceInfo cache - * - * @var array - */ - private $productPrices = []; - - /** - * @var PriceInfoFactory - */ - private $priceInfoFactory; - /** * Cache product prices so only fetch once * @@ -39,15 +25,6 @@ class Provider implements ProviderInterface */ private $minimalProductAmounts; - /** - * @param PriceInfoFactory $priceInfoFactory - */ - public function __construct( - PriceInfoFactory $priceInfoFactory - ) { - $this->priceInfoFactory = $priceInfoFactory; - } - /** * @inheritdoc */ @@ -87,8 +64,7 @@ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterf */ public function getRegularPrice(SaleableInterface $product): AmountInterface { - $priceInfo = $this->getProductPriceInfo($product); - return $priceInfo->getPrice(RegularPrice::PRICE_CODE)->getAmount(); + return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getAmount(); } /** @@ -104,7 +80,7 @@ private function getMinimalProductAmount(SaleableInterface $product, string $pri $products = $product->getTypeInstance()->getAssociatedProducts($product); $minPrice = null; foreach ($products as $item) { - $price = $this->getProductPriceInfo($item)->getPrice($priceType); + $price = $item->getPriceInfo()->getPrice($priceType); $priceValue = $price->getValue(); if (($priceValue !== false) && ($priceValue <= ($minPrice === null ? $priceValue : $minPrice))) { $minPrice = $price->getValue(); @@ -115,19 +91,4 @@ private function getMinimalProductAmount(SaleableInterface $product, string $pri return $this->minimalProductAmounts[$product->getId()][$priceType]; } - - /** - * Get price info for product - * - * @param SaleableInterface $product - * @return PriceInfoInterface - */ - private function getProductPriceInfo($product) - { - if (!isset($this->productPrices[$product->getId()])) { - $this->productPrices[$product->getId()] = $this->priceInfoFactory->create($product); - } - - return $this->productPrices[$product->getId()]; - } } From 3150b0ef3326a3a4f8fe156ca998f698966787c3 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Mon, 23 Sep 2019 14:48:35 -0500 Subject: [PATCH 0571/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality --- .../Catalog/Test/Mftf/Data/ProductData.xml | 14 +++++++++++ ...ateProductAttributeFromProductPageTest.xml | 3 +++ ...ateProductAttributesStoreViewScopeTest.xml | 24 ++++++++++++------- ...sUpdateProductStatusStoreViewScopeTest.xml | 19 +++++++++++---- .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 5 ++++ .../StorefrontProductNameWithDoubleQuote.xml | 4 ++-- .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 4 ++-- 7 files changed, 55 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index e122615eb8aa..8d7b9713f9b6 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -438,6 +438,20 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiProductNameWithNoSpaces" type="product"> + <data key="sku" unique="suffix">api-simple-product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">ApiSimpleProduct</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-simple-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="_newDefaultProduct" type="product"> <data key="sku" unique="suffix">testSku</data> <data key="type_id">simple</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml index 5c798db29b97..63a964f4b5e9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml @@ -90,6 +90,9 @@ <waitForPageLoad stepKey="waitForProductToSave"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> + <!--Run Re-Index task --> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Verify product attribute added in product form --> <scrollTo selector="{{AdminProductFormSection.contentTab}}" stepKey="scrollToContentTab"/> <waitForElementVisible selector="{{AdminProductFormSection.attributeTab}}" stepKey="waitForAttributeToVisible"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml index bee13bec370d..f16296f99cb2 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml @@ -24,10 +24,12 @@ <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> <createData entity="ApiProductWithDescription" stepKey="createProductTwo"/> + <createData entity="ApiProductNameWithNoSpaces" stepKey="createProductThree"/> </before> <after> <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> <deleteData createDataKey="createProductTwo" stepKey="deleteProductTwo"/> + <deleteData createDataKey="createProductThree" stepKey="deleteProductThree"/> <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="AdminDeleteStoreViewActionGroup"/> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> </after> @@ -54,22 +56,17 @@ <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpateSuccessMsg"/> - <!-- Run cron twice --> - <magentoCLI command="cron:run" stepKey="runCron1"/> - <magentoCLI command="cron:run" stepKey="runCron2"/> - <reloadPage stepKey="refreshPage"/> - <waitForPageLoad stepKey="waitFormToReload1"/> - <!-- Assert on storefront default view --> + <!-- Assert on storefront default view with partial word of product name --> <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> <argument name="name" value="$$createProductOne.name$$"/> <argument name="description" value="$$createProductOne.custom_attributes[description]$$"/> </actionGroup> <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + <see userInput="2 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> - <!-- Assert on storefront custom view --> + <!-- Assert on storefront custom view with partial word of product name --> <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupCustom"/> <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="StorefrontSwitchStoreViewActionGroup"/> <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameCustom"> @@ -77,6 +74,15 @@ <argument name="description" value="Updated $$createProductOne.custom_attributes[description]$$"/> </actionGroup> <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultCustom"/> - <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInCustom"/> + <see userInput="2 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInCustom"/> + + <!-- Assert Storefront default view with exact product name --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault1"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault1"> + <argument name="name" value="$$createProductThree.name$$"/> + <argument name="description" value="$$createProductThree.custom_attributes[description]$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault1"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault1"/> </test> </tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml index e9b54e3f1a3d..9eec6d000948 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -117,16 +117,25 @@ <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct1IsEnabled"/> <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct2IsEnabled"/> - <!-- Assert on storefront default view --> + <!-- Assert on storefront default view with first product --> <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> - <argument name="name" value="{{simpleProductForMassUpdate.keyword}}"/> + <argument name="name" value="{{simpleProductForMassUpdate.name}}"/> <argument name="description" value=""/> </actionGroup> <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> - <see userInput="2 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + + <!-- Assert on storefront default view with second product --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefaultToSearchSecondProduct"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefaultWithSecondProduct"> + <argument name="name" value="{{simpleProductForMassUpdate2.name}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefaultForSecondProduct"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefaultSecondProductResults"/> - <!-- Enable the product in Default store view --> + <!--Enable the product in Default store view--> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex2"/> <waitForPageLoad stepKey="waitForProductIndexPageLoad2"/> <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('1')}}" stepKey="clickCheckboxDefaultStoreView"/> @@ -148,4 +157,4 @@ <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault2"/> <see userInput="We can't find any items matching these search criteria." selector="{{StorefrontCatalogSearchAdvancedResultMainSection.message}}" stepKey="seeInDefault2"/> </test> -</tests> +</tests> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 7c0de6da18ca..495b8f2d4036 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -56,6 +56,9 @@ <deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/> </after> + <!--Re-index--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!-- Step 1: User browses catalog --> <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog" /> <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnHomePage"/> @@ -191,6 +194,8 @@ <!-- Clear comparison sidebar --> <comment userInput="Clear comparison sidebar" stepKey="commentClearComparisonSidebar" after="compareAssertSimpleProduct2ImageNotDefaultInComparison"/> <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="compareClickCategoryBeforeClear" after="commentClearComparisonSidebar"/> + + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="compareAssertCategory2"> <argument name="category" value="$$createCategory$$"/> <argument name="productCount" value="3"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml index 386633f0e947..f2c3f15ab434 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml @@ -111,11 +111,11 @@ <waitForPageLoad stepKey="waitforCategoryPageToLoad2"/> <!--Open product display page--> - <click selector="{{StorefrontCategoryProductSection.ProductTitleByNumber('1')}}" stepKey="goToProduct2DisplayPage"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByNumber('2')}}" stepKey="goToProduct2DisplayPage"/> <!--<click selector="{{StorefrontCategoryProductSection.ProductTitleByName(productWithHTMLEntityOne.name)}}" stepKey="clickProductToGoProductPage"/>--> <waitForPageLoad stepKey="waitForProductDisplayPageLoad3"/> - <!--Veriy the breadcrumbs on Product Display page--> + <!--Verify the breadcrumbs on Product Display page--> <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="Home" stepKey="seeHomePageInBreadcrumbs2"/> <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="$$createCategoryOne.name$$" stepKey="seeCorrectBreadCrumbCategory2"/> <see selector="{{StorefrontNavigationSection.breadcrumbs}}" userInput="$$productTwo.name$$" stepKey="seeCorrectBreadCrumbProduct2"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 99f3fc00a740..84c621d161f0 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -11,7 +11,7 @@ <test name="EndToEndB2CGuestUserTest"> <!-- Step 2: User searches for product --> <comment userInput="Start of searching products" stepKey="startOfSearchingProducts" after="endOfBrowsingCatalog"/> - <!-- Advanced Search with Product 1 Data --> + <!-- Advanced Search with Product Data --> <comment userInput="Advanced search" stepKey="commentAdvancedSearch" after="startOfSearchingProducts"/> <actionGroup ref="StorefrontOpenAdvancedSearchActionGroup" stepKey="searchOpenAdvancedSearchForm" after="commentAdvancedSearch"/> <!-- @TODO: Change to scalar value after MQE-498 is implemented --> @@ -22,7 +22,7 @@ <click selector="{{StorefrontCatalogSearchAdvancedFormSection.SubmitButton}}" stepKey="searchClickAdvancedSearchSubmitButton" after="searchAdvancedFillPriceTo"/> <waitForLoadingMaskToDisappear stepKey="waitForSearchProductsloaded" after="searchClickAdvancedSearchSubmitButton"/> <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="searchCheckAdvancedSearchResult" after="waitForSearchProductsloaded"/> - <see userInput="1" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productCount}} span" stepKey="searchAdvancedAssertProductCount" after="searchCheckAdvancedSearchResult"/> + <see userInput="4" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productCount}} span" stepKey="searchAdvancedAssertProductCount" after="searchCheckAdvancedSearchResult"/> <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="searchAssertSimpleProduct1" after="searchAdvancedAssertProductCount"> <argument name="product" value="$$createSimpleProduct1$$"/> </actionGroup> From 28f00aa2e1a59df9fdde12654ec9d96413d7599c Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Mon, 23 Sep 2019 16:44:55 -0500 Subject: [PATCH 0572/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - fixed - modified tests --- .../Magento/Sales/Cron/CleanExpiredQuotes.php | 70 ++++--------- .../Sales/Helper/ExpiredQuotesCollection.php | 99 +++++++++++++++++++ .../Test/Unit/Cron/CleanExpiredQuotesTest.php | 84 ---------------- 3 files changed, 116 insertions(+), 137 deletions(-) create mode 100644 app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php delete mode 100644 app/code/Magento/Sales/Test/Unit/Cron/CleanExpiredQuotesTest.php diff --git a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php index a5c7f71df66c..04db058f4231 100644 --- a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php +++ b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php @@ -5,40 +5,35 @@ */ namespace Magento\Sales\Cron; -use Magento\Store\Model\StoresConfig; +use Magento\Quote\Model\ResourceModel\Quote\Collection; +use Magento\Sales\Helper\ExpiredQuotesCollection; +use Magento\Store\Model\StoreManagerInterface; /** * Class CleanExpiredQuotes */ class CleanExpiredQuotes { - const LIFETIME = 86400; - - /** - * @var StoresConfig - */ - protected $storesConfig; - /** - * @var \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory + * @var ExpiredQuotesCollection */ - protected $quoteCollectionFactory; + private $expiredQuotesCollection; /** - * @var array + * @var StoreManagerInterface */ - protected $expireQuotesFilterFields = []; + private $storeManager; /** - * @param StoresConfig $storesConfig - * @param \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory $collectionFactory + * @param StoreManagerInterface $storeManager + * @param ExpiredQuotesCollection $expiredQuotesCollection */ public function __construct( - StoresConfig $storesConfig, - \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory $collectionFactory + StoreManagerInterface $storeManager, + ExpiredQuotesCollection $expiredQuotesCollection ) { - $this->storesConfig = $storesConfig; - $this->quoteCollectionFactory = $collectionFactory; + $this->storeManager = $storeManager; + $this->expiredQuotesCollection = $expiredQuotesCollection; } /** @@ -48,42 +43,11 @@ public function __construct( */ public function execute() { - $lifetimes = $this->storesConfig->getStoresConfigByPath('checkout/cart/delete_quote_after'); - foreach ($lifetimes as $storeId => $lifetime) { - $lifetime *= self::LIFETIME; - - /** @var $quotes \Magento\Quote\Model\ResourceModel\Quote\Collection */ - $quotes = $this->quoteCollectionFactory->create(); - - $quotes->addFieldToFilter('store_id', $storeId); - $quotes->addFieldToFilter('updated_at', ['to' => date("Y-m-d", time() - $lifetime)]); - - foreach ($this->getExpireQuotesAdditionalFilterFields() as $field => $condition) { - $quotes->addFieldToFilter($field, $condition); - } - + $stores = $this->storeManager->getStores(true); + foreach ($stores as $store) { + /** @var $quotes Collection */ + $quotes = $this->expiredQuotesCollection->getExpiredQuotes($store); $quotes->walk('delete'); } } - - /** - * Retrieve expire quotes additional fields to filter - * - * @return array - */ - protected function getExpireQuotesAdditionalFilterFields() - { - return $this->expireQuotesFilterFields; - } - - /** - * Set expire quotes additional fields to filter - * - * @param array $fields - * @return void - */ - public function setExpireQuotesAdditionalFilterFields(array $fields) - { - $this->expireQuotesFilterFields = $fields; - } } diff --git a/app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php b/app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php new file mode 100644 index 000000000000..5b62a8251d54 --- /dev/null +++ b/app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sales\Helper; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Quote\Model\ResourceModel\Quote\Collection; +use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\ScopeInterface; + +/** + * Class ExpiredQuotesCollection + */ +class ExpiredQuotesCollection +{ + const SECONDS_IN_DAY = 86400; + const QUOTE_LIFETIME = 'checkout/cart/delete_quote_after'; + + /** + * @var CollectionFactory + */ + private $quoteCollectionFactory; + + /** + * @var array + */ + private $expireQuotesFilterFields = []; + + /** + * @var ScopeConfigInterface + */ + private $config; + + /** + * @param ScopeConfigInterface $config + * @param CollectionFactory $collectionFactory + */ + public function __construct( + ScopeConfigInterface $config, + CollectionFactory $collectionFactory + ) { + $this->config = $config; + $this->quoteCollectionFactory = $collectionFactory; + } + + /** + * Gets expired quotes + * + * Quote is considered expired if the latest update date + * of the quote is greater than lifetime threshold + * + * @param StoreInterface $store + * @return Collection + */ + public function getExpiredQuotes(StoreInterface $store) + { + $lifetime = $this->config->getValue( + self::QUOTE_LIFETIME, + ScopeInterface::SCOPE_STORE, + $store->getCode() + ); + $lifetime *= self::SECONDS_IN_DAY; + + /** @var $quotes Collection */ + $quotes = $this->quoteCollectionFactory->create(); + $quotes->addFieldToFilter('store_id', $store->getId()); + $quotes->addFieldToFilter('updated_at', ['to' => date("Y-m-d", time() - $lifetime)]); + + foreach ($this->getExpireQuotesAdditionalFilterFields() as $field => $condition) { + $quotes->addFieldToFilter($field, $condition); + } + + return $quotes; + } + + /** + * Retrieve expire quotes additional fields to filter + * + * @return array + */ + private function getExpireQuotesAdditionalFilterFields() + { + return $this->expireQuotesFilterFields; + } + + /** + * Set expire quotes additional fields to filter + * + * @param array $fields + * @return void + */ + public function setExpireQuotesAdditionalFilterFields(array $fields) + { + $this->expireQuotesFilterFields = $fields; + } +} diff --git a/app/code/Magento/Sales/Test/Unit/Cron/CleanExpiredQuotesTest.php b/app/code/Magento/Sales/Test/Unit/Cron/CleanExpiredQuotesTest.php deleted file mode 100644 index ad6a3e03ba67..000000000000 --- a/app/code/Magento/Sales/Test/Unit/Cron/CleanExpiredQuotesTest.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Sales\Test\Unit\Cron; - -use \Magento\Sales\Cron\CleanExpiredQuotes; - -/** - * Tests Magento\Sales\Cron\CleanExpiredQuotes - */ -class CleanExpiredQuotesTest extends \PHPUnit\Framework\TestCase -{ - /** - * @var \Magento\Store\Model\StoresConfig|\PHPUnit_Framework_MockObject_MockObject - */ - protected $storesConfigMock; - - /** - * @var \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject - */ - protected $quoteFactoryMock; - - /** - * @var \Magento\Sales\Cron\CleanExpiredQuotes - */ - protected $observer; - - protected function setUp() - { - $this->storesConfigMock = $this->createMock(\Magento\Store\Model\StoresConfig::class); - - $this->quoteFactoryMock = $this->getMockBuilder( - \Magento\Quote\Model\ResourceModel\Quote\CollectionFactory::class - ) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - - $this->observer = new CleanExpiredQuotes($this->storesConfigMock, $this->quoteFactoryMock); - } - - /** - * @param array $lifetimes - * @param array $additionalFilterFields - * @dataProvider cleanExpiredQuotesDataProvider - */ - public function testExecute($lifetimes, $additionalFilterFields) - { - $this->storesConfigMock->expects($this->once()) - ->method('getStoresConfigByPath') - ->with($this->equalTo('checkout/cart/delete_quote_after')) - ->will($this->returnValue($lifetimes)); - - $quotesMock = $this->getMockBuilder(\Magento\Quote\Model\ResourceModel\Quote\Collection::class) - ->disableOriginalConstructor() - ->getMock(); - $this->quoteFactoryMock->expects($this->exactly(count($lifetimes))) - ->method('create') - ->will($this->returnValue($quotesMock)); - $quotesMock->expects($this->exactly((2 + count($additionalFilterFields)) * count($lifetimes))) - ->method('addFieldToFilter'); - if (!empty($lifetimes)) { - $quotesMock->expects($this->exactly(count($lifetimes))) - ->method('walk') - ->with('delete'); - } - $this->observer->setExpireQuotesAdditionalFilterFields($additionalFilterFields); - $this->observer->execute(); - } - - /** - * @return array - */ - public function cleanExpiredQuotesDataProvider() - { - return [ - [[], []], - [[1 => 100, 2 => 200], []], - [[1 => 100, 2 => 200], ['field1' => 'condition1', 'field2' => 'condition2']], - ]; - } -} From 309274063bb5ebc7c74d1933b9480d991764c082 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 23 Sep 2019 16:54:20 -0500 Subject: [PATCH 0573/1172] MC-19247: Broken translations with advanced bundling - Remove translation dependency from theme module; --- app/code/Magento/Theme/composer.json | 1 - app/code/Magento/Theme/view/frontend/layout/default.xml | 1 - app/code/Magento/Translation/ViewModel/Dictionary.php | 3 +-- app/code/Magento/Translation/view/frontend/layout/default.xml | 1 + 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json index f688d5b8863a..ecc944336cd8 100644 --- a/app/code/Magento/Theme/composer.json +++ b/app/code/Magento/Theme/composer.json @@ -15,7 +15,6 @@ "magento/module-media-storage": "*", "magento/module-require-js": "*", "magento/module-store": "*", - "magento/module-translation": "*", "magento/module-ui": "*", "magento/module-widget": "*" }, diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml index e783648f7e3e..81cffe8c040b 100644 --- a/app/code/Magento/Theme/view/frontend/layout/default.xml +++ b/app/code/Magento/Theme/view/frontend/layout/default.xml @@ -11,7 +11,6 @@ <block name="require.js" class="Magento\Framework\View\Element\Template" template="Magento_Theme::page/js/require_js.phtml" /> <referenceContainer name="after.body.start"> <block class="Magento\RequireJs\Block\Html\Head\Config" name="requirejs-config"/> - <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> <block class="Magento\Framework\View\Element\Js\Cookie" name="js_cookies" template="Magento_Theme::js/cookie.phtml"/> <block class="Magento\Theme\Block\Html\Notices" name="global_notices" template="Magento_Theme::html/notices.phtml"/> </referenceContainer> diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 011501fc219a..1587f7d0eedc 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -68,14 +68,13 @@ public function __construct( */ public function getTranslationDictionary(): string { + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); if ($this->appState->getMode() === AppState::MODE_PRODUCTION) { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); $staticViewFilePath = $this->filesystem->getDirectoryRead( DirectoryList::STATIC_VIEW )->getAbsolutePath(); $content = $this->filesystemDriver->fileGetContents($staticViewFilePath . $asset->getPath()); } else { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); $content = $asset->getContent(); } diff --git a/app/code/Magento/Translation/view/frontend/layout/default.xml b/app/code/Magento/Translation/view/frontend/layout/default.xml index e58a249b0793..6b8c8e277422 100644 --- a/app/code/Magento/Translation/view/frontend/layout/default.xml +++ b/app/code/Magento/Translation/view/frontend/layout/default.xml @@ -8,6 +8,7 @@ <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="head.additional"> + <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> <block name="translation_dictionary" template="Magento_Translation::dictionary.phtml" before="-"> <arguments> <argument name="dictionary_view_model" xsi:type="object">Magento\Translation\ViewModel\Dictionary</argument> From 1814e32b38747fdd54971b6a1ad2fadef9dce721 Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 24 Sep 2019 08:55:11 +0300 Subject: [PATCH 0574/1172] MC-20075: Fix Skipped MFTF Tests From MC-17140: MC-14536, MC-14538, MC-14720 --- .../AssertStorefrontMiniCartItemsActionGroup.xml | 6 ++---- .../ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml index 55ccf9539d43..8933ebbc1dd8 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertStorefrontMiniCartItemsActionGroup.xml @@ -19,8 +19,7 @@ <argument name="qty" type="string"/> </arguments> - <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="seeProductNameInMiniCart"/> - <see selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productPrice}}" stepKey="seeProductPriceInMiniCart"/> + <see selector="{{StorefrontMinicartSection.productPriceByName(productName)}}" userInput="{{productPrice}}" stepKey="seeProductPriceInMiniCart"/> <seeElement selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="seeCheckOutButtonInMiniCart"/> <seeElement selector="{{StorefrontMinicartSection.productQuantity(productName, qty)}}" stepKey="seeProductQuantity1"/> <seeElement selector="{{StorefrontMinicartSection.productImage}}" stepKey="seeProductImage"/> @@ -37,7 +36,6 @@ <argument name="productPrice" type="string"/> </arguments> - <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productName}}" stepKey="dontSeeProductNameInMiniCart"/> - <dontSee selector="{{StorefrontMinicartSection.miniCartItemsText}}" userInput="{{productPrice}}" stepKey="dontSeeProductPriceInMiniCart"/> + <dontSee selector="{{StorefrontMinicartSection.productPriceByName(productName)}}" userInput="{{productPrice}}" stepKey="dontSeeProductPriceInMiniCart"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml index 17beb4bebc7b..0831a476f007 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml @@ -15,13 +15,17 @@ <arguments> <argument name="ruleName" type="entity"/> </arguments> - + <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="goToCartPriceRules"/> <waitForPageLoad stepKey="waitForCartPriceRules"/> + <click selector="{{AdminCartPriceRulesFormSection.resetSearchFilter}}" stepKey="resetFilterBeforeDelete"/> + <waitForPageLoad stepKey="waitForCartPriceRulesResetFilter"/> <fillField selector="{{AdminCartPriceRulesSection.filterByNameInput}}" userInput="{{ruleName.name}}" stepKey="filterByName"/> <click selector="{{AdminCartPriceRulesSection.searchButton}}" stepKey="doFilter"/> <click selector="{{AdminCartPriceRulesSection.rowByIndex('1')}}" stepKey="goToEditRulePage"/> <click selector="{{AdminCartPriceRulesFormSection.delete}}" stepKey="clickDeleteButton"/> <click selector="{{AdminCartPriceRulesFormSection.modalAcceptButton}}" stepKey="confirmDelete"/> + <click selector="{{AdminCartPriceRulesFormSection.resetSearchFilter}}" stepKey="resetFilterAfterDelete"/> + <waitForPageLoad stepKey="waitForCartPriceRulesAfterDelete"/> </actionGroup> </actionGroups> From b59a7a12e3f078eac3e1f50e053210d8e86c4b83 Mon Sep 17 00:00:00 2001 From: Evgeny Petrov <evgeny_petrov@epam.com> Date: Tue, 24 Sep 2019 09:48:14 +0300 Subject: [PATCH 0575/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window --- app/code/Magento/Multishipping/Block/Checkout/Shipping.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php index a3b10aea9b42..9cfcb4b64794 100644 --- a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php +++ b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php @@ -158,10 +158,7 @@ public function getShippingRates($address) public function getCarrierName($carrierCode) { $name = $this->_scopeConfig->getValue('carriers/' . $carrierCode . '/title', ScopeInterface::SCOPE_STORE); - if ($name) { - return $name; - } - return $carrierCode; + return $name ?: $carrierCode; } /** From b39441a14e171e28d01b4a584cd8a963c2c33ae9 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Tue, 24 Sep 2019 10:28:06 +0300 Subject: [PATCH 0576/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Model/Cart/SetBillingAddressOnCart.php | 4 -- .../Model/Cart/SetShippingAddressesOnCart.php | 4 -- .../Customer/SetBillingAddressOnCartTest.php | 49 ------------------ .../Customer/SetShippingAddressOnCartTest.php | 50 ------------------- 4 files changed, 107 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php index e4457f274110..22dff2d5550b 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetBillingAddressOnCart.php @@ -116,10 +116,6 @@ private function createBillingAddress( if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { $this->saveQuoteAddressToCustomerAddressBook->execute($billingAddress, $customerId); } - - if (0 === $customerId) { - throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); - } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index fbb6d0e5a652..ccb35e884061 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -107,10 +107,6 @@ private function createShippingAddress( if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { $this->saveQuoteAddressToCustomerAddressBook->execute($shippingAddress, $customerId); } - - if (0 === $customerId) { - throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); - } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php index 00188014f26e..40ec237c8b23 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetBillingAddressOnCartTest.php @@ -651,55 +651,6 @@ public function testSetNewBillingAddressWithRedundantStreetLine() $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } - /** - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - */ - public function testSetBillingAddressToGuestCartWithoutAddressId() - { - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - - $query = <<<QUERY -mutation { - setBillingAddressOnCart( - input: { - cart_id: "{$maskedQuoteId}" - billing_address: { - address: { - firstname: "test firstname" - lastname: "test lastname" - company: "test company" - street: ["test street 1", "test street 2"] - city: "test city" - region: "test region" - postcode: "887766" - country_code: "US" - telephone: "88776655" - } - } - } - ) { - cart { - shipping_addresses { - region { - code - } - country { - code - } - } - } - } -} -QUERY; - $this->expectExceptionMessage( - 'The current customer isn\'t authorized.' - ); - - $this->graphQlMutation($query, [], ''); - } - /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php index 57d428822799..95c8f4118adb 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetShippingAddressOnCartTest.php @@ -619,56 +619,6 @@ public function testSetShippingAddressToGuestCart() $this->graphQlMutation($query, [], '', $this->getHeaderMap()); } - /** - * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/guest/create_empty_cart.php - * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php - */ - public function testSetShippingAddressToGuestCartWithoutAddressId() - { - $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute('test_quote'); - - $query = <<<QUERY -mutation { - setShippingAddressesOnCart( - input: { - cart_id: "{$maskedQuoteId}" - shipping_addresses: [ - { - address: { - firstname: "John" - lastname: "Doe" - street: ["6161 West Centinella Avenue"] - city: "Culver City" - region: "CA" - postcode: "90230" - country_code: "us" - telephone: "555-555-55-55" - } - } - ] - } - ) { - cart { - shipping_addresses { - region { - code - } - country { - code - } - } - } - } -} -QUERY; - $this->expectExceptionMessage( - 'The current customer isn\'t authorized.' - ); - - $this->graphQlMutation($query, [], ''); - } - /** * @magentoApiDataFixture Magento/Customer/_files/customer.php * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php From c7fc78186767522fec248fd041810b0240c6931a Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Tue, 24 Sep 2019 11:29:51 +0400 Subject: [PATCH 0577/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window - Updatetd automated test script --- .../Multishipping/Test/Mftf/Section/MultishippingSection.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index c6fc44922737..b01e5b35b41a 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -24,7 +24,6 @@ </section> <section name="StorefrontMultipleShippingMethodSection"> <element name="orderId" type="text" selector=".shipping-list:nth-child({{rowNum}}) .order-id" parameterized="true"/> - <element name="placeOrderButton" type="button" selector="#review-button"/> <element name="goToReviewYourOrderButton" type="button" selector="#payment-continue"/> <element name="continueToBillingInformationButton" type="button" selector=".action.primary.continue"/> <element name="successMessage" type="text" selector=".multicheckout.success"/> From 5c51622c3aaced8373c8ef712d3f5e20c3e48686 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Tue, 24 Sep 2019 10:38:37 +0300 Subject: [PATCH 0578/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../_files/two_orders_with_order_items.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php b/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php index 8d2132dadd69..ade37aed49d5 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/two_orders_with_order_items.php @@ -70,8 +70,8 @@ $orderRepository->save($order); /** @var Payment $payment */ -$payment2 = $objectManager->create(Payment::class); -$payment2->setMethod('checkmo') +$secondPayment = $objectManager->create(Payment::class); +$secondPayment->setMethod('checkmo') ->setAdditionalInformation('last_trans_id', '11122') ->setAdditionalInformation( 'metadata', @@ -82,8 +82,8 @@ ); /** @var OrderItem $orderItem */ -$orderItem2 = $objectManager->create(OrderItem::class); -$orderItem2->setProductId($product->getId()) +$secondOrderItem = $objectManager->create(OrderItem::class); +$secondOrderItem->setProductId($product->getId()) ->setQtyOrdered(2) ->setBasePrice($product->getPrice()) ->setPrice($product->getPrice()) @@ -93,10 +93,10 @@ ->setSku($product->getSku()); /** @var Order $order */ -$order2 = $objectManager->create(Order::class); -$order2->setIncrementId('100000002') +$secondOrder = $objectManager->create(Order::class); +$secondOrder->setIncrementId('100000002') ->setState(Order::STATE_PROCESSING) - ->setStatus($order2->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) + ->setStatus($secondOrder->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING)) ->setSubtotal(100) ->setGrandTotal(100) ->setBaseSubtotal(100) @@ -106,6 +106,6 @@ ->setBillingAddress($billingAddress) ->setShippingAddress($shippingAddress) ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId()) - ->addItem($orderItem2) - ->setPayment($payment2); -$orderRepository->save($order2); + ->addItem($secondOrderItem) + ->setPayment($secondPayment); +$orderRepository->save($secondOrder); From f6afe4dd521c8b109c563f09de5232e297ea3b80 Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Tue, 24 Sep 2019 11:25:56 +0300 Subject: [PATCH 0579/1172] MC-18825: Increase test coverage for Promotion and Loyalty functional area - Fixes for MC-6347 --- .../_files/product_simple_out_of_stock_without_categories.php | 2 +- .../testsuite/Magento/ProductAlert/Model/ObserverTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php index 4bd534b4165b..6ae4af61bc51 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_without_categories.php @@ -29,7 +29,7 @@ ->setSku('simple') ->setPrice(10) ->setWeight(1) - ->setShortDescription("Short description") + ->setShortDescription('Short description') ->setTaxClassId(0) ->setDescription('Description with <b>html tag</b>') ->setMetaTitle('meta title') diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php index 0a34711acde7..0f19edc349e8 100644 --- a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php +++ b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/ObserverTest.php @@ -63,7 +63,7 @@ public function setUp() /** * Test process() method * - * @magentoConfigFixture current_store catalog/productalert/allow_price 1 * + * @magentoConfigFixture current_store catalog/productalert/allow_price 1 * @magentoDataFixture Magento/ProductAlert/_files/product_alert.php */ public function testProcess() From 029acac9341a3052196464da63740c458fa33cd0 Mon Sep 17 00:00:00 2001 From: Thomas Klein <thomas.klein@mpbio.com> Date: Mon, 2 Sep 2019 10:39:57 +0200 Subject: [PATCH 0580/1172] #12371 allows to add handlers via di --- app/code/Magento/Catalog/Helper/Output.php | 47 +++++++++++++--------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Output.php b/app/code/Magento/Catalog/Helper/Output.php index 33e261dc353b..5c3907aa7918 100644 --- a/app/code/Magento/Catalog/Helper/Output.php +++ b/app/code/Magento/Catalog/Helper/Output.php @@ -9,9 +9,18 @@ use Magento\Catalog\Model\Category as ModelCategory; use Magento\Catalog\Model\Product as ModelProduct; +use Magento\Eav\Model\Config; +use Magento\Framework\App\Helper\AbstractHelper; +use Magento\Framework\App\Helper\Context; +use Magento\Framework\Escaper; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Filter\Template; +use function is_object; +use function method_exists; +use function preg_match; +use function strtolower; -class Output extends \Magento\Framework\App\Helper\AbstractHelper +class Output extends AbstractHelper { /** * Array of existing handlers @@ -37,12 +46,12 @@ class Output extends \Magento\Framework\App\Helper\AbstractHelper /** * Eav config * - * @var \Magento\Eav\Model\Config + * @var Config */ protected $_eavConfig; /** - * @var \Magento\Framework\Escaper + * @var Escaper */ protected $_escaper; @@ -53,23 +62,26 @@ class Output extends \Magento\Framework\App\Helper\AbstractHelper /** * Output constructor. - * @param \Magento\Framework\App\Helper\Context $context - * @param \Magento\Eav\Model\Config $eavConfig + * @param Context $context + * @param Config $eavConfig * @param Data $catalogData - * @param \Magento\Framework\Escaper $escaper + * @param Escaper $escaper * @param array $directivePatterns + * @param array $handlers */ public function __construct( - \Magento\Framework\App\Helper\Context $context, - \Magento\Eav\Model\Config $eavConfig, + Context $context, + Config $eavConfig, Data $catalogData, - \Magento\Framework\Escaper $escaper, - $directivePatterns = [] + Escaper $escaper, + $directivePatterns = [], + array $handlers = [] ) { $this->_eavConfig = $eavConfig; $this->_catalogData = $catalogData; $this->_escaper = $escaper; $this->directivePatterns = $directivePatterns; + $this->_handlers = $handlers; parent::__construct($context); } @@ -115,8 +127,7 @@ public function addHandler($method, $handler) */ public function getHandlers($method) { - $method = strtolower($method); - return $this->_handlers[$method] ?? []; + return $this->_handlers[strtolower($method)] ?? []; } /** @@ -145,21 +156,21 @@ public function process($method, $result, $params) * @param string $attributeName * @return string * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function productAttribute($product, $attributeHtml, $attributeName) { $attribute = $this->_eavConfig->getAttribute(ModelProduct::ENTITY, $attributeName); if ($attribute && $attribute->getId() && - $attribute->getFrontendInput() != 'media_image' && + $attribute->getFrontendInput() !== 'media_image' && (!$attribute->getIsHtmlAllowedOnFront() && !$attribute->getIsWysiwygEnabled()) ) { - if ($attribute->getFrontendInput() != 'price') { + if ($attribute->getFrontendInput() !== 'price') { $attributeHtml = $this->_escaper->escapeHtml($attributeHtml); } - if ($attribute->getFrontendInput() == 'textarea') { + if ($attribute->getFrontendInput() === 'textarea') { $attributeHtml = nl2br($attributeHtml); } } @@ -187,14 +198,14 @@ public function productAttribute($product, $attributeHtml, $attributeName) * @param string $attributeHtml * @param string $attributeName * @return string - * @throws \Magento\Framework\Exception\LocalizedException + * @throws LocalizedException */ public function categoryAttribute($category, $attributeHtml, $attributeName) { $attribute = $this->_eavConfig->getAttribute(ModelCategory::ENTITY, $attributeName); if ($attribute && - $attribute->getFrontendInput() != 'image' && + $attribute->getFrontendInput() !== 'image' && (!$attribute->getIsHtmlAllowedOnFront() && !$attribute->getIsWysiwygEnabled()) ) { From 81a542b7ed6fc9db6715475f047906767d06775c Mon Sep 17 00:00:00 2001 From: Thomas Klein <thomas@bird.eu> Date: Thu, 27 Jun 2019 17:46:49 +0200 Subject: [PATCH 0581/1172] Fix alias in grid massaction for eav collections --- .../Grid/Massaction/AbstractMassaction.php | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php index 891b2a3ada72..e6a51beedbfb 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php @@ -3,26 +3,36 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Backend\Block\Widget\Grid\Massaction; +use Magento\Backend\Block\Template\Context; +use Magento\Backend\Block\Widget; +use Magento\Backend\Block\Widget\Grid\Column; +use Magento\Backend\Block\Widget\Grid\ColumnSet; use Magento\Backend\Block\Widget\Grid\Massaction\VisibilityCheckerInterface as VisibilityChecker; use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\DataObject; +use Magento\Framework\DB\Select; +use Magento\Framework\Json\EncoderInterface; +use Magento\Quote\Model\Quote; +use function count; +use function is_array; /** * Grid widget massaction block * * @api - * @method \Magento\Quote\Model\Quote setHideFormElement(boolean $value) Hide Form element to prevent IE errors + * @method Quote setHideFormElement(boolean $value) Hide Form element to prevent IE errors * @method boolean getHideFormElement() * @deprecated 100.2.0 in favour of UI component implementation * @since 100.0.2 */ -abstract class AbstractMassaction extends \Magento\Backend\Block\Widget +abstract class AbstractMassaction extends Widget { /** - * @var \Magento\Framework\Json\EncoderInterface + * @var EncoderInterface */ protected $_jsonEncoder; @@ -39,13 +49,13 @@ abstract class AbstractMassaction extends \Magento\Backend\Block\Widget protected $_template = 'Magento_Backend::widget/grid/massaction.phtml'; /** - * @param \Magento\Backend\Block\Template\Context $context - * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder + * @param Context $context + * @param EncoderInterface $jsonEncoder * @param array $data */ public function __construct( - \Magento\Backend\Block\Template\Context $context, - \Magento\Framework\Json\EncoderInterface $jsonEncoder, + Context $context, + EncoderInterface $jsonEncoder, array $data = [] ) { $this->_jsonEncoder = $jsonEncoder; @@ -118,15 +128,11 @@ private function isVisible(DataObject $item) * Retrieve massaction item with id $itemId * * @param string $itemId - * @return \Magento\Backend\Block\Widget\Grid\Massaction\Item|null + * @return Item|null */ public function getItem($itemId) { - if (isset($this->_items[$itemId])) { - return $this->_items[$itemId]; - } - - return null; + return $this->_items[$itemId] ?? null; } /** @@ -161,7 +167,7 @@ public function getItemsJson() */ public function getCount() { - return sizeof($this->_items); + return count($this->_items); } /** @@ -288,11 +294,11 @@ public function getGridIdsJson() if ($collection instanceof AbstractDb) { $idsSelect = clone $collection->getSelect(); - $idsSelect->reset(\Magento\Framework\DB\Select::ORDER); - $idsSelect->reset(\Magento\Framework\DB\Select::LIMIT_COUNT); - $idsSelect->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET); - $idsSelect->reset(\Magento\Framework\DB\Select::COLUMNS); - $idsSelect->columns($this->getMassactionIdField(), 'main_table'); + $idsSelect->reset(Select::ORDER); + $idsSelect->reset(Select::LIMIT_COUNT); + $idsSelect->reset(Select::LIMIT_OFFSET); + $idsSelect->reset(Select::COLUMNS); + $idsSelect->columns($this->getMassactionIdField()); $idList = $collection->getConnection()->fetchCol($idsSelect); } else { $idList = $collection->setPageSize(0)->getColumnValues($this->getMassactionIdField()); @@ -358,7 +364,7 @@ public function prepareMassactionColumn() { $columnId = 'massaction'; $massactionColumn = $this->getLayout()->createBlock( - \Magento\Backend\Block\Widget\Grid\Column::class + Column::class )->setData( [ 'index' => $this->getMassactionIdField(), @@ -378,7 +384,7 @@ public function prepareMassactionColumn() $gridBlock = $this->getParentBlock(); $massactionColumn->setSelected($this->getSelected())->setGrid($gridBlock)->setId($columnId); - /** @var $columnSetBlock \Magento\Backend\Block\Widget\Grid\ColumnSet */ + /** @var $columnSetBlock ColumnSet */ $columnSetBlock = $gridBlock->getColumnSet(); $childNames = $columnSetBlock->getChildNames(); $siblingElement = count($childNames) ? current($childNames) : 0; From 1f3306c39aa674d02ed3d79308369c8bab6f9a9b Mon Sep 17 00:00:00 2001 From: Serhii Voloshkov <serhii.voloshkov@transoftgroup.com> Date: Tue, 24 Sep 2019 11:54:19 +0300 Subject: [PATCH 0582/1172] MC-20075: Fix Skipped MFTF Tests From MC-17140: MC-14536, MC-14538, MC-14720 --- ...orefrontCheckCartDiscountAndSummaryActionGroup.xml | 11 +++++------ .../Test/Mftf/Section/CheckoutCartSummarySection.xml | 1 + .../AdminDeleteCartPriceRuleActionGroup.xml | 7 +++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCheckCartDiscountAndSummaryActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCheckCartDiscountAndSummaryActionGroup.xml index 112abfbb5897..9f766742b545 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCheckCartDiscountAndSummaryActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontCheckCartDiscountAndSummaryActionGroup.xml @@ -17,13 +17,12 @@ <argument name="total" type="string"/> <argument name="discount" type="string"/> </arguments> - <waitForPageLoad stepKey="waitForPageLoad"/> - <waitForLoadingMaskToDisappear stepKey="waitForPrices"/> + <waitForElement time="30" selector="{{CheckoutCartSummarySection.estimateShippingAndTaxForm}}" stepKey="waitForEstimateShippingAndTaxForm"/> + <waitForElement time="30" selector="{{CheckoutCartSummarySection.shippingMethodForm}}" stepKey="waitForShippingMethodForm"/> + <waitForElementVisible time="30" selector="{{CheckoutCartSummarySection.total}}" stepKey="waitForTotalElement"/> + <see selector="{{CheckoutCartSummarySection.total}}" userInput="${{total}}" stepKey="assertTotal"/> + <waitForElementVisible selector="{{CheckoutCartSummarySection.discountAmount}}" stepKey="waitForDiscountElement"/> <see selector="{{CheckoutCartSummarySection.discountAmount}}" userInput="-${{discount}}" stepKey="assertDiscount"/> - <wait time="10" stepKey="waitForTotalPrice"/> - <reloadPage stepKey="reloadPage" after="waitForTotalPrice" /> - <waitForPageLoad after="reloadPage" stepKey="WaitForPageLoaded" /> - <see selector="{{CheckoutCartSummarySection.total}}" userInput="${{total}}" stepKey="assertTotal" after="WaitForPageLoaded"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml index 477451ef003c..7d5cecee9290 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartSummarySection.xml @@ -33,5 +33,6 @@ <element name="methodName" type="text" selector="#co-shipping-method-form label"/> <element name="shippingPrice" type="text" selector="#co-shipping-method-form span .price"/> <element name="shippingMethodElementId" type="radio" selector="#s_method_{{carrierCode}}_{{methodCode}}" parameterized="true"/> + <element name="estimateShippingAndTaxForm" type="block" selector="#shipping-zip-form"/> </section> </sections> diff --git a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml index 0831a476f007..af9c462bfd42 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/ActionGroup/AdminDeleteCartPriceRuleActionGroup.xml @@ -18,14 +18,13 @@ <amOnPage url="{{AdminCartPriceRulesPage.url}}" stepKey="goToCartPriceRules"/> <waitForPageLoad stepKey="waitForCartPriceRules"/> - <click selector="{{AdminCartPriceRulesFormSection.resetSearchFilter}}" stepKey="resetFilterBeforeDelete"/> + <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="resetFilterBeforeDelete"/> <waitForPageLoad stepKey="waitForCartPriceRulesResetFilter"/> <fillField selector="{{AdminCartPriceRulesSection.filterByNameInput}}" userInput="{{ruleName.name}}" stepKey="filterByName"/> <click selector="{{AdminCartPriceRulesSection.searchButton}}" stepKey="doFilter"/> <click selector="{{AdminCartPriceRulesSection.rowByIndex('1')}}" stepKey="goToEditRulePage"/> <click selector="{{AdminCartPriceRulesFormSection.delete}}" stepKey="clickDeleteButton"/> - <click selector="{{AdminCartPriceRulesFormSection.modalAcceptButton}}" stepKey="confirmDelete"/> - <click selector="{{AdminCartPriceRulesFormSection.resetSearchFilter}}" stepKey="resetFilterAfterDelete"/> - <waitForPageLoad stepKey="waitForCartPriceRulesAfterDelete"/> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForConfirmModal"/> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="confirmDelete"/> </actionGroup> </actionGroups> From d3771dd1efeebcdaa3e610884e95a88994baeaa3 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Tue, 24 Sep 2019 17:14:42 +0530 Subject: [PATCH 0583/1172] Replaced model load with Service Contract --- .../Controller/Adminhtml/Product/Set/Edit.php | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php index 6f6870cb0849..b07cfaf36f73 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php @@ -6,45 +6,64 @@ */ namespace Magento\Catalog\Controller\Adminhtml\Product\Set; -use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; +use Magento\Framework\Registry; +use Magento\Backend\App\Action\Context; +use Magento\Framework\App\ObjectManager; +use Magento\Backend\Model\View\Result\Page; +use Magento\Framework\View\Result\PageFactory; +use Magento\Framework\Controller\ResultInterface; +use Magento\Eav\Api\AttributeSetRepositoryInterface; +use Magento\Catalog\Controller\Adminhtml\Product\Set; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\App\Action\HttpGetActionInterface; -class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Set implements HttpGetActionInterface +class Edit extends Set implements HttpGetActionInterface { /** - * @var \Magento\Framework\View\Result\PageFactory + * @var PageFactory */ protected $resultPageFactory; /** - * @param \Magento\Backend\App\Action\Context $context - * @param \Magento\Framework\Registry $coreRegistry - * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory + * @var AttributeSetRepositoryInterface + */ + protected $attributeSetRepository; + + /** + * + * @param Context $context + * @param Registry $coreRegistry + * @param PageFactory $resultPageFactory + * @param AttributeSetRepositoryInterface $attributeSetRepository */ public function __construct( - \Magento\Backend\App\Action\Context $context, - \Magento\Framework\Registry $coreRegistry, - \Magento\Framework\View\Result\PageFactory $resultPageFactory + Context $context, + Registry $coreRegistry, + PageFactory $resultPageFactory, + AttributeSetRepositoryInterface $attributeSetRepository = null ) { parent::__construct($context, $coreRegistry); $this->resultPageFactory = $resultPageFactory; + $this->attributeSetRepository = $attributeSetRepository ?: + ObjectManager::getInstance()->get(AttributeSetRepositoryInterface::class); } /** - * @return \Magento\Backend\Model\View\Result\Page + * + * @return ResultInterface + * + * @throws NoSuchEntityException */ public function execute() { $this->_setTypeId(); - $attributeSet = $this->_objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class) - ->load($this->getRequest()->getParam('id')); - + $attributeSet = $this->attributeSetRepository->get($this->getRequest()->getParam('id')); if (!$attributeSet->getId()) { return $this->resultRedirectFactory->create()->setPath('catalog/*/index'); } - $this->_coreRegistry->register('current_attribute_set', $attributeSet); - /** @var \Magento\Backend\Model\View\Result\Page $resultPage */ + /** @var Page $resultPage */ $resultPage = $this->resultPageFactory->create(); $resultPage->setActiveMenu('Magento_Catalog::catalog_attributes_sets'); $resultPage->getConfig()->getTitle()->prepend(__('Attribute Sets')); From 3cf16dcb884a0051c8031ea872c32e0286f249f6 Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Tue, 24 Sep 2019 14:20:43 +0300 Subject: [PATCH 0584/1172] MAGETWO-99838: Error message '"customer address attribute" is a required value.' is absent on Storefront - Fixed bug - Added unit test --- .../Eav/Model/Validator/Attribute/Data.php | 10 +-- .../Model/Validator/Attribute/DataTest.php | 81 ++++++++++++++++--- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Eav/Model/Validator/Attribute/Data.php b/app/code/Magento/Eav/Model/Validator/Attribute/Data.php index cd0d5141154c..15dcea077c88 100644 --- a/app/code/Magento/Eav/Model/Validator/Attribute/Data.php +++ b/app/code/Magento/Eav/Model/Validator/Attribute/Data.php @@ -4,15 +4,15 @@ * See COPYING.txt for license details. */ +namespace Magento\Eav\Model\Validator\Attribute; + +use Magento\Eav\Model\Attribute; + /** * EAV attribute data validator * * @author Magento Core Team <core@magentocommerce.com> */ -namespace Magento\Eav\Model\Validator\Attribute; - -use Magento\Eav\Model\Attribute; - class Data extends \Magento\Framework\Validator\AbstractValidator { /** @@ -126,7 +126,7 @@ public function isValid($entity) $dataModel = $this->_attrDataFactory->create($attribute, $entity); $dataModel->setExtractedData($data); if (!isset($data[$attributeCode])) { - $data[$attributeCode] = null; + $data[$attributeCode] = ''; } $result = $dataModel->validateValue($data[$attributeCode]); if (true !== $result) { diff --git a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php index 07ce6fbfc6a4..9f1e74fccbd4 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php @@ -4,13 +4,43 @@ * See COPYING.txt for license details. */ +namespace Magento\Eav\Test\Unit\Model\Validator\Attribute; + /** * Test for \Magento\Eav\Model\Validator\Attribute\Data */ -namespace Magento\Eav\Test\Unit\Model\Validator\Attribute; - class DataTest extends \PHPUnit\Framework\TestCase { + /** + * @var \Magento\Eav\Model\AttributeDataFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $attrDataFactory; + + /** + * @var \Magento\Eav\Model\Validator\Attribute\Data + */ + private $model; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->attrDataFactory = $this->getMockBuilder(\Magento\Eav\Model\AttributeDataFactory::class) + ->setMethods(['create']) + ->setConstructorArgs( + [ + 'objectManager' => $this->createMock(\Magento\Framework\ObjectManagerInterface::class), + 'string' => $this->createMock(\Magento\Framework\Stdlib\StringUtils::class) + ] + ) + ->getMock(); + + $this->model = new \Magento\Eav\Model\Validator\Attribute\Data( + $this->attrDataFactory + ); + } + /** * Testing \Magento\Eav\Model\Validator\Attribute\Data::isValid * @@ -381,13 +411,15 @@ public function testAddErrorMessages() protected function _getAttributeMock($attributeData) { $attribute = $this->getMockBuilder(\Magento\Eav\Model\Attribute::class) - ->setMethods([ - 'getAttributeCode', - 'getDataModel', - 'getFrontendInput', - '__wakeup', - 'getIsVisible', - ]) + ->setMethods( + [ + 'getAttributeCode', + 'getDataModel', + 'getFrontendInput', + '__wakeup', + 'getIsVisible', + ] + ) ->disableOriginalConstructor() ->getMock(); @@ -466,4 +498,35 @@ protected function _getEntityMock() )->disableOriginalConstructor()->getMock(); return $entity; } + + /** + * Test for isValid() without data for attribute. + * + * @return void + */ + public function testIsValidWithoutData() : void + { + $attributeData = ['attribute_code' => 'attribute', 'frontend_input' => 'text', 'is_visible' => true]; + $entity = $this->_getEntityMock(); + $attribute = $this->_getAttributeMock($attributeData); + $this->model->setAttributes([$attribute])->setData([]); + $dataModel = $this->getMockBuilder(\Magento\Eav\Model\Attribute\Data\AbstractData::class) + ->disableOriginalConstructor() + ->setMethods(['validateValue']) + ->getMockForAbstractClass(); + $dataModel->expects($this->once()) + ->method('validateValue') + // only empty string + ->with( + $this->logicalAnd( + $this->isEmpty(), + $this->isType('string') + ) + )->willReturn(true); + $this->attrDataFactory->expects($this->once()) + ->method('create') + ->with($attribute, $entity) + ->willReturn($dataModel); + $this->assertEquals(true, $this->model->isValid($entity)); + } } From 491b65a5e84ee3e00be1aeb336dc49773a1de038 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Tue, 24 Sep 2019 09:41:39 -0500 Subject: [PATCH 0585/1172] MC-20358: Create New MFTF Suites for MySQL/Elasticsearch Specific Functionality --- .../Suite/SearchEngineElasticsearchSuite.xml | 17 ++++++++++++++ .../Search/Test/Mftf/Data/ConfigData.xml | 22 ++++++++++++++++++ .../Mftf/Suite/SearchEngineMysqlSuite.xml | 23 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml create mode 100644 app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml create mode 100644 app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml new file mode 100644 index 000000000000..ff2b86d3abd5 --- /dev/null +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> + <suite name="SearchEngineElasticsearchSuite"> + <include> + <group name="SearchEngineElasticsearch" /> + </include> + <exclude> + <group name="skip"/> + </exclude> + </suite> +</suites> diff --git a/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml b/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml new file mode 100644 index 000000000000..1761e9a73576 --- /dev/null +++ b/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SearchEngineDefaultConfigData"> + <data key="path">catalog/search/engine</data> + <data key="scope_id">1</data> + <data key="label">Elasticsearch 6.0+</data> + <data key="value">elasticsearch6</data> + </entity> + <entity name="SearchEngineMysqlConfigData"> + <data key="path">catalog/search/engine</data> + <data key="scope_id">1</data> + <data key="label">MySQL</data> + <data key="value">mysql</data> + </entity> +</entities> diff --git a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml new file mode 100644 index 000000000000..a389efbbe443 --- /dev/null +++ b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> + <suite name="SearchEngineMysqlSuite"> + <before> + <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> + </before> + <after> + <magentoCLI stepKey="restoreSearchEngineToDefault" command="config:set {{SearchEngineDefaultConfigData.path}} {{SearchEngineDefaultConfigData.value}}"/> + </after> + <include> + <group name="SearchEngineMysql" /> + </include> + <exclude> + <group name="skip"/> + </exclude> + </suite> +</suites> From f5638becdf77f28d2d8f21933d948a057ed5ced7 Mon Sep 17 00:00:00 2001 From: Kaushik Chavda <chavda@team23.de> Date: Tue, 24 Sep 2019 17:02:18 +0200 Subject: [PATCH 0586/1172] #24581 Added unique key on eav_attribute_label table - Fixed Integration tests --- app/code/Magento/Eav/etc/db_schema_whitelist.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/etc/db_schema_whitelist.json b/app/code/Magento/Eav/etc/db_schema_whitelist.json index b3f1aca50df0..c571358a6c14 100644 --- a/app/code/Magento/Eav/etc/db_schema_whitelist.json +++ b/app/code/Magento/Eav/etc/db_schema_whitelist.json @@ -304,7 +304,8 @@ "constraint": { "PRIMARY": true, "EAV_ATTRIBUTE_LABEL_ATTRIBUTE_ID_EAV_ATTRIBUTE_ATTRIBUTE_ID": true, - "EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID": true + "EAV_ATTRIBUTE_LABEL_STORE_ID_STORE_STORE_ID": true, + "EAV_ATTRIBUTE_LABEL_STORE_ID_ATTRIBUTE_ID": true } }, "eav_form_type": { From fbf61075f612a5be444acd3f8d06ebba71a9532f Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Tue, 24 Sep 2019 10:26:31 -0500 Subject: [PATCH 0587/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality --- .../AdminCheckOutOfStockProductIsVisibleInCategoryTest.xml | 4 ++++ ...ctWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml | 4 ++++ ...ProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml | 3 +++ 3 files changed, 11 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckOutOfStockProductIsVisibleInCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckOutOfStockProductIsVisibleInCategoryTest.xml index e1cb45be22b4..a863de2716c9 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckOutOfStockProductIsVisibleInCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCheckOutOfStockProductIsVisibleInCategoryTest.xml @@ -63,6 +63,10 @@ <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="clickOnSaveButton"/> <waitForLoadingMaskToDisappear stepKey="waitForLoading"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> + + <!--Run re-index task --> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Verify product is visible in category front page --> <amOnPage url="$$createCategory.name$$.html" stepKey="openCategoryStoreFrontPage"/> <waitForPageLoad stepKey="waitForCategoryPageToLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml index 637ae790c16c..7974618cde1a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml @@ -66,6 +66,7 @@ <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForSimpleProductSave"/> + <!-- Verify customer see success message --> <see selector="{{AdminProductFormSection.successMessage}}" userInput="You saved the product." stepKey="seeAssertSimpleProductSaveSuccessMessage"/> @@ -94,6 +95,9 @@ <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="clickAdminProductSEOSection1"/> <seeInField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="{{simpleProductRegularPrice245InStock.urlKey}}" stepKey="seeUrlKey"/> + <!--Run re-index task --> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Verify customer see updated simple product link on category page --> <amOnPage url="{{StorefrontCategoryPage.url($$categoryEntity.name$$)}}" stepKey="openCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPageLoad"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml index 045b3f3420ff..4817b3497c97 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml @@ -94,6 +94,9 @@ <click selector="{{AdminProductSEOSection.sectionHeader}}" stepKey="clickAdminProductSEOSection1"/> <seeInField selector="{{AdminProductSEOSection.urlKeyInput}}" userInput="{{simpleProductRegularPrice32501InStock.urlKey}}" stepKey="seeUrlKey"/> + <!--Run re-index task --> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Verify customer see updated simple product link on category page --> <amOnPage url="{{StorefrontCategoryPage.url($$categoryEntity.name$$)}}" stepKey="openCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPageLoad"/> From 635c373b87ea9217d883b84e77d547b6600d6b6a Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 24 Sep 2019 11:36:58 -0500 Subject: [PATCH 0588/1172] MC-20255: Category Breadcrumbs are missing url_path - Added category_url_path --- .../Model/Resolver/Category/DataProvider/Breadcrumbs.php | 3 ++- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php index 9e23c4f1e973..4b217d77f686 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php @@ -41,7 +41,7 @@ public function getData(string $categoryPath): array if (count($parentCategoryIds)) { $collection = $this->collectionFactory->create(); - $collection->addAttributeToSelect(['name', 'url_key']); + $collection->addAttributeToSelect(['name', 'url_key', 'url_path']); $collection->addAttributeToFilter('entity_id', $parentCategoryIds); foreach ($collection as $category) { @@ -50,6 +50,7 @@ public function getData(string $categoryPath): array 'category_name' => $category->getName(), 'category_level' => $category->getLevel(), 'category_url_key' => $category->getUrlKey(), + 'category_url_path' => $category->getUrlPath(), ]; } } diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 76a58857cebc..f4b1320485ab 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -231,6 +231,7 @@ type Breadcrumb @doc(description: "Breadcrumb item."){ category_name: String @doc(description: "Category name.") category_level: Int @doc(description: "Category level.") category_url_key: String @doc(description: "Category URL key.") + category_url_path: String @doc(description: "Category URL path.") } type CustomizableRadioOption implements CustomizableOptionInterface @doc(description: "CustomizableRadioOption contains information about a set of radio buttons that are defined as part of a customizable option.") { From db9f61dc6e9e47b32af0b9b97fd8edce3c666066 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 24 Sep 2019 12:05:27 -0500 Subject: [PATCH 0589/1172] MC-18403: Pricing :: Product pricing schema - Tier prices --- app/code/Magento/BundleGraphQl/etc/di.xml | 4 +- .../Resolver/Customer/GetCustomerGroup.php | 67 ++++++++ .../Model/Resolver/PriceTiers.php | 148 ++++++++++++++++++ .../Model/Resolver/Product/Price/Tiers.php | 123 +++++++++++++++ .../Model/Resolver/TierPrices.php | 96 +++--------- .../CatalogCustomerGraphQl/composer.json | 3 +- .../CatalogCustomerGraphQl/etc/module.xml | 1 + .../etc/schema.graphqls | 22 ++- .../Resolver/Product/Price/ProviderPool.php | 42 +++++ .../Model/Resolver/Product/PriceRange.php | 36 ++--- app/code/Magento/CatalogGraphQl/etc/di.xml | 4 +- .../CatalogGraphQl/etc/schema.graphqls | 8 +- .../ConfigurableProductGraphQl/etc/di.xml | 4 +- .../Magento/GroupedProductGraphQl/etc/di.xml | 4 +- 14 files changed, 445 insertions(+), 117 deletions(-) create mode 100644 app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Customer/GetCustomerGroup.php create mode 100644 app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php create mode 100644 app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php diff --git a/app/code/Magento/BundleGraphQl/etc/di.xml b/app/code/Magento/BundleGraphQl/etc/di.xml index edcaa34b527f..386dd5647a59 100644 --- a/app/code/Magento/BundleGraphQl/etc/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/di.xml @@ -17,9 +17,9 @@ </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> <arguments> - <argument name="priceProviders" xsi:type="array"> + <argument name="providers" xsi:type="array"> <item name="bundle" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Customer/GetCustomerGroup.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Customer/GetCustomerGroup.php new file mode 100644 index 000000000000..65ab2940a7a5 --- /dev/null +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Customer/GetCustomerGroup.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogCustomerGraphQl\Model\Resolver\Customer; + +use Magento\Customer\Api\GroupManagementInterface; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Model\GroupManagement; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; + +/** + * Get customer group + */ +class GetCustomerGroup +{ + /** + * @var GroupManagementInterface + */ + private $groupManagement; + + /** + * @var CustomerRepositoryInterface + */ + private $customerRepository; + + /** + * @param GroupManagementInterface $groupManagement + * @param CustomerRepositoryInterface $customerRepository + */ + public function __construct( + GroupManagementInterface $groupManagement, + CustomerRepositoryInterface $customerRepository + ) { + $this->groupManagement = $groupManagement; + $this->customerRepository = $customerRepository; + } + + /** + * Get customer group by id + * + * @param int|null $customerId + * @return int + * @throws GraphQlNoSuchEntityException + */ + public function execute(?int $customerId): int + { + if (!$customerId) { + $customerGroupId = GroupManagement::NOT_LOGGED_IN_ID; + } else { + try { + $customer = $this->customerRepository->getById($customerId); + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException( + __('Customer with id "%customer_id" does not exist.', ['customer_id' => $customerId]), + $e + ); + } + $customerGroupId = $customer->getGroupId(); + } + return (int)$customerGroupId; + } +} diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php new file mode 100644 index 000000000000..a7a7a3236c41 --- /dev/null +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php @@ -0,0 +1,148 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogCustomerGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Product\Price\Tiers; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Product\Price\TiersFactory; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Customer\GetCustomerGroup; +use Magento\Store\Api\Data\StoreInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool; +use Magento\Catalog\Api\Data\ProductTierPriceInterface; + +/** + * Resolver for price_tiers + */ +class PriceTiers implements ResolverInterface +{ + /** + * @var TiersFactory + */ + private $tiersFactory; + + /** + * @var ValueFactory + */ + private $valueFactory; + + /** + * @var GetCustomerGroup + */ + private $getCustomerGroup; + + /** + * @var int + */ + private $customerGroupId; + + /** + * @var Tiers + */ + private $tiers; + + /** + * @var Discount + */ + private $discount; + + /** + * @var PriceProviderPool + */ + private $priceProviderPool; + + /** + * @param ValueFactory $valueFactory + * @param TiersFactory $tiersFactory + * @param GetCustomerGroup $getCustomerGroup + * @param Discount $discount + * @param PriceProviderPool $priceProviderPool + */ + public function __construct( + ValueFactory $valueFactory, + TiersFactory $tiersFactory, + GetCustomerGroup $getCustomerGroup, + Discount $discount, + PriceProviderPool $priceProviderPool + ) { + $this->valueFactory = $valueFactory; + $this->tiersFactory = $tiersFactory; + $this->getCustomerGroup = $getCustomerGroup; + $this->discount = $discount; + $this->priceProviderPool = $priceProviderPool; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + if (empty($this->tiers)) { + $this->customerGroupId = $this->getCustomerGroup->execute($context->getUserId()); + $this->tiers = $this->tiersFactory->create(['customerGroupId' => $this->customerGroupId]); + } + + $product = $value['model']; + $productId = $product->getId(); + $productPrice = $this->priceProviderPool + ->getProviderByProductType($product->getTypeId()) + ->getMinimalRegularPrice($product) + ->getValue(); + $this->tiers->addProductFilter($productId); + + return $this->valueFactory->create( + function () use ($productId, $productPrice, $context) { + + /** @var StoreInterface $store */ + $store = $context->getExtensionAttributes()->getStore(); + + $tierPrices = $this->tiers->getProductTierPrices($productId) ?? []; + + return $this->formatProductTierPrices($tierPrices, $productPrice, $store); + } + ); + } + + /** + * Format tier prices for output + * + * @param ProductTierPriceInterface[] $tierPrices + * @param float $productPrice + * @param StoreInterface $store + * @return array + */ + private function formatProductTierPrices(array $tierPrices, float $productPrice, StoreInterface $store): array + { + $tiers = []; + + foreach ($tierPrices as $tierPrice) { + $tiers[] = [ + "discount" => $this->discount->getPriceDiscount($productPrice, (float)$tierPrice->getValue()), + "quantity" => $tierPrice->getQty(), + "final_price" => [ + "value" => $tierPrice->getValue(), + "currency" => $store->getCurrentCurrencyCode() + ] + ]; + } + return $tiers; + } +} diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php new file mode 100644 index 000000000000..b57dc80fa771 --- /dev/null +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php @@ -0,0 +1,123 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogCustomerGraphQl\Model\Resolver\Product\Price; + +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product as ProductResource; +use Magento\Customer\Model\GroupManagement; +use Magento\Catalog\Api\Data\ProductTierPriceInterface; + +/** + * Get product tier price information + */ +class Tiers +{ + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * @var ProductResource + */ + private $productResource; + + /** + * @var bool + */ + private $loaded = false; + + /** + * @var int + */ + private $customerGroupId = GroupManagement::CUST_GROUP_ALL; + + /** + * @var array + */ + private $filterProductIds = []; + + /** + * @var array + */ + private $products = []; + + /** + * @param CollectionFactory $collectionFactory + * @param ProductResource $productResource + * @param int $customerGroupId + */ + public function __construct( + CollectionFactory $collectionFactory, + ProductResource $productResource, + $customerGroupId + ) { + $this->collectionFactory = $collectionFactory; + $this->productResource = $productResource; + $this->customerGroupId = $customerGroupId; + } + + /** + * Add product ID to collection filter + * + * @param int $productId + */ + public function addProductFilter($productId): void + { + $this->filterProductIds[] = $productId; + } + + /** + * Get tier prices for product by ID + * + * @param int $productId + * @return ProductTierPriceInterface[]|null + */ + public function getProductTierPrices($productId): ?array + { + if (!$this->isLoaded()) { + $this->load(); + } + + if (empty($this->products[$productId])) { + return null; + } + return $this->products[$productId]->getTierPrices(); + } + + /** + * Check if collection has been loaded + * + * @return bool + */ + public function isLoaded(): bool + { + return $this->loaded; + } + + /** + * Load product collection + */ + private function load(): void + { + $this->loaded = false; + + $productIdField = $this->productResource->getEntityIdField(); + /** @var Collection $productCollection */ + $productCollection = $this->collectionFactory->create(); + $productCollection->addFieldToFilter($productIdField, ['in' => $this->filterProductIds]); + $productCollection->addTierPriceDataByGroupId($this->customerGroupId); + + foreach ($productCollection as $product) { + $this->products[$product->getId()] = $product; + } + + $this->loaded = true; + } +} diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/TierPrices.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/TierPrices.php index ed657ca9a998..c449d0a2ba30 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/TierPrices.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/TierPrices.php @@ -8,17 +8,14 @@ namespace Magento\CatalogCustomerGraphQl\Model\Resolver; use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\ResourceModel\Product\Collection; -use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; -use Magento\Customer\Api\CustomerRepositoryInterface; -use Magento\Customer\Model\GroupManagement; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Customer\GetCustomerGroup; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Product\Price\Tiers; +use Magento\CatalogCustomerGraphQl\Model\Resolver\Product\Price\TiersFactory; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\Exception\NoSuchEntityException; /** * @inheritdoc @@ -26,43 +23,43 @@ class TierPrices implements ResolverInterface { /** - * @var Collection + * @var ValueFactory */ - private $collection; + private $valueFactory; /** - * @var CustomerRepositoryInterface + * @var int */ - private $customerRepository; + private $customerGroupId = null; /** - * @var ValueFactory + * @var Tiers */ - private $valueFactory; + private $tiers; /** - * @var int + * @var TiersFactory */ - private $customerGroupId = null; + private $tiersFactory; /** - * @var array + * @var GetCustomerGroup */ - private $productIds = []; + private $getCustomerGroup; /** - * @param CollectionFactory $collectionFactory * @param ValueFactory $valueFactory - * @param CustomerRepositoryInterface $customerRepository + * @param TiersFactory $tiersFactory + * @param GetCustomerGroup $getCustomerGroup */ public function __construct( - CollectionFactory $collectionFactory, ValueFactory $valueFactory, - CustomerRepositoryInterface $customerRepository + TiersFactory $tiersFactory, + GetCustomerGroup $getCustomerGroup ) { - $this->collection = $collectionFactory->create(); $this->valueFactory = $valueFactory; - $this->customerRepository = $customerRepository; + $this->tiersFactory = $tiersFactory; + $this->getCustomerGroup = $getCustomerGroup; } /** @@ -80,62 +77,21 @@ public function resolve( } if (null === $this->customerGroupId) { - $this->customerGroupId = $this->getCustomerGroupId($context); + $this->customerGroupId = $this->getCustomerGroup->execute($context->getUserId()); + $this->tiers = $this->tiersFactory->create(['customerGroupId' => $this->customerGroupId]); } /** @var Product $product */ $product = $value['model']; $productId = $product->getId(); - $this->productIds[] = $productId; - $that = $this; + $this->tiers->addProductFilter($productId); return $this->valueFactory->create( - function () use ($that, $productId, $context) { - $tierPrices = []; - if (empty($that->productIds)) { - return []; - } - if (!$that->collection->isLoaded()) { - $that->collection->addIdFilter($that->productIds); - $that->collection->addTierPriceDataByGroupId($that->customerGroupId); - } - /** @var \Magento\Catalog\Model\Product $item */ - foreach ($that->collection as $item) { - if ($item->getId() === $productId) { - // Try to extract all requested fields from the loaded collection data - foreach ($item->getTierPrices() as $tierPrice) { - $tierPrices[] = $tierPrice->getData(); - } - } - } - return $tierPrices; - } - ); - } + function () use ($productId, $context) { + $tierPrices = $this->tiers->getProductTierPrices($productId); - /** - * Get the customer group Id. - * - * @param \Magento\GraphQl\Model\Query\ContextInterface $context - * - * @return int - */ - private function getCustomerGroupId(\Magento\GraphQl\Model\Query\ContextInterface $context) - { - $currentUserId = $context->getUserId(); - if (!$currentUserId) { - $customerGroupId = GroupManagement::NOT_LOGGED_IN_ID; - } else { - try { - $customer = $this->customerRepository->getById($currentUserId); - } catch (NoSuchEntityException $e) { - throw new GraphQlNoSuchEntityException( - __('Customer with id "%customer_id" does not exist.', ['customer_id' => $currentUserId]), - $e - ); + return $tierPrices ?? []; } - $customerGroupId = $customer->getGroupId(); - } - return $customerGroupId; + ); } } diff --git a/app/code/Magento/CatalogCustomerGraphQl/composer.json b/app/code/Magento/CatalogCustomerGraphQl/composer.json index 30bb86a7523e..137f610a9614 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/composer.json +++ b/app/code/Magento/CatalogCustomerGraphQl/composer.json @@ -7,7 +7,8 @@ "magento/module-catalog": "*", "magento/module-customer": "*", "magento/framework": "*", - "magento/module-graph-ql": "*" + "magento/module-graph-ql": "*", + "magento/module-catalog-graph-ql": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml b/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml index a1b2e2957972..9ee54a01b101 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml +++ b/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml @@ -11,6 +11,7 @@ <module name="Magento_Catalog"/> <module name="Magento_Customer"/> <module name="Magento_GraphQl"/> + <module name="Magento_CatalogGraphQl"/> </sequence> </module> </config> diff --git a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls index 8cf6c6f874cf..95ca45514847 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls @@ -2,13 +2,21 @@ # See COPYING.txt for license details. interface ProductInterface { - tier_prices: [ProductTierPrices] @doc(description: "An array of ProductTierPrices objects.") @resolver(class: "Magento\\CatalogCustomerGraphQl\\Model\\Resolver\\TierPrices") + tier_prices: [ProductTierPrices] @deprecated(reason: "Use price_tiers for product tier price information.") @doc(description: "An array of ProductTierPrices objects.") @resolver(class: "Magento\\CatalogCustomerGraphQl\\Model\\Resolver\\TierPrices") + price_tiers: [TierPrice] @doc(description: "An array of TierPrice objects.") @resolver(class: "Magento\\CatalogCustomerGraphQl\\Model\\Resolver\\PriceTiers") } -type ProductTierPrices @doc(description: "The ProductTierPrices object defines a tier price, which is a quantity discount offered to a specific customer group.") { - customer_group_id: String @doc(description: "The ID of the customer group.") - qty: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") - value: Float @doc(description: "The price of the fixed price item.") - percentage_value: Float @doc(description: "The percentage discount of the item.") - website_id: Float @doc(description: "The ID assigned to the website.") +type ProductTierPrices @doc(description: "ProductTierPrices is deprecated and has been replaced by TierPrice. The ProductTierPrices object defines a tier price, which is a quantity discount offered to a specific customer group.") { + customer_group_id: String @deprecated(reason: "customer_group_id is not relevant for storefront.") @doc(description: "The ID of the customer group.") + qty: Float @deprecated(reason: "ProductTierPrices is deprecated, use TierPrice.quantity.") @doc(description: "The number of items that must be purchased to qualify for tier pricing.") + value: Float @deprecated(reason: "ProductTierPrices is deprecated. Use TierPrice.final_price") @doc(description: "The price of the fixed price item.") + percentage_value: Float @decprected(reason: "ProductTierPrices is deprecated. Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") + website_id: Float @deprecated(reason: "website_id is not relevant for storefront.") @doc(description: "The ID assigned to the website.") +} + + +type TierPrice @doc(description: "TierPrice defines a tier price, which is a price offered based on a particular quantity purchased.") { + final_price: Money @doc(desription: "The price of the product at this tier.") + quantity: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") + discount: ProductDiscount @doc(description: "The price discount that this tier represents.") } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php new file mode 100644 index 000000000000..f1f3762b8dd8 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver\Product\Price; + +/** + * Pool of price providers for different product types + */ +class ProviderPool +{ + private const DEFAULT = 'default'; + /** + * @var ProviderInterface[] + */ + private $providers; + + /** + * @param ProviderInterface[] $providers + */ + public function __construct(array $providers) + { + $this->providers = $providers; + } + + /** + * Get price provider by product type + * + * @param string $productType + * @return ProviderInterface + */ + public function getProviderByProductType(string $productType): ProviderInterface + { + if (isset($this->providers[$productType])) { + return $this->providers[$productType]; + } + return $this->providers[self::DEFAULT]; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index a80f6be289e0..d354d628445a 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -8,7 +8,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Product; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\Discount; -use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -28,17 +28,17 @@ class PriceRange implements ResolverInterface private $discount; /** - * @var array + * @var PriceProviderPool */ - private $priceProviders; + private $priceProviderPool; /** - * @param array $priceProviders + * @param PriceProviderPool $priceProviderPool * @param Discount $discount */ - public function __construct(array $priceProviders, Discount $discount) + public function __construct(PriceProviderPool $priceProviderPool, Discount $discount) { - $this->priceProviders = $priceProviders; + $this->priceProviderPool = $priceProviderPool; $this->discount = $discount; } @@ -77,8 +77,9 @@ public function resolve( */ private function getMinimumProductPrice(SaleableInterface $product, StoreInterface $store): array { - $regularPrice = $this->getPriceProvider($product)->getMinimalRegularPrice($product)->getValue(); - $finalPrice = $this->getPriceProvider($product)->getMinimalFinalPrice($product)->getValue(); + $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); + $regularPrice = $priceProvider->getMinimalRegularPrice($product)->getValue(); + $finalPrice = $priceProvider->getMinimalFinalPrice($product)->getValue(); return $this->formatPrice($regularPrice, $finalPrice, $store); } @@ -92,8 +93,9 @@ private function getMinimumProductPrice(SaleableInterface $product, StoreInterfa */ private function getMaximumProductPrice(SaleableInterface $product, StoreInterface $store): array { - $regularPrice = $this->getPriceProvider($product)->getMaximalRegularPrice($product)->getValue(); - $finalPrice = $this->getPriceProvider($product)->getMaximalFinalPrice($product)->getValue(); + $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); + $regularPrice = $priceProvider->getMaximalRegularPrice($product)->getValue(); + $finalPrice = $priceProvider->getMaximalFinalPrice($product)->getValue(); return $this->formatPrice($regularPrice, $finalPrice, $store); } @@ -120,18 +122,4 @@ private function formatPrice(float $regularPrice, float $finalPrice, StoreInterf 'discount' => $this->discount->getPriceDiscount($regularPrice, $finalPrice), ]; } - - /** - * Get price provider object - * - * @param SaleableInterface $product - * @return ProviderInterface - */ - private function getPriceProvider(SaleableInterface $product): ProviderInterface - { - if (isset($this->priceProviders[$product->getTypeId()])) { - return $this->priceProviders[$product->getTypeId()]; - } - return $this->priceProviders['default']; - } } diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index eceaafb479f8..646073df9f09 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -71,9 +71,9 @@ </type> <preference type="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider" for="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface"/> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> <arguments> - <argument name="priceProviders" xsi:type="array"> + <argument name="providers" xsi:type="array"> <item name="default" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 91397f442aff..4d27dfc47aa1 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -44,7 +44,7 @@ enum PriceTypeEnum @doc(description: "This enumeration the price type.") { type ProductPrices @deprecated(reason: "Use PriceRange instead.") @doc(description: "The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { minimalPrice: Price @deprecated(reason: "Use PriceRange.minimum_price.") @doc(description: "The lowest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the from value.") maximalPrice: Price @deprecated(reason: "Use PriceRange.maximum_price.") @doc(description: "The highest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the to value.") - regularPrice: Price @deprecated(reason: "Use regular_price from PriceRange.minimum_price or PriceRange.minimum_price.") @doc(description: "The base price of a product.") + regularPrice: Price @deprecated(reason: "Use regular_price from PriceRange.minimum_price or PriceRange.maximum_price.") @doc(description: "The base price of a product.") } type PriceRange @doc(description: "Price range for a product. If the product only has a single price minimum and maximum price will be the same."){ @@ -63,12 +63,6 @@ type ProductDiscount @doc(description: "Price discount applied to a product.") { amount_off: Float @doc(description: "The discount expressed an absolute value.") } -type TierPrice @doc(description: "TierPrice defines a tier price, which is a price offered based on a particular quantity purchased.") { - final_price: Money @doc(desription: "The price of the product at this tier.") - quantity: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") - discount: ProductDiscount @doc(description: "The price discount that this tier represents.") -} - type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { } diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml index 323390d9eb27..629a6ef84255 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml @@ -6,9 +6,9 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> <arguments> - <argument name="priceProviders" xsi:type="array"> + <argument name="providers" xsi:type="array"> <item name="configurable" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/di.xml index c0e6d0742a19..d5e208910eef 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/di.xml @@ -14,9 +14,9 @@ </arguments> </type> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\PriceRange"> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> <arguments> - <argument name="priceProviders" xsi:type="array"> + <argument name="providers" xsi:type="array"> <item name="grouped" xsi:type="object">Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> </argument> </arguments> From 4844c67145e87ae77dc30b09907fa3dfbf181fd5 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Tue, 24 Sep 2019 12:51:58 -0500 Subject: [PATCH 0590/1172] MC-20381: Elasticsearch doesn't find products by dropdown attribute values on Frontend --- .../SearchAdapter/Query/Builder/Match.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php index afd383c13421..ddf75c0a78e2 100644 --- a/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php +++ b/app/code/Magento/Elasticsearch/SearchAdapter/Query/Builder/Match.php @@ -138,7 +138,12 @@ protected function buildQueries(array $matches, array $queryValue) $transformedTypes = []; foreach ($matches as $match) { - $attributeAdapter = $this->attributeProvider->getByAttributeCode($match['field']); + $resolvedField = $this->fieldMapper->getFieldName( + $match['field'], + ['type' => FieldMapperInterface::TYPE_QUERY] + ); + + $attributeAdapter = $this->attributeProvider->getByAttributeCode($resolvedField); $fieldType = $this->fieldTypeResolver->getFieldType($attributeAdapter); $valueTransformer = $this->valueTransformerPool->get($fieldType ?? 'text'); $valueTransformerHash = \spl_object_hash($valueTransformer); @@ -151,10 +156,6 @@ protected function buildQueries(array $matches, array $queryValue) continue; } - $resolvedField = $this->fieldMapper->getFieldName( - $match['field'], - ['type' => FieldMapperInterface::TYPE_QUERY] - ); $conditions[] = [ 'condition' => $queryValue['condition'], 'body' => [ From 4e3202f6aeed48574c070a47695f514450580d0d Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Tue, 24 Sep 2019 13:03:38 -0500 Subject: [PATCH 0591/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality --- .../Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml index d17078d794b4..b613068893b0 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMoveCategoryFromParentAnchoredCategoryTest.xml @@ -59,6 +59,9 @@ <waitForPageLoad stepKey="waitForSecondCategoryToSave"/> <seeElement selector="{{AdminCategoryMessagesSection.SuccessMessage}}" stepKey="seeSuccessMessage"/> + <!--Run re-index task --> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Verify category displayed in store front page--> <amOnPage url="/$$createDefaultCategory.name$$/{{SimpleSubCategory.name}}.html" stepKey="seeTheCategoryInStoreFrontPage"/> <waitForPageLoad stepKey="waitForStoreFrontPageLoad"/> From 1fa73b7fa97c3faab2eb7356e5b6bb8c9753efb0 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 24 Sep 2019 13:22:16 -0500 Subject: [PATCH 0592/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - small refactor --- .../Magento/Sales/Cron/CleanExpiredQuotes.php | 2 +- .../Collection}/ExpiredQuotesCollection.php | 43 +++++-------------- 2 files changed, 11 insertions(+), 34 deletions(-) rename app/code/Magento/Sales/{Helper => Model/ResourceModel/Collection}/ExpiredQuotesCollection.php (66%) diff --git a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php index 04db058f4231..ca5e850038d8 100644 --- a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php +++ b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php @@ -6,7 +6,7 @@ namespace Magento\Sales\Cron; use Magento\Quote\Model\ResourceModel\Quote\Collection; -use Magento\Sales\Helper\ExpiredQuotesCollection; +use Magento\Sales\Model\ResourceModel\ExpiredQuotesCollection; use Magento\Store\Model\StoreManagerInterface; /** diff --git a/app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php similarity index 66% rename from app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php rename to app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php index 5b62a8251d54..9865951c9f55 100644 --- a/app/code/Magento/Sales/Helper/ExpiredQuotesCollection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php @@ -16,18 +16,20 @@ */ class ExpiredQuotesCollection { - const SECONDS_IN_DAY = 86400; - const QUOTE_LIFETIME = 'checkout/cart/delete_quote_after'; + /** + * @var int + */ + private $secondsInDay = 86400; /** - * @var CollectionFactory + * @var string */ - private $quoteCollectionFactory; + private $quoteLifetime = 'checkout/cart/delete_quote_after'; /** - * @var array + * @var CollectionFactory */ - private $expireQuotesFilterFields = []; + private $quoteCollectionFactory; /** * @var ScopeConfigInterface @@ -58,42 +60,17 @@ public function __construct( public function getExpiredQuotes(StoreInterface $store) { $lifetime = $this->config->getValue( - self::QUOTE_LIFETIME, + $this->quoteLifetime, ScopeInterface::SCOPE_STORE, $store->getCode() ); - $lifetime *= self::SECONDS_IN_DAY; + $lifetime *= $this->secondsInDay; /** @var $quotes Collection */ $quotes = $this->quoteCollectionFactory->create(); $quotes->addFieldToFilter('store_id', $store->getId()); $quotes->addFieldToFilter('updated_at', ['to' => date("Y-m-d", time() - $lifetime)]); - foreach ($this->getExpireQuotesAdditionalFilterFields() as $field => $condition) { - $quotes->addFieldToFilter($field, $condition); - } - return $quotes; } - - /** - * Retrieve expire quotes additional fields to filter - * - * @return array - */ - private function getExpireQuotesAdditionalFilterFields() - { - return $this->expireQuotesFilterFields; - } - - /** - * Set expire quotes additional fields to filter - * - * @param array $fields - * @return void - */ - public function setExpireQuotesAdditionalFilterFields(array $fields) - { - $this->expireQuotesFilterFields = $fields; - } } From 143179b07cdee30a3241d39098c384c5694bf28f Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 24 Sep 2019 13:59:38 -0500 Subject: [PATCH 0593/1172] MC-18403: Pricing :: Product pricing schema --- .../Model/Resolver/Product/Price/ProviderPool.php | 1 + .../Model/Resolver/Product/Price/Provider.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php index f1f3762b8dd8..a23c28a868b6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/ProviderPool.php @@ -13,6 +13,7 @@ class ProviderPool { private const DEFAULT = 'default'; + /** * @var ProviderInterface[] */ diff --git a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php index a876824d99fe..b2336a074129 100644 --- a/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/GroupedProductGraphQl/Model/Resolver/Product/Price/Provider.php @@ -9,6 +9,7 @@ use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Catalog\Pricing\Price\RegularPrice; +use Magento\Framework\Pricing\PriceInfoInterface; use Magento\Framework\Pricing\Amount\AmountInterface; use Magento\Framework\Pricing\SaleableInterface; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; @@ -80,6 +81,7 @@ private function getMinimalProductAmount(SaleableInterface $product, string $pri $products = $product->getTypeInstance()->getAssociatedProducts($product); $minPrice = null; foreach ($products as $item) { + $item->setQty(PriceInfoInterface::PRODUCT_QUANTITY_DEFAULT); $price = $item->getPriceInfo()->getPrice($priceType); $priceValue = $price->getValue(); if (($priceValue !== false) && ($priceValue <= ($minPrice === null ? $priceValue : $minPrice))) { From ee5e71612a7a3251d11df6a7e81b854cfed1ad14 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 24 Sep 2019 14:03:32 -0500 Subject: [PATCH 0594/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - static test fix --- .../Model/ResourceModel/Collection/ExpiredQuotesCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php index 9865951c9f55..390f8e51499f 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php @@ -3,7 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Sales\Helper; +namespace Magento\Sales\Model\ResourceModel\Collection; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Quote\Model\ResourceModel\Quote\Collection; From b7faf2473d5e077d5054bb0dec6c1099bd03e9a8 Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Tue, 24 Sep 2019 14:21:04 -0500 Subject: [PATCH 0595/1172] MC-20255: Category Breadcrumbs are missing url_path - Added api functional test --- .../Magento/GraphQl/Catalog/CategoryTest.php | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php index cc0ef7aaf0f5..8f0260a1b1da 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryTest.php @@ -502,6 +502,57 @@ public function testAnchorCategory() $this->assertEquals($expectedResponse, $response); } + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testBreadCrumbs() + { + /** @var CategoryCollection $categoryCollection */ + $categoryCollection = $this->objectManager->create(CategoryCollection::class); + $categoryCollection->addFieldToFilter('name', 'Category 1.1.1'); + /** @var CategoryInterface $category */ + $category = $categoryCollection->getFirstItem(); + $categoryId = $category->getId(); + $this->assertNotEmpty($categoryId, "Preconditions failed: category is not available."); + $query = <<<QUERY +{ + category(id: {$categoryId}) { + name + breadcrumbs { + category_id + category_name + category_level + category_url_key + category_url_path + } + } +} +QUERY; + $response = $this->graphQlQuery($query); + $expectedResponse = [ + 'category' => [ + 'name' => 'Category 1.1.1', + 'breadcrumbs' => [ + [ + 'category_id' => 3, + 'category_name' => "Category 1", + 'category_level' => 2, + 'category_url_key' => "category-1", + 'category_url_path' => "category-1" + ], + [ + 'category_id' => 4, + 'category_name' => "Category 1.1", + 'category_level' => 3, + 'category_url_key' => "category-1-1", + 'category_url_path' => "category-1/category-1-1" + ], + ] + ] + ]; + $this->assertEquals($expectedResponse, $response); + } + /** * @param ProductInterface $product * @param array $actualResponse From 58c0999ce5f2bfe30535ce8e546051e7ed9a0821 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Tue, 24 Sep 2019 14:30:27 -0500 Subject: [PATCH 0596/1172] MC-20358: Create New MFTF Suites for MySQL/Elasticsearch Specific Functionality --- .../Elasticsearch6/Test/Mftf/Data/ConfigData.xml | 16 ++++++++++++++++ .../Magento/Search/Test/Mftf/Data/ConfigData.xml | 6 ------ .../Test/Mftf/Suite/SearchEngineMysqlSuite.xml | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 app/code/Magento/Elasticsearch6/Test/Mftf/Data/ConfigData.xml diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Data/ConfigData.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Data/ConfigData.xml new file mode 100644 index 000000000000..f1f2f39f4457 --- /dev/null +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Data/ConfigData.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SearchEngineElasticsearchConfigData"> + <data key="path">catalog/search/engine</data> + <data key="scope_id">1</data> + <data key="label">Elasticsearch 6.0+</data> + <data key="value">elasticsearch6</data> + </entity> +</entities> diff --git a/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml b/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml index 1761e9a73576..4a742b290c98 100644 --- a/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml +++ b/app/code/Magento/Search/Test/Mftf/Data/ConfigData.xml @@ -7,12 +7,6 @@ --> <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="SearchEngineDefaultConfigData"> - <data key="path">catalog/search/engine</data> - <data key="scope_id">1</data> - <data key="label">Elasticsearch 6.0+</data> - <data key="value">elasticsearch6</data> - </entity> <entity name="SearchEngineMysqlConfigData"> <data key="path">catalog/search/engine</data> <data key="scope_id">1</data> diff --git a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml index a389efbbe443..7fb3c5474d89 100644 --- a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml +++ b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml @@ -11,7 +11,7 @@ <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> </before> <after> - <magentoCLI stepKey="restoreSearchEngineToDefault" command="config:set {{SearchEngineDefaultConfigData.path}} {{SearchEngineDefaultConfigData.value}}"/> + <magentoCLI stepKey="setSearchEngineToElasticsearch" command="config:set {{SearchEngineElasticsearchConfigData.path}} {{SearchEngineElasticsearchConfigData.value}}"/> </after> <include> <group name="SearchEngineMysql" /> From 1e821dd8aa6f11c9fbef3c2f6b118c03c3b17a92 Mon Sep 17 00:00:00 2001 From: Sergey Dovbenko <sdovbenko@magecom.us> Date: Tue, 24 Sep 2019 19:59:12 +0000 Subject: [PATCH 0597/1172] Corrected Code Styles --- .../Quote/AddSimpleProductWithCustomOptionsToCartTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php index 272c0df29e04..95f2e05e6395 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/AddSimpleProductWithCustomOptionsToCartTest.php @@ -127,7 +127,8 @@ public function testAddSimpleProductWithDateOption() self::assertArrayHasKey('items', $response['addSimpleProductsToCart']['cart']); self::assertCount(1, $response['addSimpleProductsToCart']['cart']); - $customizableOptionOutput = $response['addSimpleProductsToCart']['cart']['items'][0]['customizable_options'][0]['values'][0]['value']; + $cartItem = $response['addSimpleProductsToCart']['cart']['items'][0]; + $customizableOptionOutput = $cartItem['customizable_options'][0]['values'][0]['value']; $expectedValue = date("M d, Y", strtotime($customOptionsValues[0]['value_string'])); self::assertEquals($expectedValue, $customizableOptionOutput); From b00b336dc7356e1d775217eddc0f217e75f58b6d Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 24 Sep 2019 16:04:26 -0500 Subject: [PATCH 0598/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - static test fails namespaces --- app/code/Magento/Sales/Cron/CleanExpiredQuotes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php index ca5e850038d8..a3242228b28e 100644 --- a/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php +++ b/app/code/Magento/Sales/Cron/CleanExpiredQuotes.php @@ -6,7 +6,7 @@ namespace Magento\Sales\Cron; use Magento\Quote\Model\ResourceModel\Quote\Collection; -use Magento\Sales\Model\ResourceModel\ExpiredQuotesCollection; +use Magento\Sales\Model\ResourceModel\Collection\ExpiredQuotesCollection; use Magento\Store\Model\StoreManagerInterface; /** From 7ec3c72ee14b40e1326e44fab82cbe179c0fe84c Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 24 Sep 2019 14:15:16 -0500 Subject: [PATCH 0599/1172] MC-20181: Elasticsearch failing with fielddata error --- .../LayeredNavigation/Test/TestCase/FilterProductListTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml index 9c9c917f8a66..72b89916a08d 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml @@ -95,6 +95,7 @@ </variation> <variation name="FilterProductListTestVariation4" summary="Use sorting category filter when layered navigation is applied" ticketId="MAGETWO-42701"> <data name="configData" xsi:type="string">layered_navigation_manual_range_10</data> + <data name="runReindex" xsi:type="boolean">true</data> <data name="category/dataset" xsi:type="string">default_anchor_subcategory</data> <data name="category/data/category_products/dataset" xsi:type="string">catalogProductSimple::product_10_dollar, catalogProductSimple::product_20_dollar, configurableProduct::filterable_two_options_with_zero_price</data> <data name="layeredNavigation" xsi:type="array"> From ede0d63dd0237e5c3d7b041c2a85930b9e15cd92 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Tue, 24 Sep 2019 17:00:32 -0500 Subject: [PATCH 0600/1172] MC-20358: Create New MFTF Suites for MySQL/Elasticsearch Specific Functionality --- .../Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml | 10 ++++++++++ .../Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml index ff2b86d3abd5..81debdb0d448 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml @@ -7,6 +7,16 @@ --> <suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> <suite name="SearchEngineElasticsearchSuite"> + <before> + <magentoCLI stepKey="setSearchEngineToElasticsearch" command="config:set {{SearchEngineElasticsearchConfigData.path}} {{SearchEngineElasticsearchConfigData.value}}"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </after> <include> <group name="SearchEngineElasticsearch" /> </include> diff --git a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml index 7fb3c5474d89..eaa90f7590bf 100644 --- a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml +++ b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml @@ -7,12 +7,6 @@ --> <suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> <suite name="SearchEngineMysqlSuite"> - <before> - <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> - </before> - <after> - <magentoCLI stepKey="setSearchEngineToElasticsearch" command="config:set {{SearchEngineElasticsearchConfigData.path}} {{SearchEngineElasticsearchConfigData.value}}"/> - </after> <include> <group name="SearchEngineMysql" /> </include> From 6d0225b9bccf11395b12861561a10abe1f26425b Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Tue, 24 Sep 2019 17:05:01 -0500 Subject: [PATCH 0601/1172] MC-18403: Pricing :: Product pricing schema - fix bundle product fixed pricing --- .../Magento/BundleGraphQl/etc/graphql/di.xml | 10 ++++++ .../AttributeProcessor.php | 33 ++++++++++++++----- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 10 ++++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml index 50a2e32b8c9d..e9f76386c535 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml @@ -40,4 +40,14 @@ </argument> </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\AttributeProcessor"> + <arguments> + <argument name="fieldToAttributeMap" xsi:type="array"> + <item name="price_range" xsi:type="array"> + <item name="price_type" xsi:type="string">price_type</item> + </item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php index 824551f31ac5..2ad05fbfa1e0 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/Product/CollectionProcessor/AttributeProcessor.php @@ -23,9 +23,7 @@ class AttributeProcessor implements CollectionProcessorInterface * * @var array */ - private $fieldToAttributeMap = [ - 'price_range' => 'price' - ]; + private $fieldToAttributeMap = []; /** * @param array $fieldToAttributeMap @@ -44,13 +42,32 @@ public function process( array $attributeNames ): Collection { foreach ($attributeNames as $name) { - $attributeName = $name; - if (isset($this->fieldToAttributeMap[$name])) { - $attributeName = $this->fieldToAttributeMap[$name]; - } - $collection->addAttributeToSelect($attributeName); + $this->addAttribute($collection, $name); } return $collection; } + + /** + * Add attribute to collection select + * + * @param Collection $collection + * @param string $attribute + */ + private function addAttribute(Collection $collection, string $attribute): void + { + if (isset($this->fieldToAttributeMap[$attribute])) { + $attributeMap = $this->fieldToAttributeMap[$attribute]; + if (is_array($attributeMap)) { + foreach ($attributeMap as $attributeName) { + $collection->addAttributeToSelect($attributeName); + } + } else { + $collection->addAttributeToSelect($attributeMap); + } + + } else { + $collection->addAttributeToSelect($attribute); + } + } } diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index fe3413dc3b21..56b881a35a8c 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -118,4 +118,14 @@ </argument> </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\AttributeProcessor"> + <arguments> + <argument name="fieldToAttributeMap" xsi:type="array"> + <item name="price_range" xsi:type="array"> + <item name="price" xsi:type="string">price</item> + </item> + </argument> + </arguments> + </type> </config> From 9c9172f2e5ecf68257fc14968b0775714418e10c Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 24 Sep 2019 17:10:25 -0500 Subject: [PATCH 0602/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - small changes --- .../ResourceModel/Collection/ExpiredQuotesCollection.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php index 390f8e51499f..785427b7040d 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Sales\Model\ResourceModel\Collection; use Magento\Framework\App\Config\ScopeConfigInterface; @@ -57,7 +59,7 @@ public function __construct( * @param StoreInterface $store * @return Collection */ - public function getExpiredQuotes(StoreInterface $store) + public function getExpiredQuotes(StoreInterface $store): Collection { $lifetime = $this->config->getValue( $this->quoteLifetime, From 7774abcb8ffb50937ad568893c073d997164b62d Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Tue, 24 Sep 2019 14:08:29 -0500 Subject: [PATCH 0603/1172] MC-20346: Update Regions list for Belgium country --- .../Customer/Test/Mftf/Data/AddressData.xml | 15 +++ ...efrontUpdateCustomerAddressBelgiumTest.xml | 51 ++++++++++ .../Setup/Patch/Data/AddDataForBelgium.php | 94 +++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml create mode 100644 app/code/Magento/Directory/Setup/Patch/Data/AddDataForBelgium.php diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 4d7a39b3246e..f1d1a1d683db 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -312,4 +312,19 @@ <data key="postcode">90230</data> <data key="telephone">555-55-555-55</data> </entity> + <entity name="updateCustomerBelgiumAddress" type="address"> + <data key="firstname">John</data> + <data key="lastname">Doe</data> + <data key="company">Magento</data> + <array key="street"> + <item>Chaussee de Wavre</item> + <item>318</item> + </array> + <data key="city">Bihain</data> + <data key="state">Hainaut</data> + <data key="country_id">BE</data> + <data key="country">Belgium</data> + <data key="postcode">6690</data> + <data key="telephone">0477-58-77867</data> + </entity> </entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml new file mode 100644 index 000000000000..6c0615f701df --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontUpdateCustomerAddressBelgiumTest.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontUpdateCustomerAddressBelgiumTest"> + <annotations> + <stories value="Update Regions list for Belgium country"/> + <title value="Update customer address on storefront with Belgium address"/> + <description value="Update customer address on storefront with Belgium address and verify you can select a region"/> + <testCaseId value="MC-20234"/> + <severity value="AVERAGE"/> + <group value="customer"/> + </annotations> + + <before> + <actionGroup ref = "LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="SignUpNewUserFromStorefrontActionGroup" stepKey="SignUpNewUser"> + <argument name="Customer" value="CustomerEntityOne"/> + </actionGroup> + </before> + <after> + <actionGroup ref="DeleteCustomerByEmailActionGroup" stepKey="deleteNewUser"> + <argument name="email" value="{{CustomerEntityOne.email}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!--Update customer address Belgium in storefront--> + <actionGroup ref="EnterCustomerAddressInfo" stepKey="enterAddress"> + <argument name="Address" value="updateCustomerBelgiumAddress"/> + </actionGroup> + <!--Verify customer address save success message--> + <see selector="{{AdminCustomerMessagesSection.successMessage}}" userInput="You saved the address." stepKey="seeAssertCustomerAddressSuccessSaveMessage"/> + + <!--Verify customer default billing address--> + <actionGroup ref="VerifyCustomerBillingAddressWithState" stepKey="verifyBillingAddress"> + <argument name="address" value="updateCustomerBelgiumAddress"/> + </actionGroup> + + <!--Verify customer default shipping address--> + <actionGroup ref="VerifyCustomerShippingAddressWithState" stepKey="verifyShippingAddress"> + <argument name="address" value="updateCustomerBelgiumAddress"/> + </actionGroup> + </test> +</tests> diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForBelgium.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForBelgium.php new file mode 100644 index 000000000000..7e53198cb9a4 --- /dev/null +++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForBelgium.php @@ -0,0 +1,94 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Directory\Setup\Patch\Data; + +use Magento\Directory\Setup\DataInstaller; +use Magento\Framework\Setup\ModuleDataSetupInterface; +use Magento\Framework\Setup\Patch\DataPatchInterface; + +/** + * Add Regions for Belgium. + */ +class AddDataForBelgium implements DataPatchInterface +{ + /** + * @var ModuleDataSetupInterface + */ + private $moduleDataSetup; + + /** + * @var \Magento\Directory\Setup\DataInstallerFactory + */ + private $dataInstallerFactory; + + /** + * @param ModuleDataSetupInterface $moduleDataSetup + * @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + */ + public function __construct( + ModuleDataSetupInterface $moduleDataSetup, + \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory + ) { + $this->moduleDataSetup = $moduleDataSetup; + $this->dataInstallerFactory = $dataInstallerFactory; + } + + /** + * @inheritdoc + */ + public function apply() + { + /** @var DataInstaller $dataInstaller */ + $dataInstaller = $this->dataInstallerFactory->create(); + $dataInstaller->addCountryRegions( + $this->moduleDataSetup->getConnection(), + $this->getDataForBelgium() + ); + } + + /** + * Belgium states data. + * + * @return array + */ + private function getDataForBelgium() + { + return [ + ['BE', 'VAN', 'Antwerpen'], + ['BE', 'WBR', 'Brabant wallon'], + ['BE', 'BRU', 'Brussels Hoofdstedelijk Gewest'], + ['BE', 'WHT', 'Hainaut'], + ['BE', 'VLI', 'Limburg'], + ['BE', 'WLG', 'Liege'], + ['BE', 'WLX', 'Luxembourg'], + ['BE', 'WNA', 'Namur'], + ['BE', 'VOV', 'Oost-Vlaanderen'], + ['BE', 'VLG', 'Vlaams Gewest'], + ['BE', 'VBR', 'Vlaams-Brabant'], + ['BE', 'VWV', 'West-Vlaanderen'], + ['BE', 'WAL', 'Wallonne, Region'] + ]; + } + + /** + * @inheritdoc + */ + public static function getDependencies() + { + return [ + InitializeDirectoryData::class, + ]; + } + + /** + * @inheritdoc + */ + public function getAliases() + { + return []; + } +} From 391d449c2b710e1079687cf8b5e9ab6319c78247 Mon Sep 17 00:00:00 2001 From: OlgaVasyltsun <olga.vasyltsun@gmail.com> Date: Wed, 25 Sep 2019 07:55:52 +0300 Subject: [PATCH 0604/1172] MC-20292: Automation MC-11396 --- .../StorefrontOpenProductPageActionGroup.xml | 11 ++++++++ .../Mftf/Data/CatalogConfigurationData.xml | 25 +++++++++++++++++++ .../Catalog/Test/Mftf/Data/ProductData.xml | 9 +++++++ .../Page/StorefrontStoreViewProductPage.xml | 14 +++++++++++ .../Store/Test/Mftf/Data/StoreData.xml | 5 +++- 5 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogConfigurationData.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Page/StorefrontStoreViewProductPage.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontOpenProductPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontOpenProductPageActionGroup.xml index 899603aa27d7..e0229906ad55 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontOpenProductPageActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontOpenProductPageActionGroup.xml @@ -18,4 +18,15 @@ <amOnPage url="{{StorefrontProductPage.url(productUrl)}}" stepKey="openProductPage"/> <waitForPageLoad stepKey="waitForProductPageLoaded"/> </actionGroup> + <actionGroup name="StorefrontOpenProductPageOnSecondStore"> + <annotations> + <description>Goes to the Storefront Product page for the provided store code and Product URL.</description> + </annotations> + <arguments> + <argument name="storeCode" type="string"/> + <argument name="productUrl" type="string"/> + </arguments> + + <amOnPage url="{{StorefrontStoreViewProductPage.url(storeCode,productUrl)}}" stepKey="openProductPage"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogConfigurationData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogConfigurationData.xml new file mode 100644 index 000000000000..cb2bacfd2f2d --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogConfigurationData.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <!-- Catalog > Price --> + <entity name="GlobalCatalogPriceScopeConfigData"> + <!-- Default configuration --> + <data key="path">catalog/price/scope</data> + <data key="scope_id">0</data> + <data key="label">Global</data> + <data key="value">0</data> + </entity> + <entity name="WebsiteCatalogPriceScopeConfigData"> + <data key="path">catalog/price/scope</data> + <data key="scope_id">0</data> + <data key="label">Website</data> + <data key="value">1</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index e122615eb8aa..55b5089e5b0a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -1224,4 +1224,13 @@ <requiredEntity type="product_extension_attribute">EavStock1</requiredEntity> <requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity> </entity> + <entity name="SimpleProductUpdatePrice11" type="product2"> + <data key="price">11.00</data> + </entity> + <entity name="SimpleProductUpdatePrice14" type="product2"> + <data key="price">14.00</data> + </entity> + <entity name="SimpleProductUpdatePrice16" type="product2"> + <data key="price">16.00</data> + </entity> </entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontStoreViewProductPage.xml b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontStoreViewProductPage.xml new file mode 100644 index 000000000000..046323bb368d --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Page/StorefrontStoreViewProductPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <!-- It is created to open product page with store code setting--> + <page name="StorefrontStoreViewProductPage" url="/{{storeCode}}/{{productUrlKey}}.html" area="storefront" module="Magento_Catalog" parameterized="true"> + </page> +</pages> diff --git a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml index 1a1847bf3830..982d829b5715 100644 --- a/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml +++ b/app/code/Magento/Store/Test/Mftf/Data/StoreData.xml @@ -11,6 +11,9 @@ <data key="code">default</data> <data key="is_active">1</data> </entity> + <entity name="DefaultAllStoreView" type="store"> + <data key="name">All Store Views</data> + </entity> <entity name="customStore" type="store"> <!--data key="group_id">customStoreGroup.id</data--> <data key="name" unique="suffix">store</data> @@ -194,4 +197,4 @@ <data key="name">third_store_view</data> <data key="code">third_store_view</data> </entity> -</entities> \ No newline at end of file +</entities> From 542395bbacc83eb4d28c1b835ea1a462ec600bef Mon Sep 17 00:00:00 2001 From: Vaha <vaha@atwix.com> Date: Wed, 25 Sep 2019 09:57:54 +0300 Subject: [PATCH 0605/1172] magento/graphql-ce#877 renamed order_id for Order type (added order_number, marked order_id as deprecated) --- .../Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php | 2 ++ .../Model/Resolver/SetPaymentAndPlaceOrder.php | 2 ++ app/code/Magento/QuoteGraphQl/etc/schema.graphqls | 3 ++- .../Customer/SetPaymentMethodTest.php | 6 +++--- .../AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php | 6 +++--- .../GraphQl/Braintree/Customer/SetPaymentMethodTest.php | 6 +++--- .../GraphQl/Braintree/Guest/SetPaymentMethodTest.php | 6 +++--- .../GraphQl/Quote/Customer/CheckoutEndToEndTest.php | 8 ++++---- .../Magento/GraphQl/Quote/Customer/PlaceOrderTest.php | 8 ++++---- .../Quote/Customer/SetPaymentMethodAndPlaceOrderTest.php | 6 +++--- .../GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php | 2 +- .../Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php | 6 +++--- .../Magento/GraphQl/Quote/Guest/PlaceOrderTest.php | 8 ++++---- .../Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php | 6 +++--- .../Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php | 6 +++--- .../Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php | 6 +++--- .../Customer/PaypalExpressSetPaymentMethodTest.php | 6 +++--- .../Resolver/Customer/PlaceOrderWithPayflowLinkTest.php | 6 +++--- .../Resolver/Customer/PlaceOrderWithPayflowProTest.php | 6 +++--- .../Resolver/Guest/PaypalExpressSetPaymentMethodTest.php | 6 +++--- .../Guest/PaypalPayflowProSetPaymentMethodTest.php | 6 +++--- .../Model/Resolver/Guest/PlaceOrderWithHostedProTest.php | 8 ++++---- .../Resolver/Guest/PlaceOrderWithPayflowLinkTest.php | 8 ++++---- .../Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php | 6 +++--- 24 files changed, 72 insertions(+), 67 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php index 1a0740a75c8f..3a10c773c5f2 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/PlaceOrder.php @@ -89,6 +89,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'order' => [ + 'order_number' => $order->getIncrementId(), + // @deprecated The order_id field is deprecated, use order_number instead 'order_id' => $order->getIncrementId(), ], ]; diff --git a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentAndPlaceOrder.php b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentAndPlaceOrder.php index 03e1e6ffe822..dd4ce8fe7f7a 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentAndPlaceOrder.php +++ b/app/code/Magento/QuoteGraphQl/Model/Resolver/SetPaymentAndPlaceOrder.php @@ -99,6 +99,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return [ 'order' => [ + 'order_number' => $order->getIncrementId(), + // @deprecated The order_id field is deprecated, use order_number instead 'order_id' => $order->getIncrementId(), ], ]; diff --git a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls index 0904268316fb..221f8ba2e620 100644 --- a/app/code/Magento/QuoteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/QuoteGraphQl/etc/schema.graphqls @@ -358,5 +358,6 @@ type CartItemSelectedOptionValuePrice { } type Order { - order_id: String + order_number: String! + order_id: String @deprecated(reason: "The order_id field is deprecated, use order_number instead.") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php index 5f70cf4fd668..e975892019a6 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php @@ -220,8 +220,8 @@ private function assertPlaceOrderResponse(array $response, string $reservedOrder { self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } private function assertSetPaymentMethodResponse(array $response, string $methodCode): void @@ -278,7 +278,7 @@ private function getPlaceOrderMutation(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php index 3bd7ade23ae4..322d984f5fa7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Guest/SetPaymentMethodTest.php @@ -113,8 +113,8 @@ private function assertPlaceOrderResponse(array $response, string $reservedOrder { self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } private function assertSetPaymentMethodResponse(array $response, string $methodCode): void @@ -171,7 +171,7 @@ private function getPlaceOrderMutation(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php index 84a639af30b0..269442368795 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php @@ -273,8 +273,8 @@ private function assertPlaceOrderResponse(array $response, string $reservedOrder { self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } private function assertSetPaymentMethodResponse(array $response, string $methodCode): void @@ -407,7 +407,7 @@ private function getPlaceOrderQuery(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Guest/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Guest/SetPaymentMethodTest.php index 1d48c5253fe8..5ee7dd457657 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Guest/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Guest/SetPaymentMethodTest.php @@ -159,8 +159,8 @@ private function assertPlaceOrderResponse(array $response, string $reservedOrder { self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } private function assertSetPaymentMethodResponse(array $response, string $methodCode): void @@ -259,7 +259,7 @@ private function getPlaceOrderQuery(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php index 6a06b143d5fc..273799446a8e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/CheckoutEndToEndTest.php @@ -426,7 +426,7 @@ private function placeOrder(string $cartId): string } ) { order { - order_id + order_number } } } @@ -434,10 +434,10 @@ private function placeOrder(string $cartId): string $response = $this->graphQlMutation($query, [], '', $this->headers); self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertNotEmpty($response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertNotEmpty($response['placeOrder']['order']['order_number']); - return $response['placeOrder']['order']['order_id']; + return $response['placeOrder']['order']['order_number']; } /** diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php index cb471d8f0f93..38d9ddc4fecc 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/PlaceOrderTest.php @@ -86,8 +86,8 @@ public function testPlaceOrder() $response = $this->graphQlMutation($query, [], '', $this->getHeaderMap()); self::assertArrayHasKey('placeOrder', $response); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } /** @@ -114,7 +114,7 @@ public function testPlaceOrderIfCartIdIsMissed() mutation { placeOrder(input: {}) { order { - order_id + order_number } } } @@ -313,7 +313,7 @@ private function getQuery(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodAndPlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodAndPlaceOrderTest.php index 192c10a67aa6..981b2af6a9a0 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodAndPlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Customer/SetPaymentMethodAndPlaceOrderTest.php @@ -85,7 +85,7 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); } /** @@ -128,7 +128,7 @@ public function testSetPaymentOnCartWithVirtualProduct() self::assertEquals($methodCode, $response['setPaymentMethodOnCart']['cart']['selected_payment_method']['code']); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); } /** @@ -254,7 +254,7 @@ private function getQuery( } ) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php index 16f291be9107..bb9fc77d0a71 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/AllowGuestCheckoutOptionTest.php @@ -318,7 +318,7 @@ private function getQuery(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php index 95308a350c95..6fbff7659c63 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/CheckoutEndToEndTest.php @@ -386,7 +386,7 @@ private function placeOrder(string $cartId): void } ) { order { - order_id + order_number } } } @@ -394,8 +394,8 @@ private function placeOrder(string $cartId): void $response = $this->graphQlMutation($query); self::assertArrayHasKey('placeOrder', $response); self::assertArrayHasKey('order', $response['placeOrder']); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertNotEmpty($response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertNotEmpty($response['placeOrder']['order']['order_number']); } public function tearDown() diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php index 2dc5b53b31c7..52caf836d3b4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/PlaceOrderTest.php @@ -79,8 +79,8 @@ public function testPlaceOrder() $response = $this->graphQlMutation($query); self::assertArrayHasKey('placeOrder', $response); - self::assertArrayHasKey('order_id', $response['placeOrder']['order']); - self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_id']); + self::assertArrayHasKey('order_number', $response['placeOrder']['order']); + self::assertEquals($reservedOrderId, $response['placeOrder']['order']['order_number']); } /** @@ -105,7 +105,7 @@ public function testPlaceOrderIfCartIdIsMissed() mutation { placeOrder(input: {}) { order { - order_id + order_number } } } @@ -304,7 +304,7 @@ private function getQuery(string $maskedQuoteId): string mutation { placeOrder(input: {cart_id: "{$maskedQuoteId}"}) { order { - order_id + order_number } } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php index 50fd9647d7c5..e38ccf78d420 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/Guest/SetPaymentMethodAndPlaceOrderTest.php @@ -73,7 +73,7 @@ public function testSetPaymentOnCartWithSimpleProduct() self::assertArrayHasKey('setPaymentMethodAndPlaceOrder', $response); self::assertArrayHasKey('order', $response['setPaymentMethodAndPlaceOrder']); - self::assertArrayHasKey('order_id', $response['setPaymentMethodAndPlaceOrder']['order']); + self::assertArrayHasKey('order_number', $response['setPaymentMethodAndPlaceOrder']['order']); } /** @@ -111,7 +111,7 @@ public function testSetPaymentOnCartWithVirtualProduct() self::assertArrayHasKey('setPaymentMethodAndPlaceOrder', $response); self::assertArrayHasKey('order', $response['setPaymentMethodAndPlaceOrder']); - self::assertArrayHasKey('order_id', $response['setPaymentMethodAndPlaceOrder']['order']); + self::assertArrayHasKey('order_number', $response['setPaymentMethodAndPlaceOrder']['order']); } /** @@ -232,7 +232,7 @@ private function getQuery( } }) { order { - order_id + order_number } } } diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php index 794e589002e7..fa3869d49bd2 100644 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php +++ b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Customer/PlaceOrderWithAuthorizeNetTest.php @@ -108,7 +108,7 @@ public function testDispatchToPlaceOrderWithRegisteredCustomer(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } @@ -142,12 +142,12 @@ public function testDispatchToPlaceOrderWithRegisteredCustomer(): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } diff --git a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php index 070543a0880e..4946448f91cc 100644 --- a/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php +++ b/dev/tests/integration/testsuite/Magento/AuthorizenetGraphQl/Model/Resolver/Guest/PlaceOrderWithAuthorizeNetTest.php @@ -108,7 +108,7 @@ public function testDispatchToPlaceAnOrderWithAuthorizenet(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } @@ -137,12 +137,12 @@ public function testDispatchToPlaceAnOrderWithAuthorizenet(): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PaypalExpressSetPaymentMethodTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PaypalExpressSetPaymentMethodTest.php index cfefd7d3e6d6..3528fd744fe0 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PaypalExpressSetPaymentMethodTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PaypalExpressSetPaymentMethodTest.php @@ -113,7 +113,7 @@ public function testResolve(string $paymentMethod): void } placeOrder(input: {cart_id: "{$maskedCartId}"}) { order { - order_id + order_number } } } @@ -205,11 +205,11 @@ public function testResolve(string $paymentMethod): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowLinkTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowLinkTest.php index d55820ccffc1..51745fb6aaf9 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowLinkTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowLinkTest.php @@ -134,7 +134,7 @@ public function testResolvePlaceOrderWithPayflowLinkForCustomer(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } @@ -190,11 +190,11 @@ public function testResolvePlaceOrderWithPayflowLinkForCustomer(): void $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowProTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowProTest.php index 899af918b04b..024340dc91c2 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowProTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Customer/PlaceOrderWithPayflowProTest.php @@ -122,7 +122,7 @@ public function testResolveCustomer(): void } placeOrder(input: {cart_id: "{$cartId}"}) { order { - order_id + order_number } } } @@ -207,11 +207,11 @@ public function testResolveCustomer(): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalExpressSetPaymentMethodTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalExpressSetPaymentMethodTest.php index 1b5f14c7df63..6744b9209281 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalExpressSetPaymentMethodTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalExpressSetPaymentMethodTest.php @@ -112,7 +112,7 @@ public function testResolveGuest(string $paymentMethod): void } placeOrder(input: {cart_id: "{$cartId}"}) { order { - order_id + order_number } } } @@ -191,11 +191,11 @@ public function testResolveGuest(string $paymentMethod): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalPayflowProSetPaymentMethodTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalPayflowProSetPaymentMethodTest.php index 0e1a74fa817d..69fe913a9161 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalPayflowProSetPaymentMethodTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PaypalPayflowProSetPaymentMethodTest.php @@ -122,7 +122,7 @@ public function testResolveGuest(): void } placeOrder(input: {cart_id: "{$cartId}"}) { order { - order_id + order_number } } } @@ -198,11 +198,11 @@ public function testResolveGuest(): void ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithHostedProTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithHostedProTest.php index a8136fda73c0..bf716fe19d17 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithHostedProTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithHostedProTest.php @@ -115,7 +115,7 @@ public function testPlaceOrderWithHostedPro(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } @@ -140,11 +140,11 @@ public function testPlaceOrderWithHostedPro(): void $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } @@ -189,7 +189,7 @@ public function testOrderWithHostedProDeclined(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPayflowLinkTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPayflowLinkTest.php index f4fe3e7e60fd..7f13d11ce98c 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPayflowLinkTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPayflowLinkTest.php @@ -133,7 +133,7 @@ public function testResolvePlaceOrderWithPayflowLink(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } @@ -183,11 +183,11 @@ public function testResolvePlaceOrderWithPayflowLink(): void $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] ); $this->assertTrue( - isset($responseData['data']['placeOrder']['order']['order_id']) + isset($responseData['data']['placeOrder']['order']['order_number']) ); $this->assertEquals( 'test_quote', - $responseData['data']['placeOrder']['order']['order_id'] + $responseData['data']['placeOrder']['order']['order_number'] ); } @@ -235,7 +235,7 @@ public function testResolveWithPayflowLinkDeclined(): void } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } diff --git a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php index a40a56be5fae..6a757cbb102e 100644 --- a/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php +++ b/dev/tests/integration/testsuite/Magento/PaypalGraphQl/Model/Resolver/Guest/PlaceOrderWithPaymentsAdvancedTest.php @@ -149,8 +149,8 @@ public function testResolvePlaceOrderWithPaymentsAdvanced(): void $paymentMethod, $responseData['data']['setPaymentMethodOnCart']['cart']['selected_payment_method']['code'] ); - $this->assertNotEmpty(isset($responseData['data']['placeOrder']['order']['order_id'])); - $this->assertEquals('test_quote', $responseData['data']['placeOrder']['order']['order_id']); + $this->assertNotEmpty(isset($responseData['data']['placeOrder']['order']['order_number'])); + $this->assertEquals('test_quote', $responseData['data']['placeOrder']['order']['order_number']); } /** @@ -265,7 +265,7 @@ private function setPaymentMethodAndPlaceOrder(string $cartId, string $paymentMe } placeOrder(input: {cart_id: "$cartId"}) { order { - order_id + order_number } } } From 6998007cd070876782f7d74a460c084f3d2bcebd Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Wed, 25 Sep 2019 12:56:05 +0300 Subject: [PATCH 0606/1172] MC-18821: Increase test coverage for Catalog functional area - Integration test for MC-11151 --- .../Catalog/Controller/Adminhtml/Product/Set/SaveTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php index 80cc6c192324..187fddae1ce4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Set/SaveTest.php @@ -182,7 +182,7 @@ public function testRemoveAttributeFromAttributeSet() * * @return string */ - private function getSyslogPath() + private function getSyslogPath(): string { if (!$this->systemLogPath) { foreach ($this->logger->getHandlers() as $handler) { From cd63f18ab7be3acb4cc3b6804bd72a8d286a82d2 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <51681487+engcom-Foxtrot@users.noreply.github.com> Date: Wed, 25 Sep 2019 13:18:09 +0300 Subject: [PATCH 0607/1172] magento/magento2#24674: Static tests fix. --- .../Catalog/Controller/Adminhtml/Product/Set/Edit.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php index b07cfaf36f73..178615d0c6a2 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php @@ -17,6 +17,9 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\App\Action\HttpGetActionInterface; +/** + * Edit attribute set controller. + */ class Edit extends Set implements HttpGetActionInterface { /** @@ -30,7 +33,6 @@ class Edit extends Set implements HttpGetActionInterface protected $attributeSetRepository; /** - * * @param Context $context * @param Registry $coreRegistry * @param PageFactory $resultPageFactory @@ -49,10 +51,7 @@ public function __construct( } /** - * - * @return ResultInterface - * - * @throws NoSuchEntityException + * @inheritdoc */ public function execute() { From 41e9fff03dfdb9e55faf3fe25541b81981cb7c5c Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Wed, 25 Sep 2019 13:48:03 +0300 Subject: [PATCH 0608/1172] magento/magento2#23827: Integration test fix. --- .../testsuite/Magento/User/Model/UserTest.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php b/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php index a6fc9999ad26..ba273f3d1b73 100644 --- a/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php +++ b/dev/tests/integration/testsuite/Magento/User/Model/UserTest.php @@ -6,7 +6,6 @@ namespace Magento\User\Model; -use Magento\Framework\Serialize\Serializer\Json; use Magento\Framework\Encryption\Encryptor; /** @@ -29,11 +28,6 @@ class UserTest extends \PHPUnit\Framework\TestCase */ protected static $_newRole; - /** - * @var Json - */ - private $serializer; - /** * @var Encryptor */ @@ -47,9 +41,6 @@ protected function setUp() $this->_dateTime = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Framework\Stdlib\DateTime::class ); - $this->serializer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - Json::class - ); $this->encryptor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( Encryptor::class ); @@ -133,7 +124,7 @@ public function testSaveExtra() $this->_model->loadByUsername(\Magento\TestFramework\Bootstrap::ADMIN_NAME); $this->_model->saveExtra(['test' => 'val']); $this->_model->loadByUsername(\Magento\TestFramework\Bootstrap::ADMIN_NAME); - $extra = $this->serializer->unserialize($this->_model->getExtra()); + $extra = $this->_model->getExtra(); $this->assertEquals($extra['test'], 'val'); } From da05cc8a24613ce8b37166d17c1ce2b719914b44 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Wed, 25 Sep 2019 15:34:34 +0300 Subject: [PATCH 0609/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../Sales/Model/Order/ShipmentTest.php | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index 0c9728b71c82..c52450d413ad 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -155,6 +155,7 @@ private function getOrder(string $incrementId): OrderInterface */ public function testGetTracksCollection() { + $trackCount = 1; $order = $this->getOrder('100000001'); $items = []; foreach ($order->getItems() as $item) { @@ -175,6 +176,7 @@ public function testGetTracksCollection() $shipment->addTrack($track); $this->shipmentRepository->save($shipment); + $shipmentTracksCollection = $shipment->getTracksCollection(); $secondOrder = $this->getOrder('100000002'); $secondOrderItems = []; @@ -193,11 +195,26 @@ public function testGetTracksCollection() $secondOrderShipment->addTrack($secondShipmentTrack); $this->shipmentRepository->save($secondOrderShipment); + $secondShipmentTrackCollection = $secondOrderShipment->getTracksCollection(); + + $shipmentId = $shipment->getId(); + $shipmentTrackIds = $shipmentTracksCollection->getColumnValues('parent_id'); + foreach ($shipmentTrackIds as $trackShipmentId) { + self::assertEquals($shipmentId, $trackShipmentId); + } + self::assertCount($trackCount, $shipmentTrackIds); + + $secondShipmentId = $secondOrderShipment->getId(); + $secondShipmentTrackIds = $secondShipmentTrackCollection->getColumnValues('parent_id'); + foreach ($secondShipmentTrackIds as $trackShipmentId) { + self::assertEquals($secondShipmentId, $trackShipmentId); + } + self::assertCount($trackCount, $secondShipmentTrackIds); self::assertEmpty( array_intersect( - $shipment->getTracksCollection()->getColumnValues('id'), - $secondOrderShipment->getTracksCollection()->getColumnValues('id') + $shipmentTracksCollection->getColumnValues('id'), + $secondShipmentTrackCollection->getColumnValues('id') ) ); } From dd0d07b5f545c46c47c231a8cf698dbe6388112f Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 25 Sep 2019 09:00:58 -0500 Subject: [PATCH 0610/1172] MC-18403: Pricing :: Product pricing schema - schema fixes --- app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls index 95ca45514847..84a3d172dab8 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls @@ -10,13 +10,13 @@ type ProductTierPrices @doc(description: "ProductTierPrices is deprecated and ha customer_group_id: String @deprecated(reason: "customer_group_id is not relevant for storefront.") @doc(description: "The ID of the customer group.") qty: Float @deprecated(reason: "ProductTierPrices is deprecated, use TierPrice.quantity.") @doc(description: "The number of items that must be purchased to qualify for tier pricing.") value: Float @deprecated(reason: "ProductTierPrices is deprecated. Use TierPrice.final_price") @doc(description: "The price of the fixed price item.") - percentage_value: Float @decprected(reason: "ProductTierPrices is deprecated. Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") + percentage_value: Float @deprecated(reason: "ProductTierPrices is deprecated. Use TierPrice.discount.") @doc(description: "The percentage discount of the item.") website_id: Float @deprecated(reason: "website_id is not relevant for storefront.") @doc(description: "The ID assigned to the website.") } type TierPrice @doc(description: "TierPrice defines a tier price, which is a price offered based on a particular quantity purchased.") { final_price: Money @doc(desription: "The price of the product at this tier.") - quantity: Float @doc(description: "The number of items that must be purchased to qualify for tier pricing.") + quantity: Float @doc(description: "The number of items that must be purchased to qualify for this price tier.") discount: ProductDiscount @doc(description: "The price discount that this tier represents.") } From fd4f88d17e90656b91642caa2185177c813d8c4c Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Wed, 25 Sep 2019 19:42:47 +0530 Subject: [PATCH 0611/1172] Fixed LayeredNavigation color filter show only loader for out of stock product --- .../Catalog/view/frontend/templates/product/list.phtml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml index ce44884a575b..efcf2a3e4aaf 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml @@ -72,7 +72,9 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class); </strong> <?= $block->getReviewsSummaryHtml($_product, $templateType) ?> <?= /* @noEscape */ $block->getProductPrice($_product) ?> - <?= $block->getProductDetailsHtml($_product) ?> + <?php if ($_product->isAvailable()): ?> + <?= $block->getProductDetailsHtml($_product) ?> + <?php endif; ?> <div class="product-item-inner"> <div class="product actions product-item-actions"<?= strpos($pos, $viewMode . '-actions') ? $block->escapeHtmlAttr($position) : '' ?>> From 6bcc8ff98c1f0dd779f68758f0c8cce788b887da Mon Sep 17 00:00:00 2001 From: Prabhu Ram <pganapat@adobe.com> Date: Wed, 25 Sep 2019 09:38:22 -0500 Subject: [PATCH 0612/1172] MC-20255: Category Breadcrumbs are missing url_path - Static test fix --- .../Model/Resolver/Category/DataProvider/Breadcrumbs.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php index 4b217d77f686..863e621bd8df 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/DataProvider/Breadcrumbs.php @@ -29,8 +29,11 @@ public function __construct( } /** + * Get breadcrumbs data + * * @param string $categoryPath * @return array + * @throws \Magento\Framework\Exception\LocalizedException */ public function getData(string $categoryPath): array { From 87d6d063e160bb8e23503fc52cc8e687633508a7 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Wed, 25 Sep 2019 10:12:15 -0500 Subject: [PATCH 0613/1172] MC-20212: [On premise] Data loss due to core cron job called sales_clean_quotes - changed return type --- .../ResourceModel/Collection/ExpiredQuotesCollection.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php index 785427b7040d..895d73cc4cff 100644 --- a/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php +++ b/app/code/Magento/Sales/Model/ResourceModel/Collection/ExpiredQuotesCollection.php @@ -8,6 +8,7 @@ namespace Magento\Sales\Model\ResourceModel\Collection; use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; use Magento\Quote\Model\ResourceModel\Quote\Collection; use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory; use Magento\Store\Api\Data\StoreInterface; @@ -57,9 +58,9 @@ public function __construct( * of the quote is greater than lifetime threshold * * @param StoreInterface $store - * @return Collection + * @return AbstractCollection */ - public function getExpiredQuotes(StoreInterface $store): Collection + public function getExpiredQuotes(StoreInterface $store): AbstractCollection { $lifetime = $this->config->getValue( $this->quoteLifetime, From 239a3ad85148967f5a9eacf891a5cc7d825846ef Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 25 Sep 2019 11:05:09 -0500 Subject: [PATCH 0614/1172] MC-18403: Pricing :: Product pricing schema - fix dependencies --- app/code/Magento/CatalogCustomerGraphQl/composer.json | 5 +++-- app/code/Magento/GroupedProductGraphQl/composer.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/composer.json b/app/code/Magento/CatalogCustomerGraphQl/composer.json index 137f610a9614..a16e368d7a70 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/composer.json +++ b/app/code/Magento/CatalogCustomerGraphQl/composer.json @@ -4,11 +4,12 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0||~7.3.0", + "magento/framework": "*", "magento/module-catalog": "*", "magento/module-customer": "*", - "magento/framework": "*", "magento/module-graph-ql": "*", - "magento/module-catalog-graph-ql": "*" + "magento/module-catalog-graph-ql": "*", + "magento/module-store": "*" }, "license": [ "OSL-3.0", diff --git a/app/code/Magento/GroupedProductGraphQl/composer.json b/app/code/Magento/GroupedProductGraphQl/composer.json index cd22c6066eb4..9578aa27ba18 100644 --- a/app/code/Magento/GroupedProductGraphQl/composer.json +++ b/app/code/Magento/GroupedProductGraphQl/composer.json @@ -5,6 +5,7 @@ "require": { "php": "~7.1.3||~7.2.0||~7.3.0", "magento/module-grouped-product": "*", + "magento/module-catalog": "*", "magento/module-catalog-graph-ql": "*", "magento/framework": "*" }, From ff1a40b265c78a0eb8d8d449d22ad3a12628c3a1 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 25 Sep 2019 11:15:57 -0500 Subject: [PATCH 0615/1172] MC-20279: Update AdvancedSearch related MFTF tests to Elasticsearch --- .../AdvanceCatalogSearchBundleProductTest.xml | 173 ++++++++++++++++++ ...CatalogSearchAdvancedResultMainSection.xml | 1 + ...AdvanceCatalogSearchGroupedProductTest.xml | 153 ++++++++++++++++ 3 files changed, 327 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml index 52bce6760088..13ea7c68c684 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml @@ -17,6 +17,47 @@ <severity value="MAJOR"/> <testCaseId value="MC-139"/> <group value="Bundle"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple2"/> + </createData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchBundleByNameMysqlTest" extends="AdvanceCatalogSearchSimpleProductByNameTest"> + <annotations> + <features value="Bundle"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Bundle product with product name using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Bundle product with product name using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="Bundle"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -87,6 +128,47 @@ <severity value="MAJOR"/> <testCaseId value="MC-242"/> <group value="Bundle"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple2"/> + </createData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchBundleByDescriptionMysqlTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> + <annotations> + <features value="Bundle"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Bundle product with product description using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Bundle product with product description using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="Bundle"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -122,6 +204,47 @@ <severity value="MAJOR"/> <testCaseId value="MC-250"/> <group value="Bundle"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple2"/> + </createData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchBundleByShortDescriptionMysqlTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> + <annotations> + <features value="Bundle"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Bundle product with product short description using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Bundle product with product short description using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="Bundle"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -157,6 +280,56 @@ <severity value="MAJOR"/> <testCaseId value="MC-251"/> <group value="Bundle"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple2"/> + </createData> + <getData entity="GetProduct" stepKey="arg1"> + <requiredEntity createDataKey="product"/> + </getData> + <getData entity="GetProduct" stepKey="arg2"> + <requiredEntity createDataKey="simple1"/> + </getData> + <getData entity="GetProduct" stepKey="arg3"> + <requiredEntity createDataKey="simple2"/> + </getData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchBundleByPriceMysqlTest" extends="AdvanceCatalogSearchSimpleProductByPriceTest"> + <annotations> + <features value="Bundle"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Bundle product with product price using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Bundle product with product price the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="Bundle"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Section/StorefrontCatalogSearchAdvancedResultMainSection.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Section/StorefrontCatalogSearchAdvancedResultMainSection.xml index 6b28b4f36c6a..eb3bc8e79d7b 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Section/StorefrontCatalogSearchAdvancedResultMainSection.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Section/StorefrontCatalogSearchAdvancedResultMainSection.xml @@ -17,5 +17,6 @@ <element name="message" type="text" selector="div.message div"/> <element name="itemFound" type="text" selector=".search.found>strong"/> <element name="productName" type="text" selector=".product.name.product-item-name>a"/> + <element name="nthProductName" type="text" selector="li.product-item:nth-of-type({{var1}}) .product-item-name>a" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml index 2a600d38250f..5b7c0cf4c4a0 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml @@ -17,6 +17,42 @@ <severity value="MAJOR"/> <testCaseId value="MC-141"/> <group value="GroupedProduct"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="OneSimpleProductLink" stepKey="addProductOne"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple2"/> + </updateData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchGroupedProductByNameMysqlTest" extends="AdvanceCatalogSearchSimpleProductByNameTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Grouped product with product name using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Grouped product with product name using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="GroupedProduct"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -77,6 +113,42 @@ <severity value="MAJOR"/> <testCaseId value="MC-282"/> <group value="GroupedProduct"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="OneSimpleProductLink" stepKey="addProductOne"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple2"/> + </updateData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchGroupedProductByDescriptionMysqlTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Grouped product with product description using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Grouped product with product description using the MYSQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="GroupedProduct"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -107,6 +179,42 @@ <severity value="MAJOR"/> <testCaseId value="MC-283"/> <group value="GroupedProduct"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="OneSimpleProductLink" stepKey="addProductOne"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple2"/> + </updateData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchGroupedProductByShortDescriptionMysqlTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Grouped product with product short description using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Grouped product with product short description using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="GroupedProduct"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> @@ -137,6 +245,51 @@ <severity value="MAJOR"/> <testCaseId value="MC-284"/> <group value="GroupedProduct"/> + <group value="SearchEngineElasticsearch"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="OneSimpleProductLink" stepKey="addProductOne"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple2"/> + </updateData> + <getData entity="GetProduct3" stepKey="arg1"> + <requiredEntity createDataKey="product"/> + </getData> + <getData entity="GetProduct" stepKey="arg2"> + <requiredEntity createDataKey="simple1"/> + </getData> + <getData entity="GetProduct" stepKey="arg3"> + <requiredEntity createDataKey="simple2"/> + </getData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + <see userInput="3 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="see"/> + <see userInput="$$product.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('1')}}" stepKey="seeProductName"/> + <see userInput="$$simple1.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('2')}}" stepKey="seeSimple1ProductName"/> + <see userInput="$$simple2.name$$" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.nthProductName('3')}}" stepKey="seeSimple2ProductName"/> + </test> + <test name="AdvanceCatalogSearchGroupedProductByPriceMysqlTest" extends="AdvanceCatalogSearchSimpleProductByPriceTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Grouped product with product price using the MySQL search engine"/> + <description value="Guest customer should be able to advance search Grouped product with product price using the MySQL search engine"/> + <severity value="MAJOR"/> + <testCaseId value=""/> + <group value="GroupedProduct"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> From 95ac9f75226155ff50d2fb159a7da7f6b2e484a1 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 25 Sep 2019 11:49:35 -0500 Subject: [PATCH 0616/1172] MC-18403: Pricing :: Product pricing schema - fix dependencies --- app/code/Magento/CatalogCustomerGraphQl/composer.json | 1 - app/code/Magento/CatalogCustomerGraphQl/etc/module.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/composer.json b/app/code/Magento/CatalogCustomerGraphQl/composer.json index a16e368d7a70..859a5c623569 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/composer.json +++ b/app/code/Magento/CatalogCustomerGraphQl/composer.json @@ -7,7 +7,6 @@ "magento/framework": "*", "magento/module-catalog": "*", "magento/module-customer": "*", - "magento/module-graph-ql": "*", "magento/module-catalog-graph-ql": "*", "magento/module-store": "*" }, diff --git a/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml b/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml index 9ee54a01b101..6131435258b5 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml +++ b/app/code/Magento/CatalogCustomerGraphQl/etc/module.xml @@ -10,7 +10,6 @@ <sequence> <module name="Magento_Catalog"/> <module name="Magento_Customer"/> - <module name="Magento_GraphQl"/> <module name="Magento_CatalogGraphQl"/> </sequence> </module> From 113519abdc1f16450d2f6c3b34d52cdb6ad908c7 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Wed, 25 Sep 2019 11:54:46 -0500 Subject: [PATCH 0617/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality "Added review comments to remove extra spaces" --- ...oductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml index 7974618cde1a..82395e5d6e0e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml @@ -66,7 +66,6 @@ <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton"/> <waitForPageLoad stepKey="waitForSimpleProductSave"/> - <!-- Verify customer see success message --> <see selector="{{AdminProductFormSection.successMessage}}" userInput="You saved the product." stepKey="seeAssertSimpleProductSaveSuccessMessage"/> From 055710132d6b560b7b3a12b69f18d2ef9fd6cd70 Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Thu, 22 Aug 2019 10:35:57 -0500 Subject: [PATCH 0618/1172] MC-19303: Shipping price shows 0 on Order view page after multiple address checkout - MFTF tests cases updated --- .../Model/Checkout/Type/Multishipping.php | 13 ++++ .../AdminSalesOrderActionGroup.xml | 29 ++++++++ ...eckingWithMultipleAddressesActionGroup.xml | 3 +- .../ActionGroup/PlaceOrderActionGroup.xml | 3 +- .../ActionGroup/ReviewOrderActionGroup.xml | 3 +- .../ActionGroup/SalesOrderActionGroup.xml | 38 ++++++++++ .../SelectBillingInfoActionGroup.xml | 3 +- .../SelectShippingInfoActionGroup.xml | 3 +- .../Mftf/Page/MultishippingCheckoutPage.xml | 2 +- .../Mftf/Section/PaymentMethodSection.xml | 2 +- .../Test/Mftf/Section/ReviewOrderSection.xml | 3 +- .../Test/Mftf/Section/SalesOrderSection.xml | 15 ++++ .../Mftf/Section/ShippingMethodSection.xml | 3 +- ...oreFrontMyAccountWithMultishipmentTest.xml | 69 +++++++++++++++++++ .../Model/Checkout/Type/MultishippingTest.php | 30 +++++++- 15 files changed, 201 insertions(+), 18 deletions(-) create mode 100644 app/code/Magento/Multishipping/Test/Mftf/ActionGroup/AdminSalesOrderActionGroup.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SalesOrderActionGroup.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/Section/SalesOrderSection.xml create mode 100644 app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index 7105fd4e9d26..d1103abfbb94 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -691,6 +691,19 @@ protected function _prepareOrder(\Magento\Quote\Model\Quote\Address $address) $this->quoteAddressToOrder->convert($address) ); + $shippingMethodCode = $address->getShippingMethod(); + if (isset($shippingMethodCode) && !empty($shippingMethodCode)) { + $rate = $address->getShippingRateByCode($shippingMethodCode); + $shippingPrice = $rate->getPrice(); + } else { + $shippingPrice = $order->getShippingAmount(); + } + $store = $order->getStore(); + $amountPrice = $store->getBaseCurrency() + ->convert($shippingPrice, $store->getCurrentCurrencyCode()); + $order->setBaseShippingAmount($shippingPrice); + $order->setShippingAmount($amountPrice); + $order->setQuote($quote); $order->setBillingAddress($this->quoteAddressToOrderAddress->convert($quote->getBillingAddress())); diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/AdminSalesOrderActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/AdminSalesOrderActionGroup.xml new file mode 100644 index 000000000000..67ba256f50ea --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/AdminSalesOrderActionGroup.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <actionGroup name="AdminSalesOrderActionGroup"> + <waitForPageLoad stepKey="waitForAdminSalesPageToLoad"/> + <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRowLink"/> + <waitForPageLoad stepKey="waitForOrderPageToLoad"/> + <waitForPageLoad stepKey="waitForCheckTotalActionGroup"/> + <scrollTo selector="{{AdminOrderTotalSection.subTotal}}" stepKey="scrollToOrderTotalSection"/> + <grabTextFrom selector="{{AdminOrderTotalSection.subTotal}}" stepKey="grabvalueForSubtotal"/> + <grabTextFrom selector="{{AdminOrderTotalSection.shippingAndHandling}}" stepKey="grabvalueForShippingHandling"/> + <grabTextFrom selector="{{AdminOrderTotalSection.grandTotal}}" stepKey="grabvalueForGrandTotal"/> + <executeJS stepKey="sum_TotalValue" function=" + var subtotal = '{$grabvalueForSubtotal}'.substr(1); + var handling = '{$grabvalueForShippingHandling}'.substr(1); + var subtotal_handling = (parseFloat(subtotal) + parseFloat(handling)).toFixed(2); + return ('$' + subtotal_handling);"/> + <assertEquals stepKey="assertSubTotalPrice"> + <expectedResult type="string">$sum_TotalValue</expectedResult> + <actualResult type="string">$grabvalueForGrandTotal</actualResult> + </assertEquals> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml index 333c2aec6c28..722578a993d3 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml @@ -23,5 +23,4 @@ <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}" after="selectSecondShippingMethod" /> <waitForPageLoad stepKey="waitForShippingInformation" after="clickOnUpdateAddress" /> </actionGroup> -</actionGroups> - +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/PlaceOrderActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/PlaceOrderActionGroup.xml index efb860e31478..349d31ef1da5 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/PlaceOrderActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/PlaceOrderActionGroup.xml @@ -16,5 +16,4 @@ <see selector="{{CheckoutSuccessMainSection.successTitle}}" userInput="Thank you for your purchase!" stepKey="waitForLoadSuccessPage"/> </actionGroup> -</actionGroups> - +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/ReviewOrderActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/ReviewOrderActionGroup.xml index af7d897910ca..bbd0e9ebad7a 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/ReviewOrderActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/ReviewOrderActionGroup.xml @@ -35,5 +35,4 @@ </assertEquals> </actionGroup> -</actionGroups> - +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SalesOrderActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SalesOrderActionGroup.xml new file mode 100644 index 000000000000..47cc3ffa455a --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SalesOrderActionGroup.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <actionGroup name="SalesOrderForMultiShipmentActionGroup"> + <arguments> + <argument name="shippingPrice" defaultValue="$5.00" type="string" /> + <argument name="subtotalPrice" defaultValue="$123.00" type="string" /> + <argument name="totalPrice" defaultValue="$128.00" type="string" /> + </arguments> + <waitForPageLoad stepKey="waitForSalesOrderHistoryPageToLoad" /> + <!--Click on View Order Link--> + <click stepKey="viewOrderAction" selector="{{SalesOrderSection.viewOrderLink}}"/> + <waitForPageLoad stepKey="waitForViewOrderPageToLoad" /> + <!--Check Shipping Method, Subtotal and Total Price--> + <grabTextFrom selector="{{SalesOrderSection.salesOrderPrice('subtotal')}}" stepKey="salesOrderSubtotalPrice"/> + <grabTextFrom selector="{{SalesOrderSection.salesOrderPrice('shipping')}}" stepKey="salesOrderShippingPrice"/> + <grabTextFrom selector="{{SalesOrderSection.salesOrderPrice('grand_total')}}" stepKey="salesOrderGrandTotalPrice"/> + <assertEquals stepKey="assertSubtotalPrice"> + <expectedResult type="string">{{subtotalPrice}}</expectedResult> + <actualResult type="string">$salesOrderSubtotalPrice</actualResult> + </assertEquals> + <assertEquals stepKey="assertShippingMethodPrice"> + <expectedResult type="string">{{shippingPrice}}</expectedResult> + <actualResult type="string">$salesOrderShippingPrice</actualResult> + </assertEquals> + <assertEquals stepKey="assertTotalPrice"> + <expectedResult type="string">{{totalPrice}}</expectedResult> + <actualResult type="string">$salesOrderGrandTotalPrice</actualResult> + </assertEquals> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectBillingInfoActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectBillingInfoActionGroup.xml index 3f7578953df7..c5dd97cadcc2 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectBillingInfoActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectBillingInfoActionGroup.xml @@ -12,5 +12,4 @@ <waitForPageLoad stepKey="waitForBillingInfoPageLoad"/> <click stepKey="goToReviewOrder" selector="{{PaymentMethodSection.goToReviewOrder}}"/> </actionGroup> -</actionGroups> - +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml index af0b2467862b..6d1f83d174ff 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml @@ -29,5 +29,4 @@ <waitForPageLoad stepKey="waitForRadioOptions"/> <click stepKey="goToBillingInformation" selector="{{ShippingMethodSection.goToBillingInfo}}"/> </actionGroup> -</actionGroups> - +</actionGroups> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/Page/MultishippingCheckoutPage.xml b/app/code/Magento/Multishipping/Test/Mftf/Page/MultishippingCheckoutPage.xml index 001002e98271..beee76a632b2 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Page/MultishippingCheckoutPage.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Page/MultishippingCheckoutPage.xml @@ -15,4 +15,4 @@ <section name="PaymentMethodSection"/> <section name="ReviewOrderSection"/> </page> -</pages> +</pages> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/PaymentMethodSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/PaymentMethodSection.xml index 4e7f4a497ad4..8113ed3aa0c0 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/PaymentMethodSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/PaymentMethodSection.xml @@ -11,4 +11,4 @@ <section name="PaymentMethodSection"> <element name="goToReviewOrder" type="button" selector="//span[text()='Go to Review Your Order']"/> </section> -</sections> +</sections> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/ReviewOrderSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/ReviewOrderSection.xml index e13f28929dcc..7961a0f811f6 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/ReviewOrderSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/ReviewOrderSection.xml @@ -23,5 +23,4 @@ <element name="secondOrderTotalPrice" type="text" selector="//div[@class='block-content'][position()=2]//table[position()=1]//tr[@class='grand totals'][position()=1]//td//span[@class='price']"/> <element name="grandTotalPrice" type="text" selector="//div[@class='checkout-review']//div[@class='grand totals']//span[@class='price']"/> </section> -</sections> - +</sections> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/SalesOrderSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/SalesOrderSection.xml new file mode 100644 index 000000000000..c788ef5978ad --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/SalesOrderSection.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <section name="SalesOrderSection"> + <element name="viewOrderLink" type="text" selector="//span[text()='View Order']"/> + <element name="salesOrderPrice" type="text" selector="//div[@class='order-details-items ordered']//tr[@class='{{price_type}}']//td[@class='amount']//span[@class='price']" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/ShippingMethodSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/ShippingMethodSection.xml index 6a2290bcf1a4..311b3ae95906 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/ShippingMethodSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/ShippingMethodSection.xml @@ -14,5 +14,4 @@ <element name="secondShippingMethodRadioButton" type="select" selector="//div[@class='block block-shipping'][position()=2]//div[@class='block-content']//div[@class='box box-shipping-method']//div[@class='box-content']//dl//dd[position()=2]//fieldset//div//div//input[@class='radio']"/> <element name="goToBillingInfo" type="button" selector="//span[text()='Continue to Billing Information']"/> </section> -</sections> - +</sections> \ No newline at end of file diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml new file mode 100644 index 000000000000..a81d24e99563 --- /dev/null +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StoreFrontMyAccountWithMultishipmentTest.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StoreFrontMyAccountWithMultishipmentTest"> + <annotations> + <features value="Multishipping"/> + <stories value="Shipping price shows 0 on Order view page after multiple address checkout"/> + <title value="Verify Shipping price for Storefront after multiple address checkout"/> + <description value="Verify that shipping price on My account matches with shipping method prices after multiple addresses checkout (Order view page)"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-19303"/> + <group value="multishipping"/> + </annotations> + + <before> + <createData stepKey="category" entity="SimpleSubCategory"/> + <createData stepKey="product1" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData stepKey="product2" entity="SimpleProduct"> + <requiredEntity createDataKey="category"/> + </createData> + <createData entity="Simple_US_Customer_Two_Addresses" stepKey="customer"/> + <createData entity="FreeShippinMethodConfig" stepKey="enableFreeShipping"/> + <createData entity="FlatRateShippingMethodDefault" stepKey="enableFlatRateShipping"/> + <magentoCLI command="config:set payment/checkmo/active 1" stepKey="enableCheckMoneyOrderPaymentMethod"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginToStorefrontAccount"> + <argument name="Customer" value="$$customer$$"/> + </actionGroup> + </before> + + <amOnPage url="$$product1.name$$.html" stepKey="goToProduct1"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct1"> + <argument name="productName" value="$$product1.name$$"/> + </actionGroup> + <amOnPage url="$$product2.name$$.html" stepKey="goToProduct2"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProduct2"> + <argument name="productName" value="$$product2.name$$"/> + </actionGroup> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> + <actionGroup ref="CheckingWithMultipleAddressesActionGroup" stepKey="checkoutWithMultipleAddresses"/> + <actionGroup ref="SelectMultiShippingInfoActionGroup" stepKey="checkoutWithMultipleShipping"/> + <actionGroup ref="SelectBillingInfoActionGroup" stepKey="checkoutWithPaymentMethod"/> + <actionGroup ref="ReviewOrderForMultiShipmentActionGroup" stepKey="reviewOrderForMultiShipment"/> + <actionGroup ref="PlaceOrderActionGroup" stepKey="placeOrder"/> + <amOnPage url="{{StorefrontCustomerOrdersHistoryPage.url}}" stepKey="goToSalesOrder"/> + <actionGroup ref="SalesOrderForMultiShipmentActionGroup" stepKey="salesOrderForMultiShipment"/> + <waitForPageLoad stepKey="waitForAdminPageToLoad"/> + <!-- Go to Stores > Configuration > Sales > Orders --> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onAdminOrdersPage"/> + <actionGroup ref="AdminSalesOrderActionGroup" stepKey="ValidateOrderTotals"/> + <after> + <deleteData stepKey="deleteCategory" createDataKey="category"/> + <deleteData stepKey="deleteProduct1" createDataKey="product1"/> + <deleteData stepKey="deleteProduct2" createDataKey="product2"/> + <deleteData stepKey="deleteCustomer" createDataKey="customer"/> + <createData entity="FreeShippinMethodDefault" stepKey="disableFreeShipping"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + </test> +</tests> diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index 02bc96687377..731365974c23 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -11,6 +11,7 @@ use Magento\Customer\Api\Data\AddressInterface; use Magento\Customer\Api\Data\AddressSearchResultsInterface; use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Directory\Model\Currency; use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderDefault; use Magento\Multishipping\Model\Checkout\Type\Multishipping\PlaceOrderFactory; use Magento\Quote\Model\Quote\Address; @@ -44,6 +45,7 @@ use Magento\Quote\Model\ShippingAssignment; use Magento\Sales\Model\Order\Email\Sender\OrderSender; use Magento\Sales\Model\OrderFactory; +use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; use PHPUnit_Framework_MockObject_MockObject; use \PHPUnit\Framework\TestCase; @@ -453,7 +455,8 @@ public function testCreateOrders(): void ]; $quoteItemId = 1; $paymentProviderCode = 'checkmo'; - + $shippingPrice = '0.00'; + $currencyCode = 'USD'; $simpleProductTypeMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Type\Simple::class) ->disableOriginalConstructor() ->setMethods(['getOrderOptions']) @@ -467,6 +470,17 @@ public function testCreateOrders(): void $this->getQuoteAddressesMock($quoteAddressItemMock, $addressTotal); $this->setQuoteMockData($paymentProviderCode, $shippingAddressMock, $billingAddressMock); + $currencyMock = $this->getMockBuilder(Currency::class) + ->disableOriginalConstructor() + ->setMethods([ 'convert' ]) + ->getMock(); + $currencyMock->method('convert')->willReturn($shippingPrice); + $storeMock = $this->getMockBuilder(Store::class) + ->disableOriginalConstructor() + ->setMethods(['getBaseCurrency','getCurrentCurrencyCode' ]) + ->getMock(); + $storeMock->method('getBaseCurrency')->willReturn($currencyMock); + $storeMock->method('getCurrentCurrencyCode')->willReturn($currencyCode); $orderAddressMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderAddressInterface::class); $orderPaymentMock = $this->createSimpleMock(\Magento\Sales\Api\Data\OrderPaymentInterface::class); $orderItemMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Item::class) @@ -476,6 +490,9 @@ public function testCreateOrders(): void $orderItemMock->method('getQuoteItemId')->willReturn($quoteItemId); $orderMock = $this->getOrderMock($orderAddressMock, $orderPaymentMock, $orderItemMock); + $orderMock->expects($this->once())->method('getStore')->willReturn($storeMock); + $orderMock->expects($this->once())->method('setBaseShippingAmount')->with($shippingPrice)->willReturnSelf(); + $orderMock->expects($this->once())->method('setShippingAmount')->with($shippingPrice)->willReturnSelf(); $this->orderFactoryMock->expects($this->once())->method('create')->willReturn($orderMock); $this->dataObjectHelperMock->expects($this->once())->method('mergeDataObjects') ->with( @@ -608,12 +625,18 @@ private function getQuoteAddressesMock($quoteAddressItemMock, int $addressTotal) )->getMock(); $shippingAddressMock->method('validate')->willReturn(true); $shippingAddressMock->method('getShippingMethod')->willReturn('carrier'); - $shippingAddressMock->method('getShippingRateByCode')->willReturn('code'); $shippingAddressMock->method('getCountryId')->willReturn('EN'); $shippingAddressMock->method('getAllItems')->willReturn([$quoteAddressItemMock]); $shippingAddressMock->method('getAddressType')->willReturn('shipping'); $shippingAddressMock->method('getGrandTotal')->willReturn($addressTotal); + $shippingRateMock = $this->getMockBuilder(Address\Rate::class) + ->disableOriginalConstructor() + ->setMethods([ 'getPrice' ]) + ->getMock(); + $shippingRateMock->method('getPrice')->willReturn('0.00'); + $shippingAddressMock->method('getShippingRateByCode')->willReturn($shippingRateMock); + $billingAddressMock = $this->getMockBuilder(Address::class) ->disableOriginalConstructor() ->setMethods(['validate']) @@ -673,6 +696,9 @@ private function getOrderMock( 'getCanSendNewEmailFlag', 'getItems', 'setShippingMethod', + 'getStore', + 'setShippingAmount', + 'setBaseShippingAmount' ] )->getMock(); $orderMock->method('setQuote')->with($this->quoteMock); From e41a8166b2b48cdd88444ba4d2a9935d04fde2f8 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Wed, 25 Sep 2019 13:24:06 -0500 Subject: [PATCH 0619/1172] MC-20336: Update tests related to Catalog Search and Swatches --- .../Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml | 2 ++ .../Test/Mftf/Section/CatalogSearchAdminConfigSection.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml index a6e3dfd7eaad..08cffcccd520 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml @@ -25,6 +25,8 @@ <see userInput="{{MinMaxQueryLength.Hint}}" selector="{{AdminCatalogSearchConfigurationSection.maxQueryLengthHint}}" stepKey="seeHint2"/> <uncheckOption selector="{{AdminCatalogSearchConfigurationSection.minQueryLengthInherit}}" stepKey="uncheckSystemValue"/> <fillField selector="{{AdminCatalogSearchConfigurationSection.minQueryLength}}" userInput="{{minLength}}" stepKey="setMinQueryLength"/> + <!--Scrolling till Category Permissions to make sure the collapse tab for Catalog Search is visible--> + <scrollTo selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="scrollToCatalogSearchTab1"/> <click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseTab"/> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig"/> <waitForPageLoad stepKey="waitForConfigSaved"/> diff --git a/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml index e82ad4670f9b..ff4c0fead0ee 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml @@ -7,6 +7,7 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCatalogSearchConfigurationSection"> + <element name="categoryPermissions" type="button" selector="#catalog_magento_catalogpermissions-head"/> <element name="catalogSearchTab" type="button" selector="#catalog_search-head"/> <element name="checkIfCatalogSearchTabExpand" type="button" selector="#catalog_search-head:not(.open)"/> <element name="searchEngineDefaultSystemValue" type="checkbox" selector="#catalog_search_engine_inherit"/> From 629fcdfc22c35ce0cc2f3732b54b9885e8b2b362 Mon Sep 17 00:00:00 2001 From: Pieter Hoste <hoste.pieter@gmail.com> Date: Mon, 23 Sep 2019 20:43:19 +0200 Subject: [PATCH 0620/1172] Satisfy static and integration tests. --- .../Magento/Bundle/Model/Product/CopyConstructor/Bundle.php | 3 +++ .../Magento/Bundle/Controller/Adminhtml/ProductTest.php | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php index 20e4828835d0..ecbf4cc80a3a 100644 --- a/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php +++ b/app/code/Magento/Bundle/Model/Product/CopyConstructor/Bundle.php @@ -8,6 +8,9 @@ use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Type; +/** + * Provides duplicating bundle options and selections + */ class Bundle implements \Magento\Catalog\Model\Product\CopyConstructorInterface { /** diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php index f48f2019dd52..4c598c16c3c4 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/Controller/Adminhtml/ProductTest.php @@ -10,6 +10,7 @@ use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Type; +use Magento\Framework\App\Request\Http as HttpRequest; use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Message\MessageInterface; use Magento\TestFramework\Helper\Bootstrap; @@ -30,6 +31,7 @@ class ProductTest extends AbstractBackendController public function testDuplicateProduct() { $params = $this->getRequestParamsForDuplicate(); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); $this->getRequest()->setParams(['type' => Type::TYPE_BUNDLE]); $this->getRequest()->setPostValue($params); $this->dispatch('backend/catalog/product/save'); @@ -49,6 +51,7 @@ public function testDuplicateProduct() * Get necessary request post params for creating and duplicating bundle product. * * @return array + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ private function getRequestParamsForDuplicate() { From 5618292173f8e9e7716b2f6677d6a0861f3183ee Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 25 Sep 2019 14:22:37 -0500 Subject: [PATCH 0621/1172] MC-19247: Broken translations with advanced bundling - Remove inline translation dictionary from html for production mode; --- .../Translation/ViewModel/Dictionary.php | 56 +++++++++---------- .../view/base/templates/dictionary.phtml | 28 +++++++--- dev/tests/js/jasmine/require.conf.js | 2 +- .../jasmine/tests/lib/mage/fake-dictionary.js | 2 +- lib/web/mage/translate.js | 2 +- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index 1587f7d0eedc..d857b1182408 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -6,18 +6,15 @@ namespace Magento\Translation\ViewModel; -use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Filesystem; use Magento\Framework\View\Asset\Repository as AssetRepository; use Magento\Framework\View\Element\Block\ArgumentInterface; use Magento\Translation\Model\Js\Config as JsConfig; use Magento\Framework\App\State as AppState; -use Magento\Framework\Filesystem\DriverInterface; /** - * View model responsible for getting translate dictionary file content for the layout. + * View model responsible for handling translation dictionary in layout. */ class Dictionary implements ArgumentInterface { @@ -31,32 +28,16 @@ class Dictionary implements ArgumentInterface */ private $appState; - /** - * @var Filesystem - */ - private $filesystem; - - /** - * @var DriverInterface - */ - private $filesystemDriver; - /** * @param AssetRepository $assetRepo * @param AppState $appState - * @param Filesystem $filesystem - * @param DriverInterface $filesystemDriver */ public function __construct( AssetRepository $assetRepo, - AppState $appState, - Filesystem $filesystem, - DriverInterface $filesystemDriver + AppState $appState ) { $this->assetRepo = $assetRepo; $this->appState = $appState; - $this->filesystem = $filesystem; - $this->filesystemDriver = $filesystemDriver; } /** @@ -69,15 +50,30 @@ public function __construct( public function getTranslationDictionary(): string { $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - if ($this->appState->getMode() === AppState::MODE_PRODUCTION) { - $staticViewFilePath = $this->filesystem->getDirectoryRead( - DirectoryList::STATIC_VIEW - )->getAbsolutePath(); - $content = $this->filesystemDriver->fileGetContents($staticViewFilePath . $asset->getPath()); - } else { - $content = $asset->getContent(); - } - return $content; + return $asset->getContent(); + } + + /** + * Get translation dictionary url. + * + * @return string + * @throws LocalizedException + */ + public function getTranslationDictionaryUrl(): string + { + $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); + + return $asset->getUrl(); + } + + /** + * Check if application is in production mode. + * + * @return bool + */ + public function isAppStateProduction(): bool + { + return $this->appState->getMode() === AppState::MODE_PRODUCTION; } } diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 2e1389abcffd..6b39f43a028c 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -6,12 +6,24 @@ /** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ $viewModel = $block->getData('dictionary_view_model'); -$dictionary = json_encode($viewModel->getTranslationDictionary(), JSON_HEX_APOS | JSON_UNESCAPED_SLASHES); +if (!$viewModel->isAppStateProduction()) { + $dictionary = json_encode($viewModel->getTranslationDictionary(), JSON_HEX_APOS | JSON_UNESCAPED_SLASHES); + // Use of JSON.parse below is intentional as JSON is significantly faster to parse than JavaScript + ?> + <script> + define('mageTranslationDictionary', function () { + var dict = <?= /* @noEscape */ $dictionary ?>; + return JSON.parse(dict); + }); + </script> + <?php +} else { + ?> + <script> + define('mageTranslationDictionary', ['text!<?= /* @noEscape */ $viewModel->getTranslationDictionaryUrl() ?>'], function (dict) { + return JSON.parse(dict); + }); + </script> +<?php +} ?> -<script> - define('dictionary', function () { - var dict = <?= /* @noEscape */ $dictionary ?>; - // Use of JSON.parse is intentional as JSON is significantly faster to parse than JavaScript - return JSON.parse(dict); - }); -</script> diff --git a/dev/tests/js/jasmine/require.conf.js b/dev/tests/js/jasmine/require.conf.js index 43ea596007f0..6af6221276c2 100644 --- a/dev/tests/js/jasmine/require.conf.js +++ b/dev/tests/js/jasmine/require.conf.js @@ -21,7 +21,7 @@ require.config({ }, map: { '*': { - dictionary: '../../../../../../dev/tests/js/jasmine/tests/lib/mage/fake-dictionary' + mageTranslationDictionary: '../../../../../../dev/tests/js/jasmine/tests/lib/mage/fake-dictionary' } }, shim: { diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js index 005a5817dfa1..f85840fd7720 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js +++ b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js @@ -2,7 +2,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -// Fake dictionary for js unit tests as real dictionary is defined in template and cannot be initialized by requirejs +// Fake translation dictionary for js unit tests as real dictionary is defined in template and cannot be initialized by requirejs define([], function () { 'use strict'; diff --git a/lib/web/mage/translate.js b/lib/web/mage/translate.js index db341807364e..65ec33266aeb 100644 --- a/lib/web/mage/translate.js +++ b/lib/web/mage/translate.js @@ -6,7 +6,7 @@ define([ 'jquery', 'mage/mage', - 'dictionary' + 'mageTranslationDictionary' ], function ($, mage, dictionary) { 'use strict'; From 38fc5037c461b4f04dd1c7037cc11cb04a27c761 Mon Sep 17 00:00:00 2001 From: Oleksandr Iegorov <oiegorov@magento.com> Date: Wed, 25 Sep 2019 14:40:17 -0500 Subject: [PATCH 0622/1172] MC-19396: Customer attributes are not displayed on add new company page --- .../Magento/Customer/Model/AttributeMetadataResolver.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php index 979730eb1c9c..d548ef826a2e 100644 --- a/app/code/Magento/Customer/Model/AttributeMetadataResolver.php +++ b/app/code/Magento/Customer/Model/AttributeMetadataResolver.php @@ -16,6 +16,7 @@ use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Model\Config\Share as ShareConfig; +use Magento\Customer\Model\FileUploaderDataResolver; /** * Class to build meta data of the customer or customer address attribute @@ -77,14 +78,14 @@ class AttributeMetadataResolver /** * @param CountryWithWebsites $countryWithWebsiteSource * @param EavValidationRules $eavValidationRules - * @param \Magento\Customer\Model\FileUploaderDataResolver $fileUploaderDataResolver + * @param FileUploaderDataResolver $fileUploaderDataResolver * @param ContextInterface $context * @param ShareConfig $shareConfig */ public function __construct( CountryWithWebsites $countryWithWebsiteSource, EavValidationRules $eavValidationRules, - fileUploaderDataResolver $fileUploaderDataResolver, + FileUploaderDataResolver $fileUploaderDataResolver, ContextInterface $context, ShareConfig $shareConfig ) { From 8808f4398fe994ff0950e33acb962c67b0ba8eb5 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Wed, 25 Sep 2019 15:19:12 -0500 Subject: [PATCH 0623/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality "Based on review comments duplicated tests to also support Mysql search engine functionality" --- ...ateProductAttributesStoreViewScopeTest.xml | 73 +++++++ ...sUpdateProductStatusStoreViewScopeTest.xml | 142 +++++++++++++ .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 192 ++++++++++++++++++ .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 66 ++++++ 4 files changed, 473 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml index f16296f99cb2..18d4b9e341cc 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-128"/> <group value="Catalog"/> <group value="Product Attributes"/> + <group value="SearchEngineElasticsearch"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> @@ -85,4 +86,76 @@ <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault1"/> <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault1"/> </test> + <test name="AdminMassUpdateProductAttributesStoreViewScopeMysqlTest"> + <annotations> + <features value="Catalog"/> + <stories value="Mass update product attributes"/> + <title value="Admin should be able to mass update product attributes in store view scope using the Mysql search engine"/> + <description value="Admin should be able to mass update product attributes in store view scope using the Mysql search engine"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-20467"/> + <group value="Catalog"/> + <group value="Product Attributes"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView" /> + <createData entity="ApiProductWithDescription" stepKey="createProductOne"/> + <createData entity="ApiProductWithDescription" stepKey="createProductTwo"/> + </before> + <after> + <deleteData createDataKey="createProductOne" stepKey="deleteProductOne"/> + <deleteData createDataKey="createProductTwo" stepKey="deleteProductTwo"/> + <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="AdminDeleteStoreViewActionGroup"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + + <!-- Search and select products --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="searchProductGridByKeyword2" stepKey="searchByKeyword"> + <argument name="keyword" value="api-simple-product"/> + </actionGroup> + <actionGroup ref="sortProductsByIdDescending" stepKey="sortProductsByIdDescending"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('1')}}" stepKey="clickCheckbox1"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckbox2"/> + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Update attributes')}}" stepKey="clickOption"/> + <waitForPageLoad stepKey="waitForBulkUpdatePage"/> + <seeInCurrentUrl stepKey="seeInUrl" url="catalog/product_action_attribute/edit/"/> + <!-- Switch store view --> + <actionGroup ref="AdminSwitchStoreViewActionGroup" stepKey="AdminSwitchStoreViewActionGroup"/> + <!-- Update attribute --> + <click selector="{{AdminEditProductAttributesSection.ChangeAttributeDescriptionToggle}}" stepKey="toggleToChangeDescription"/> + <fillField selector="{{AdminEditProductAttributesSection.AttributeDescription}}" userInput="Updated $$createProductOne.custom_attributes[description]$$" stepKey="fillAttributeDescriptionField"/> + <click selector="{{AdminEditProductAttributesSection.Save}}" stepKey="save"/> + <see selector="{{AdminProductMessagesSection.successMessage}}" userInput="Message is added to queue" stepKey="seeAttributeUpateSuccessMsg"/> + + <!-- Run cron twice --> + <magentoCLI command="cron:run" stepKey="runCron1"/> + <magentoCLI command="cron:run" stepKey="runCron2"/> + <reloadPage stepKey="refreshPage"/> + <waitForPageLoad stepKey="waitFormToReload1"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> + <argument name="name" value="$$createProductOne.name$$"/> + <argument name="description" value="$$createProductOne.custom_attributes[description]$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + + <!-- Assert on storefront custom view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupCustom"/> + <actionGroup ref="StorefrontSwitchStoreViewActionGroup" stepKey="StorefrontSwitchStoreViewActionGroup"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameCustom"> + <argument name="name" value="$$createProductOne.name$$"/> + <argument name="description" value="Updated $$createProductOne.custom_attributes[description]$$"/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultCustom"/> + <see userInput="1 item" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInCustom"/> + </test> </tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml index 9eec6d000948..02e8157282de 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductStatusStoreViewScopeTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MAGETWO-59361"/> <group value="Catalog"/> <group value="Product Attributes"/> + <group value="SearchEngineElasticsearch"/> </annotations> <before> <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> @@ -157,4 +158,145 @@ <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault2"/> <see userInput="We can't find any items matching these search criteria." selector="{{StorefrontCatalogSearchAdvancedResultMainSection.message}}" stepKey="seeInDefault2"/> </test> + <test name="AdminMassUpdateProductStatusStoreViewScopeMysqlTest"> + <annotations> + <features value="Catalog"/> + <stories value="Mass update product status"/> + <title value="Admin should be able to mass update product statuses in store view scope using the Mysql search engine"/> + <description value="Admin should be able to mass update product statuses in store view scope using the Mysql search engine"/> + <severity value="AVERAGE"/> + <testCaseId value="MC-20471"/> + <group value="Catalog"/> + <group value="Product Attributes"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdmin"/> + + <!--Create Website --> + <actionGroup ref="AdminCreateWebsiteActionGroup" stepKey="createAdditionalWebsite"> + <argument name="newWebsiteName" value="Second Website"/> + <argument name="websiteCode" value="second_website"/> + </actionGroup> + + <!--Create Store --> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createNewStore"> + <argument name="website" value="Second Website"/> + <argument name="storeGroupName" value="Second Store"/> + <argument name="storeGroupCode" value="second_store"/> + </actionGroup> + + <!--Create Store view --> + <amOnPage url="{{AdminSystemStorePage.url}}" stepKey="amOnAdminSystemStorePage"/> + <waitForPageLoad stepKey="waitForSystemStorePage"/> + <click selector="{{AdminStoresMainActionsSection.createStoreViewButton}}" stepKey="createStoreViewButton"/> + <waitForPageLoad stepKey="waitForProductPageLoad"/> + <waitForElementVisible selector="//legend[contains(., 'Store View Information')]" stepKey="waitForNewStorePageToOpen"/> + <selectOption userInput="Second Store" selector="{{AdminNewStoreSection.storeGrpDropdown}}" stepKey="selectStoreGroup"/> + <fillField userInput="Second Store View" selector="{{AdminNewStoreSection.storeNameTextField}}" stepKey="fillStoreViewName"/> + <fillField userInput="second_store_view" selector="{{AdminNewStoreSection.storeCodeTextField}}" stepKey="fillStoreViewCode"/> + <selectOption selector="{{AdminNewStoreSection.statusDropdown}}" userInput="1" stepKey="enableStoreViewStatus"/> + <click selector="{{AdminNewStoreViewActionsSection.saveButton}}" stepKey="clickSaveStoreView" /> + <waitForElementVisible selector="{{AdminConfirmationModalSection.ok}}" stepKey="waitForModal" /> + <see selector="{{AdminConfirmationModalSection.title}}" userInput="Warning message" stepKey="seeWarning" /> + <click selector="{{AdminConfirmationModalSection.ok}}" stepKey="dismissModal" /> + <waitForPageLoad stepKey="waitForPageLoad2" time="180" /> + <waitForElementVisible selector="{{AdminStoresGridSection.storeFilterTextField}}" time="150" stepKey="waitForPageReolad"/> + <see userInput="You saved the store view." stepKey="seeSavedMessage" /> + + <!--Create a Simple Product 1 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct1"> + <argument name="product" value="simpleProductForMassUpdate"/> + <argument name="website" value="Second Website"/> + </actionGroup> + + <!--Create a Simple Product 2 --> + <actionGroup ref="createSimpleProductAndAddToWebsite" stepKey="createSimpleProduct2"> + <argument name="product" value="simpleProductForMassUpdate2"/> + <argument name="website" value="Second Website"/> + </actionGroup> + </before> + <after> + <!--Delete website --> + <actionGroup ref="AdminDeleteWebsiteActionGroup" stepKey="deleteSecondWebsite"> + <argument name="websiteName" value="Second Website"/> + </actionGroup> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + + <!--Delete Products --> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct1"> + <argument name="productName" value="simpleProductForMassUpdate.name"/> + </actionGroup> + <actionGroup ref="DeleteProductActionGroup" stepKey="deleteProduct2"> + <argument name="productName" value="simpleProductForMassUpdate2.name"/> + </actionGroup> + <actionGroup ref="logout" stepKey="amOnLogoutPage"/> + </after> + + <!-- Search and select products --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad"/> + <actionGroup ref="searchProductGridByKeyword2" stepKey="searchByKeyword"> + <argument name="keyword" value="{{simpleProductForMassUpdate.keyword}}"/> + </actionGroup> + <actionGroup ref="sortProductsByIdDescending" stepKey="sortProductsByIdDescending"/> + + <!-- Filter to Second Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterStoreView" > + <argument name="customStore" value="'Second Store View'" /> + </actionGroup> + + <!-- Select Product 2 --> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckbox2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdown"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOption"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabled"/> + <waitForPageLoad stepKey="waitForBulkUpdatePage"/> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabled"/> + + <!-- Filter to Default Store View --> + <actionGroup ref="AdminFilterStoreViewActionGroup" stepKey="filterDefaultStoreView"> + <argument name="customStore" value="'Default'" /> + </actionGroup> + + <!-- Verify Product Statuses --> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct1IsEnabled"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('2')}}" userInput="Enabled" stepKey="checkIfDefaultViewProduct2IsEnabled"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault"> + <argument name="name" value="{{simpleProductForMassUpdate.keyword}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault"/> + <see userInput="2 items" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.itemFound}}" stepKey="seeInDefault"/> + + <!-- Enable the product in Default store view --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="navigateToProductIndex2"/> + <waitForPageLoad stepKey="waitForProductIndexPageLoad2"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('1')}}" stepKey="clickCheckboxDefaultStoreView"/> + <click selector="{{AdminProductGridSection.productGridCheckboxOnRow('2')}}" stepKey="clickCheckboxDefaultStoreView2"/> + + <!-- Mass update attributes --> + <click selector="{{AdminProductGridSection.bulkActionDropdown}}" stepKey="clickDropdownDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Change status')}}" stepKey="clickOptionDefaultStoreView"/> + <click selector="{{AdminProductGridSection.bulkActionOption('Disable')}}" stepKey="clickDisabledDefaultStoreView"/> + <waitForPageLoad stepKey="waitForBulkUpdatePageDefaultStoreView"/> + <see selector="{{AdminProductGridSection.productGridContentsOnRow('1')}}" userInput="Disabled" stepKey="checkIfProduct2IsDisabledDefaultStoreView"/> + + <!-- Assert on storefront default view --> + <actionGroup ref="GoToStoreViewAdvancedCatalogSearchActionGroup" stepKey="GoToStoreViewAdvancedCatalogSearchActionGroupDefault2"/> + <actionGroup ref="StorefrontAdvancedCatalogSearchByProductNameAndDescriptionActionGroup" stepKey="searchByNameDefault2"> + <argument name="name" value="{{simpleProductForMassUpdate.name}}"/> + <argument name="description" value=""/> + </actionGroup> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="StorefrontCheckAdvancedSearchResultDefault2"/> + <see userInput="We can't find any items matching these search criteria." selector="{{StorefrontCatalogSearchAdvancedResultMainSection.message}}" stepKey="seeInDefault2"/> + </test> </tests> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 495b8f2d4036..ad66214e902f 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -17,6 +17,7 @@ <description value="User browses catalog, searches for product, adds product to cart, adds product to wishlist, compares products, uses coupon code and checks out."/> <severity value="CRITICAL"/> <testCaseId value="MAGETWO-87435"/> + <group value="SearchEngineElasticsearch"/> </annotations> <before> <resetCookie userInput="PHPSESSID" stepKey="resetCookieForCart"/> @@ -196,6 +197,197 @@ <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="compareClickCategoryBeforeClear" after="commentClearComparisonSidebar"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="compareAssertCategory2"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontClearCompareActionGroup" stepKey="compareClearCompare"/> + <comment userInput="End of Comparing Products" stepKey="endOfComparingProducts" /> + </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <annotations> + <features value="End to End scenarios"/> + <stories value="B2C guest user - MAGETWO-75411"/> + <group value="e2e"/> + <title value="You should be able to pass End to End B2C Guest User scenario using the Mysql search engine"/> + <description value="User browses catalog, searches for product, adds product to cart, adds product to wishlist, compares products, uses coupon code and checks out using the Mysql search engine."/> + <severity value="CRITICAL"/> + <testCaseId value="MC-20476"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <resetCookie userInput="PHPSESSID" stepKey="resetCookieForCart"/> + + <createData entity="ApiCategory" stepKey="createCategory"/> + + <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct1"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="createSimpleProduct1Image"> + <requiredEntity createDataKey="createSimpleProduct1"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryMagentoLogo" stepKey="createSimpleProduct1Image1"> + <requiredEntity createDataKey="createSimpleProduct1"/> + </createData> + <updateData entity="ApiSimpleProductUpdateDescription" stepKey="updateSimpleProduct1" createDataKey="createSimpleProduct1"/> + + <createData entity="ApiSimpleProduct" stepKey="createSimpleProduct2"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="createSimpleProduct2Image"> + <requiredEntity createDataKey="createSimpleProduct2"/> + </createData> + <updateData entity="ApiSimpleProductUpdateDescription" stepKey="updateSimpleProduct2" createDataKey="createSimpleProduct2"/> + </before> + <after> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createSimpleProduct1Image" stepKey="deleteSimpleProduct1Image"/>--> + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createSimpleProduct1Image1" stepKey="deleteSimpleProduct1Image1"/>--> + <deleteData createDataKey="createSimpleProduct1" stepKey="deleteSimpleProduct1"/> + + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createSimpleProduct2Image" stepKey="deleteSimpleProduct2Image"/>--> + <deleteData createDataKey="createSimpleProduct2" stepKey="deleteSimpleProduct2"/> + </after> + + <!-- Step 1: User browses catalog --> + <comment userInput="Start of browsing catalog" stepKey="startOfBrowsingCatalog" /> + <amOnPage url="{{StorefrontHomePage.url}}" stepKey="amOnHomePage"/> + <waitForPageLoad stepKey="homeWaitForPageLoad"/> + <waitForElementVisible selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeWaitForWelcomeMessage"/> + <see userInput="Default welcome msg!" selector="{{StorefrontPanelHeaderSection.WelcomeMessage}}" stepKey="homeCheckWelcome"/> + + <!-- Open Category --> + <comment userInput="Open category" stepKey="commentOpenCategory" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="browseClickCategory"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="browseAssertCategory"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <!-- Check simple product 1 in category --> + <comment userInput="Check simple product 1 in category" stepKey="commentCheckSimpleProductInCategory" /> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="browseAssertCategoryProduct1"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="browseGrabSimpleProduct1ImageSrc"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$browseGrabSimpleProduct1ImageSrc" stepKey="browseAssertSimpleProduct1ImageNotDefault"/> + <!-- Check simple product 2 in category --> + <comment userInput="Check simple product 2 in category" stepKey="commentCheckSimpleProduct2InCategory" /> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="browseAssertCategoryProduct2"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="browseGrabSimpleProduct2ImageSrc"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$browseGrabSimpleProduct2ImageSrc" stepKey="browseAssertSimpleProduct2ImageNotDefault"/> + + <!-- View Simple Product 1 --> + <comment userInput="View simple product 1" stepKey="commentViewSimpleProduct1" after="browseAssertSimpleProduct2ImageNotDefault"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createSimpleProduct1.name$$)}}" stepKey="browseClickCategorySimpleProduct1View" after="commentViewSimpleProduct1"/> + <waitForLoadingMaskToDisappear stepKey="waitForSimpleProduct1Viewloaded" /> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="browseAssertProduct1Page"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="browseGrabSimpleProduct1PageImageSrc"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$browseGrabSimpleProduct1PageImageSrc" stepKey="browseAssertSimpleProduct1PageImageNotDefault"/> + + <!-- View Simple Product 2 --> + <comment userInput="View simple product 2" stepKey="commentViewSimpleProduct2" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="clickCategory1"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createSimpleProduct2.name$$)}}" stepKey="browseClickCategorySimpleProduct2View"/> + <waitForLoadingMaskToDisappear stepKey="waitForSimpleProduct2ViewLoaded" /> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="browseAssertProduct2Page"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="browseGrabSimpleProduct2PageImageSrc"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$browseGrabSimpleProduct2PageImageSrc" stepKey="browseAssertSimpleProduct2PageImageNotDefault"/> + <comment userInput="End of browsing catalog" stepKey="endOfBrowsingCatalog" after="browseAssertSimpleProduct2PageImageNotDefault"/> + + <!-- Step 4: User compares products --> + <comment userInput="Start of comparing products" stepKey="startOfComparingProducts" after="endOfBrowsingCatalog"/> + <!-- Add Simple Product 1 to comparison --> + <comment userInput="Add simple product 1 to comparison" stepKey="commentAddSimpleProduct1ToComparison" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="compareClickCategory" /> + <waitForLoadingMaskToDisappear stepKey="waitForCategoryloaded" /> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="compareAssertCategory"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="compareAssertSimpleProduct1"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="compareGrabSimpleProduct1ImageSrc"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabSimpleProduct1ImageSrc" stepKey="compareAssertSimpleProduct1ImageNotDefault"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createSimpleProduct1.name$$)}}" stepKey="compareClickSimpleProduct1"/> + <waitForLoadingMaskToDisappear stepKey="waitForCompareSimpleProduct1loaded" /> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="compareAssertProduct1Page"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="compareGrabSimpleProduct1PageImageSrc"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$compareGrabSimpleProduct1PageImageSrc" stepKey="compareAssertSimpleProduct2PageImageNotDefault"/> + <actionGroup ref="StorefrontAddProductToCompareActionGroup" stepKey="compareAddSimpleProduct1ToCompare"> + <argument name="productVar" value="$$createSimpleProduct1$$"/> + </actionGroup> + + <!-- Add Simple Product 2 to comparison --> + <comment userInput="Add simple product 2 to comparison" stepKey="commentAddSimpleProduct2ToComparison" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="compareClickCategory1"/> + <waitForLoadingMaskToDisappear stepKey="waitForCompareCategory1loaded" /> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="compareAssertCategory1"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="compareAssertSimpleProduct2"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="compareGrabSimpleProduct2ImageSrc"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabSimpleProduct2ImageSrc" stepKey="compareAssertSimpleProduct2ImageNotDefault"/> + <actionGroup ref="StorefrontAddCategoryProductToCompareActionGroup" stepKey="compareAddSimpleProduct2ToCompare"> + <argument name="productVar" value="$$createSimpleProduct2$$"/> + </actionGroup> + + <!-- Check products in comparison sidebar --> + <!-- Check simple product 1 in comparison sidebar --> + <comment userInput="Check simple product 1 in comparison sidebar" stepKey="commentCheckSimpleProduct1InComparisonSidebar" after="compareAddSimpleProduct2ToCompare"/> + <actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="compareSimpleProduct1InSidebar" after="commentCheckSimpleProduct1InComparisonSidebar"> + <argument name="productVar" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- Check simple product 2 in comparison sidebar --> + <comment userInput="Check simple product 2 in comparison sidebar" stepKey="commentCheckSimpleProduct2InComparisonSidebar" /> + <actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="compareSimpleProduct2InSidebar"> + <argument name="productVar" value="$$createSimpleProduct2$$"/> + </actionGroup> + + <!-- Check products on comparison page --> + <!-- Check simple product 1 on comparison page --> + <comment userInput="Check simple product 1 on comparison page" stepKey="commentCheckSimpleProduct1OnComparisonPage" after="compareSimpleProduct2InSidebar"/> + <actionGroup ref="StorefrontOpenAndCheckComparisionActionGroup" stepKey="compareOpenComparePage" after="commentCheckSimpleProduct1OnComparisonPage"/> + <actionGroup ref="StorefrontCheckCompareSimpleProductActionGroup" stepKey="compareAssertSimpleProduct1InComparison"> + <argument name="productVar" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductCompareMainSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="compareGrabSimpleProduct1ImageSrcInComparison"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabSimpleProduct1ImageSrcInComparison" stepKey="compareAssertSimpleProduct1ImageNotDefaultInComparison"/> + <!-- Check simple product2 on comparison page --> + <comment userInput="Check simple product 2 on comparison page" stepKey="commentCheckSimpleProduct2OnComparisonPage" /> + <actionGroup ref="StorefrontCheckCompareSimpleProductActionGroup" stepKey="compareAssertSimpleProduct2InComparison"> + <argument name="productVar" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductCompareMainSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="compareGrabSimpleProduct2ImageSrcInComparison"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabSimpleProduct2ImageSrcInComparison" stepKey="compareAssertSimpleProduct2ImageNotDefaultInComparison"/> + + <!-- Clear comparison sidebar --> + <comment userInput="Clear comparison sidebar" stepKey="commentClearComparisonSidebar" after="compareAssertSimpleProduct2ImageNotDefaultInComparison"/> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="compareClickCategoryBeforeClear" after="commentClearComparisonSidebar"/> <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="compareAssertCategory2"> <argument name="category" value="$$createCategory$$"/> <argument name="productCount" value="3"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 84c621d161f0..aa7cf933f632 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -65,6 +65,72 @@ <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="searchGrabSimpleProduct2ImageSrc" after="searchAssertFilterCategorySimpleProduct2"/> <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$searchGrabSimpleProduct2ImageSrc" stepKey="searchAssertSimpleProduct2ImageNotDefault" after="searchGrabSimpleProduct2ImageSrc"/> + <!-- Quick Search with non-existent product name --> + <comment userInput="Quick Search with non-existent product name" stepKey="commentQuickSearchWithNonExistentProductName" after="searchAssertSimpleProduct2ImageNotDefault" /> + <actionGroup ref="StorefrontCheckQuickSearchActionGroup" stepKey="searchFillQuickSearchNonExistent" after="commentQuickSearchWithNonExistentProductName"> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="phrase" value="CONST.nonexistentProductName"/> + </actionGroup> + <see userInput="Your search returned no results." selector="{{StorefrontCatalogSearchMainSection.message}}" stepKey="searchAssertQuickSearchMessageNonExistent" after="searchFillQuickSearchNonExistent"/> + <comment userInput="End of searching products" stepKey="endOfSearchingProducts" after="searchAssertQuickSearchMessageNonExistent" /> + </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <!-- Step 2: User searches for product --> + <comment userInput="Start of searching products" stepKey="startOfSearchingProducts" after="endOfBrowsingCatalog"/> + <!-- Advanced Search with Product 1 Data --> + <comment userInput="Advanced search" stepKey="commentAdvancedSearch" after="startOfSearchingProducts"/> + <actionGroup ref="StorefrontOpenAdvancedSearchActionGroup" stepKey="searchOpenAdvancedSearchForm" after="commentAdvancedSearch"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <fillField userInput="$$createSimpleProduct1.name$$" selector="{{StorefrontCatalogSearchAdvancedFormSection.ProductName}}" stepKey="searchAdvancedFillProductName" after="searchOpenAdvancedSearchForm"/> + <fillField userInput="$$createSimpleProduct1.sku$$" selector="{{StorefrontCatalogSearchAdvancedFormSection.SKU}}" stepKey="searchAdvancedFillSKU" after="searchAdvancedFillProductName"/> + <fillField userInput="$$createSimpleProduct1.price$$" selector="{{StorefrontCatalogSearchAdvancedFormSection.PriceFrom}}" stepKey="searchAdvancedFillPriceFrom" after="searchAdvancedFillSKU"/> + <fillField userInput="$$createSimpleProduct1.price$$" selector="{{StorefrontCatalogSearchAdvancedFormSection.PriceTo}}" stepKey="searchAdvancedFillPriceTo" after="searchAdvancedFillPriceFrom"/> + <click selector="{{StorefrontCatalogSearchAdvancedFormSection.SubmitButton}}" stepKey="searchClickAdvancedSearchSubmitButton" after="searchAdvancedFillPriceTo"/> + <waitForLoadingMaskToDisappear stepKey="waitForSearchProductsloaded" after="searchClickAdvancedSearchSubmitButton"/> + <actionGroup ref="StorefrontCheckAdvancedSearchResultActionGroup" stepKey="searchCheckAdvancedSearchResult" after="waitForSearchProductsloaded"/> + <see userInput="1" selector="{{StorefrontCatalogSearchAdvancedResultMainSection.productCount}} span" stepKey="searchAdvancedAssertProductCount" after="searchCheckAdvancedSearchResult"/> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="searchAssertSimpleProduct1" after="searchAdvancedAssertProductCount"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="searchAdvancedGrabSimpleProduct1ImageSrc" after="searchAssertSimpleProduct1"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$searchAdvancedGrabSimpleProduct1ImageSrc" stepKey="searchAdvancedAssertSimpleProduct1ImageNotDefault" after="searchAdvancedGrabSimpleProduct1ImageSrc"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createSimpleProduct1.name$$)}}" stepKey="searchClickSimpleProduct1View" after="searchAdvancedAssertSimpleProduct1ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForSearchSimpleProduct1Viewloaded" after="searchClickSimpleProduct1View"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="searchAssertSimpleProduct1Page" after="waitForSearchSimpleProduct1Viewloaded"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="searchAdvancedGrabSimpleProduct1PageImageSrc" after="searchAssertSimpleProduct1Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$searchAdvancedGrabSimpleProduct1PageImageSrc" stepKey="searchAdvancedAssertSimpleProduct1PageImageNotDefault" after="searchAdvancedGrabSimpleProduct1PageImageSrc"/> + + <!-- Quick Search with common part of product names --> + <comment userInput="Quick search" stepKey="commentQuickSearch" after="searchAdvancedAssertSimpleProduct1PageImageNotDefault"/> + <actionGroup ref="StorefrontCheckQuickSearchActionGroup" stepKey="searchQuickSearchCommonPart" after="commentQuickSearch"> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="phrase" value="CONST.apiSimpleProduct"/> + </actionGroup> + <actionGroup ref="StorefrontSelectSearchFilterCategoryActionGroup" stepKey="searchSelectFilterCategoryCommonPart" after="searchQuickSearchCommonPart"> + <argument name="category" value="$$createCategory$$"/> + </actionGroup> + <see userInput="3" selector="{{StorefrontCategoryMainSection.productCount}} span" stepKey="searchAssertFilterCategoryProductCountCommonPart" after="searchSelectFilterCategoryCommonPart"/> + + <!-- Search simple product 1 --> + <comment userInput="Search simple product 1" stepKey="commentSearchSimpleProduct1" after="searchAssertFilterCategoryProductCountCommonPart"/> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="searchAssertFilterCategorySimpleProduct1" after="commentSearchSimpleProduct1"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="searchGrabSimpleProduct1ImageSrc" after="searchAssertFilterCategorySimpleProduct1"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$searchGrabSimpleProduct1ImageSrc" stepKey="searchAssertSimpleProduct1ImageNotDefault" after="searchGrabSimpleProduct1ImageSrc"/> + <!-- Search simple product2 --> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="searchAssertFilterCategorySimpleProduct2" after="searchAssertSimpleProduct1ImageNotDefault"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="searchGrabSimpleProduct2ImageSrc" after="searchAssertFilterCategorySimpleProduct2"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$searchGrabSimpleProduct2ImageSrc" stepKey="searchAssertSimpleProduct2ImageNotDefault" after="searchGrabSimpleProduct2ImageSrc"/> + <!-- Quick Search with non-existent product name --> <comment userInput="Quick Search with non-existent product name" stepKey="commentQuickSearchWithNonExistentProductName" after="searchAssertSimpleProduct2ImageNotDefault" /> <actionGroup ref="StorefrontCheckQuickSearchActionGroup" stepKey="searchFillQuickSearchNonExistent" after="commentQuickSearchWithNonExistentProductName"> From 6153cf31d8b8579f45771ddf40a9f3872e1ba9e0 Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Wed, 25 Sep 2019 23:30:29 +0300 Subject: [PATCH 0624/1172] MAGETWO-99490: gift messaging options are not saved with multi-address checkout - Updated functional test. --- .../Section/StorefrontOrderGiftSection.xml | 2 +- ...eckingWithMultipleAddressesActionGroup.xml | 27 +++++++++------- .../SelectShippingInfoActionGroup.xml | 2 +- .../Mftf/Section/MultishippingSection.xml | 3 +- ...frontCheckoutWithMultipleAddressesTest.xml | 32 ++++++++++++++++--- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml index 301767561166..45e7531f0b4a 100644 --- a/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml +++ b/app/code/Magento/GiftMessage/Test/Mftf/Section/StorefrontOrderGiftSection.xml @@ -9,7 +9,7 @@ <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="StorefrontOrderGiftSection"> - <element name="giftMessageLink" type="button" selector="//div[contains(@class, 'table-wrapper order-items')]//a[contains(@id, 'order-item-gift-message-link')]"/> + <element name="giftMessageLink" type="button" selector=".table-wrapper.order-items .options .action.show"/> <element name="giftMessage" type="text" selector=".order-gift-message .item-message" /> </section> </sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml index c5d04c6ab730..861b97427b44 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/CheckingWithMultipleAddressesActionGroup.xml @@ -23,17 +23,22 @@ <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}" after="selectSecondShippingMethod" /> <waitForPageLoad stepKey="waitForShippingInformation" after="clickOnUpdateAddress" /> </actionGroup> - <actionGroup name="CheckingWithThreeDifferentAddressesActionGroup" extends="CheckingWithSingleAddressActionGroup"> - <grabTextFrom stepKey="firstShippingAddressValue" selector="{{MultishippingSection.firstShippingAddressValue}}" after="waitForMultipleAddressPageLoad" /> - <selectOption selector="{{MultishippingSection.firstShippingAddressOption}}" userInput="{$firstShippingAddressValue}" stepKey="selectFirstShippingMethod" after="firstShippingAddressValue" /> - <waitForPageLoad stepKey="waitForSecondShippingAddresses" after="selectFirstShippingMethod" /> - <grabTextFrom stepKey="secondShippingAddressValue" selector="{{MultishippingSection.secondShippingAddressValue}}" after="waitForSecondShippingAddresses" /> - <selectOption selector="{{MultishippingSection.secondShippingAddressOption}}" userInput="{$secondShippingAddressValue}" stepKey="selectSecondShippingMethod" after="secondShippingAddressValue" /> - <waitForPageLoad stepKey="waitForLastShippingAddressValue" after="selectSecondShippingMethod" /> - <grabTextFrom stepKey="lastShippingAddressValue" selector="{{MultishippingSection.lastShippingAddressValue}}" after="waitForLastShippingAddressValue"/> - <selectOption selector="{{MultishippingSection.lastShippingAddressOption}}" userInput="{$lastShippingAddressValue}" stepKey="selectLastShippingMethod" after="lastShippingAddressValue"/> - <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}" after="selectLastShippingMethod"/> - <waitForPageLoad stepKey="waitForShippingInformationAfterUpdated" after="clickOnUpdateAddress"/> + <actionGroup name="StorefrontCheckoutWithMultipleAddressesActionGroup"> + <click selector="{{SingleShippingSection.checkoutWithMultipleAddresses}}" stepKey="clickOnCheckoutWithMultipleAddresses"/> + <waitForPageLoad stepKey="waitForMultipleAddressPageLoad"/> + </actionGroup> + <actionGroup name="StorefrontSelectAddressActionGroup"> + <arguments> + <argument name="sequenceNumber" type="string" defaultValue="1"/> + <argument name="option" type="string" defaultValue="1"/> + </arguments> + <selectOption selector="{{MultishippingSection.selectShippingAddress(sequenceNumber)}}" userInput="{{option}}" stepKey="selectShippingAddress"/> + </actionGroup> + <actionGroup name="StorefrontSaveAddressActionGroup"> + <click stepKey="clickOnUpdateAddress" selector="{{SingleShippingSection.updateAddress}}"/> + <waitForPageLoad stepKey="waitForShippingInformationAfterUpdated" time="90"/> + <click stepKey="goToShippingInformation" selector="{{SingleShippingSection.goToShippingInfo}}"/> + <waitForPageLoad stepKey="waitForShippingPageLoad"/> </actionGroup> </actionGroups> diff --git a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml index 29d90c9083e8..bcaeb8ba4800 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/ActionGroup/SelectShippingInfoActionGroup.xml @@ -29,7 +29,7 @@ <waitForPageLoad stepKey="waitForRadioOptions"/> <click stepKey="goToBillingInformation" selector="{{ShippingMethodSection.goToBillingInfo}}"/> </actionGroup> - <actionGroup name="defaultShippingInfoActionGroup"> + <actionGroup name="StorefrontLeaveDefaultShippingMethodsAndGoToBillingInfoActionGroup"> <waitForPageLoad stepKey="waitForShippingInfo"/> <click stepKey="goToBillingInformation" selector="{{ShippingMethodSection.goToBillingInfo}}"/> </actionGroup> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml index e182cb3c68c0..dddf26683164 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Section/MultishippingSection.xml @@ -20,7 +20,6 @@ <element name="firstShippingAddressOption" type="select" selector="//table//tbody//tr[position()=1]//td[position()=3]//div//select"/> <element name="secondShippingAddressValue" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select//option[1]"/> <element name="secondShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> - <element name="lastShippingAddressValue" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select//option[last()]"/> - <element name="lastShippingAddressOption" type="select" selector="//table//tbody//tr[position()=2]//td[position()=3]//div//select"/> + <element name="selectShippingAddress" type="select" selector="(//table[@id='multiship-addresses-table'] //div[@class='field address'] //select)[{{sequenceNumber}}]" parameterized="true"/> </section> </sections> diff --git a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml index c45465598959..138ab5df26ab 100644 --- a/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml +++ b/app/code/Magento/Multishipping/Test/Mftf/Test/StorefrontCheckoutWithMultipleAddressesTest.xml @@ -66,10 +66,20 @@ </actionGroup> <!--Go to Cart --> <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCart"/> + <!--Check Out with Multiple Addresses --> + <actionGroup ref="StorefrontCheckoutWithMultipleAddressesActionGroup" stepKey="checkoutWithMultipleAddresses"/> <!-- Select different addresses and click 'Go to Shipping Information' --> - <actionGroup ref="CheckingWithMultipleAddressesActionGroup" stepKey="checkoutWithMultipleAddresses"/> + <actionGroup ref="StorefrontSelectAddressActionGroup" stepKey="selectFirstAddress"> + <argument name="sequenceNumber" value="1"/> + <argument name="option" value="John Doe, 368 Broadway St. 113, New York, New York 10001, United States"/> + </actionGroup> + <actionGroup ref="StorefrontSelectAddressActionGroup" stepKey="selectSecondAddress"> + <argument name="sequenceNumber" value="2"/> + <argument name="option" value="John Doe, Augsburger Strabe 41, Berlin, 10789, Germany"/> + </actionGroup> + <actionGroup ref="StorefrontSaveAddressActionGroup" stepKey="saveAddresses"/> <!-- Click 'Continue to Billing Information' --> - <actionGroup ref="defaultShippingInfoActionGroup" stepKey="useDefaultShippingMethod"/> + <actionGroup ref="StorefrontLeaveDefaultShippingMethodsAndGoToBillingInfoActionGroup" stepKey="useDefaultShippingMethod"/> <!-- Click 'Go to Review Your Order' --> <actionGroup ref="SelectBillingInfoActionGroup" stepKey="useDefaultBillingMethod"/> <!-- Click 'Place Order' --> @@ -85,10 +95,24 @@ </actionGroup> <!--Go to Cart --> <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openCartWithIdenticalProducts"/> + <!--Check Out with Multiple Addresses --> + <actionGroup ref="StorefrontCheckoutWithMultipleAddressesActionGroup" stepKey="checkoutWithThreeDifferentAddresses"/> <!-- Select different addresses and click 'Go to Shipping Information' --> - <actionGroup ref="CheckingWithThreeDifferentAddressesActionGroup" stepKey="checkoutThreeDifferentAddresses"/> + <actionGroup ref="StorefrontSelectAddressActionGroup" stepKey="selectFirstAddressFromThree"> + <argument name="sequenceNumber" value="1"/> + <argument name="option" value="John Doe, 368 Broadway St. 113, New York, New York 10001, United States"/> + </actionGroup> + <actionGroup ref="StorefrontSelectAddressActionGroup" stepKey="selectSecondAddressFromThree"> + <argument name="sequenceNumber" value="2"/> + <argument name="option" value="John Doe, Augsburger Strabe 41, Berlin, 10789, Germany"/> + </actionGroup> + <actionGroup ref="StorefrontSelectAddressActionGroup" stepKey="selectThirdAddressFromThree"> + <argument name="sequenceNumber" value="3"/> + <argument name="option" value="Jane Doe, 172, Westminster Bridge Rd, London, SE1 7RW, United Kingdom"/> + </actionGroup> + <actionGroup ref="StorefrontSaveAddressActionGroup" stepKey="saveThreeDifferentAddresses"/> <!-- Click 'Continue to Billing Information' --> - <actionGroup ref="defaultShippingInfoActionGroup" stepKey="useDefaultShippingMethodForIdenticalProducts"/> + <actionGroup ref="StorefrontLeaveDefaultShippingMethodsAndGoToBillingInfoActionGroup" stepKey="useDefaultShippingMethodForIdenticalProducts"/> <!-- Click 'Go to Review Your Order' --> <actionGroup ref="SelectBillingInfoActionGroup" stepKey="UseDefaultBillingMethodForIdenticalProducts"/> <!-- Click 'Place Order' --> From f23070c9ab907a1f42e3d47ab60cc16870ee8080 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 25 Sep 2019 15:35:22 -0500 Subject: [PATCH 0625/1172] MC-20279: Update AdvancedSearch related MFTF tests to Elasticsearch * Update test case ids for duplicate MySQL tests --- .../Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml | 8 ++++---- .../Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml index 13ea7c68c684..ddbd0fa9172a 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml @@ -55,7 +55,7 @@ <title value="Guest customer should be able to advance search Bundle product with product name using the MySQL search engine"/> <description value="Guest customer should be able to advance search Bundle product with product name using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20472"/> <group value="Bundle"/> <group value="SearchEngineMysql"/> </annotations> @@ -166,7 +166,7 @@ <title value="Guest customer should be able to advance search Bundle product with product description using the MySQL search engine"/> <description value="Guest customer should be able to advance search Bundle product with product description using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20473"/> <group value="Bundle"/> <group value="SearchEngineMysql"/> </annotations> @@ -242,7 +242,7 @@ <title value="Guest customer should be able to advance search Bundle product with product short description using the MySQL search engine"/> <description value="Guest customer should be able to advance search Bundle product with product short description using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20474"/> <group value="Bundle"/> <group value="SearchEngineMysql"/> </annotations> @@ -327,7 +327,7 @@ <title value="Guest customer should be able to advance search Bundle product with product price using the MySQL search engine"/> <description value="Guest customer should be able to advance search Bundle product with product price the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20475"/> <group value="Bundle"/> <group value="SearchEngineMysql"/> </annotations> diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml index 5b7c0cf4c4a0..8c04ae4569e7 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml @@ -50,7 +50,7 @@ <title value="Guest customer should be able to advance search Grouped product with product name using the MySQL search engine"/> <description value="Guest customer should be able to advance search Grouped product with product name using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20464"/> <group value="GroupedProduct"/> <group value="SearchEngineMysql"/> </annotations> @@ -146,7 +146,7 @@ <title value="Guest customer should be able to advance search Grouped product with product description using the MySQL search engine"/> <description value="Guest customer should be able to advance search Grouped product with product description using the MYSQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20468"/> <group value="GroupedProduct"/> <group value="SearchEngineMysql"/> </annotations> @@ -212,7 +212,7 @@ <title value="Guest customer should be able to advance search Grouped product with product short description using the MySQL search engine"/> <description value="Guest customer should be able to advance search Grouped product with product short description using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20469"/> <group value="GroupedProduct"/> <group value="SearchEngineMysql"/> </annotations> @@ -287,7 +287,7 @@ <title value="Guest customer should be able to advance search Grouped product with product price using the MySQL search engine"/> <description value="Guest customer should be able to advance search Grouped product with product price using the MySQL search engine"/> <severity value="MAJOR"/> - <testCaseId value=""/> + <testCaseId value="MC-20470"/> <group value="GroupedProduct"/> <group value="SearchEngineMysql"/> </annotations> From a02d821d5d9c356a057f29e33aaf2b6749f5f0af Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 25 Sep 2019 16:04:11 -0500 Subject: [PATCH 0626/1172] MC-19247: Broken translations with advanced bundling - Add escape url to layout; --- .../Translation/ViewModel/Dictionary.php | 22 ++++++++++++++++++- .../view/base/templates/dictionary.phtml | 4 ++-- .../jasmine/tests/lib/mage/fake-dictionary.js | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php index d857b1182408..d551a3f106ea 100644 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ b/app/code/Magento/Translation/ViewModel/Dictionary.php @@ -6,6 +6,7 @@ namespace Magento\Translation\ViewModel; +use Magento\Framework\Escaper; use Magento\Framework\Exception\FileSystemException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\View\Asset\Repository as AssetRepository; @@ -28,16 +29,24 @@ class Dictionary implements ArgumentInterface */ private $appState; + /** + * @var Escaper + */ + private $escaper; + /** * @param AssetRepository $assetRepo * @param AppState $appState + * @param Escaper $escaper */ public function __construct( AssetRepository $assetRepo, - AppState $appState + AppState $appState, + Escaper $escaper ) { $this->assetRepo = $assetRepo; $this->appState = $appState; + $this->escaper = $escaper; } /** @@ -76,4 +85,15 @@ public function isAppStateProduction(): bool { return $this->appState->getMode() === AppState::MODE_PRODUCTION; } + + /** + * Escape URL. + * + * @param string $url + * @return string + */ + public function escapeUrl(string $url): string + { + return $this->escaper->escapeUrl($url); + } } diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index 6b39f43a028c..c6bfc30dcab8 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -20,10 +20,10 @@ if (!$viewModel->isAppStateProduction()) { } else { ?> <script> - define('mageTranslationDictionary', ['text!<?= /* @noEscape */ $viewModel->getTranslationDictionaryUrl() ?>'], function (dict) { + define('mageTranslationDictionary', ['text!<?= $viewModel->escapeUrl($viewModel->getTranslationDictionaryUrl()) ?>'], function (dict) { return JSON.parse(dict); }); </script> -<?php + <?php } ?> diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js index f85840fd7720..eeeed2a5864e 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js +++ b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js @@ -2,7 +2,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -// Fake translation dictionary for js unit tests as real dictionary is defined in template and cannot be initialized by requirejs +// Fake translation dictionary as real dictionary is defined in template and cannot be initialized by requirejs define([], function () { 'use strict'; From 28d119cdb20899c7881ed06b8d3ab99dd8a78b63 Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Wed, 25 Sep 2019 16:18:57 -0500 Subject: [PATCH 0627/1172] MC-15986: Category Filtering - added Schema changes --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 140aab37c9ce..24a2123ff60f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -11,7 +11,8 @@ type Query { ): Products @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Identity") category ( - id: Int @doc(description: "Id of the category.") + id: Int @doc(description: "Id of the category.") + filter: CategoryFilterInput @doc(description: "Identifies which Category inputs to search for and return."), ): CategoryTree @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") } @@ -277,6 +278,12 @@ input ProductAttributeFilterInput @doc(description: "ProductAttributeFilterInput category_id: FilterEqualTypeInput @doc(description: "Filter product by category id") } +input CategoryFilterInput @doc(description: "CategoryFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { + id: FilterEqualTypeInput @doc(description: "Filter by category ID that uniquely identifies and filters the category."), + url_key: FilterEqualTypeInput @doc(description: "Filter by the part of the URL that identifies the category"), + name: FilterEqualTypeInput @doc(description: "Filter by the display name of the category.") +} + input ProductFilterInput @doc(description: "ProductFilterInput is deprecated, use @ProductAttributeFilterInput instead. ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.") sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer.") From 188d766e76c8ce4104bbe4eb60bb611ed8b3a4d5 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 25 Sep 2019 16:03:14 -0500 Subject: [PATCH 0628/1172] MC-20358: Create New MFTF Suites for MySQL/Elasticsearch Specific Functionality * Added before block to suite to ensure config is properly set --- .../Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml index eaa90f7590bf..9ed6ccda6220 100644 --- a/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml +++ b/app/code/Magento/Search/Test/Mftf/Suite/SearchEngineMysqlSuite.xml @@ -7,6 +7,12 @@ --> <suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> <suite name="SearchEngineMysqlSuite"> + <before> + <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after></after> <include> <group name="SearchEngineMysql" /> </include> From 99d8cf17e6727b4f5768d78eefa5d94cff1af772 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 25 Sep 2019 16:22:03 -0500 Subject: [PATCH 0629/1172] MC-18403: Pricing :: Product pricing schema - Fix percent-based tier price --- .../Model/Resolver/PriceTiers.php | 9 ++--- .../Model/Resolver/Product/Price/Tiers.php | 33 ++++++++++++++++++- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php index a7a7a3236c41..2e337238536c 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php @@ -102,20 +102,17 @@ public function resolve( $product = $value['model']; $productId = $product->getId(); - $productPrice = $this->priceProviderPool - ->getProviderByProductType($product->getTypeId()) - ->getMinimalRegularPrice($product) - ->getValue(); $this->tiers->addProductFilter($productId); return $this->valueFactory->create( - function () use ($productId, $productPrice, $context) { - + function () use ($productId, $context) { /** @var StoreInterface $store */ $store = $context->getExtensionAttributes()->getStore(); + $productPrice = $this->tiers->getProductRegularPrice($productId) ?? 0.0; $tierPrices = $this->tiers->getProductTierPrices($productId) ?? []; + return $this->formatProductTierPrices($tierPrices, $productPrice, $store); } ); diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php index b57dc80fa771..f227b10b73a0 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php @@ -12,6 +12,7 @@ use Magento\Catalog\Model\ResourceModel\Product as ProductResource; use Magento\Customer\Model\GroupManagement; use Magento\Catalog\Api\Data\ProductTierPriceInterface; +use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool as PriceProviderPool; /** * Get product tier price information @@ -28,6 +29,11 @@ class Tiers */ private $productResource; + /** + * @var PriceProviderPool + */ + private $priceProviderPool; + /** * @var bool */ @@ -36,7 +42,7 @@ class Tiers /** * @var int */ - private $customerGroupId = GroupManagement::CUST_GROUP_ALL; + private $customerGroupId = GroupManagement::CUST_GROUP_ALL; /** * @var array @@ -51,15 +57,18 @@ class Tiers /** * @param CollectionFactory $collectionFactory * @param ProductResource $productResource + * @param PriceProviderPool $priceProviderPool * @param int $customerGroupId */ public function __construct( CollectionFactory $collectionFactory, ProductResource $productResource, + PriceProviderPool $priceProviderPool, $customerGroupId ) { $this->collectionFactory = $collectionFactory; $this->productResource = $productResource; + $this->priceProviderPool = $priceProviderPool; $this->customerGroupId = $customerGroupId; } @@ -91,6 +100,26 @@ public function getProductTierPrices($productId): ?array return $this->products[$productId]->getTierPrices(); } + /** + * Get product regular price by ID + * + * @param int $productId + * @return float|null + */ + public function getProductRegularPrice($productId): ?float + { + if (!$this->isLoaded()) { + $this->load(); + } + + if (empty($this->products[$productId])) { + return null; + } + $product = $this->products[$productId]; + $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); + return $priceProvider->getMinimalRegularPrice($product)->getValue(); + } + /** * Check if collection has been loaded * @@ -112,6 +141,8 @@ private function load(): void /** @var Collection $productCollection */ $productCollection = $this->collectionFactory->create(); $productCollection->addFieldToFilter($productIdField, ['in' => $this->filterProductIds]); + $productCollection->addAttributeToSelect('price'); + $productCollection->load(); $productCollection->addTierPriceDataByGroupId($this->customerGroupId); foreach ($productCollection as $product) { From 5b0835ea55f276b766b6d839e009d900172dbf29 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Wed, 25 Sep 2019 17:55:07 -0500 Subject: [PATCH 0630/1172] MC-18403: Pricing :: Product pricing schema - move di.xml to graphql area --- app/code/Magento/BundleGraphQl/etc/di.xml | 8 -------- .../Magento/BundleGraphQl/etc/graphql/di.xml | 8 ++++++++ app/code/Magento/CatalogGraphQl/etc/di.xml | 7 ------- .../Magento/CatalogGraphQl/etc/graphql/di.xml | 9 +++++++++ .../ConfigurableProductGraphQl/etc/di.xml | 16 ---------------- .../etc/graphql/di.xml | 7 +++++++ .../Magento/GroupedProductGraphQl/etc/di.xml | 8 -------- .../GroupedProductGraphQl/etc/graphql/di.xml | 8 ++++++++ 8 files changed, 32 insertions(+), 39 deletions(-) delete mode 100644 app/code/Magento/ConfigurableProductGraphQl/etc/di.xml diff --git a/app/code/Magento/BundleGraphQl/etc/di.xml b/app/code/Magento/BundleGraphQl/etc/di.xml index 386dd5647a59..4f41f3cb8dc8 100644 --- a/app/code/Magento/BundleGraphQl/etc/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/di.xml @@ -16,12 +16,4 @@ </argument> </arguments> </type> - - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> - <arguments> - <argument name="providers" xsi:type="array"> - <item name="bundle" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Product\Price\Provider</item> - </argument> - </arguments> - </type> </config> diff --git a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml index e9f76386c535..98dbe012c900 100644 --- a/app/code/Magento/BundleGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/BundleGraphQl/etc/graphql/di.xml @@ -41,6 +41,14 @@ </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="bundle" xsi:type="object">Magento\BundleGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\AttributeProcessor"> <arguments> <argument name="fieldToAttributeMap" xsi:type="array"> diff --git a/app/code/Magento/CatalogGraphQl/etc/di.xml b/app/code/Magento/CatalogGraphQl/etc/di.xml index 646073df9f09..1fe62fc442ec 100644 --- a/app/code/Magento/CatalogGraphQl/etc/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/di.xml @@ -71,11 +71,4 @@ </type> <preference type="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider" for="\Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface"/> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> - <arguments> - <argument name="providers" xsi:type="array"> - <item name="default" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> - </argument> - </arguments> - </type> </config> diff --git a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml index 56b881a35a8c..ad1b450f5215 100644 --- a/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/CatalogGraphQl/etc/graphql/di.xml @@ -119,6 +119,15 @@ </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="default" xsi:type="object">Magento\CatalogGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> + <type name="Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionProcessor\AttributeProcessor"> <arguments> <argument name="fieldToAttributeMap" xsi:type="array"> diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml deleted file mode 100644 index 629a6ef84255..000000000000 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/di.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> - <arguments> - <argument name="providers" xsi:type="array"> - <item name="configurable" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> - </argument> - </arguments> - </type> -</config> diff --git a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml index 1d72524a31b7..f82bb0dbd4d9 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/ConfigurableProductGraphQl/etc/graphql/di.xml @@ -29,4 +29,11 @@ </argument> </arguments> </type> + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="configurable" xsi:type="object">Magento\ConfigurableProductGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/di.xml index d5e208910eef..35b63370baf2 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/di.xml @@ -13,12 +13,4 @@ </argument> </arguments> </type> - - <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> - <arguments> - <argument name="providers" xsi:type="array"> - <item name="grouped" xsi:type="object">Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> - </argument> - </arguments> - </type> </config> diff --git a/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml b/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml index 5c41fc26e615..4c408b38b5ec 100644 --- a/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml +++ b/app/code/Magento/GroupedProductGraphQl/etc/graphql/di.xml @@ -29,4 +29,12 @@ </argument> </arguments> </type> + + <type name="Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderPool"> + <arguments> + <argument name="providers" xsi:type="array"> + <item name="grouped" xsi:type="object">Magento\GroupedProductGraphQl\Model\Resolver\Product\Price\Provider</item> + </argument> + </arguments> + </type> </config> From 2c88465acc700e9ccd3db4f97806a9fcaf88472e Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Wed, 25 Sep 2019 18:17:45 -0500 Subject: [PATCH 0631/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality "Duplicated above tests as well as they had reference in the main test" --- .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 188 ++++++++++++++++ .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 209 ++++++++++++++++++ .../Mftf/Test/EndToEndB2CGuestUserTest.xml | 39 ++++ .../Test/EndToEndB2CGuestUserTest.xml | 19 ++ 4 files changed, 455 insertions(+) diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 5335ec2ad775..4281a0eb77da 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -184,6 +184,194 @@ <argument name="productVar" value="$$createSimpleProduct2$$"/> </actionGroup> + <comment userInput="Place order with check money order payment" stepKey="commentPlaceOrderWithCheckMoneyOrderPayment" after="guestCheckoutCheckSimpleProduct2InCartItems" /> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" after="commentPlaceOrderWithCheckMoneyOrderPayment"/> + <actionGroup ref="CheckBillingAddressInCheckoutActionGroup" stepKey="guestSeeBillingAddress" after="guestSelectCheckMoneyOrderPayment"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="CustomerAddressSimple" /> + </actionGroup> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="guestPlaceorder" after="guestSeeBillingAddress"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + <comment userInput="End of checking out" stepKey="endOfCheckingOut" after="guestPlaceorder" /> + </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <!-- Step 3: User adds products to cart --> + <comment userInput="Start of adding products to cart" stepKey="startOfAddingProductsToCart" after="endOfBrowsingCatalog"/> + <!-- Add Simple Product 1 to cart --> + <comment userInput="Add Simple Product 1 to cart" stepKey="commentAddSimpleProduct1ToCart" after="startOfAddingProductsToCart" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="cartClickCategory" after="commentAddSimpleProduct1ToCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartCategoryloaded" after="cartClickCategory"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="cartAssertCategory" after="waitForCartCategoryloaded"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="cartAssertSimpleProduct1" after="cartAssertCategory"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="cartGrabSimpleProduct1ImageSrc" after="cartAssertSimpleProduct1"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartGrabSimpleProduct1ImageSrc" stepKey="cartAssertSimpleProduct1ImageNotDefault" after="cartGrabSimpleProduct1ImageSrc"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createSimpleProduct1.name$$)}}" stepKey="cartClickSimpleProduct1" after="cartAssertSimpleProduct1ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartSimpleProduct1loaded" after="cartClickSimpleProduct1"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="cartAssertProduct1Page" after="waitForCartSimpleProduct1loaded"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartGrabSimpleProduct1PageImageSrc" after="cartAssertProduct1Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartGrabSimpleProduct1PageImageSrc" stepKey="cartAssertSimpleProduct1PageImageNotDefault" after="cartGrabSimpleProduct1PageImageSrc"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddProduct1ToCart" after="cartAssertSimpleProduct1PageImageNotDefault"> + <argument name="product" value="$$createSimpleProduct1$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + + <!-- Add Simple Product 2 to cart --> + <comment userInput="Add Simple Product 2 to cart" stepKey="commentAddSimpleProduct2ToCart" after="cartAddProduct1ToCart" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="cartClickCategory1" after="commentAddSimpleProduct2ToCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartCategory1loaded" after="cartClickCategory1"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="cartAssertCategory1ForSimpleProduct2" after="waitForCartCategory1loaded"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategorySimpleProduct" stepKey="cartAssertSimpleProduct2" after="cartAssertCategory1ForSimpleProduct2"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="cartGrabSimpleProduct2ImageSrc" after="cartAssertSimpleProduct2"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartGrabSimpleProduct2ImageSrc" stepKey="cartAssertSimpleProduct2ImageNotDefault" after="cartGrabSimpleProduct2ImageSrc"/> + <actionGroup ref="StorefrontAddCategoryProductToCartActionGroup" stepKey="cartAddProduct2ToCart" after="cartAssertSimpleProduct2ImageNotDefault"> + <argument name="product" value="$$createSimpleProduct2$$"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="productCount" value="CONST.two"/> + </actionGroup> + + <!-- Check products in minicart --> + <!-- Check simple product 1 in minicart --> + <comment userInput="Check simple product 1 in minicart" stepKey="commentCheckSimpleProduct1InMinicart" after="cartAddProduct2ToCart"/> + <actionGroup ref="StorefrontOpenMinicartAndCheckSimpleProductActionGroup" stepKey="cartOpenMinicartAndCheckSimpleProduct1" after="commentCheckSimpleProduct1InMinicart"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="cartMinicartGrabSimpleProduct1ImageSrc" after="cartOpenMinicartAndCheckSimpleProduct1"/> + <assertNotRegExp expected="'/placeholder\/thumbnail\.jpg/'" actual="$cartMinicartGrabSimpleProduct1ImageSrc" stepKey="cartMinicartAssertSimpleProduct1ImageNotDefault" after="cartMinicartGrabSimpleProduct1ImageSrc"/> + <click selector="{{StorefrontMinicartSection.productLinkByName($$createSimpleProduct1.name$$)}}" stepKey="cartMinicartClickSimpleProduct1" after="cartMinicartAssertSimpleProduct1ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForMinicartSimpleProduct1loaded" after="cartMinicartClickSimpleProduct1"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="cartAssertMinicartProduct1Page" after="waitForMinicartSimpleProduct1loaded"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartMinicartGrabSimpleProduct1PageImageSrc" after="cartAssertMinicartProduct1Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartMinicartGrabSimpleProduct1PageImageSrc" stepKey="cartMinicartAssertSimpleProduct1PageImageNotDefault" after="cartMinicartGrabSimpleProduct1PageImageSrc"/> + <actionGroup ref="StorefrontOpenMinicartAndCheckSimpleProductActionGroup" stepKey="cartOpenMinicartAndCheckSimpleProduct2" after="cartMinicartAssertSimpleProduct1PageImageNotDefault"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- Check simple product2 in minicart --> + <comment userInput="Check simple product 2 in minicart" stepKey="commentCheckSimpleProduct2InMinicart" after="cartOpenMinicartAndCheckSimpleProduct2"/> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="cartMinicartGrabSimpleProduct2ImageSrc" after="commentCheckSimpleProduct2InMinicart"/> + <assertNotRegExp expected="'/placeholder\/thumbnail\.jpg/'" actual="$cartMinicartGrabSimpleProduct2ImageSrc" stepKey="cartMinicartAssertSimpleProduct2ImageNotDefault" after="cartMinicartGrabSimpleProduct2ImageSrc"/> + <click selector="{{StorefrontMinicartSection.productLinkByName($$createSimpleProduct2.name$$)}}" stepKey="cartMinicartClickSimpleProduct2" after="cartMinicartAssertSimpleProduct2ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForMinicartSimpleProduct2loaded" after="cartMinicartClickSimpleProduct2"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="cartAssertMinicartProduct2Page" after="waitForMinicartSimpleProduct2loaded"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartMinicartGrabSimpleProduct2PageImageSrc" after="cartAssertMinicartProduct2Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartMinicartGrabSimpleProduct2PageImageSrc" stepKey="cartMinicartAssertSimpleProduct2PageImageNotDefault" after="cartMinicartGrabSimpleProduct2PageImageSrc"/> + + <!-- Check products in cart --> + <comment userInput="Check cart information" stepKey="commentCheckCartInformation" after="cartMinicartAssertSimpleProduct2PageImageNotDefault" /> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="cartOpenCart" after="commentCheckCartInformation"/> + <actionGroup ref="StorefrontCheckCartActionGroup" stepKey="cartAssertCart" after="cartOpenCart"> + <argument name="subtotal" value="480.00"/> + <argument name="shipping" value="15.00"/> + <argument name="shippingMethod" value="Flat Rate - Fixed"/> + <argument name="total" value="495.00"/> + </actionGroup> + + <!-- Check simple product 1 in cart --> + <comment userInput="Check simple product 1 in cart" stepKey="commentCheckSimpleProduct1InCart" after="cartAssertCart"/> + <actionGroup ref="StorefrontCheckCartSimpleProductActionGroup" stepKey="cartAssertCartSimpleProduct1" after="commentCheckSimpleProduct1InCart"> + <argument name="product" value="$$createSimpleProduct1$$"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="productQuantity" value="CONST.one"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{CheckoutCartProductSection.ProductImageByName($$createSimpleProduct1.name$$)}}" userInput="src" stepKey="cartCartGrabSimpleProduct1ImageSrc" after="cartAssertCartSimpleProduct1"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartCartGrabSimpleProduct1ImageSrc" stepKey="cartCartAssertSimpleProduct1ImageNotDefault" after="cartCartGrabSimpleProduct1ImageSrc"/> + <click selector="{{CheckoutCartProductSection.ProductLinkByName($$createSimpleProduct1.name$$)}}" stepKey="cartClickCartSimpleProduct1" after="cartCartAssertSimpleProduct1ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartSimpleProduct1loadedAgain" after="cartClickCartSimpleProduct1"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="cartAssertCartProduct1Page" after="waitForCartSimpleProduct1loadedAgain"> + <argument name="product" value="$$createSimpleProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartCartGrabSimpleProduct2PageImageSrc1" after="cartAssertCartProduct1Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartCartGrabSimpleProduct2PageImageSrc1" stepKey="cartCartAssertSimpleProduct2PageImageNotDefault1" after="cartCartGrabSimpleProduct2PageImageSrc1"/> + + <!-- Check simple product 2 in cart --> + <comment userInput="Check simple product 2 in cart" stepKey="commentCheckSimpleProduct2InCart" after="cartCartAssertSimpleProduct2PageImageNotDefault1"/> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="cartOpenCart1" after="commentCheckSimpleProduct2InCart"/> + <actionGroup ref="StorefrontCheckCartSimpleProductActionGroup" stepKey="cartAssertCartSimpleProduct2" after="cartOpenCart1"> + <argument name="product" value="$$createSimpleProduct2$$"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="productQuantity" value="CONST.one"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{CheckoutCartProductSection.ProductImageByName($$createSimpleProduct2.name$$)}}" userInput="src" stepKey="cartCartGrabSimpleProduct2ImageSrc" after="cartAssertCartSimpleProduct2"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartCartGrabSimpleProduct2ImageSrc" stepKey="cartCartAssertSimpleProduct2ImageNotDefault" after="cartCartGrabSimpleProduct2ImageSrc"/> + <click selector="{{CheckoutCartProductSection.ProductLinkByName($$createSimpleProduct2.name$$)}}" stepKey="cartClickCartSimpleProduct2" after="cartCartAssertSimpleProduct2ImageNotDefault"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartSimpleProduct2loaded" after="cartClickCartSimpleProduct2"/> + <actionGroup ref="StorefrontCheckSimpleProduct" stepKey="cartAssertCartProduct2Page" after="waitForCartSimpleProduct2loaded"> + <argument name="product" value="$$createSimpleProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartCartGrabSimpleProduct2PageImageSrc2" after="cartAssertCartProduct2Page"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartCartGrabSimpleProduct2PageImageSrc2" stepKey="cartCartAssertSimpleProduct2PageImageNotDefault2" after="cartCartGrabSimpleProduct2PageImageSrc2"/> + <comment userInput="End of adding products to cart" stepKey="endOfAddingProductsToCart" after="cartCartAssertSimpleProduct2PageImageNotDefault2" /> + + <!-- Step 6: Check out --> + <comment userInput="Start of checking out" stepKey="startOfCheckingOut" after="endOfUsingCouponCode" /> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="guestGoToCheckoutFromMinicart" after="startOfCheckingOut"/> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutFillingShippingSection" after="guestGoToCheckoutFromMinicart"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="CustomerAddressSimple" /> + </actionGroup> + + <!-- Check order summary in checkout --> + <comment userInput="Check order summary in checkout" stepKey="commentCheckOrderSummaryInCheckout" after="guestCheckoutFillingShippingSection" /> + <actionGroup ref="CheckOrderSummaryInCheckoutActionGroup" stepKey="guestCheckoutCheckOrderSummary" after="commentCheckOrderSummaryInCheckout"> + <argument name="subtotal" value="480.00"/> + <argument name="shippingTotal" value="15.00"/> + <argument name="shippingMethod" value="Flat Rate - Fixed"/> + <argument name="total" value="495.00"/> + </actionGroup> + + <!-- Check ship to information in checkout --> + <comment userInput="Check ship to information in checkout" stepKey="commentCheckShipToInformationInCheckout" after="guestCheckoutCheckOrderSummary" /> + <actionGroup ref="CheckShipToInformationInCheckoutActionGroup" stepKey="guestCheckoutCheckShipToInformation" after="commentCheckShipToInformationInCheckout"> + <argument name="customerVar" value="CustomerEntityOne" /> + <argument name="customerAddressVar" value="CustomerAddressSimple" /> + </actionGroup> + + <!-- Check shipping method in checkout --> + <comment userInput="Check shipping method in checkout" stepKey="commentCheckShippingMethodInCheckout" after="guestCheckoutCheckShipToInformation" /> + <actionGroup ref="CheckShippingMethodInCheckoutActionGroup" stepKey="guestCheckoutCheckShippingMethod" after="commentCheckShippingMethodInCheckout"> + <argument name="shippingMethod" value="E2EB2CQuote.shippingMethod" /> + </actionGroup> + + <!-- Verify Simple Product 1 is in checkout cart items --> + <comment userInput="Verify Simple Product 1 is in checkout cart items" stepKey="commentVerifySimpleProduct1IsInCheckoutCartItems" after="guestCheckoutCheckShippingMethod" /> + <actionGroup ref="CheckProductInCheckoutCartItemsActionGroup" stepKey="guestCheckoutCheckSimpleProduct1InCartItems" after="commentVerifySimpleProduct1IsInCheckoutCartItems"> + <argument name="productVar" value="$$createSimpleProduct1$$"/> + </actionGroup> + + <!-- Verify Simple Product 2 is in checkout cart items --> + <comment userInput="Verify Simple Product 2 is in checkout cart items" stepKey="commentVerifySimpleProduct2IsInCheckoutCartItems" after="guestCheckoutCheckSimpleProduct1InCartItems" /> + <actionGroup ref="CheckProductInCheckoutCartItemsActionGroup" stepKey="guestCheckoutCheckSimpleProduct2InCartItems" after="commentVerifySimpleProduct2IsInCheckoutCartItems"> + <argument name="productVar" value="$$createSimpleProduct2$$"/> + </actionGroup> + <comment userInput="Place order with check money order payment" stepKey="commentPlaceOrderWithCheckMoneyOrderPayment" after="guestCheckoutCheckSimpleProduct2InCartItems" /> <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" after="commentPlaceOrderWithCheckMoneyOrderPayment"/> <actionGroup ref="CheckBillingAddressInCheckoutActionGroup" stepKey="guestSeeBillingAddress" after="guestSelectCheckMoneyOrderPayment"> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 47ee09e4b208..04687a2314dc 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -217,4 +217,213 @@ <grabAttributeFrom selector="{{StorefrontProductCompareMainSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="compareGrabConfigProductImageSrcInComparison" after="compareAssertConfigProductInComparison"/> <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabConfigProductImageSrcInComparison" stepKey="compareAssertConfigProductImageNotDefaultInComparison" after="compareGrabConfigProductImageSrcInComparison"/> </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <before> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <createData entity="productAttributeWithTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="productAttributeOption2" stepKey="createConfigProductAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getConfigAttributeOption2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <createData entity="ApiSimpleOne" stepKey="createConfigChildProduct1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="createConfigChildProduct1Image"> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ApiSimpleTwo" stepKey="createConfigChildProduct2"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryMagentoLogo" stepKey="createConfigChildProduct2Image"> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption1"/> + <requiredEntity createDataKey="getConfigAttributeOption2"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild1"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild2"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct2"/> + </createData> + <createData entity="ApiProductAttributeMediaGalleryEntryTestImage" stepKey="createConfigProductImage"> + <requiredEntity createDataKey="createConfigProduct"/> + </createData> + <updateData entity="ApiSimpleProductUpdateDescription" stepKey="updateConfigProduct" createDataKey="createConfigProduct"/> + </before> + <after> + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createConfigChildProduct1Image" stepKey="deleteConfigChildProduct1Image"/>--> + <deleteData createDataKey="createConfigChildProduct1" stepKey="deleteConfigChildProduct1"/> + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createConfigChildProduct2Image" stepKey="deleteConfigChildProduct2Image"/>--> + <deleteData createDataKey="createConfigChildProduct2" stepKey="deleteConfigChildProduct2"/> + <!-- @TODO: Uncomment once MQE-679 is fixed --> + <!--<deleteData createDataKey="createConfigProductImage" stepKey="deleteConfigProductImage"/>--> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + </after> + + <!-- Verify Configurable Product in checkout cart items --> + <comment userInput="Verify Configurable Product in checkout cart items" stepKey="commentVerifyConfigurableProductInCheckoutCartItems" after="guestCheckoutCheckSimpleProduct2InCartItems" /> + <actionGroup ref="CheckConfigurableProductInCheckoutCartItemsActionGroup" stepKey="guestCheckoutCheckConfigurableProductInCartItems" after="commentVerifyConfigurableProductInCheckoutCartItems"> + <argument name="productVar" value="$$createConfigProduct$$"/> + <argument name="optionLabel" value="$$createConfigProductAttribute.attribute[frontend_labels][0][label]$$" /> + <argument name="optionValue" value="$$createConfigProductAttributeOption2.option[store_labels][1][label]$$" /> + </actionGroup> + + <!-- Check configurable product in category --> + <comment userInput="Verify Configurable Product in category" stepKey="commentVerifyConfigurableProductInCategory" after="browseAssertSimpleProduct2ImageNotDefault" /> + <actionGroup ref="StorefrontCheckCategoryConfigurableProduct" stepKey="browseAssertCategoryConfigProduct" after="commentVerifyConfigurableProductInCategory"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="browseGrabConfigProductImageSrc" after="browseAssertCategoryConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$browseGrabConfigProductImageSrc" stepKey="browseAssertConfigProductImageNotDefault" after="browseGrabConfigProductImageSrc"/> + + <!-- View Configurable Product --> + <comment userInput="View Configurable Product" stepKey="commentViewConfigurableProduct" after="browseAssertSimpleProduct2PageImageNotDefault" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="clickCategory2" after="commentViewConfigurableProduct"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="browseClickCategoryConfigProductView" after="clickCategory2"/> + <waitForLoadingMaskToDisappear stepKey="waitForConfigurableProductViewloaded" after="browseClickCategoryConfigProductView"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="browseAssertConfigProductPage" after="waitForConfigurableProductViewloaded"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="browseGrabConfigProductPageImageSrc" after="browseAssertConfigProductPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$browseGrabConfigProductPageImageSrc" stepKey="browseAssertConfigProductPageImageNotDefault" after="browseGrabConfigProductPageImageSrc"/> + + <!-- Add Configurable Product to cart --> + <comment userInput="Add Configurable Product to cart" stepKey="commentAddConfigurableProductToCart" after="cartAddProduct2ToCart" /> + <click selector="{{StorefrontHeaderSection.NavigationCategoryByName($$createCategory.name$$)}}" stepKey="cartClickCategory2" after="commentAddConfigurableProductToCart"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartCategory2loaded" after="cartClickCategory2"/> + <actionGroup ref="StorefrontCheckCategoryActionGroup" stepKey="cartAssertCategory1ForConfigurableProduct" after="waitForCartCategory2loaded"> + <argument name="category" value="$$createCategory$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCategoryConfigurableProduct" stepKey="cartAssertConfigProduct" after="cartAssertCategory1ForConfigurableProduct"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="cartGrabConfigProductImageSrc" after="cartAssertConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartGrabConfigProductImageSrc" stepKey="cartAssertConfigProductImageNotDefault" after="cartGrabConfigProductImageSrc"/> + <click selector="{{StorefrontCategoryProductSection.ProductAddToCartByName($$createConfigProduct.name$$)}}" stepKey="cartClickCategoryConfigProductAddToCart" after="cartAssertConfigProductImageNotDefault"/> + <waitForElement selector="{{StorefrontMessagesSection.message('You need to choose options for your item.')}}" time="30" stepKey="cartWaitForConfigProductPageLoad" after="cartClickCategoryConfigProductAddToCart"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="cartAssertConfigProductPage" after="cartWaitForConfigProductPageLoad"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartGrabConfigProductPageImageSrc1" after="cartAssertConfigProductPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartGrabConfigProductPageImageSrc1" stepKey="cartAssertConfigProductPageImageNotDefault1" after="cartGrabConfigProductPageImageSrc1"/> + <selectOption userInput="$$createConfigProductAttributeOption2.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="cartConfigProductFillOption" after="cartAssertConfigProductPageImageNotDefault1"/> + <waitForLoadingMaskToDisappear stepKey="waitForConfigurableProductOptionloaded" after="cartConfigProductFillOption"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="cartAssertConfigProductWithOptionPage" after="waitForConfigurableProductOptionloaded"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartGrabConfigProductPageImageSrc2" after="cartAssertConfigProductWithOptionPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartGrabConfigProductPageImageSrc2" stepKey="cartAssertConfigProductPageImageNotDefault2" after="cartGrabConfigProductPageImageSrc2"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="cartAddConfigProductToCart" after="cartAssertConfigProductPageImageNotDefault2"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="productCount" value="3"/> + </actionGroup> + + <!-- Check configurable product in minicart --> + <comment userInput="Check configurable product in minicart" stepKey="commentCheckConfigurableProductInMinicart" after="cartMinicartAssertSimpleProduct2PageImageNotDefault" /> + <actionGroup ref="StorefrontOpenMinicartAndCheckConfigurableProductActionGroup" stepKey="cartOpenMinicartAndCheckConfigProduct" after="commentCheckConfigurableProductInMinicart"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct2$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontMinicartSection.productImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="cartMinicartGrabConfigProductImageSrc" after="cartOpenMinicartAndCheckConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/thumbnail\.jpg/'" actual="$cartMinicartGrabConfigProductImageSrc" stepKey="cartMinicartAssertConfigProductImageNotDefault" after="cartMinicartGrabConfigProductImageSrc"/> + <click selector="{{StorefrontMinicartSection.productOptionsDetailsByName($$createConfigProduct.name$$)}}" stepKey="cartMinicartClickConfigProductDetails" after="cartMinicartAssertConfigProductImageNotDefault"/> + <see userInput="$$createConfigProductAttributeOption2.option[store_labels][1][label]$$" selector="{{StorefrontMinicartSection.productOptionByNameAndAttribute($$createConfigProduct.name$$, $$createConfigProductAttribute.attribute[frontend_labels][0][label]$$)}}" stepKey="cartMinicartCheckConfigProductOption" after="cartMinicartClickConfigProductDetails"/> + <click selector="{{StorefrontMinicartSection.productLinkByName($$createConfigProduct.name$$)}}" stepKey="cartMinicartClickConfigProduct" after="cartMinicartCheckConfigProductOption"/> + <waitForLoadingMaskToDisappear stepKey="waitForMinicartConfigProductloaded" after="cartMinicartClickConfigProduct"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="cartAssertMinicartConfigProductPage" after="waitForMinicartConfigProductloaded"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartMinicartGrabConfigProductPageImageSrc" after="cartAssertMinicartConfigProductPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartMinicartGrabConfigProductPageImageSrc" stepKey="cartMinicartAssertConfigProductPageImageNotDefault" after="cartMinicartGrabConfigProductPageImageSrc"/> + + <!-- Check configurable product in cart --> + <comment userInput="Check configurable product in cart" stepKey="commentCheckConfigurableProductInCart" after="cartCartAssertSimpleProduct2PageImageNotDefault2" /> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="cartOpenCart2" after="commentCheckConfigurableProductInCart"/> + <actionGroup ref="StorefrontCheckCartConfigurableProductActionGroup" stepKey="cartAssertCartConfigProduct" after="cartOpenCart2"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct2$$"/> + <!-- @TODO: Change to scalar value after MQE-498 is implemented --> + <argument name="productQuantity" value="CONST.one"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{CheckoutCartProductSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="cartCartGrabConfigProduct2ImageSrc" after="cartAssertCartConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$cartCartGrabConfigProduct2ImageSrc" stepKey="cartCartAssertConfigProduct2ImageNotDefault" after="cartCartGrabConfigProduct2ImageSrc"/> + <see userInput="$$createConfigProductAttributeOption2.option[store_labels][1][label]$$" selector="{{CheckoutCartProductSection.ProductOptionByNameAndAttribute($$createConfigProduct.name$$, $$createConfigProductAttribute.attribute[frontend_labels][0][label]$$)}}" stepKey="cartCheckConfigProductOption" after="cartCartAssertConfigProduct2ImageNotDefault"/> + <click selector="{{CheckoutCartProductSection.ProductLinkByName($$createConfigProduct.name$$)}}" stepKey="cartClickCartConfigProduct" after="cartCheckConfigProductOption"/> + <waitForLoadingMaskToDisappear stepKey="waitForCartConfigProductloaded" after="cartClickCartConfigProduct"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="cartAssertCartConfigProductPage" after="waitForCartConfigProductloaded"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="cartCartGrabConfigProductPageImageSrc" after="cartAssertCartConfigProductPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$cartCartGrabConfigProductPageImageSrc" stepKey="cartCartAssertConfigProductPageImageNotDefault" after="cartCartGrabConfigProductPageImageSrc"/> + + <!-- Add Configurable Product to comparison --> + <comment userInput="Add Configurable Product to comparison" stepKey="commentAddConfigurableProductToComparison" after="compareAddSimpleProduct2ToCompare" /> + <actionGroup ref="StorefrontCheckCategoryConfigurableProduct" stepKey="compareAssertConfigProduct" after="commentAddConfigurableProductToComparison"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="compareGrabConfigProductImageSrc" after="compareAssertConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabConfigProductImageSrc" stepKey="compareAssertConfigProductImageNotDefault" after="compareGrabConfigProductImageSrc"/> + <actionGroup ref="StorefrontAddCategoryProductToCompareActionGroup" stepKey="compareAddConfigProductToCompare" after="compareAssertConfigProductImageNotDefault"> + <argument name="productVar" value="$$createConfigProduct$$"/> + </actionGroup> + + <!-- Check configurable product in comparison sidebar --> + <comment userInput="Add Configurable Product in comparison sidebar" stepKey="commentAddConfigurableProductInComparisonSidebar" after="compareSimpleProduct2InSidebar" /> + <actionGroup ref="StorefrontCheckCompareSidebarProductActionGroup" stepKey="compareConfigProductInSidebar" after="commentAddConfigurableProductInComparisonSidebar"> + <argument name="productVar" value="$$createConfigProduct$$"/> + </actionGroup> + + <!-- Check configurable product on comparison page --> + <comment userInput="Add Configurable Product on comparison page" stepKey="commentAddConfigurableProductOnComparisonPage" after="compareAssertSimpleProduct2ImageNotDefaultInComparison" /> + <actionGroup ref="StorefrontCheckCompareConfigurableProductActionGroup" stepKey="compareAssertConfigProductInComparison" after="commentAddConfigurableProductOnComparisonPage"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductCompareMainSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="compareGrabConfigProductImageSrcInComparison" after="compareAssertConfigProductInComparison"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$compareGrabConfigProductImageSrcInComparison" stepKey="compareAssertConfigProductImageNotDefaultInComparison" after="compareGrabConfigProductImageSrcInComparison"/> + </test> </tests> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml index 0d365dc089e4..e4e9a6278094 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Test/EndToEndB2CGuestUserTest.xml @@ -38,6 +38,45 @@ <argument name="total" value="447.00"/> </actionGroup> + <actionGroup ref="StorefrontCancelCouponActionGroup" stepKey="couponCancelCoupon" after="couponCheckCartWithDiscount"/> + <actionGroup ref="StorefrontCheckCartActionGroup" stepKey="cartAssertCartAfterCancelCoupon" after="couponCancelCoupon"> + <argument name="subtotal" value="480.00"/> + <argument name="shipping" value="15.00"/> + <argument name="shippingMethod" value="Flat Rate - Fixed"/> + <argument name="total" value="495.00"/> + </actionGroup> + <comment userInput="End of using coupon code" stepKey="endOfUsingCouponCode" after="cartAssertCartAfterCancelCoupon" /> + </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <before> + <createData entity="ApiSalesRule" stepKey="createSalesRule"/> + <createData entity="ApiSalesRuleCoupon" stepKey="createSalesRuleCoupon"> + <requiredEntity createDataKey="createSalesRule"/> + </createData> + </before> + <after> + <deleteData createDataKey="createSalesRule" stepKey="deleteSalesRule"/> + </after> + + <!-- Step 5: User uses coupon codes --> + <comment userInput="Start of using coupon code" stepKey="startOfUsingCouponCode" after="endOfComparingProducts" /> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="couponOpenCart" after="startOfUsingCouponCode"/> + + <actionGroup ref="StorefrontApplyCouponActionGroup" stepKey="couponApplyCoupon" after="couponOpenCart"> + <argument name="coupon" value="$$createSalesRuleCoupon$$"/> + </actionGroup> + + <actionGroup ref="StorefrontCheckCouponAppliedActionGroup" stepKey="couponCheckAppliedDiscount" after="couponApplyCoupon"> + <argument name="rule" value="$$createSalesRule$$"/> + <argument name="discount" value="48.00"/> + </actionGroup> + <actionGroup ref="StorefrontCheckCartActionGroup" stepKey="couponCheckCartWithDiscount" after="couponCheckAppliedDiscount"> + <argument name="subtotal" value="480.00"/> + <argument name="shipping" value="15.00"/> + <argument name="shippingMethod" value="Flat Rate - Fixed"/> + <argument name="total" value="447.00"/> + </actionGroup> + <actionGroup ref="StorefrontCancelCouponActionGroup" stepKey="couponCancelCoupon" after="couponCheckCartWithDiscount"/> <actionGroup ref="StorefrontCheckCartActionGroup" stepKey="cartAssertCartAfterCancelCoupon" after="couponCancelCoupon"> <argument name="subtotal" value="480.00"/> diff --git a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/Test/EndToEndB2CGuestUserTest.xml b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/Test/EndToEndB2CGuestUserTest.xml index f0bfec543f28..cac9d0c3cb55 100644 --- a/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/Test/EndToEndB2CGuestUserTest.xml +++ b/dev/tests/acceptance/tests/functional/Magento/FunctionalTest/ConfigurableProductCatalogSearch/Test/EndToEndB2CGuestUserTest.xml @@ -27,4 +27,23 @@ <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="searchGrabConfigProductPageImageSrc" after="searchAssertConfigProductPage"/> <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$searchGrabConfigProductPageImageSrc" stepKey="searchAssertConfigProductPageImageNotDefault" after="searchGrabConfigProductPageImageSrc"/> </test> + <test name="EndToEndB2CGuestUserMysqlTest"> + <!-- Search configurable product --> + <comment userInput="Search configurable product" stepKey="commentSearchConfigurableProduct" after="searchAssertSimpleProduct2ImageNotDefault" /> + <actionGroup ref="StorefrontCheckCategoryConfigurableProduct" stepKey="searchAssertFilterCategoryConfigProduct" after="commentSearchConfigurableProduct"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontCategoryProductSection.ProductImageByName($$createConfigProduct.name$$)}}" userInput="src" stepKey="searchGrabConfigProductImageSrc" after="searchAssertFilterCategoryConfigProduct"/> + <assertNotRegExp expected="'/placeholder\/small_image\.jpg/'" actual="$searchGrabConfigProductImageSrc" stepKey="searchAssertConfigProductImageNotDefault" after="searchGrabConfigProductImageSrc"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName($$createConfigProduct.name$$)}}" stepKey="searchClickConfigProductView" after="searchAssertConfigProductImageNotDefault"/> + <actionGroup ref="StorefrontCheckConfigurableProduct" stepKey="searchAssertConfigProductPage" after="searchClickConfigProductView"> + <argument name="product" value="$$createConfigProduct$$"/> + <argument name="optionProduct" value="$$createConfigChildProduct1$$"/> + </actionGroup> + <!-- @TODO: Move Image check to action group after MQE-697 is fixed --> + <grabAttributeFrom selector="{{StorefrontProductInfoMainSection.productImage}}" userInput="src" stepKey="searchGrabConfigProductPageImageSrc" after="searchAssertConfigProductPage"/> + <assertNotRegExp expected="'/placeholder\/image\.jpg/'" actual="$searchGrabConfigProductPageImageSrc" stepKey="searchAssertConfigProductPageImageNotDefault" after="searchGrabConfigProductPageImageSrc"/> + </test> </tests> From aee517e347f75748c2a80e8f54864f4125bc80cd Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 25 Sep 2019 18:22:13 -0500 Subject: [PATCH 0632/1172] MC-19247: Broken translations with advanced bundling - Move translation dictionary to separate js; --- .../Translation/view/base/templates/dictionary.phtml | 9 --------- .../view/base/web/js/mageTranslationDictionary.js | 9 +++++++++ .../Translation/view/frontend/requirejs-config.js | 6 ++++-- 3 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml index c6bfc30dcab8..48ffef51a364 100644 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ b/app/code/Magento/Translation/view/base/templates/dictionary.phtml @@ -17,13 +17,4 @@ if (!$viewModel->isAppStateProduction()) { }); </script> <?php -} else { - ?> - <script> - define('mageTranslationDictionary', ['text!<?= $viewModel->escapeUrl($viewModel->getTranslationDictionaryUrl()) ?>'], function (dict) { - return JSON.parse(dict); - }); - </script> - <?php } -?> diff --git a/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js b/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js new file mode 100644 index 000000000000..581cdd5f954f --- /dev/null +++ b/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js @@ -0,0 +1,9 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define(['text!js-translation.json'], + function (dict) { + return JSON.parse(dict); +}); diff --git a/app/code/Magento/Translation/view/frontend/requirejs-config.js b/app/code/Magento/Translation/view/frontend/requirejs-config.js index b4b3ce0f8c55..73f913ce23f2 100644 --- a/app/code/Magento/Translation/view/frontend/requirejs-config.js +++ b/app/code/Magento/Translation/view/frontend/requirejs-config.js @@ -8,10 +8,12 @@ var config = { '*': { editTrigger: 'mage/edit-trigger', addClass: 'Magento_Translation/js/add-class', - 'Magento_Translation/add-class': 'Magento_Translation/js/add-class' + 'Magento_Translation/add-class': 'Magento_Translation/js/add-class', + mageTranslationDictionary: 'Magento_Translation/js/mageTranslationDictionary' } }, deps: [ - 'mage/translate-inline' + 'mage/translate-inline', + 'mageTranslationDictionary' ] }; From 2cab120ea86e431a7bc8196d8e94f9524e204e42 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Thu, 26 Sep 2019 10:32:24 +0530 Subject: [PATCH 0633/1172] Static Tests build --- .../Magento/Catalog/view/frontend/templates/product/list.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml index efcf2a3e4aaf..8c32302cf7c2 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/list.phtml @@ -72,7 +72,7 @@ $_helper = $this->helper(Magento\Catalog\Helper\Output::class); </strong> <?= $block->getReviewsSummaryHtml($_product, $templateType) ?> <?= /* @noEscape */ $block->getProductPrice($_product) ?> - <?php if ($_product->isAvailable()): ?> + <?php if ($_product->isAvailable()) :?> <?= $block->getProductDetailsHtml($_product) ?> <?php endif; ?> From 3a79507dc12c61480814b83958c989b7106582b4 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 25 Sep 2019 17:46:46 +0400 Subject: [PATCH 0634/1172] MC-18215: Error message while creating shipping label - Added automated test script --- .../AdminGeneralStoreInfomationConfigData.xml | 37 +++++ .../ActionGroup/AdminProductActionGroup.xml | 6 + .../Mftf/ActionGroup/CheckoutActionGroup.xml | 1 + .../Customer/Test/Mftf/Data/AddressData.xml | 1 + .../Fedex/Test/Mftf/Data/FexExConfigData.xml | 49 +++++++ .../Test/AdminCreatingShippingLabelTest.xml | 130 ++++++++++++++++++ .../ActionGroup/AdminShipmentActionGroup.xml | 20 +++ .../Data/AdminShippingSettingsConfigData.xml | 26 ++++ .../AdminShipmentCreatePackageSection.xml | 20 +++ .../Section/AdminShipmentTotalSection.xml | 1 + ...mentTrackingInformationShippingSection.xml | 17 +++ 11 files changed, 308 insertions(+) create mode 100644 app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml create mode 100644 app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml create mode 100644 app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Data/AdminShippingSettingsConfigData.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentCreatePackageSection.xml create mode 100644 app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTrackingInformationShippingSection.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml b/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml new file mode 100644 index 000000000000..ae0801736d3a --- /dev/null +++ b/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminGeneralSetStoreNameConfigData"> + <data key="path">general/store_information/name</data> + <data key="value">New Store Information</data> + </entity> + <entity name="AdminGeneralSetStorePhoneConfigData"> + <data key="path">general/store_information/phone</data> + </entity> + <entity name="AdminGeneralSetCountryConfigData"> + <data key="path">general/store_information/country_id</data> + </entity> + <entity name="AdminGeneralSetCityConfigData"> + <data key="path">general/store_information/city</data> + </entity> + <entity name="AdminGeneralSetPostcodeConfigData"> + <data key="path">general/store_information/postcode</data> + </entity> + <entity name="AdminGeneralSetStreetAddressConfigData"> + <data key="path">general/store_information/street_line1</data> + </entity> + <entity name="AdminGeneralSetStreetAddress2ConfigData"> + <data key="path">general/store_information/street_line2</data> + </entity> + <entity name="AdminGeneralSetVatNumberConfigData"> + <data key="path">general/store_information/merchant_vat_number</data> + <data key="value">111607872</data> + </entity> +</entities> diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml index 5c5ee0f9cb32..0a8a93fac414 100644 --- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml +++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml @@ -108,6 +108,12 @@ <fillField selector="{{AdminProductFormSection.productName}}" userInput="{{product.name}}" stepKey="fillProductName"/> <fillField selector="{{AdminProductFormSection.productSku}}" userInput="{{product.sku}}" stepKey="fillProductSku"/> </actionGroup> + <actionGroup name="AdminFillProductCountryOfManufactureActionGroup"> + <arguments> + <argument name="countryId" type="string" defaultValue="US"/> + </arguments> + <selectOption selector="{{AdminProductFormBundleSection.countryOfManufactureDropDown}}" userInput="{{countryId}}" stepKey="countryOfManufactureDropDown"/> + </actionGroup> <!--Check that required fields are actually required--> <actionGroup name="checkRequiredFieldsInProductForm"> diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml index 7f6980d0c974..66f8ed541ffd 100644 --- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml +++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/CheckoutActionGroup.xml @@ -64,6 +64,7 @@ <fillField selector="{{CheckoutShippingSection.postcode}}" userInput="{{customerAddressVar.postcode}}" stepKey="enterPostcode"/> <fillField selector="{{CheckoutShippingSection.telephone}}" userInput="{{customerAddressVar.telephone}}" stepKey="enterTelephone"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMask"/> + <waitForElement selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('shippingMethod')}}" stepKey="waitForShippingMethod"/> <click selector="{{CheckoutShippingMethodsSection.checkShippingMethodByName('shippingMethod')}}" stepKey="selectShippingMethod"/> <waitForElement selector="{{CheckoutShippingSection.next}}" time="30" stepKey="waitForNextButton"/> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickNext"/> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 4d7a39b3246e..986369f4ebc6 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -291,6 +291,7 @@ <data key="company">Magento</data> <array key="street"> <item>Augsburger Strabe 41</item> + <item>Augsburger Strabe 42</item> </array> <data key="city">Berlin</data> <data key="country_id">DE</data> diff --git a/app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml b/app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml new file mode 100644 index 000000000000..d03403970ae5 --- /dev/null +++ b/app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminFedexEnableForCheckoutConfigData" type="fedex_config"> + <data key="path">carriers/fedex/active</data> + <data key="value">1</data> + <data key="label">Yes</data> + </entity> + <entity name="AdminFedexEnableSandboxModeConfigData" type="fedex_config"> + <data key="path">carriers/fedex/sandbox_mode</data> + <data key="value">1</data> + <data key="label">Yes</data> + </entity> + <entity name="AdminFedexEnableDebugConfigData" type="fedex_config"> + <data key="path">carriers/fedex/debug</data> + <data key="value">1</data> + <data key="label">Yes</data> + </entity> + <entity name="AdminFedexEnableShowMethodConfigData" type="fedex_config"> + <data key="path">carriers/fedex/showmethod</data> + <data key="value">1</data> + <data key="label">Yes</data> + </entity> + <entity name="AdminFedexDisableShowMethodConfigData" type="fedex_config"> + <data key="path">carriers/fedex/showmethod</data> + <data key="value">0</data> + <data key="label">No</data> + </entity> + <entity name="AdminFedexDisableDebugConfigData" type="fedex_config"> + <data key="path">carriers/fedex/debug</data> + <data key="value">0</data> + <data key="label">No</data> + </entity> + <entity name="AdminFedexDisableSandboxModeConfigData" type="fedex_config"> + <data key="path">carriers/fedex/sandbox_mode</data> + <data key="value">0</data> + <data key="label">No</data> + </entity> + <entity name="AdminFedexDisableForCheckoutConfigData" type="fedex_config"> + <data key="path">carriers/fedex/active</data> + <data key="value">0</data> + <data key="label">No</data> + </entity> +</entities> diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml new file mode 100644 index 000000000000..4b4654abb2bf --- /dev/null +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCreatingShippingLabelTest"> + <annotations> + <features value="Fedex"/> + <stories value="Shipping label"/> + <title value="Creating shipping label"/> + <description value="Creating shipping label"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20287"/> + <useCaseId value="MC-18215"/> + <group value="shipping"/> + <skip> + <issueId value="MQE-1578"/> + </skip> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!-- Create product --> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + <createData entity="SimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!--Set Fedex configs data--> + <magentoCLI command="config:set {{AdminFedexEnableForCheckoutConfigData.path}} {{AdminFedexEnableForCheckoutConfigData.value}}" stepKey="enableCheckout"/> + <magentoCLI command="config:set {{AdminFedexEnableSandboxModeConfigData.path}} {{AdminFedexEnableSandboxModeConfigData.value}}" stepKey="enableSandbox"/> + <magentoCLI command="config:set {{AdminFedexEnableDebugConfigData.path}} {{AdminFedexEnableDebugConfigData.value}}" stepKey="enableDebug"/> + <magentoCLI command="config:set {{AdminFedexEnableShowMethodConfigData.path}} {{AdminFedexEnableShowMethodConfigData.value}}" stepKey="enableShowMethod"/> + <!--TODO: add fedex credentials--> + <!--Set StoreInformation configs data--> + <magentoCLI command="config:set {{AdminGeneralSetStoreNameConfigData.path}} '{{AdminGeneralSetStoreNameConfigData.value}}'" stepKey="setStoreInformationName"/> + <magentoCLI command="config:set {{AdminGeneralSetStorePhoneConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.telephone}}" stepKey="setStoreInformationPhone"/> + <magentoCLI command="config:set {{AdminGeneralSetCountryConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.country_id}}" stepKey="setStoreInformationCountry"/> + <magentoCLI command="config:set {{AdminGeneralSetCityConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.city}}" stepKey="setStoreInformationCity"/> + <magentoCLI command="config:set {{AdminGeneralSetPostcodeConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.postcode}}" stepKey="setStoreInformationPostcode"/> + <magentoCLI command="config:set {{AdminGeneralSetStreetAddressConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[0]}}'" stepKey="setStoreInformationStreetAddress"/> + <magentoCLI command="config:set {{AdminGeneralSetStreetAddress2ConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[1]}}'" stepKey="setStoreInformationStreetAddress2"/> + <magentoCLI command="config:set {{AdminGeneralSetVatNumberConfigData.path}} {{AdminGeneralSetVatNumberConfigData.value}}" stepKey="setStoreInformationVatNumber"/> + <!--Set Shipping settings origin data--> + <magentoCLI command="config:set {{AdminShippingSettingsOriginCountryConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.country_id}}" stepKey="setOriginCountry"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginCityConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.city}}" stepKey="setOriginCity"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginZipCodeConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.postcode}}" stepKey="setOriginZipCode"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddressConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[0]}}'" stepKey="setOriginStreetAddress"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddress2ConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[1]}}'" stepKey="setOriginStreetAddress2"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <!--Reset configs--> + <magentoCLI command="config:set {{AdminFedexDisableForCheckoutConfigData.path}} {{AdminFedexDisableForCheckoutConfigData.value}}" stepKey="disableCheckout"/> + <magentoCLI command="config:set {{AdminFedexDisableSandboxModeConfigData.path}} {{AdminFedexDisableSandboxModeConfigData.value}}" stepKey="disableSandbox"/> + <magentoCLI command="config:set {{AdminFedexDisableDebugConfigData.path}} {{AdminFedexDisableDebugConfigData.value}}" stepKey="disableDebug"/> + <magentoCLI command="config:set {{AdminFedexDisableShowMethodConfigData.path}} {{AdminFedexDisableShowMethodConfigData.value}}" stepKey="disableShowMethod"/> + <magentoCLI command="config:set {{AdminGeneralSetStoreNameConfigData.path}} ''" stepKey="setStoreInformationName"/> + <magentoCLI command="config:set {{AdminGeneralSetStorePhoneConfigData.path}} ''" stepKey="setStoreInformationPhone"/> + <magentoCLI command="config:set {{AdminGeneralSetCityConfigData.path}} ''" stepKey="setStoreInformationCity"/> + <magentoCLI command="config:set {{AdminGeneralSetPostcodeConfigData.path}} ''" stepKey="setStoreInformationPostcode"/> + <magentoCLI command="config:set {{AdminGeneralSetStreetAddressConfigData.path}} ''" stepKey="setStoreInformationStreetAddress"/> + <magentoCLI command="config:set {{AdminGeneralSetStreetAddress2ConfigData.path}} ''" stepKey="setStoreInformationStreetAddress2"/> + <magentoCLI command="config:set {{AdminGeneralSetVatNumberConfigData.path}} ''" stepKey="setStoreInformationVatNumber"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginCityConfigData.path}} ''" stepKey="setOriginCity"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginZipCodeConfigData.path}} ''" stepKey="setOriginZipCode"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddressConfigData.path}} ''" stepKey="setOriginStreetAddress"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddress2ConfigData.path}} ''" stepKey="setOriginStreetAddress2"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + <!--Delete created data--> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Add country of manufacture to product--> + <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="amOnEditPage"/> + <waitForPageLoad stepKey="waitForEditPage"/> + <actionGroup ref="AdminFillProductCountryOfManufactureActionGroup" stepKey="fillCountryOfManufacture"> + <argument name="countryId" value="DE"/> + </actionGroup> + <actionGroup ref="saveProductForm" stepKey="saveSimpleProduct"/> + <!--Place for order using FedEx shipping method--> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="amOnStorefrontProductPage"/> + <actionGroup ref="StorefrontAddProductToCartActionGroup" stepKey="addProductToCart"> + <argument name="product" value="$$createProduct$$"/> + <argument name="productCount" value="1"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart"/> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="addAddress"> + <argument name="customerVar" value="Simple_US_Utah_Customer"/> + <argument name="customerAddressVar" value="US_Address_California"/> + <argument name="shippingMethod" value="Federal Express"/> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="selectPaymentMethod"/> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="customerPlaceOrder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage"/> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage"/> + </actionGroup> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <!--Open created order in admin--> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="onOrdersPage"/> + <actionGroup ref="searchAdminDataGridByKeyword" stepKey="searchOrder"> + <argument name="keyword" value="$grabOrderNumber"/> + </actionGroup> + <click selector="{{AdminOrdersGridSection.firstRow}}" stepKey="clickOrderRow"/> + <!--Create Invoice--> + <actionGroup ref="AdminCreateInvoiceActionGroup" stepKey="createInvoice"/> + <!--Create shipping label--> + <actionGroup ref="goToShipmentIntoOrder" stepKey="goToShipmentIntoOrder"/> + <checkOption selector="{{AdminShipmentTotalSection.createShippingLabel}}" stepKey="checkCreateShippingLabel"/> + <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> + <actionGroup ref="AdminShipmentCreatePackageActionGroup" stepKey="createPackage"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> + <actionGroup ref="AdminGoToShipmentTabActionGroup" stepKey="goToShipmentTab"/> + <click selector="{{AdminOrderShipmentsTabSection.viewGridRow('1')}}" stepKey="clickRowToViewShipment"/> + <waitForPageLoad stepKey="waitForShipmentItemsSection"/> + <seeElement selector="{{AdminShipmentTrackingInformationShippingSection.shippingInfoTable}}" stepKey="seeInformationTable"/> + <seeElement selector="{{AdminShipmentTrackingInformationShippingSection.shippingNumber}}" stepKey="seeShippingNumberElement"/> + <grabTextFrom selector="{{AdminShipmentTrackingInformationShippingSection.shippingMethod}}" stepKey="grabShippingMethod"/> + <grabTextFrom selector="{{AdminShipmentTrackingInformationShippingSection.shippingMethodTitle}}" stepKey="grabShippingMethodTitle"/> + <assertEquals actual="$grabShippingMethod" expectedType="string" expected="Federal Express" stepKey="assertShippingMethodIsFedEx"/> + <assertEquals actual="$grabShippingMethodTitle" expectedType="string" expected="Federal Express" stepKey="assertShippingMethodTitleIsFedEx"/> + </test> +</tests> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml index e9809ae0f3e7..d160f95e2a9c 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml @@ -62,4 +62,24 @@ <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageShipping"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="seeShipmentCreateSuccess"/> </actionGroup> + <actionGroup name="AdminShipmentCreatePackageActionGroup"> + <arguments> + <argument name="productName" type="string" defaultValue="{{SimpleProduct.name}}"/> + </arguments> + <waitForElementVisible selector="{{AdminShipmentCreatePackageMainSection.addProductsToPackage}}" stepKey="waitForAddProductElement"/> + <click selector="{{AdminShipmentCreatePackageMainSection.addProductsToPackage}}" stepKey="clickAddProducts"/> + <waitForElementVisible selector="{{AdminShipmentCreatePackageProductGridSection.concreteProductCheckbox('productName')}}" stepKey="waitForProductBeVisible"/> + <checkOption selector="{{AdminShipmentCreatePackageProductGridSection.concreteProductCheckbox('productName')}}" stepKey="checkProductCheckbox"/> + <waitForElementVisible selector="{{AdminShipmentCreatePackageMainSection.addSelectedProductToPackage}}" stepKey="waitForAddSelectedProductElement"/> + <click selector="{{AdminShipmentCreatePackageMainSection.addSelectedProductToPackage}}" stepKey="clickAddSelectedProduct"/> + <waitForElementNotVisible selector="{{AdminShipmentCreatePackageMainSection.saveButtonDisabled}}" stepKey="waitForBeEnabled"/> + <click selector="{{AdminShipmentCreatePackageMainSection.save}}" stepKey="clickSave"/> + <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskDisappear"/> + <waitForPageLoad stepKey="waitForSaving"/> + <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created. You created the shipping label." stepKey="seeShipmentCreateSuccess"/> + </actionGroup> + <actionGroup name="AdminGoToShipmentTabActionGroup"> + <click selector="{{AdminOrderDetailsOrderViewSection.shipments}}" stepKey="clickOrderShipmentsTab"/> + <waitForLoadingMaskToDisappear stepKey="waitForShipmentTabLoad" after="clickOrderShipmentsTab"/> + </actionGroup> </actionGroups> diff --git a/app/code/Magento/Shipping/Test/Mftf/Data/AdminShippingSettingsConfigData.xml b/app/code/Magento/Shipping/Test/Mftf/Data/AdminShippingSettingsConfigData.xml new file mode 100644 index 000000000000..ad366fd7294e --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Data/AdminShippingSettingsConfigData.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminShippingSettingsOriginCountryConfigData"> + <data key="path">shipping/origin/country_id</data> + </entity> + <entity name="AdminShippingSettingsOriginZipCodeConfigData"> + <data key="path">shipping/origin/postcode</data> + </entity> + <entity name="AdminShippingSettingsOriginCityConfigData"> + <data key="path">shipping/origin/city</data> + </entity> + <entity name="AdminShippingSettingsOriginStreetAddressConfigData"> + <data key="path">shipping/origin/street_line1</data> + </entity> + <entity name="AdminShippingSettingsOriginStreetAddress2ConfigData"> + <data key="path">shipping/origin/street_line2</data> + </entity> +</entities> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentCreatePackageSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentCreatePackageSection.xml new file mode 100644 index 000000000000..5f33921b5a44 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentCreatePackageSection.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShipmentCreatePackageMainSection"> + <element name="addProductsToPackage" type="button" selector="#package_block_1 button[data-action='package-add-items']"/> + <element name="addSelectedProductToPackage" type="button" selector="#package_block_1 button[data-action='package-save-items']"/> + <element name="save" type="button" selector="button[data-action='save-packages']"/> + <element name="saveButtonDisabled" type="button" selector="button[data-action='save-packages']._disabled"/> + </section> + <section name="AdminShipmentCreatePackageProductGridSection"> + <element name="concreteProductCheckbox" type="checkbox" selector="//td[contains(text(), '{{productName}}')]/parent::tr//input[contains(@class,'checkbox')]" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTotalSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTotalSection.xml index f2f39d77d8d7..d76ba0493829 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTotalSection.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTotalSection.xml @@ -12,5 +12,6 @@ <element name="CommentText" type="textarea" selector="#shipment_comment_text"/> <element name="AppendComments" type="checkbox" selector=".order-totals input#notify_customer"/> <element name="EmailCopy" type="checkbox" selector=".order-totals input#send_email"/> + <element name="createShippingLabel" type="checkbox" selector="input#create_shipping_label"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTrackingInformationShippingSection.xml b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTrackingInformationShippingSection.xml new file mode 100644 index 000000000000..bbb61ed013a3 --- /dev/null +++ b/app/code/Magento/Shipping/Test/Mftf/Section/AdminShipmentTrackingInformationShippingSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminShipmentTrackingInformationShippingSection"> + <element name="shippingInfoTable" type="block" selector="#shipment_tracking_info"/> + <element name="shippingMethod" type="text" selector="#shipment_tracking_info .odd .col-carrier"/> + <element name="shippingMethodTitle" type="text" selector="#shipment_tracking_info .odd .col-title"/> + <element name="shippingNumber" type="text" selector="#shipment_tracking_info .odd .col-number"/> + </section> +</sections> \ No newline at end of file From 3f8060aa5a125e4af4fe8788d4c03083572848af Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Wed, 25 Sep 2019 17:06:38 +0300 Subject: [PATCH 0635/1172] magento/magento2#24645: Added unit test. --- .../Unit/Controller/Unsubscribe/PriceTest.php | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 app/code/Magento/ProductAlert/Test/Unit/Controller/Unsubscribe/PriceTest.php diff --git a/app/code/Magento/ProductAlert/Test/Unit/Controller/Unsubscribe/PriceTest.php b/app/code/Magento/ProductAlert/Test/Unit/Controller/Unsubscribe/PriceTest.php new file mode 100644 index 000000000000..a07c93337c04 --- /dev/null +++ b/app/code/Magento/ProductAlert/Test/Unit/Controller/Unsubscribe/PriceTest.php @@ -0,0 +1,125 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\ProductAlert\Test\Unit\Controller\Unsubscribe; + +use Magento\Backend\App\Action\Context; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Customer\Model\Session; +use Magento\Framework\App\Request\Http; +use Magento\Framework\Controller\Result\Redirect; +use Magento\Framework\Controller\ResultFactory; +use Magento\Framework\Message\Manager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\ProductAlert\Controller\Unsubscribe\Price; + +/** + * Test class for \Magento\ProductAlert\Controller\Unsubscribe\Price + */ +class PriceTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Price + */ + private $priceController; + + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var Http|\PHPUnit\Framework\MockObject\MockObject + */ + private $requestMock; + + /** + * @var Redirect|\PHPUnit\Framework\MockObject\MockObject + */ + private $resultRedirectMock; + + /** + * @var ResultFactory|\PHPUnit\Framework\MockObject\MockObject + */ + private $resultFactoryMock; + + /** + * @var Manager|\PHPUnit\Framework\MockObject\MockObject + */ + private $messageManagerMock; + + /** + * @var Product|\PHPUnit\Framework\MockObject\MockObject + */ + private $productMock; + + /** + * @var Session|\PHPUnit\Framework\MockObject\MockObject + */ + private $customerSessionMock; + + /** + * @var Context|\PHPUnit\Framework\MockObject\MockObject + */ + private $contextMock; + + /** + * @var ProductRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $productRepositoryMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = new ObjectManager($this); + $this->requestMock = $this->createMock(Http::class); + $this->resultFactoryMock = $this->createMock(ResultFactory::class); + $this->resultRedirectMock = $this->createMock(Redirect::class); + $this->messageManagerMock = $this->createMock(Manager::class); + $this->productMock = $this->createMock(Product::class); + $this->contextMock = $this->createMock(Context::class); + $this->customerSessionMock = $this->createMock(Session::class); + $this->productRepositoryMock = $this->createMock(ProductRepositoryInterface::class); + $this->resultFactoryMock->expects($this->any()) + ->method('create') + ->with(ResultFactory::TYPE_REDIRECT) + ->willReturn($this->resultRedirectMock); + $this->contextMock->expects($this->any())->method('getRequest')->willReturn($this->requestMock); + $this->contextMock->expects($this->any())->method('getResultFactory')->willReturn($this->resultFactoryMock); + $this->contextMock->expects($this->any())->method('getMessageManager')->willReturn($this->messageManagerMock); + + $this->priceController = $this->objectManager->getObject( + Price::class, + [ + 'context' => $this->contextMock, + 'customerSession' => $this->customerSessionMock, + 'productRepository' => $this->productRepositoryMock, + ] + ); + } + + public function testProductIsNotVisibleInCatalog() + { + $productId = 123; + $this->requestMock->expects($this->any())->method('getParam')->with('product')->willReturn($productId); + $this->productRepositoryMock->expects($this->any()) + ->method('getById') + ->with($productId) + ->willReturn($this->productMock); + $this->productMock->expects($this->any())->method('isVisibleInCatalog')->willReturn(false); + $this->messageManagerMock->expects($this->once())->method('addErrorMessage')->with(__("The product wasn't found. Verify the product and try again.")); + $this->resultRedirectMock->expects($this->once())->method('setPath')->with('customer/account/'); + + $this->assertEquals( + $this->resultRedirectMock, + $this->priceController->execute() + ); + } +} From dfb0c46bb092785659d6dee354f62d5f034f79b5 Mon Sep 17 00:00:00 2001 From: vital_pantsialeyeu <vital_pantsialeyeu@epam.com> Date: Thu, 26 Sep 2019 13:29:48 +0300 Subject: [PATCH 0636/1172] MAGETWO-99838: Error message '"customer address attribute" is a required value.' is absent on Storefront - Updated unit test --- .../Model/Validator/Attribute/DataTest.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php index 9f1e74fccbd4..acba37cc4578 100644 --- a/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/Validator/Attribute/DataTest.php @@ -4,6 +4,8 @@ * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Eav\Test\Unit\Model\Validator\Attribute; /** @@ -21,11 +23,17 @@ class DataTest extends \PHPUnit\Framework\TestCase */ private $model; + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager + */ + private $objectManager; + /** * @inheritdoc */ protected function setUp() { + $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->attrDataFactory = $this->getMockBuilder(\Magento\Eav\Model\AttributeDataFactory::class) ->setMethods(['create']) ->setConstructorArgs( @@ -36,8 +44,11 @@ protected function setUp() ) ->getMock(); - $this->model = new \Magento\Eav\Model\Validator\Attribute\Data( - $this->attrDataFactory + $this->model = $this->objectManager->getObject( + \Magento\Eav\Model\Validator\Attribute\Data::class, + [ + '_attrDataFactory' => $this->attrDataFactory + ] ); } @@ -468,7 +479,7 @@ protected function _getDataModelMock($returnValue, $argument = null) $dataModel = $this->getMockBuilder( \Magento\Eav\Model\Attribute\Data\AbstractData::class )->disableOriginalConstructor()->setMethods( - ['validateValue'] + ['setExtractedData', 'validateValue'] )->getMockForAbstractClass(); if ($argument) { $dataModel->expects( @@ -509,24 +520,13 @@ public function testIsValidWithoutData() : void $attributeData = ['attribute_code' => 'attribute', 'frontend_input' => 'text', 'is_visible' => true]; $entity = $this->_getEntityMock(); $attribute = $this->_getAttributeMock($attributeData); - $this->model->setAttributes([$attribute])->setData([]); - $dataModel = $this->getMockBuilder(\Magento\Eav\Model\Attribute\Data\AbstractData::class) - ->disableOriginalConstructor() - ->setMethods(['validateValue']) - ->getMockForAbstractClass(); - $dataModel->expects($this->once()) - ->method('validateValue') - // only empty string - ->with( - $this->logicalAnd( - $this->isEmpty(), - $this->isType('string') - ) - )->willReturn(true); + $dataModel = $this->_getDataModelMock(true, $this->logicalAnd($this->isEmpty(), $this->isType('string'))); + $dataModel->expects($this->once())->method('setExtractedData')->with([])->willReturnSelf(); $this->attrDataFactory->expects($this->once()) ->method('create') ->with($attribute, $entity) ->willReturn($dataModel); - $this->assertEquals(true, $this->model->isValid($entity)); + $this->model->setAttributes([$attribute])->setData([]); + $this->assertTrue($this->model->isValid($entity)); } } From 70fa65be9a3ee0bfdf79f871035fa431f4af72ca Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Wed, 25 Sep 2019 23:42:55 +0400 Subject: [PATCH 0637/1172] MC-10974: Return "Is Active" toggle to Catalog Price Rule Page - Updated automated test script. --- .../Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml | 2 +- .../Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml | 2 +- .../Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml index 2d4ef3786d1c..e1c168b4a025 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml @@ -25,7 +25,7 @@ <element name="websites" type="select" selector="[name='website_ids']"/> <element name="active" type="checkbox" selector="//div[contains(@class, 'admin__actions-switch')]/input[@name='is_active']/../label"/> <element name="activeIsEnabled" type="checkbox" selector="(//div[contains(@class, 'admin__actions-switch')])[1]/input[@value='1']"/> - <element name="activePosition" type="checkbox" selector="//fieldset[@class='admin__fieldset']//div[4]"/> + <element name="activePosition" type="checkbox" selector="fieldset[class='admin__fieldset'] div[class*='_required']:nth-of-type(4)"/> <element name="websitesOptions" type="select" selector="[name='website_ids'] option"/> <element name="customerGroups" type="select" selector="[name='customer_group_ids']"/> <element name="customerGroupsOptions" type="select" selector="[name='customer_group_ids'] option"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml index be195f564145..1b85f3b045c5 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutCartProductSection.xml @@ -18,7 +18,7 @@ <element name="ProductRegularPriceByName" type="text" selector="//div[descendant::*[contains(text(), '{{var1}}')]]//*[contains(@class, 'subtotal')]" parameterized="true"/> - <element name="productFirstPriceByName" type="text" selector="(//tbody//a[@title='{{prodName}}']/../following-sibling::*//span[@class='price'])[1]" parameterized="true"/> + <element name="productFirstPrice" type="text" selector="td[class~=price] span[class='price']"/> <element name="ProductImageByName" type="text" selector="//main//table[@id='shopping-cart-table']//tbody//tr//img[contains(@class, 'product-image-photo') and @alt='{{var1}}']" parameterized="true"/> diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml index 443b4bf649eb..e00906386e46 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml @@ -14,8 +14,8 @@ <element name="productLinkByName" type="button" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details']//a[contains(text(), '{{var1}}')]" parameterized="true"/> <element name="productPriceByName" type="text" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//span[@class='price']" parameterized="true"/> <element name="productPriceByItsName" type="text" selector="//a[normalize-space()='{{prodName}}']/../following-sibling::*//*[@class='price']" parameterized="true"/> - <element name="productImageByName" type="text" selector="//header//ol[@id='mini-cart']//span[@class='product-image-container']//img[@alt='{{var1}}']" parameterized="true"/> - <element name="productImageByItsName" type="text" selector="//img[@alt='{{prodName}}']" parameterized="true"/> + <element name="productImageByName" type="text" selector="header ol[id='mini-cart'] span[class='product-image-container'] img[alt='{{prodName}}']" parameterized="true"/> + <element name="productImageByItsName" type="text" selector="img[alt='{{prodName}}']" parameterized="true"/> <element name="productName" type="text" selector=".product-item-name"/> <element name="productOptionsDetailsByName" type="button" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//span[.='See Details']" parameterized="true"/> <element name="productOptionByNameAndAttribute" type="text" selector="//header//ol[@id='mini-cart']//div[@class='product-item-details'][.//a[contains(text(), '{{var1}}')]]//dt[@class='label' and .='{{var2}}']/following-sibling::dd[@class='values']//span" parameterized="true"/> From b94db91dee2e18da7ab87edad428d49953fc152c Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Thu, 26 Sep 2019 15:09:38 +0300 Subject: [PATCH 0638/1172] MC-18821: Increase test coverage for Catalog functional area - Fixed MC-13641 --- .../Test/AdminSaveConfProductWithCustomProductAttributeTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml index 084dceb004b4..b91acdf5d723 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-13641"/> <useCaseId value="MC-10968"/> <group value="developer_mode_only"/> + <group value="Swatches"/> </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> From 9788ab394334ad9952d341339568222d50fccfad Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Tue, 24 Sep 2019 17:37:36 +0300 Subject: [PATCH 0639/1172] MC-17653: Cannot schedule update for catalog price rule for date attribute - Updated automated test script. --- .../Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml | 2 +- .../Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml | 1 + .../Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml | 1 - .../SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index 06dda3722206..c364dca59223 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -67,7 +67,7 @@ <scrollTo selector="{{AdminNewCatalogPriceRule.conditionsTab}}" stepKey="scrollToConditionsTab" after="expandConditions"/> <waitForElementVisible selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="waitForNewRule" after="scrollToConditionsTab"/> <click selector="{{PriceRuleConditionsSection.createNewRule}}" stepKey="clickNewRule" after="waitForNewRule"/> - <selectOption selector="{{PriceRuleConditionsSection.conditionsDropdown}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="selectProductAttribute" after="clickNewRule"/> + <selectOption selector="{{AdminNewCatalogPriceRuleConditions.conditionsDropdown}}" userInput="{{ProductAttributeFrontendLabel.label}}" stepKey="selectProductAttribute" after="clickNewRule"/> <waitForPageLoad stepKey="waitForAttributeLoad" after="selectProductAttribute"/> <!--Assert that attribute contains today date without time--> <comment userInput="Assert that attribute contains today date without time" stepKey="assertDate" after="waitForAttributeLoad"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml index ba0493d8e995..02bd539deffe 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml @@ -43,6 +43,7 @@ <section name="AdminNewCatalogPriceRuleConditions"> <element name="newCondition" type="button" selector=".rule-param.rule-param-new-child"/> + <element name="conditionsDropdown" type="select" selector="select[data-form-part='catalog_rule_form'][data-ui-id='newchild-0-select-rule-conditions-1-new-child']"/> <element name="conditionSelect" type="select" selector="select#conditions__{{var}}__new_child" parameterized="true"/> <element name="targetEllipsis" type="button" selector="//li[{{var}}]//a[@class='label'][text() = '...']" parameterized="true"/> <element name="targetEllipsisValue" type="button" selector="//ul[@id='conditions__{{var}}__children']//a[contains(text(), '{{var1}}')]" parameterized="true" timeout="30"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml index c37b023317bf..749d1bee0661 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVisibilityOfDuplicateProductTest.xml @@ -11,7 +11,6 @@ <annotations> <stories value="Duplicate Product"/> <features value="ConfigurableProduct"/> - <stories value="Duplicate Product"/> <title value="Visibility of duplicate product on the Storefront"/> <description value="Check visibility of duplicate product on the Storefront"/> <severity value="AVERAGE"/> diff --git a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml index 7e0cd323f114..89398051fcf6 100644 --- a/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml +++ b/app/code/Magento/SalesRule/Test/Mftf/Section/PriceRuleConditionsSection.xml @@ -9,7 +9,6 @@ <element name="conditionsTab" type="text" selector="//div[@data-index='conditions']//span[contains(.,'Conditions')][1]"/> <element name="createNewRule" type="text" selector="span.rule-param.rule-param-new-child"/> <element name="rulesDropdown" type="select" selector="select[data-form-part='sales_rule_form'][data-ui-id='newchild-0-select-rule-conditions-1-new-child']"/> - <element name="conditionsDropdown" type="select" selector="select[data-form-part='catalog_rule_form'][data-ui-id='newchild-0-select-rule-conditions-1-new-child']"/> <element name="addProductAttributesButton" type="text" selector="#conditions__1--1__children>li>span>a"/> <element name="productAttributesDropdown" type="select" selector="#conditions__1--1__new_child"/> <element name="firstProductAttributeSelected" type="select" selector="#conditions__1__children .rule-param:nth-of-type(2) a:nth-child(1)"/> From 72183b7b3ca6bdb93f53ed07b717f8e68b230ea4 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Thu, 26 Sep 2019 16:40:34 +0300 Subject: [PATCH 0640/1172] MAGETWO-67450: The rate in order is duplicated - Fix bug - Add mftf test --- .../AdminCurrencyRatesActionGroup.xml | 22 ++++++ .../StorefrontCurrencyRatesActionGroup.xml | 20 +++++ .../Data/AdminCurrencyRatesMessageData.xml | 14 ++++ .../Test/Mftf/Page/AdminCurrencyRatesPage.xml | 14 ++++ .../Section/AdminCurrencyRatesSection.xml | 17 ++++ .../StorefrontSwitchCurrencyRatesSection.xml | 16 ++++ ...ayWhenChooseThreeAllowedCurrenciesTest.xml | 75 ++++++++++++++++++ .../AdminOrderRateDisplayedInOneLineTest.xml | 77 +++++++++++++++++++ .../AdminOrderDetailsInformationSection.xml | 2 + .../adminhtml/templates/order/view/info.phtml | 3 +- 10 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminCurrencyRatesActionGroup.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/StorefrontCurrencyRatesActionGroup.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Data/AdminCurrencyRatesMessageData.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Section/StorefrontSwitchCurrencyRatesSection.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminCurrencyRatesActionGroup.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminCurrencyRatesActionGroup.xml new file mode 100644 index 000000000000..6b8a93ef3542 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminCurrencyRatesActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="AdminSetCurrencyRatesActionGroup"> + <arguments> + <argument name="firstCurrency" type="string" defaultValue="USD"/> + <argument name="secondCurrency" type="string" defaultValue="EUR"/> + <argument name="rate" type="string" defaultValue="0.5"/> + </arguments> + <fillField selector="{{AdminCurrencyRatesSection.currencyRate(firstCurrency, secondCurrency)}}" userInput="{{rate}}" stepKey="setCurrencyRate"/> + <click selector="{{AdminCurrencyRatesSection.saveCurrencyRates}}" stepKey="clickSaveCurrencyRates"/> + <waitForPageLoad stepKey="waitForSave"/> + <see selector="{{AdminMessagesSection.success}}" userInput="{{AdminSaveCurrencyRatesMessageData.success}}" stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/StorefrontCurrencyRatesActionGroup.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/StorefrontCurrencyRatesActionGroup.xml new file mode 100644 index 000000000000..61a6123b1a7a --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/StorefrontCurrencyRatesActionGroup.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="StorefrontSwitchCurrency"> + <arguments> + <argument name="currency" type="string" defaultValue="EUR"/> + </arguments> + <click selector="{{StorefrontSwitchCurrencyRatesSection.currencyTrigger}}" stepKey="openTrigger"/> + <waitForElementVisible selector="{{StorefrontSwitchCurrencyRatesSection.currency(currency)}}" stepKey="waitForCurrency"/> + <click selector="{{StorefrontSwitchCurrencyRatesSection.currency(currency)}}" stepKey="chooseCurrency"/> + <see selector="{{StorefrontSwitchCurrencyRatesSection.selectedCurrency}}" userInput="{{currency}}" stepKey="seeSelectedCurrency"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/AdminCurrencyRatesMessageData.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/AdminCurrencyRatesMessageData.xml new file mode 100644 index 000000000000..90d22b06fcb8 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/AdminCurrencyRatesMessageData.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminSaveCurrencyRatesMessageData"> + <data key="success">All valid rates have been saved.</data> + </entity> +</entities> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml new file mode 100644 index 000000000000..7cfb177ecec3 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminCurrencyRatesPage" url="admin/system_currency/" area="admin" module="Currency"> + <section name="AdminCurrencyRatesSection"/> + </page> +</pages> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml new file mode 100644 index 000000000000..a5799356eb45 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminCurrencyRatesSection"> + <element name="import" type="button" selector="//button[@title='Import']"/> + <element name="saveCurrencyRates" type="button" selector="//button[@title='Save Currency Rates']"/> + <element name="oldRate" type="text" selector="//div[contains(@class, 'admin__field-note') and contains(text(), 'Old rate:')]/strong"/> + <element name="currencyRate" type="input" selector="input[name='rate[{{fistCurrency}}][{{secondCurrency}}]']" parameterized="true"/> + </section> +</sections> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Section/StorefrontSwitchCurrencyRatesSection.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/StorefrontSwitchCurrencyRatesSection.xml new file mode 100644 index 000000000000..e69823ad68e0 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Section/StorefrontSwitchCurrencyRatesSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="StorefrontSwitchCurrencyRatesSection"> + <element name="currencyTrigger" type="select" selector="#switcher-currency-trigger" timeout="30"/> + <element name="currency" type="button" selector="//div[@id='switcher-currency-trigger']/following-sibling::ul//a[contains(text(), '{{currency}}')]" parameterized="true" timeout="10"/> + <element name="selectedCurrency" type="text" selector="#switcher-currency-trigger span"/> + </section> +</sections> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml new file mode 100644 index 000000000000..823e9d1f1557 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest" extends="AdminOrderRateDisplayedInOneLineTest"> + <annotations> + <features value="CurrencySymbol"/> + <stories value="Currency rates order page"/> + <title value="Order rate converting currency for 'Base Currency' and 'Default Display Currency' displayed correct"/> + <description value="Order rate converting currency for 'Base Currency' and 'Default Display Currency' displayed correct"/> + <severity value="MAJOR"/> + <testCaseId value="MC-17255" /> + <useCaseId value="MAGETWO-67450"/> + <group value="currency"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create product--> + <createData entity="SimpleProduct2" stepKey="createNewProduct"/> + <!--Set Currency options for Website--> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow EUR,USD,RUB" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default EUR" stepKey="setCurrencyDefaultUSDWebsites"/> + </before> + <after> + <!--Delete created product--> + <comment userInput="Delete created product" stepKey="commentDeleteCreatedProduct"/> + <deleteData createDataKey="createNewProduct" stepKey="deleteNewProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Set currency rates--> + <amOnPage url="{{AdminCurrencyRatesPage.url}}" stepKey="gotToCurrencyRatesPageSecondTime"/> + <waitForPageLoad stepKey="waitForLoadRatesPageSecondTime"/> + <actionGroup ref="AdminSetCurrencyRatesActionGroup" stepKey="setCurrencyRates"> + <argument name="firstCurrency" value="USD"/> + <argument name="secondCurrency" value="RUB"/> + <argument name="rate" value="0.8"/> + </actionGroup> + <!--Open created product on Storefront and place for order--> + <amOnPage url="{{StorefrontProductPage.url($$createNewProduct.custom_attributes[url_key]$$)}}" stepKey="goToNewProductPage"/> + <waitForPageLoad stepKey="waitForNewProductPagePageLoad"/> + <actionGroup ref="StorefrontSwitchCurrency" stepKey="switchCurrency"> + <argument name="currency" value="RUB"/> + </actionGroup> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontNewProductPage"> + <argument name="productName" value="$$createNewProduct.name$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="guestGoToCheckoutNewProductFromMinicart" /> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutNewFillingShippingSection"> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectNewCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="guestPlaceNewOrder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabNewOrderNumber"/> + <!--Open order and check rates display in one line--> + <actionGroup ref="OpenOrderById" stepKey="openNewOrderById"> + <argument name="orderId" value="$grabNewOrderNumber"/> + </actionGroup> + <see selector="{{AdminOrderDetailsInformationSection.orderInformationTable}}" userInput="EUR / USD rate" stepKey="seeUSDandEURRate"/> + <see selector="{{AdminOrderDetailsInformationSection.orderInformationTable}}" userInput="RUB / USD rate:" stepKey="seeRUBandEURRate"/> + <grabMultiple selector="{{AdminOrderDetailsInformationSection.rate}}" stepKey="grabRates" /> + <assertEquals stepKey="assertRates"> + <actualResult type="variable">grabRates</actualResult> + <expectedResult type="array">['EUR / USD rate:', 'RUB / USD rate:']</expectedResult> + </assertEquals> + </test> +</tests> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml new file mode 100644 index 000000000000..1d96fa1de611 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminOrderRateDisplayedInOneLineTest"> + <annotations> + <features value="CurrencySymbol"/> + <stories value="Currency rates order page"/> + <title value="Order rate converting currency for 'Base Currency' and 'Default Display Currency' displayed correct once"/> + <description value="Order rate converting currency for 'Base Currency' and 'Default Display Currency' displayed correct once"/> + <severity value="MAJOR"/> + <testCaseId value="MC-17255" /> + <useCaseId value="MAGETWO-67450"/> + <group value="currency"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create product--> + <createData entity="SimpleProduct2" stepKey="createProduct"/> + <!--Set price scope website--> + <magentoCLI command="config:set catalog/price/scope 1" stepKey="setCatalogPriceScopeWebsite"/> + <!--Set Currency options for Default Config--> + <magentoCLI command="config:set currency/options/base EUR" stepKey="setCurrencyBaseEUR"/> + <magentoCLI command="config:set currency/options/allow EUR,USD" stepKey="setAllowedCurrencyEUR"/> + <magentoCLI command="config:set currency/options/default EUR" stepKey="setCurrencyDefaultEUR"/> + <!--Set Currency options for Website--> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseEURWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow EUR,USD" stepKey="setAllowedCurrencyEURWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default EUR" stepKey="setCurrencyDefaultEURWebsites"/> + </before> + <after> + <!--Delete created product--> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <!--Reset configurations--> + <magentoCLI command="config:set catalog/price/scope 0" stepKey="setCatalogPriceScopeGlobal"/> + <magentoCLI command="config:set currency/options/base USD" stepKey="setCurrencyBaseUSD"/> + <magentoCLI command="config:set currency/options/default USD" stepKey="setCurrencyDefaultUSD"/> + <magentoCLI command="config:set currency/options/allow USD" stepKey="setAllowedCurrencyUSD"/> + <!--Set Currency options for Website--> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default USD" stepKey="setCurrencyDefaultUSDWebsites"/> + <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow USD" stepKey="setAllowedCurrencyUSDWebsites"/> + <actionGroup ref="logout" stepKey="logout"/> + </after> + <!--Open created product on Storefront and place for order--> + <amOnPage url="{{StorefrontProductPage.url($$createProduct.custom_attributes[url_key]$$)}}" stepKey="goToProductPage"/> + <waitForPageLoad stepKey="waitForProductPagePageLoad"/> + <actionGroup ref="addToCartFromStorefrontProductPage" stepKey="addToCartFromStorefrontProductPage"> + <argument name="productName" value="$$createProduct.name$$"/> + </actionGroup> + <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="guestGoToCheckoutFromMinicart" /> + <actionGroup ref="GuestCheckoutFillingShippingSectionActionGroup" stepKey="guestCheckoutFillingShippingSection"> + </actionGroup> + <actionGroup ref="CheckoutSelectCheckMoneyOrderPaymentActionGroup" stepKey="guestSelectCheckMoneyOrderPayment" /> + <actionGroup ref="CheckoutPlaceOrderActionGroup" stepKey="guestPlaceOrder"> + <argument name="orderNumberMessage" value="CONST.successGuestCheckoutOrderNumberMessage" /> + <argument name="emailYouMessage" value="CONST.successCheckoutEmailYouMessage" /> + </actionGroup> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber}}" stepKey="grabOrderNumber"/> + <!--Open order and check rates display in one line--> + <actionGroup ref="OpenOrderById" stepKey="openOrderById"> + <argument name="orderId" value="$grabOrderNumber"/> + </actionGroup> + <see selector="{{AdminOrderDetailsInformationSection.orderInformationTable}}" userInput="EUR / USD rate" stepKey="seeEURandUSDRate"/> + <grabMultiple selector="{{AdminOrderDetailsInformationSection.rate}}" stepKey="grabRate" /> + <assertEquals stepKey="assertSelectedCategories"> + <actualResult type="variable">grabRate</actualResult> + <expectedResult type="array">[EUR / USD rate:]</expectedResult> + </assertEquals> + </test> +</tests> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml index 71a96dc10938..653b1d48686e 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderDetailsInformationSection.xml @@ -13,6 +13,8 @@ <element name="orderStatus" type="text" selector=".order-information table.order-information-table #order_status"/> <element name="purchasedFrom" type="text" selector=".order-information table.order-information-table tr:last-of-type > td"/> <element name="accountInformation" type="text" selector=".order-account-information-table"/> + <element name="orderInformationTable" type="block" selector=".order-information-table"/> + <element name="rate" type="text" selector="//table[contains(@class, 'order-information-table')]//th[contains(text(), 'rate:')]"/> <element name="customerName" type="text" selector=".order-account-information table tr:first-of-type > td span"/> <element name="customerEmail" type="text" selector=".order-account-information table tr:nth-of-type(2) > td a"/> <element name="customerGroup" type="text" selector=".order-account-information table tr:nth-of-type(3) > td"/> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml index ab5cd49449ec..8ada10450c96 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml @@ -23,6 +23,7 @@ $orderStoreDate = $block->formatDate( ); $customerUrl = $block->getCustomerViewUrl(); + $allowedAddressHtmlTags = ['b', 'br', 'em', 'i', 'li', 'ol', 'p', 'strong', 'sub', 'sup', 'ul']; ?> @@ -99,7 +100,7 @@ $allowedAddressHtmlTags = ['b', 'br', 'em', 'i', 'li', 'ol', 'p', 'strong', 'sub <td><?= $block->escapeHtml($order->getBaseToGlobalRate()) ?></td> </tr> <?php endif; ?> - <?php if ($order->getBaseCurrencyCode() != $order->getOrderCurrencyCode()) : ?> + <?php if ($order->getBaseCurrencyCode() != $order->getOrderCurrencyCode() && $order->getGlobalCurrencyCode() != $order->getOrderCurrencyCode()) : ?> <tr> <th><?= $block->escapeHtml(__('%1 / %2 rate:', $order->getOrderCurrencyCode(), $order->getBaseCurrencyCode())) ?></th> <td><?= $block->escapeHtml($order->getBaseToOrderRate()) ?></td> From 58d5830676e826736625741d733c0af27de30200 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Thu, 26 Sep 2019 09:17:07 -0500 Subject: [PATCH 0641/1172] MC-20338: Api-functional tests for Product prices - added test coverage for all types of product --- .../GraphQl/Catalog/ProductPriceTest.php | 341 +++++++++++++++++- 1 file changed, 336 insertions(+), 5 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php index 393063be9d97..465c40933401 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php @@ -7,6 +7,14 @@ namespace Magento\GraphQl\Catalog; +use Magento\Bundle\Model\Product\OptionList; +use Magento\Catalog\Api\Data\ProductInterface; +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Customer\Model\Group; +use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; class ProductPriceTest extends GraphQlAbstract @@ -58,6 +66,8 @@ public function testProductWithSinglePrice() } /** + * Pricing for Simple, Grouped and Configurable products + * * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable_12345.php * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped_with_simple.php * @magentoApiDataFixture Magento/Catalog/_files/product_simple_duplicated.php @@ -160,18 +170,41 @@ public function testMultipleProductTypes() } /** + * Simple products with special price and tier price with % discount + * * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php */ - public function testProductWithSpecialPrice() + public function testSimpleProductsWithSpecialPriceAndTierPrice() { $skus = ["simple1", "simple2"]; - $query = $this->getProductQuery($skus); + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + /** @var $tpExtensionAttributes */ + $tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); + $tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); + $tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2 + ] + ] + )->setExtensionAttributes($tierPriceExtensionAttribute); + foreach ($skus as $sku) { + /** @var Product $simpleProduct */ + $simpleProduct = $productRepository->get($sku); + $simpleProduct->setTierPrices($tierPrices); + $productRepository->save($simpleProduct); + } + $query = $this->getProductQuery($skus); $result = $this->graphQlQuery($query); $this->assertArrayNotHasKey('errors', $result); $this->assertCount(2, $result['products']['items']); - $expected = [ + $expectedPriceRange = [ "simple1" => [ "minimum_price" => [ "regular_price" => [ @@ -225,11 +258,280 @@ public function testProductWithSpecialPrice() ] ] ]; + $expectedTierPrices = [ + "simple1" => [ + 0 => [ + 'discount' =>[ + 'amount_off' => 1, + 'percent_off' => 10 + ], + 'final_price' =>['value'=> 9], + 'quantity' => 2 + ] + ], + "simple2" => [ + 0 => [ + 'discount' =>[ + 'amount_off' => 2, + 'percent_off' => 10 + ], + 'final_price' =>['value'=> 18], + 'quantity' => 2 + ] + + ] + ]; foreach ($result['products']['items'] as $product) { $this->assertNotEmpty($product['price_range']); - $this->assertPrices($expected[$product['sku']], $product['price_range']); + $this->assertNotEmpty($product['price_tiers']); + $this->assertPrices($expectedPriceRange[$product['sku']], $product['price_range']); + $this->assertResponseFields($product['price_tiers'], $expectedTierPrices[$product['sku']]); + } + } + + /** + * Check the pricing for a grouped product with simple products having special price set + * + * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped_with_simple.php + */ + public function testGroupedProductsWithSpecialPriceAndTierPrices() + { + $groupedProductSku = 'grouped'; + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + $grouped = $productRepository->get($groupedProductSku); + //get the associated products + $groupedProductLinks = $grouped->getProductLinks(); + $associatedProductSkus = []; + $tierPriceData = [ + [ + 'customer_group_id' => Group::CUST_GROUP_ALL, + 'percentage_value'=> null, + 'qty'=> 2, + 'value'=> 87 + ] + ]; + foreach ($groupedProductLinks as $groupedProductLink) { + $associatedProductSkus[] = $groupedProductLink ->getLinkedProductSku(); + } + $associatedProduct = []; + foreach ($associatedProductSkus as $associatedProductSku) { + $associatedProduct = $productRepository->get($associatedProductSku); + $associatedProduct->setSpecialPrice('95.75'); + $productRepository->save($associatedProduct); + $this->saveProductTierPrices($associatedProduct, $tierPriceData); + } + + //select one of the simple associated products and add a special price + // $associatedProductSku = $groupedProductLinks[0]->getLinkedProductSku(); + /** @var Product $associatedProduct */ +// $associatedProduct = $productRepository->get($associatedProductSku); +// $associatedProduct->setSpecialPrice('95.75'); +// $productRepository->save($associatedProduct); + $skus = ['grouped']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + $discountAmount = $associatedProduct->getPrice() - $associatedProduct->getSpecialPrice(); + $percentageDiscount = $discountAmount; + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => $associatedProduct->getPrice() + ], + "final_price" => [ + "value" => $associatedProduct->getSpecialPrice() + ], + "discount" => [ + "amount_off" => $discountAmount, + "percent_off" => $percentageDiscount + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $associatedProduct->getPrice() + ], + "final_price" => [ + "value" => $associatedProduct->getSpecialPrice() + ], + "discount" => [ + "amount_off" => $discountAmount, + "percent_off" => $percentageDiscount + ] + ] + ]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + $this->assertEmpty($product['price_tiers']); + + // update default quantity of each of the associated products to be greater than tier price qty of each of them + foreach ($groupedProductLinks as $groupedProductLink) { + $groupedProductLink->getExtensionAttributes()->setQty(3); } + $productRepository->save($grouped); + $result = $this->graphQlQuery($query); + $product = $result['products']['items'][0]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + $this->assertEmpty($product['price_tiers']); + } + + /** + * Check pricing for bundled product with one of bundle items having special price set and no dynamic price type set + * + * @magentoApiDataFixture Magento/Bundle/_files/product_with_multiple_options_1.php + */ + public function testBundledProductWithSpecialPriceAndTierPrice() + { + $bundledProductSku = 'bundle-product'; + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + /** @var Product $bundled */ + $bundled = $productRepository->get($bundledProductSku); + $skus = ['bundle-product']; + $query = $this->getProductQuery($skus); + $bundled->setSpecialPrice(10); + // Price view set to price_range + $bundled->setPriceView(0); + $productRepository->save($bundled); + $bundleRegularPrice = $bundled->getPrice(); + /** @var OptionList $optionList */ + $optionList = $objectManager->get(\Magento\Bundle\Model\Product\OptionList::class); + $options = $optionList->getItems($bundled); + $option = $options[0]; + /** @var \Magento\Bundle\Api\Data\LinkInterface $bundleProductLinks */ + $bundleProductLinks = $option->getProductLinks(); + $firstOptionPrice = $bundleProductLinks[0]->getPrice(); + $secondOptionPrice = $bundleProductLinks[1]->getPrice(); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + + //special price of 10% discount + $minRegularPrice = $bundleRegularPrice + $firstOptionPrice ; + //10% discount(caused by special price) of minRegular price + $minFinalPrice = round($minRegularPrice * 0.1, 2); + $maxRegularPrice = $bundleRegularPrice + $secondOptionPrice; + $maxFinalPrice = round($maxRegularPrice* 0.1, 2); + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => $minRegularPrice + ], + "final_price" => [ + "value" => $minFinalPrice + ], + "discount" => [ + "amount_off" => $minRegularPrice - $minFinalPrice, + "percent_off" => round(($minRegularPrice - $minFinalPrice)*100/$minRegularPrice, 2) + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $maxRegularPrice + ], + "final_price" => [ + "value" => $maxFinalPrice + ], + "discount" => [ + "amount_off" => $maxRegularPrice - $maxFinalPrice, + "percent_off" => round(($maxRegularPrice - $maxFinalPrice)*100/$maxRegularPrice, 2) + ] + ] + ]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + } + + /** + * Check the pricing for bundled product with one of bundle items having special price set + * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * + */ + public function testDownloadableProductWithSpecialPriceAndTierPrices() + { + $downloadableProductSku = 'downloadable-product'; + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + /** @var Product $downloadableProduct */ + $downloadableProduct = $productRepository->get($downloadableProductSku); + //setting the special price for the product + $downloadableProduct->setSpecialPrice('5.75'); + $productRepository->save($downloadableProduct); + //setting the tier price data for the product + $tierPriceData = [ + [ + 'customer_group_id' => Group::CUST_GROUP_ALL, + 'percentage_value'=> null, + 'qty'=> 2, + 'value'=> 7 + ] + ]; + $this->saveProductTierPrices($downloadableProduct, $tierPriceData); + $skus = ['downloadable-product']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + $this->assertNotEmpty($product['price_tiers']); + $discountAmount = $downloadableProduct->getPrice() - $downloadableProduct->getSpecialPrice(); + $percentageDiscount = ($discountAmount/$downloadableProduct->getPrice())*100; + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => $downloadableProduct->getPrice() + ], + "final_price" => [ + "value" => $downloadableProduct->getSpecialPrice() + ], + "discount" => [ + "amount_off" => $discountAmount, + "percent_off" => $percentageDiscount + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $downloadableProduct->getPrice() + ], + "final_price" => [ + "value" => $downloadableProduct->getSpecialPrice() + ], + "discount" => [ + "amount_off" => $discountAmount, + "percent_off" => $percentageDiscount + ] + ] + ]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + $this->assertResponseFields( + $product['price_tiers'], + [ + 0 => [ + 'discount' =>[ + 'amount_off' => 3, + 'percent_off' => 30 + ], + 'final_price' =>['value'=> 7], + 'quantity' => 2 + ] + ] + ); } /** @@ -340,7 +642,7 @@ private function getProductQuery(array $skus): string maximum_price { regular_price { value - currency + currency } final_price { value @@ -352,6 +654,16 @@ private function getProductQuery(array $skus): string } } } + price_tiers{ + discount{ + amount_off + percent_off + } + final_price{ + value + } + quantity + } } } } @@ -386,4 +698,23 @@ private function assertPrices($expectedPrices, $actualPrices, $currency = 'USD') $this->assertEquals($expected['discount']['percent_off'], $actual['discount']['percent_off']); } } + + /** + * @param ProductInterface $product + * @param array $tierPriceData + */ + private function saveProductTierPrices(ProductInterface $product, array $tierPriceData) + { + $tierPrices =[]; + $objectManager = Bootstrap::getObjectManager(); + $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + foreach ($tierPriceData as $tierPrice) { + $tierPrices[] = $tierPriceFactory->create([ + 'data' => $tierPrice + ]); + /** ProductInterface $product */ + $product->setTierPrices($tierPrices); + $product->save(); + } + } } From d9dcd9f849e33cbef68158ec595466d0cea212a1 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Thu, 26 Sep 2019 09:53:34 -0500 Subject: [PATCH 0642/1172] Make property private --- .../Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php index 178615d0c6a2..89d2c1b8a066 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php @@ -30,7 +30,7 @@ class Edit extends Set implements HttpGetActionInterface /** * @var AttributeSetRepositoryInterface */ - protected $attributeSetRepository; + private $attributeSetRepository; /** * @param Context $context From 8261058252bbd4ea1cb424342d1a1cd7bb3d6831 Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Thu, 26 Sep 2019 12:17:42 -0300 Subject: [PATCH 0643/1172] set customer contryid and vatid to address --- .../Observer/Frontend/Quote/Address/CollectTotalsObserver.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php index 77dfec9603a5..f3edce45d533 100644 --- a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php +++ b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php @@ -111,6 +111,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) if (empty($customerCountryCode) && empty($customerVatNumber) && $customer->getDefaultShipping()) { $customerAddress = $this->addressRepository->getById($customer->getDefaultShipping()); + $address->setCountryId($customerAddress->getCountryId()); + $address->setVatId($customerAddress->getVatId()); $customerCountryCode = $customerAddress->getCountryId(); $customerVatNumber = $customerAddress->getVatId(); } From c6427ed3cedb6a8c1a7848bc8b6517b0d31c3bc9 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 26 Sep 2019 10:22:51 -0500 Subject: [PATCH 0644/1172] MC-18403: Pricing :: Product pricing schema - fix tier prices --- .../Model/Resolver/Product/Price/Provider.php | 5 +++ .../Model/Resolver/PriceTiers.php | 10 ++++-- .../Model/Resolver/Product/Price/Tiers.php | 3 +- .../Model/Resolver/Product/Price/Discount.php | 32 ++++++++++++++++++- .../Model/Resolver/Product/PriceRange.php | 2 +- .../Resolver/Product/Price/DiscountTest.php | 2 +- 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php index b6515c98c078..fead6f923d8f 100644 --- a/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php +++ b/app/code/Magento/BundleGraphQl/Model/Resolver/Product/Price/Provider.php @@ -8,6 +8,8 @@ namespace Magento\BundleGraphQl\Model\Resolver\Product\Price; use Magento\Bundle\Pricing\Price\FinalPrice; +use Magento\Catalog\Pricing\Price\BasePrice; +use Magento\Bundle\Model\Product\Price; use Magento\Catalog\Pricing\Price\RegularPrice; use Magento\CatalogGraphQl\Model\Resolver\Product\Price\ProviderInterface; use Magento\Framework\Pricing\Amount\AmountInterface; @@ -55,6 +57,9 @@ public function getMaximalRegularPrice(SaleableInterface $product): AmountInterf */ public function getRegularPrice(SaleableInterface $product): AmountInterface { + if ($product->getPriceType() == Price::PRICE_TYPE_FIXED) { + return $product->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getAmount(); + } return $product->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getAmount(); } } diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php index 2e337238536c..4e75139c1a88 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/PriceTiers.php @@ -112,7 +112,6 @@ function () use ($productId, $context) { $productPrice = $this->tiers->getProductRegularPrice($productId) ?? 0.0; $tierPrices = $this->tiers->getProductTierPrices($productId) ?? []; - return $this->formatProductTierPrices($tierPrices, $productPrice, $store); } ); @@ -131,8 +130,15 @@ private function formatProductTierPrices(array $tierPrices, float $productPrice, $tiers = []; foreach ($tierPrices as $tierPrice) { + $percentValue = $tierPrice->getExtensionAttributes()->getPercentageValue(); + if ($percentValue && is_numeric($percentValue)) { + $discount = $this->discount->getDiscountByPercent($productPrice, (float)$percentValue); + } else { + $discount = $this->discount->getDiscountByDifference($productPrice, (float)$tierPrice->getValue()); + } + $tiers[] = [ - "discount" => $this->discount->getPriceDiscount($productPrice, (float)$tierPrice->getValue()), + "discount" => $discount, "quantity" => $tierPrice->getQty(), "final_price" => [ "value" => $tierPrice->getValue(), diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php index f227b10b73a0..7c5e13783f20 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php @@ -117,7 +117,7 @@ public function getProductRegularPrice($productId): ?float } $product = $this->products[$productId]; $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); - return $priceProvider->getMinimalRegularPrice($product)->getValue(); + return $priceProvider->getRegularPrice($product)->getValue(); } /** @@ -142,6 +142,7 @@ private function load(): void $productCollection = $this->collectionFactory->create(); $productCollection->addFieldToFilter($productIdField, ['in' => $this->filterProductIds]); $productCollection->addAttributeToSelect('price'); + $productCollection->addAttributeToSelect('price_type'); $productCollection->load(); $productCollection->addTierPriceDataByGroupId($this->customerGroupId); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php index b7fb8dc2938c..c56e05bf267a 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/Price/Discount.php @@ -24,7 +24,7 @@ class Discount * @param float $finalPrice * @return array */ - public function getPriceDiscount(float $regularPrice, float $finalPrice): array + public function getDiscountByDifference(float $regularPrice, float $finalPrice): array { return [ 'amount_off' => $this->getPriceDifferenceAsValue($regularPrice, $finalPrice), @@ -32,6 +32,21 @@ public function getPriceDiscount(float $regularPrice, float $finalPrice): array ]; } + /** + * Get formatted discount based on percent off + * + * @param float $regularPrice + * @param float $percentOff + * @return array + */ + public function getDiscountByPercent(float $regularPrice, float $percentOff): array + { + return [ + 'amount_off' => $this->getPercentDiscountAsValue($regularPrice, $percentOff), + 'percent_off' => $percentOff + ]; + } + /** * Get value difference between two prices * @@ -65,4 +80,19 @@ private function getPriceDifferenceAsPercent(float $regularPrice, float $finalPr return round(($difference / $regularPrice) * 100, 2); } + + /** + * Get amount difference that percentOff represents + * + * @param float $regularPrice + * @param float $percentOff + * @return float + */ + private function getPercentDiscountAsValue(float $regularPrice, float $percentOff): float + { + $percentDecimal = $percentOff / 100; + $valueDiscount = $regularPrice * $percentDecimal; + + return round($valueDiscount, 2); + } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index d354d628445a..2607af0ed0ab 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -119,7 +119,7 @@ private function formatPrice(float $regularPrice, float $finalPrice, StoreInterf 'value' => $finalPrice, 'currency' => $store->getCurrentCurrencyCode() ], - 'discount' => $this->discount->getPriceDiscount($regularPrice, $finalPrice), + 'discount' => $this->discount->getDiscountByDifference($regularPrice, $finalPrice), ]; } } diff --git a/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php index ad688474c889..5ebb48f761c0 100644 --- a/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php +++ b/app/code/Magento/CatalogGraphQl/Test/Unit/Model/Resolver/Product/Price/DiscountTest.php @@ -31,7 +31,7 @@ protected function setUp() */ public function testGetPriceDiscount($regularPrice, $finalPrice, $expectedAmountOff, $expectedPercentOff) { - $discountResult = $this->discount->getPriceDiscount($regularPrice, $finalPrice); + $discountResult = $this->discount->getDiscountByDifference($regularPrice, $finalPrice); $this->assertEquals($expectedAmountOff, $discountResult['amount_off']); $this->assertEquals($expectedPercentOff, $discountResult['percent_off']); From 357b449e3d9f6a522802561cb46c7610d5e6ac9b Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Thu, 26 Sep 2019 13:04:21 -0300 Subject: [PATCH 0645/1172] changes to unit tests --- .../Frontend/Quote/Address/CollectTotalsObserver.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php index f3edce45d533..a94157b46b88 100644 --- a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php +++ b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php @@ -111,10 +111,11 @@ public function execute(\Magento\Framework\Event\Observer $observer) if (empty($customerCountryCode) && empty($customerVatNumber) && $customer->getDefaultShipping()) { $customerAddress = $this->addressRepository->getById($customer->getDefaultShipping()); - $address->setCountryId($customerAddress->getCountryId()); - $address->setVatId($customerAddress->getVatId()); $customerCountryCode = $customerAddress->getCountryId(); $customerVatNumber = $customerAddress->getVatId(); + $address->setCountryId($customerCountryCode); + $address->setVatId($customerVatNumber); + } $groupId = null; From 024d7c54ad0b901b1dada878814bd463c5ca67ba Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Thu, 26 Sep 2019 11:06:37 -0500 Subject: [PATCH 0646/1172] MC-19451: Adapt functional tests to Elasticsearch * Reverting default search engine config --- app/code/Magento/CatalogSearch/etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/etc/config.xml b/app/code/Magento/CatalogSearch/etc/config.xml index 911d9da2fa5e..7ea15c6caa59 100644 --- a/app/code/Magento/CatalogSearch/etc/config.xml +++ b/app/code/Magento/CatalogSearch/etc/config.xml @@ -12,7 +12,7 @@ <search_terms>1</search_terms> </seo> <search> - <engine>elasticsearch6</engine> + <engine>mysql</engine> <min_query_length>3</min_query_length> <max_query_length>128</max_query_length> <max_count_cacheable_search_terms>100</max_count_cacheable_search_terms> From 5d4452531f0ddd6ef973220447220f61a6d44378 Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Thu, 26 Sep 2019 14:45:12 -0300 Subject: [PATCH 0647/1172] adjust unnecessary new line --- .../Observer/Frontend/Quote/Address/CollectTotalsObserver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php index a94157b46b88..a1228903e232 100644 --- a/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php +++ b/app/code/Magento/Quote/Observer/Frontend/Quote/Address/CollectTotalsObserver.php @@ -115,7 +115,6 @@ public function execute(\Magento\Framework\Event\Observer $observer) $customerVatNumber = $customerAddress->getVatId(); $address->setCountryId($customerCountryCode); $address->setVatId($customerVatNumber); - } $groupId = null; From 9d16144d8e8ceb94a435409911a68c551afbd277 Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Thu, 26 Sep 2019 12:53:19 -0500 Subject: [PATCH 0648/1172] MC-19652: Product Categories Indexer stuck --- .../Model/Indexer/Product/Category/Action/Rows.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php index cb708695255d..08e281111a57 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php @@ -123,8 +123,12 @@ private function getProductIdsWithParents(array $childProductIds) ); $parentProductIds = $this->connection->fetchCol($select); + $ids = array_unique(array_merge($childProductIds, $parentProductIds)); + foreach ($ids as $key => $id) { + $ids[$key] = (int) $id; + } - return array_unique(array_merge($childProductIds, $parentProductIds)); + return $ids; } /** @@ -175,7 +179,7 @@ protected function removeEntries() protected function getNonAnchorCategoriesSelect(\Magento\Store\Model\Store $store) { $select = parent::getNonAnchorCategoriesSelect($store); - return $select->where('ccp.product_id IN (?) OR relation.child_id IN (?)', $this->limitationByProducts); + return $select->where('ccp.product_id IN (?)', $this->limitationByProducts); } /** From d657e00c8bc70aa073f074d8a72f960e45cd486f Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Thu, 26 Sep 2019 13:21:24 -0500 Subject: [PATCH 0649/1172] MC-20336: Update tests related to Catalog Search and Swatches --- .../Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml | 4 ++++ var/.htaccess | 8 -------- 2 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 var/.htaccess diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml index 210b474af2e0..c8f84c732d6b 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml @@ -57,6 +57,10 @@ <fillField selector="{{AdminProductAttributeSection.customAttribute($$createPriceAttribute.attribute_code$$)}}" userInput="70" stepKey="fillCustomPrice2"/> <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton2"/> <waitForPageLoad stepKey="waitForSimpleProductSaved2"/> + + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Navigate to category on Storefront--> <comment userInput="Navigate to category on Storefront" stepKey="comment3"/> <amOnPage url="{{StorefrontCategoryPage.url($$subCategory.name$$)}}" stepKey="goToCategoryStorefront"/> diff --git a/var/.htaccess b/var/.htaccess deleted file mode 100644 index 707c26b075e1..000000000000 --- a/var/.htaccess +++ /dev/null @@ -1,8 +0,0 @@ -<IfVersion < 2.4> - order allow,deny - deny from all -</IfVersion> -<IfVersion >= 2.4> - Require all denied -</IfVersion> - From 4799d8f935fc334b1ea0cfad1a09e2b6b34d5f69 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Thu, 26 Sep 2019 14:24:23 -0500 Subject: [PATCH 0650/1172] magento-engcom/magento2ce#3285: Fixed minor code style issues --- .../Framework/MessageQueue/MessageValidator.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php index abb2918d459a..7c1a947623e9 100644 --- a/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php +++ b/lib/internal/Magento/Framework/MessageQueue/MessageValidator.php @@ -11,8 +11,7 @@ use Magento\Framework\Communication\ConfigInterface as CommunicationConfig; /** - * Class MessageValidator to validate message with topic schema - * + * Class MessageValidator to validate message with topic schema. */ class MessageValidator { @@ -90,6 +89,8 @@ public function validate($topic, $message, $requestType = true) } /** + * Validate queue message. + * * @param string $message * @param string $messageType * @param string $topic @@ -105,6 +106,8 @@ protected function validateMessage($message, $messageType, $topic) } /** + * Validate message primitive type. + * * @param string $message * @param string $messageType * @param string $topic @@ -136,6 +139,8 @@ protected function validatePrimitiveType($message, $messageType, $topic) } /** + * Validate class type + * * @param string $message * @param string $messageType * @param string $topic @@ -168,6 +173,8 @@ protected function validateClassType($message, $messageType, $topic) } /** + * Returns message real type + * * @param string $message * @return string */ From 8e3f3ace6f9303f4b7a404ae7e08ac917934300b Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Thu, 26 Sep 2019 14:44:50 -0500 Subject: [PATCH 0651/1172] MC-19247: Broken translations with advanced bundling - Load translation dictionary from js component; --- .../Translation/ViewModel/Dictionary.php | 99 ------------------- app/code/Magento/Translation/etc/di.xml | 5 - .../view/base/templates/dictionary.phtml | 20 ---- .../web/js/mage-translation-dictionary.js | 12 +++ .../base/web/js/mageTranslationDictionary.js | 9 -- .../view/frontend/layout/default.xml | 5 - .../view/frontend/requirejs-config.js | 2 +- dev/tests/js/jasmine/require.conf.js | 5 - .../jasmine/tests/lib/mage/fake-dictionary.js | 10 -- 9 files changed, 13 insertions(+), 154 deletions(-) delete mode 100644 app/code/Magento/Translation/ViewModel/Dictionary.php delete mode 100644 app/code/Magento/Translation/view/base/templates/dictionary.phtml create mode 100644 app/code/Magento/Translation/view/base/web/js/mage-translation-dictionary.js delete mode 100644 app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js delete mode 100644 dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js diff --git a/app/code/Magento/Translation/ViewModel/Dictionary.php b/app/code/Magento/Translation/ViewModel/Dictionary.php deleted file mode 100644 index d551a3f106ea..000000000000 --- a/app/code/Magento/Translation/ViewModel/Dictionary.php +++ /dev/null @@ -1,99 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Translation\ViewModel; - -use Magento\Framework\Escaper; -use Magento\Framework\Exception\FileSystemException; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\View\Asset\Repository as AssetRepository; -use Magento\Framework\View\Element\Block\ArgumentInterface; -use Magento\Translation\Model\Js\Config as JsConfig; -use Magento\Framework\App\State as AppState; - -/** - * View model responsible for handling translation dictionary in layout. - */ -class Dictionary implements ArgumentInterface -{ - /** - * @var AssetRepository - */ - private $assetRepo; - - /** - * @var AppState - */ - private $appState; - - /** - * @var Escaper - */ - private $escaper; - - /** - * @param AssetRepository $assetRepo - * @param AppState $appState - * @param Escaper $escaper - */ - public function __construct( - AssetRepository $assetRepo, - AppState $appState, - Escaper $escaper - ) { - $this->assetRepo = $assetRepo; - $this->appState = $appState; - $this->escaper = $escaper; - } - - /** - * Get translation dictionary file content. - * - * @return string - * @throws FileSystemException - * @throws LocalizedException - */ - public function getTranslationDictionary(): string - { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - - return $asset->getContent(); - } - - /** - * Get translation dictionary url. - * - * @return string - * @throws LocalizedException - */ - public function getTranslationDictionaryUrl(): string - { - $asset = $this->assetRepo->createAsset(JsConfig::DICTIONARY_FILE_NAME); - - return $asset->getUrl(); - } - - /** - * Check if application is in production mode. - * - * @return bool - */ - public function isAppStateProduction(): bool - { - return $this->appState->getMode() === AppState::MODE_PRODUCTION; - } - - /** - * Escape URL. - * - * @param string $url - * @return string - */ - public function escapeUrl(string $url): string - { - return $this->escaper->escapeUrl($url); - } -} diff --git a/app/code/Magento/Translation/etc/di.xml b/app/code/Magento/Translation/etc/di.xml index acb24bcd0a71..d17dac23933e 100644 --- a/app/code/Magento/Translation/etc/di.xml +++ b/app/code/Magento/Translation/etc/di.xml @@ -15,11 +15,6 @@ <preference for="Magento\Framework\Phrase\RendererInterface" type="Magento\Framework\Phrase\Renderer\Composite" /> <preference for="Magento\Translation\Model\Js\DataProviderInterface" type="Magento\Translation\Model\Js\DataProvider"/> <preference for="Magento\Framework\Translate\Js\Config" type="Magento\Translation\Model\Js\Config"/> - <type name="Magento\Translation\ViewModel\Dictionary"> - <arguments> - <argument name="filesystemDriver" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument> - </arguments> - </type> <type name="Magento\Framework\Translate\Inline"> <arguments> <argument name="templateFileName" xsi:type="string">Magento_Translation::translate_inline.phtml</argument> diff --git a/app/code/Magento/Translation/view/base/templates/dictionary.phtml b/app/code/Magento/Translation/view/base/templates/dictionary.phtml deleted file mode 100644 index 48ffef51a364..000000000000 --- a/app/code/Magento/Translation/view/base/templates/dictionary.phtml +++ /dev/null @@ -1,20 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -/** @var \Magento\Translation\ViewModel\Dictionary $viewModel */ -$viewModel = $block->getData('dictionary_view_model'); -if (!$viewModel->isAppStateProduction()) { - $dictionary = json_encode($viewModel->getTranslationDictionary(), JSON_HEX_APOS | JSON_UNESCAPED_SLASHES); - // Use of JSON.parse below is intentional as JSON is significantly faster to parse than JavaScript - ?> - <script> - define('mageTranslationDictionary', function () { - var dict = <?= /* @noEscape */ $dictionary ?>; - return JSON.parse(dict); - }); - </script> - <?php -} diff --git a/app/code/Magento/Translation/view/base/web/js/mage-translation-dictionary.js b/app/code/Magento/Translation/view/base/web/js/mage-translation-dictionary.js new file mode 100644 index 000000000000..72f497dde9ad --- /dev/null +++ b/app/code/Magento/Translation/view/base/web/js/mage-translation-dictionary.js @@ -0,0 +1,12 @@ +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +define([ + 'text!js-translation.json' +], function (dict) { + 'use strict'; + + return JSON.parse(dict); +}); diff --git a/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js b/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js deleted file mode 100644 index 581cdd5f954f..000000000000 --- a/app/code/Magento/Translation/view/base/web/js/mageTranslationDictionary.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -define(['text!js-translation.json'], - function (dict) { - return JSON.parse(dict); -}); diff --git a/app/code/Magento/Translation/view/frontend/layout/default.xml b/app/code/Magento/Translation/view/frontend/layout/default.xml index 6b8c8e277422..244c0464301d 100644 --- a/app/code/Magento/Translation/view/frontend/layout/default.xml +++ b/app/code/Magento/Translation/view/frontend/layout/default.xml @@ -9,11 +9,6 @@ <body> <referenceBlock name="head.additional"> <block class="Magento\Translation\Block\Html\Head\Config" name="translate-config"/> - <block name="translation_dictionary" template="Magento_Translation::dictionary.phtml" before="-"> - <arguments> - <argument name="dictionary_view_model" xsi:type="object">Magento\Translation\ViewModel\Dictionary</argument> - </arguments> - </block> </referenceBlock> </body> </page> diff --git a/app/code/Magento/Translation/view/frontend/requirejs-config.js b/app/code/Magento/Translation/view/frontend/requirejs-config.js index 73f913ce23f2..b5351b9d471c 100644 --- a/app/code/Magento/Translation/view/frontend/requirejs-config.js +++ b/app/code/Magento/Translation/view/frontend/requirejs-config.js @@ -9,7 +9,7 @@ var config = { editTrigger: 'mage/edit-trigger', addClass: 'Magento_Translation/js/add-class', 'Magento_Translation/add-class': 'Magento_Translation/js/add-class', - mageTranslationDictionary: 'Magento_Translation/js/mageTranslationDictionary' + mageTranslationDictionary: 'Magento_Translation/js/mage-translation-dictionary' } }, deps: [ diff --git a/dev/tests/js/jasmine/require.conf.js b/dev/tests/js/jasmine/require.conf.js index 6af6221276c2..cd5d6fe836da 100644 --- a/dev/tests/js/jasmine/require.conf.js +++ b/dev/tests/js/jasmine/require.conf.js @@ -19,11 +19,6 @@ require.config({ 'tests': '../../../../../../dev/tests/js/jasmine', 'squire': '../../../../../../node_modules/squirejs/src/Squire' }, - map: { - '*': { - mageTranslationDictionary: '../../../../../../dev/tests/js/jasmine/tests/lib/mage/fake-dictionary' - } - }, shim: { squire: { exports: 'squire' diff --git a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js b/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js deleted file mode 100644 index eeeed2a5864e..000000000000 --- a/dev/tests/js/jasmine/tests/lib/mage/fake-dictionary.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -// Fake translation dictionary as real dictionary is defined in template and cannot be initialized by requirejs -define([], function () { - 'use strict'; - - return {}; -}); From a14f7a983cdf90891e79dc96679ac13e6177ee6e Mon Sep 17 00:00:00 2001 From: Dmytro Horytskyi <horytsky@adobe.com> Date: Thu, 26 Sep 2019 14:52:15 -0500 Subject: [PATCH 0652/1172] MC-19652: Product Categories Indexer stuck --- .../Indexer/Product/Category/Action/Rows.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php index 08e281111a57..15ba6c8f3758 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Category/Action/Rows.php @@ -105,7 +105,7 @@ public function execute(array $entityIds = [], $useTempTable = false) * @throws \Exception if metadataPool doesn't contain metadata for ProductInterface * @throws \DomainException */ - private function getProductIdsWithParents(array $childProductIds) + private function getProductIdsWithParents(array $childProductIds): array { /** @var \Magento\Framework\EntityManager\EntityMetadataInterface $metadata */ $metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); @@ -220,28 +220,28 @@ protected function isRangingNeeded() * Returns a list of category ids which are assigned to product ids in the index * * @param array $productIds - * @return \Magento\Framework\Indexer\CacheContext + * @return array */ - private function getCategoryIdsFromIndex(array $productIds) + private function getCategoryIdsFromIndex(array $productIds): array { $categoryIds = []; foreach ($this->storeManager->getStores() as $store) { - $categoryIds = array_merge( - $categoryIds, - $this->connection->fetchCol( - $this->connection->select() - ->from($this->getIndexTable($store->getId()), ['category_id']) - ->where('product_id IN (?)', $productIds) - ->distinct() - ) + $storeCategories = $this->connection->fetchCol( + $this->connection->select() + ->from($this->getIndexTable($store->getId()), ['category_id']) + ->where('product_id IN (?)', $productIds) + ->distinct() ); + $categoryIds[] = $storeCategories; } - $parentCategories = $categoryIds; + $categoryIds = array_merge(...$categoryIds); + + $parentCategories = [$categoryIds]; foreach ($categoryIds as $categoryId) { $parentIds = explode('/', $this->getPathFromCategoryId($categoryId)); - $parentCategories = array_merge($parentCategories, $parentIds); + $parentCategories[] = $parentIds; } - $categoryIds = array_unique($parentCategories); + $categoryIds = array_unique(array_merge(...$parentCategories)); return $categoryIds; } From 50cd54614e0de959fbc9d94eb93cf9f9a5e90fce Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Thu, 26 Sep 2019 15:02:51 -0500 Subject: [PATCH 0653/1172] MC-20333: Fix All Catalog Module MFTF tests that are failing with the use of Elastic Search functionality "Add re-index task as few tests were failing in the mainline branch" "Reverted MAGETWO-93794 changes as there is a bug created for https://jira.corp.magento.com/browse/MC-17380 where sorting by position is not working with Elastic Search feature." --- .../ProductAvailableAfterEnablingSubCategoriesTest.xml | 4 ++++ .../Mftf/Test/StorefrontProductNameWithDoubleQuote.xml | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml index 461ebde29fca..c8a7cdee66b5 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/ProductAvailableAfterEnablingSubCategoriesTest.xml @@ -49,6 +49,10 @@ <click selector="{{AdminCategoryMainActionsSection.SaveButton}}" stepKey="saveCategoryWithProducts"/> <waitForPageLoad stepKey="waitForCategorySaved"/> <see userInput="You saved the category." stepKey="seeSuccessMessage"/> + + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <amOnPage url="$$createCategory.name$$.html" stepKey="goToCategoryStorefront"/> <waitForPageLoad stepKey="waitForCategoryStorefrontPage"/> <seeElement selector="{{StorefrontCategoryProductSection.ProductImageByName($$createSimpleProduct.name$$)}}" stepKey="seeCreatedProduct"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml index f2c3f15ab434..be5d9dca425a 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml @@ -41,6 +41,9 @@ </actionGroup> <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Check product in category listing--> <amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="goToCategoryPage"/> <seeElement selector="{{StorefrontCategoryProductSection.ProductImageByNameAndSrc(SimpleProductNameWithDoubleQuote.name, ProductImage.fileName)}}" stepKey="seeCorrectImageCategoryPage"/> @@ -88,6 +91,9 @@ <deleteData createDataKey="createCategoryOne" stepKey="deleteCategory"/> </after> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Check product in category listing--> <amOnPage url="{{StorefrontCategoryPage.url($$createCategoryOne.name$$)}}" stepKey="navigateToCategoryPage"/> <waitForPageLoad stepKey="waitforCategoryPageToLoad"/> @@ -111,7 +117,7 @@ <waitForPageLoad stepKey="waitforCategoryPageToLoad2"/> <!--Open product display page--> - <click selector="{{StorefrontCategoryProductSection.ProductTitleByNumber('2')}}" stepKey="goToProduct2DisplayPage"/> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByNumber('1')}}" stepKey="goToProduct2DisplayPage"/> <!--<click selector="{{StorefrontCategoryProductSection.ProductTitleByName(productWithHTMLEntityOne.name)}}" stepKey="clickProductToGoProductPage"/>--> <waitForPageLoad stepKey="waitForProductDisplayPageLoad3"/> From c5e08c86766f206845bca6cc3e1ebb26b9e90865 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Thu, 26 Sep 2019 16:43:55 -0500 Subject: [PATCH 0654/1172] MC-20336: Update tests related to Catalog Search and Swatches "Fixed tests that are failing using elastic search engine." --- .../Test/StorefrontDisplayAllCharactersOnTextSwatchTest.xml | 3 +++ .../Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml | 3 +++ .../Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml | 3 +++ .../Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml | 3 +++ 4 files changed, 12 insertions(+) diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontDisplayAllCharactersOnTextSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontDisplayAllCharactersOnTextSwatchTest.xml index 470421776cf8..1bcdd6fcf9a3 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontDisplayAllCharactersOnTextSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontDisplayAllCharactersOnTextSwatchTest.xml @@ -29,6 +29,9 @@ <fillField selector="{{AdminManageSwatchSection.swatchTextByIndex('3')}}" userInput="123456789012345678901" stepKey="fillSwatch3" after="clickAddSwatch3"/> <fillField selector="{{AdminManageSwatchSection.swatchAdminDescriptionByIndex('3')}}" userInput="123456789012345678901BrownD" stepKey="fillDescription3" after="fillSwatch3"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <see selector="{{StorefrontCategorySidebarSection.attributeNthOption(ProductAttributeFrontendLabel.label, '3')}}" userInput="123456789012345678901" stepKey="seeGreen" after="seeBlue"/> <see selector="{{StorefrontCategorySidebarSection.attributeNthOption(ProductAttributeFrontendLabel.label, '4')}}" userInput="123456789012345678901" stepKey="seeBrown" after="seeGreen"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml index b1ae06428c0a..b213537ca1ab 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByImageSwatchTest.xml @@ -103,6 +103,9 @@ <argument name="image" value="TestImageAdobe"/> </actionGroup> + <!-- Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!-- Go to the category page --> <amOnPage url="$$createCategory.name$$.html" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPage"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml index 28df5ffd5343..85da0e34ef41 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByTextSwatchTest.xml @@ -82,6 +82,9 @@ <argument name="attributeCode" value="{{ProductAttributeFrontendLabel.label}}"/> </actionGroup> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!-- Go to the category page --> <amOnPage url="$$createCategory.name$$.html" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPage"/> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml index d12cb0433fed..34d440dc5421 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Test/StorefrontFilterByVisualSwatchTest.xml @@ -94,6 +94,9 @@ <argument name="attributeCode" value="{{ProductAttributeFrontendLabel.label}}"/> </actionGroup> + <!-- Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!-- Go to the category page --> <amOnPage url="$$createCategory.name$$.html" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPage"/> From 21699ee749483c5dbe7fab04f368a8e6ae095013 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 26 Sep 2019 16:50:11 -0500 Subject: [PATCH 0655/1172] MC-20244: Pricing :: FPT calculation - initial schema --- .../Model/Resolver/FptResolver.php | 29 +++++++++++++++++++ .../Magento/WeeeGraphQl/etc/schema.graphqls | 13 +++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php new file mode 100644 index 000000000000..1e47642aadd1 --- /dev/null +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -0,0 +1,29 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; + +class FptResolver implements ResolverInterface +{ + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + + return []; + } +} diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 731260ce9e1e..4a5067125758 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -2,6 +2,15 @@ # See COPYING.txt for license details. enum PriceAdjustmentCodesEnum { - WEE - WEETAX + WEEE + WEEETAX +} + +type ProductPrice { + fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FptResolver") +} + +type FixedProductTax @doc(description: "A single FPT that can be applied to a product price.") { + amount: Money @doc(description: "Amount of the FPT as a money object.") + label: String @doc(description: "The label assigned to the FPT to be displayed on the frontend.") } From 31875feda09ec5b2edb96e7c07d05c9cf807d8b1 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 26 Sep 2019 17:02:10 -0500 Subject: [PATCH 0656/1172] MC-20334: Update tests related to SKU field issue in AdvancedSearch --- .../Bundle/Test/Mftf/Data/ProductData.xml | 14 +++ .../AdvanceCatalogSearchBundleProductTest.xml | 2 +- ...CatalogSearchBundleBySkuWithHyphenTest.xml | 47 ++++++++++ .../Catalog/Test/Mftf/Data/ProductData.xml | 28 ++++++ .../AdvanceCatalogSearchSimpleProductTest.xml | 2 +- ...AdvanceCatalogSearchVirtualProductTest.xml | 2 +- ...SearchSimpleProductBySkuWithHyphenTest.xml | 29 +++++++ ...earchVirtualProductBySkuWithHyphenTest.xml | 26 ++++++ .../Mftf/Data/ConfigurableProductData.xml | 13 +++ .../AdvanceCatalogSearchConfigurableTest.xml | 2 +- ...gSearchConfigurableBySkuWithHyphenTest.xml | 86 +++++++++++++++++++ .../Test/Mftf/Data/ProductData.xml | 15 ++++ ...ceCatalogSearchDownloadableProductTest.xml | 2 +- ...gSearchDownloadableBySkuWithHyphenTest.xml | 32 +++++++ .../Test/Mftf/Data/GroupedProductData.xml | 11 +++ ...AdvanceCatalogSearchGroupedProductTest.xml | 2 +- ...logSearchGroupedProductBySkuWithHyphenTest | 42 +++++++++ 17 files changed, 349 insertions(+), 6 deletions(-) create mode 100644 app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdvanceCatalogSearchBundleBySkuWithHyphenTest.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchSimpleProductBySkuWithHyphenTest.xml create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchVirtualProductBySkuWithHyphenTest.xml create mode 100644 app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml create mode 100644 app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml create mode 100644 app/code/Magento/GroupedProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchGroupedProductBySkuWithHyphenTest diff --git a/app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml index 6e7e4a7a1657..e5f557dd22de 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Data/ProductData.xml @@ -61,6 +61,20 @@ <requiredEntity type="custom_attribute">CustomAttributeDynamicPrice</requiredEntity> <requiredEntity type="custom_attribute">CustomAttributePriceView</requiredEntity> </entity> + <entity name="ApiBundleProductUnderscoredSku" type="product2"> + <data key="name" unique="suffix">Api Bundle Product</data> + <data key="sku" unique="suffix">api_bundle_product</data> + <data key="type_id">bundle</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="status">1</data> + <data key="urlKey" unique="suffix">api-bundle-product</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute">ApiProductShortDescription</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributeDynamicPrice</requiredEntity> + <requiredEntity type="custom_attribute">CustomAttributePriceView</requiredEntity> + </entity> <entity name="ApiBundleProductPriceViewRange" type="product2"> <data key="name" unique="suffix">Api Bundle Product</data> <data key="sku" unique="suffix">api-bundle-product</data> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml index 52bce6760088..c6775641fe21 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdvanceCatalogSearchBundleProductTest.xml @@ -56,7 +56,7 @@ <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> - <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="ApiBundleProductUnderscoredSku" stepKey="product"/> <createData entity="DropDownBundleOption" stepKey="bundleOption"> <requiredEntity createDataKey="product"/> </createData> diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdvanceCatalogSearchBundleBySkuWithHyphenTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdvanceCatalogSearchBundleBySkuWithHyphenTest.xml new file mode 100644 index 000000000000..d8d6034cd1a2 --- /dev/null +++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdvanceCatalogSearchBundleBySkuWithHyphenTest.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchBundleBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="Bundle"/> + <stories value="Advanced Catalog Product Search for all product types "/> + <title value="Guest customer should be able to advance search Bundle product with product sku that contains hyphen"/> + <description value="Guest customer should be able to advance search Bundle product with product sku that contains hyphen"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20359"/> + <group value="Bundle"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiBundleProduct" stepKey="product"/> + <createData entity="DropDownBundleOption" stepKey="bundleOption"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <createData entity="ApiBundleLink" stepKey="createBundleLink2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="bundleOption"/> + <requiredEntity createDataKey="simple2"/> + </createData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index e122615eb8aa..ec3bf326b124 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -438,6 +438,20 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiProductWithDescriptionAndUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_simple_product</data> + <data key="type_id">simple</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Simple Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-simple-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="_newDefaultProduct" type="product"> <data key="sku" unique="suffix">testSku</data> <data key="type_id">simple</data> @@ -531,6 +545,20 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiVirtualProductWithDescriptionAndUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_virtual_product</data> + <data key="type_id">virtual</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Virtual Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-virtual-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="SimpleProductWithNewFromDate" type="product"> <data key="sku" unique="suffix">SimpleProduct</data> <data key="type_id">simple</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchSimpleProductTest.xml index a4c8b492d9d8..867f097042a1 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchSimpleProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchSimpleProductTest.xml @@ -36,7 +36,7 @@ <group value="Catalog"/> </annotations> <before> - <createData entity="ApiProductWithDescription" stepKey="product"/> + <createData entity="ApiProductWithDescriptionAndUnderscoredSku" stepKey="product"/> </before> <after> <deleteData createDataKey="product" stepKey="delete"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchVirtualProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchVirtualProductTest.xml index 84c3f81ef6db..07b802637b2e 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchVirtualProductTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdvanceCatalogSearchVirtualProductTest.xml @@ -33,7 +33,7 @@ <group value="Catalog"/> </annotations> <before> - <createData entity="ApiVirtualProductWithDescription" stepKey="product"/> + <createData entity="ApiVirtualProductWithDescriptionAndUnderscoredSku" stepKey="product"/> </before> </test> <test name="AdvanceCatalogSearchVirtualProductByDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchSimpleProductBySkuWithHyphenTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchSimpleProductBySkuWithHyphenTest.xml new file mode 100644 index 000000000000..3b1cd7ff02e6 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchSimpleProductBySkuWithHyphenTest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchSimpleProductBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search simple product with product sku that contains hyphen"/> + <description value="Guest customer should be able to advance search simple product with product sku that contains hyphen"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20361"/> + <group value="Catalog"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="product"/> + </before> + <after> + <deleteData createDataKey="product" stepKey="delete"/> + </after> + </test> +</tests> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchVirtualProductBySkuWithHyphenTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchVirtualProductBySkuWithHyphenTest.xml new file mode 100644 index 000000000000..d6b3a060ffd3 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontAdvanceCatalogSearchVirtualProductBySkuWithHyphenTest.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchVirtualProductBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="Catalog"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search virtual product with product sku that contains hyphen"/> + <description value="Guest customer should be able to advance search virtual product with product sku that contains hyphen"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20385"/> + <group value="Catalog"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="ApiVirtualProductWithDescription" stepKey="product"/> + </before> + </test> +</tests> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductData.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductData.xml index 3f21c98068d8..6ae3c4f4e16c 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductData.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Data/ConfigurableProductData.xml @@ -60,6 +60,19 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiConfigurableProductWithDescriptionUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_configurable_product</data> + <data key="type_id">configurable</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">API Configurable Product</data> + <data key="urlKey" unique="suffix">api-configurable-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="ConfigurableProductAddChild" type="ConfigurableProductAddChild"> <var key="sku" entityKey="sku" entityType="product" /> <var key="childSku" entityKey="sku" entityType="product2"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml index c303e4d19db8..0d1925ef538a 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml @@ -104,7 +104,7 @@ </createData> <!-- TODO: Move configurable product creation to an actionGroup when MQE-697 is fixed --> - <createData entity="ApiConfigurableProductWithDescription" stepKey="product"/> + <createData entity="ApiConfigurableProductWithDescriptionUnderscoredSku" stepKey="product"/> <createData entity="productDropDownAttribute" stepKey="productAttributeHandle"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml new file mode 100644 index 000000000000..8a7d7d5394ee --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search configurable product with product sku that contains hyphen"/> + <description value="Guest customer should be able to advance search configurable product with product sku that contains hyphen"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20389"/> + <group value="ConfigurableProduct"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="SimpleSubCategory" stepKey="categoryHandle" before="simple1Handle"/> + + <createData entity="SimpleProduct" stepKey="simple1Handle" before="simple2Handle"> + <requiredEntity createDataKey="categoryHandle"/> + </createData> + + <createData entity="SimpleProduct" stepKey="simple2Handle" before="product"> + <requiredEntity createDataKey="categoryHandle"/> + </createData> + + <!-- TODO: Move configurable product creation to an actionGroup when MQE-697 is fixed --> + <createData entity="ApiConfigurableProductWithDescription" stepKey="product"/> + + <createData entity="productDropDownAttribute" stepKey="productAttributeHandle"/> + + <createData entity="productAttributeOption1" stepKey="productAttributeOption1Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + <createData entity="productAttributeOption2" stepKey="productAttributeOption2Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + + <createData entity="AddToDefaultSet" stepKey="addToAttributeSetHandle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </createData> + + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getAttributeOption1Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </getData> + <getData entity="ProductAttributeOptionGetter" index="2" stepKey="getAttributeOption2Handle"> + <requiredEntity createDataKey="productAttributeHandle"/> + </getData> + + <createData entity="SimpleOne" stepKey="childProductHandle1"> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption1Handle"/> + </createData> + <createData entity="SimpleOne" stepKey="childProductHandle2"> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption2Handle"/> + </createData> + + <createData entity="ConfigurableProductTwoOptions" stepKey="configProductOptionHandle"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="productAttributeHandle"/> + <requiredEntity createDataKey="getAttributeOption1Handle"/> + <requiredEntity createDataKey="getAttributeOption2Handle"/> + </createData> + + <createData entity="ConfigurableProductAddChild" stepKey="configProductHandle1"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="childProductHandle1"/> + </createData> + <createData entity="ConfigurableProductAddChild" stepKey="configProductHandle2"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="childProductHandle2"/> + </createData> + </before> + <after> + <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + </after> + </test> +</tests> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml index 1a6be43b38d2..2986532ef113 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml @@ -74,6 +74,21 @@ <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> <requiredEntity type="downloadable_link">apiDownloadableLink</requiredEntity> </entity> + <entity name="ApiDownloadableProductUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_downloadable_product</data> + <data key="type_id">downloadable</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Downloadable Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-downloadable-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + <requiredEntity type="downloadable_link">apiDownloadableLink</requiredEntity> + </entity> <entity name="DownloadableProductWithTwoLink100" type="product"> <data key="sku" unique="suffix">downloadableproduct</data> <data key="type_id">downloadable</data> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml index 66177b6875dd..39260b897ee1 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdvanceCatalogSearchDownloadableProductTest.xml @@ -39,7 +39,7 @@ <group value="Downloadable"/> </annotations> <before> - <createData entity="ApiDownloadableProduct" stepKey="product"/> + <createData entity="ApiDownloadableProductUnderscoredSku" stepKey="product"/> <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> <requiredEntity createDataKey="product"/> </createData> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml new file mode 100644 index 000000000000..717412276057 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> + <!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> + + <tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchDownloadableBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="Downloadable"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Downloadable product with product sku that contains hyphen"/> + <description value="Guest customer should be able to advance search Downloadable product with product that contains hyphen"/> + <severity value="MAJOR"/> + <testCaseId value="MC-252"/> + <group value="Downloadable"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="ApiDownloadableProduct" stepKey="product"/> + <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink1"> + <requiredEntity createDataKey="product"/> + </createData> + <createData entity="ApiDownloadableLink" stepKey="addDownloadableLink2"> + <requiredEntity createDataKey="product"/> + </createData> + </before> + </test> + </tests> diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Data/GroupedProductData.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Data/GroupedProductData.xml index ba3703e7b0ed..e6d7588289c3 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Data/GroupedProductData.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Data/GroupedProductData.xml @@ -28,6 +28,17 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiGroupedProductAndUnderscoredSku" type="product3"> + <data key="sku" unique="suffix">api_grouped_product</data> + <data key="type_id">grouped</data> + <data key="attribute_set_id">4</data> + <data key="name" unique="suffix">Api Grouped Product</data> + <data key="status">1</data> + <data key="urlKey" unique="suffix">api-grouped-product</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="ApiGroupedProduct2" type="product3"> <data key="sku" unique="suffix">apiGroupedProduct</data> <data key="type_id">grouped</data> diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml index 2a600d38250f..8b2daa157077 100644 --- a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdvanceCatalogSearchGroupedProductTest.xml @@ -51,7 +51,7 @@ <before> <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> - <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="ApiGroupedProductAndUnderscoredSku" stepKey="product"/> <createData entity="OneSimpleProductLink" stepKey="addProductOne"> <requiredEntity createDataKey="product"/> <requiredEntity createDataKey="simple1"/> diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchGroupedProductBySkuWithHyphenTest b/app/code/Magento/GroupedProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchGroupedProductBySkuWithHyphenTest new file mode 100644 index 000000000000..5220349a4aac --- /dev/null +++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchGroupedProductBySkuWithHyphenTest @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontAdvanceCatalogSearchGroupedProductBySkuWithHyphenTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> + <annotations> + <features value="GroupedProduct"/> + <stories value="Advanced Catalog Product Search for all product types"/> + <title value="Guest customer should be able to advance search Grouped product with product sku that in camelCase format"/> + <description value="Guest customer should be able to advance search Grouped product with product sku that in camelCase format"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20519"/> + <group value="GroupedProduct"/> + <group value="SearchEngineMysql"/> + </annotations> + <before> + <createData entity="ApiProductWithDescription" stepKey="simple1" before="simple2"/> + <createData entity="ApiProductWithDescription" stepKey="simple2" before="product"/> + <createData entity="ApiGroupedProduct" stepKey="product"/> + <createData entity="OneSimpleProductLink" stepKey="addProductOne"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple1"/> + </createData> + <updateData entity="OneMoreSimpleProductLink" createDataKey="addProductOne" stepKey="addProductTwo"> + <requiredEntity createDataKey="product"/> + <requiredEntity createDataKey="simple2"/> + </updateData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> + </before> + <after> + <deleteData createDataKey="simple1" stepKey="deleteSimple1" before="deleteSimple2"/> + <deleteData createDataKey="simple2" stepKey="deleteSimple2" before="delete"/> + </after> + </test> +</tests> From 37754f6e79198715b774d88f28bdad1357155a93 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Thu, 26 Sep 2019 17:04:11 -0500 Subject: [PATCH 0657/1172] MC-18403: Pricing :: Product pricing schema - fix variant tier prices --- .../Model/Resolver/Product/Price/Tiers.php | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php index 7c5e13783f20..73a2ba83d509 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php +++ b/app/code/Magento/CatalogCustomerGraphQl/Model/Resolver/Product/Price/Tiers.php @@ -127,6 +127,11 @@ public function getProductRegularPrice($productId): ?float */ public function isLoaded(): bool { + $numFilterProductIds = count(array_unique($this->filterProductIds)); + if ($numFilterProductIds > count($this->products)) { + //New products were added to the filter after load, so we should reload + return false; + } return $this->loaded; } @@ -146,10 +151,26 @@ private function load(): void $productCollection->load(); $productCollection->addTierPriceDataByGroupId($this->customerGroupId); + $this->setProducts($productCollection); + $this->loaded = true; + } + + /** + * Set products from collection + * + * @param Collection $productCollection + */ + private function setProducts(Collection $productCollection): void + { + $this->products = []; + foreach ($productCollection as $product) { $this->products[$product->getId()] = $product; } - $this->loaded = true; + $missingProducts = array_diff($this->filterProductIds, array_keys($this->products)); + foreach (array_unique($missingProducts) as $missingProductId) { + $this->products[$missingProductId] = null; + } } } From 1e6023399c47ed1c251ea045a920296081bad090 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Thu, 26 Sep 2019 21:33:38 -0500 Subject: [PATCH 0658/1172] MC-20336: Update tests related to Catalog Search and Swatches "Reverted previous commit "d657e00c8bc70aa073f074d8a72f960e45cd486f" as it deleted var/.htaccess file and added only changes to Test file" --- .../Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml | 4 ---- var/.htaccess | 8 ++++++++ 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 var/.htaccess diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml index c8f84c732d6b..210b474af2e0 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml @@ -57,10 +57,6 @@ <fillField selector="{{AdminProductAttributeSection.customAttribute($$createPriceAttribute.attribute_code$$)}}" userInput="70" stepKey="fillCustomPrice2"/> <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton2"/> <waitForPageLoad stepKey="waitForSimpleProductSaved2"/> - - <!--Run re-index task--> - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - <!--Navigate to category on Storefront--> <comment userInput="Navigate to category on Storefront" stepKey="comment3"/> <amOnPage url="{{StorefrontCategoryPage.url($$subCategory.name$$)}}" stepKey="goToCategoryStorefront"/> diff --git a/var/.htaccess b/var/.htaccess new file mode 100644 index 000000000000..707c26b075e1 --- /dev/null +++ b/var/.htaccess @@ -0,0 +1,8 @@ +<IfVersion < 2.4> + order allow,deny + deny from all +</IfVersion> +<IfVersion >= 2.4> + Require all denied +</IfVersion> + From 4e4320f5fa662ee23580a036830094388da6c830 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Thu, 26 Sep 2019 21:36:25 -0500 Subject: [PATCH 0659/1172] MC-20336: Update tests related to Catalog Search and Swatches "Reverted previous commit "d657e00c8bc70aa073f074d8a72f960e45cd486f" as it accidentally deleted var/.htaccess file and made now changes only to Test file" --- .../Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml index 210b474af2e0..c8f84c732d6b 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/LayerNavigationOfCatalogSearchTest.xml @@ -57,6 +57,10 @@ <fillField selector="{{AdminProductAttributeSection.customAttribute($$createPriceAttribute.attribute_code$$)}}" userInput="70" stepKey="fillCustomPrice2"/> <click selector="{{AdminProductFormSection.save}}" stepKey="clickSaveButton2"/> <waitForPageLoad stepKey="waitForSimpleProductSaved2"/> + + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Navigate to category on Storefront--> <comment userInput="Navigate to category on Storefront" stepKey="comment3"/> <amOnPage url="{{StorefrontCategoryPage.url($$subCategory.name$$)}}" stepKey="goToCategoryStorefront"/> From 038f134d3070d9f6b26da3000a3957e077c6e6d4 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 27 Sep 2019 10:08:53 +0400 Subject: [PATCH 0660/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6411 --- .../AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml | 2 +- .../tests/_data/{test_tablerates.csv => usa_tablerates.csv} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename dev/tests/acceptance/tests/_data/{test_tablerates.csv => usa_tablerates.csv} (100%) diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml index 6f9327d68d45..3decca9a971d 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -61,7 +61,7 @@ <argument name="status" value="1"/> </actionGroup> <actionGroup ref="AdminImportFileTableRatesShippingMethodActionGroup" stepKey="importCSVFile"> - <argument name="file" value="test_tablerates.csv"/> + <argument name="file" value="usa_tablerates.csv"/> </actionGroup> <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> diff --git a/dev/tests/acceptance/tests/_data/test_tablerates.csv b/dev/tests/acceptance/tests/_data/usa_tablerates.csv similarity index 100% rename from dev/tests/acceptance/tests/_data/test_tablerates.csv rename to dev/tests/acceptance/tests/_data/usa_tablerates.csv From acc65002f2b14daf6052bdb34d22ed3815bb6507 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 27 Sep 2019 10:30:09 +0400 Subject: [PATCH 0661/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6405 --- app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml | 4 ++-- app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml | 2 +- app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 756574b76d4e..cfcb563fb67c 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -312,7 +312,7 @@ <data key="postcode">90230</data> <data key="telephone">555-55-555-55</data> </entity> - <entity name="US_Address_AFE" type="address"> + <entity name="US_Address_AE" type="address"> <data key="firstname">John</data> <data key="lastname">Doe</data> <data key="company">Magento</data> @@ -328,6 +328,6 @@ <data key="telephone">512-345-6789</data> <data key="default_billing">Yes</data> <data key="default_shipping">Yes</data> - <requiredEntity type="region">RegionAFE</requiredEntity> + <requiredEntity type="region">RegionAE</requiredEntity> </entity> </entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml index f10732c55903..89dc8c7e100f 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml @@ -320,6 +320,6 @@ <data key="password">pwdTest123!</data> <data key="store_id">0</data> <data key="website_id">0</data> - <requiredEntity type="address">US_Address_AFE</requiredEntity> + <requiredEntity type="address">US_Address_AE</requiredEntity> </entity> </entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml b/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml index 1e6589057fa7..0a956f16767b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/RegionData.xml @@ -32,7 +32,7 @@ <data key="region_code">UT</data> <data key="region_id">58</data> </entity> - <entity name="RegionAFE" type="region"> + <entity name="RegionAE" type="region"> <data key="region">Armed Forces Europe</data> <data key="region_code">AFE</data> <data key="region_id">9</data> From 41890d6bcc8f046993e2c67e6b299414a20b7364 Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Fri, 27 Sep 2019 09:30:37 +0300 Subject: [PATCH 0662/1172] [PayPal] Rename PaypalExpressToken type --- app/code/Magento/PaypalGraphQl/etc/schema.graphqls | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/PaypalGraphQl/etc/schema.graphqls b/app/code/Magento/PaypalGraphQl/etc/schema.graphqls index 78335e089cdc..45ebb0d7871f 100644 --- a/app/code/Magento/PaypalGraphQl/etc/schema.graphqls +++ b/app/code/Magento/PaypalGraphQl/etc/schema.graphqls @@ -7,7 +7,7 @@ type Query { } type Mutation { - createPaypalExpressToken(input: PaypalExpressTokenInput!): PaypalExpressToken @resolver(class: "\\Magento\\PaypalGraphQl\\Model\\Resolver\\PaypalExpressToken") @doc(description:"Initiates an Express Checkout transaction and receives a token. Use this mutation for Express Checkout and Payments Standard payment methods.") + createPaypalExpressToken(input: PaypalExpressTokenInput!): PaypalExpressTokenOutput @resolver(class: "\\Magento\\PaypalGraphQl\\Model\\Resolver\\PaypalExpressToken") @doc(description:"Initiates an Express Checkout transaction and receives a token. Use this mutation for Express Checkout and Payments Standard payment methods.") createPayflowProToken(input: PayflowProTokenInput!): CreatePayflowProTokenOutput @resolver(class: "\\Magento\\PaypalGraphQl\\Model\\Resolver\\PayflowProToken") @doc(description: "Initiates a transaction and receives a token. Use this mutation for Payflow Pro and Payments Pro payment methods") handlePayflowProResponse(input: PayflowProResponseInput!): PayflowProResponseOutput @resolver(class: "\\Magento\\PaypalGraphQl\\Model\\Resolver\\PayflowProResponse") @doc(description: "Handles payment response and saves payment in Quote. Use this mutations for Payflow Pro and Payments Pro payment methods.") } @@ -20,7 +20,12 @@ input PaypalExpressTokenInput @doc(description: "Defines the attributes required express_button: Boolean @doc(description: "Indicates whether the buyer selected the quick checkout button. The default value is false") } -type PaypalExpressToken @doc(description: "Contains the token returned by PayPal and a set of URLs that allow the buyer to authorize payment and adjust checkout details. Applies to Express Checkout and Payments Standard payment methods.") { +type PaypalExpressToken @doc(description: "Deprecated: use type PaypalExpressTokenOutput instead") { + token: String @deprecated(reason: "Use field `token` of type PaypalExpressTokenOutput instead") @doc(description:"The token returned by PayPal") + paypal_urls: PaypalExpressUrlList @deprecated(reason: "Use field `PaypalExpressUrlList` of type PaypalExpressTokenOutput instead") @doc(description:"A set of URLs that allow the buyer to authorize payment and adjust checkout details") +} + +type PaypalExpressTokenOutput @doc(description: "Contains the token returned by PayPal and a set of URLs that allow the buyer to authorize payment and adjust checkout details. Applies to Express Checkout and Payments Standard payment methods.") { token: String @doc(description:"The token returned by PayPal") paypal_urls: PaypalExpressUrlList @doc(description:"A set of URLs that allow the buyer to authorize payment and adjust checkout details") } From 62ac658d22f4abc4c73803a68edccc06876e9869 Mon Sep 17 00:00:00 2001 From: George Babarus <george.babarus@emag.ro> Date: Fri, 27 Sep 2019 09:32:41 +0300 Subject: [PATCH 0663/1172] replace DIRECTORY_SEPARATOR with / --- lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php b/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php index 9c5cd2fe1232..a53ea9423d44 100644 --- a/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php +++ b/lib/internal/Magento/Framework/App/DeploymentConfig/Reader.php @@ -108,7 +108,7 @@ public function load($fileKey = null) } else { $configFiles = $this->getFiles(); foreach ($configFiles as $file) { - $configFile = $path . DIRECTORY_SEPARATOR . $file; + $configFile = $path . '/' . $file; if ($fileDriver->isExists($configFile)) { $fileData = include $configFile; if (!is_array($fileData)) { From 1ed98c65e632fc649de46cf5b97d994784cfe6f1 Mon Sep 17 00:00:00 2001 From: Eden <quocviet312@gmail.com> Date: Fri, 27 Sep 2019 14:03:54 +0700 Subject: [PATCH 0664/1172] Resolve Suggested Terms Yes/No not in camel case #24739 --- .../view/adminhtml/layout/search_term_grid_block.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml b/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml index 38c6fa52455b..e7f31097368e 100644 --- a/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml +++ b/app/code/Magento/Search/view/adminhtml/layout/search_term_grid_block.xml @@ -81,16 +81,7 @@ <argument name="sortable" xsi:type="string">1</argument> <argument name="index" xsi:type="string">display_in_terms</argument> <argument name="type" xsi:type="string">options</argument> - <argument name="options" xsi:type="array"> - <item name="yes" xsi:type="array"> - <item name="value" xsi:type="string">1</item> - <item name="label" xsi:type="string" translate="true">yes</item> - </item> - <item name="no" xsi:type="array"> - <item name="value" xsi:type="string">0</item> - <item name="label" xsi:type="string" translate="true">no</item> - </item> - </argument> + <argument name="options" xsi:type="options" model="Magento\Config\Model\Config\Source\Yesno"/> </arguments> </block> <block class="Magento\Backend\Block\Widget\Grid\Column" name="adminhtml.catalog.search.grid.columnSet.action" as="action"> From 8247d578c633ee7fa2df63a6af937e0aa81a4f30 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 10:16:43 +0300 Subject: [PATCH 0665/1172] graphQl-912: fixing api functional test --- .../Magento/GraphQl/Customer/CreateCustomerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index 5b3ff041d481..1b28b1639d77 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -114,7 +114,7 @@ public function testCreateCustomerAccountWithoutPassword() /** * @expectedException \Exception - * @expectedExceptionMessage "input" value should be specified + * @expectedExceptionMessage Field CustomerInput.email of required type String! was not provided */ public function testCreateCustomerIfInputDataIsEmpty() { @@ -140,7 +140,7 @@ public function testCreateCustomerIfInputDataIsEmpty() /** * @expectedException \Exception - * @expectedExceptionMessage Required parameters are missing: Email + * @expectedExceptionMessage GraphQL response contains errors: Field CustomerInput.email of required type String! was not provided */ public function testCreateCustomerIfEmailMissed() { @@ -275,7 +275,7 @@ public function testCreateCustomerIfNameEmpty() QUERY; $this->graphQlMutation($query); } - + /** * @magentoConfigFixture default_store newsletter/general/active 0 */ From f9ff771264c854223bc931c4567e391c17fd0e13 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 11:02:26 +0300 Subject: [PATCH 0666/1172] graphQl-912: fixed static tests --- .../testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index 1b28b1639d77..7c86ebeaa363 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -140,7 +140,8 @@ public function testCreateCustomerIfInputDataIsEmpty() /** * @expectedException \Exception - * @expectedExceptionMessage GraphQL response contains errors: Field CustomerInput.email of required type String! was not provided + * @expectedExceptionMessage + * GraphQL response contains errors: Field CustomerInput.email of required type String! was not provided */ public function testCreateCustomerIfEmailMissed() { From 30e8127e1f63e7e1fc67eea90d16c289c613c71b Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 11:06:46 +0300 Subject: [PATCH 0667/1172] graphQl-912: removed redundant check --- .../testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index 7c86ebeaa363..7ef86a120882 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -140,8 +140,6 @@ public function testCreateCustomerIfInputDataIsEmpty() /** * @expectedException \Exception - * @expectedExceptionMessage - * GraphQL response contains errors: Field CustomerInput.email of required type String! was not provided */ public function testCreateCustomerIfEmailMissed() { From be95cfa563f30a94db9e517c16ee921afa91e2bc Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 11:07:42 +0300 Subject: [PATCH 0668/1172] graphQl-912: fixed expectedExceptionMessage --- .../testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php index 7ef86a120882..0be968d6d340 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerTest.php @@ -140,6 +140,7 @@ public function testCreateCustomerIfInputDataIsEmpty() /** * @expectedException \Exception + * @expectedExceptionMessage Field CustomerInput.email of required type String! was not provided */ public function testCreateCustomerIfEmailMissed() { From 502146f7f2d086b3a1beaea41de3edc488f78b3c Mon Sep 17 00:00:00 2001 From: Artem Voloznov <volozart@gmail.com> Date: Wed, 25 Sep 2019 12:28:03 +0300 Subject: [PATCH 0669/1172] Added unique key on eav_attribute_option_value table --- app/code/Magento/Eav/etc/db_schema.xml | 4 ++++ app/code/Magento/Eav/etc/db_schema_whitelist.json | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Eav/etc/db_schema.xml b/app/code/Magento/Eav/etc/db_schema.xml index b6c42d725e5e..7cbdc809d5fb 100644 --- a/app/code/Magento/Eav/etc/db_schema.xml +++ b/app/code/Magento/Eav/etc/db_schema.xml @@ -458,6 +458,10 @@ <constraint xsi:type="foreign" referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID" table="eav_attribute_option_value" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/> + <constraint xsi:type="unique" referenceId="EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_OPTION_ID"> + <column name="store_id"/> + <column name="option_id"/> + </constraint> <index referenceId="EAV_ATTRIBUTE_OPTION_VALUE_OPTION_ID" indexType="btree"> <column name="option_id"/> </index> diff --git a/app/code/Magento/Eav/etc/db_schema_whitelist.json b/app/code/Magento/Eav/etc/db_schema_whitelist.json index b3f1aca50df0..3e08c44410f7 100644 --- a/app/code/Magento/Eav/etc/db_schema_whitelist.json +++ b/app/code/Magento/Eav/etc/db_schema_whitelist.json @@ -287,7 +287,8 @@ "constraint": { "PRIMARY": true, "EAV_ATTR_OPT_VAL_OPT_ID_EAV_ATTR_OPT_OPT_ID": true, - "EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID": true + "EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_STORE_STORE_ID": true, + "EAV_ATTRIBUTE_OPTION_VALUE_STORE_ID_OPTION_ID": true } }, "eav_attribute_label": { From ae2e92bcf91ac8c5efe522269344255f2cd2b21f Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 12:30:56 +0300 Subject: [PATCH 0670/1172] MAGETWO-24676: fixed adding variation from another configurable product to cart if variation belongs to same super attribute --- .../Cart/BuyRequest/SuperAttributeDataProvider.php | 5 +++++ .../AddConfigurableProductToCartTest.php | 11 +++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php index f1971e228ac0..222c81803f23 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php @@ -9,6 +9,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\Stdlib\ArrayManager; use Magento\QuoteGraphQl\Model\Cart\BuyRequest\BuyRequestDataProviderInterface; @@ -76,6 +77,10 @@ public function execute(array $cartItemData): array } catch (NoSuchEntityException $e) { throw new GraphQlNoSuchEntityException(__('Could not find specified product.')); } + $configurableProductLinks = $parentProduct->getExtensionAttributes()->getConfigurableProductLinks(); + if (!in_array($product->getId(), $configurableProductLinks)) { + throw new GraphQlInputException(__('The child product do not belong to the parent product.')); + } $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $this->optionCollection->addProductId((int)$parentProduct->getData($linkField)); $options = $this->optionCollection->getAttributesByProductId((int)$parentProduct->getData($linkField)); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php index 5ea5cef63a13..8767b3e2b904 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php @@ -141,19 +141,14 @@ public function testAddMultipleConfigurableProductToCart() } /** - * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_products.php + * @magentoApiDataFixture Magento/Catalog/_files/configurable_products_with_custom_attribute_layered_navigation.php * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php * * @expectedException Exception - * @expectedExceptionMessage You need to choose options for your item. + * @expectedExceptionMessage The child product do not belong to the parent product. */ public function testAddVariationFromAnotherConfigurableProductWithTheSameSuperAttributeToCart() { - $this->markTestSkipped( - 'Magento automatically selects the correct child product according to the super attribute - https://github.com/magento/graphql-ce/issues/940' - ); - $searchResponse = $this->graphQlQuery($this->getFetchProductQuery('configurable_12345')); $product = current($searchResponse['products']['items']); @@ -178,7 +173,7 @@ public function testAddVariationFromAnotherConfigurableProductWithTheSameSuperAt * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php * * @expectedException Exception - * @expectedExceptionMessage You need to choose options for your item. + * @expectedExceptionMessage The child product do not belong to the parent product. */ public function testAddVariationFromAnotherConfigurableProductWithDifferentSuperAttributeToCart() { From 33d81489258c765ba6d5f4c6e4f8c5f78c835f21 Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Fri, 27 Sep 2019 12:34:18 +0300 Subject: [PATCH 0671/1172] [Customer] Rename dob to date_of_birth #911 --- .../CustomerGraphQl/Model/Customer/ExtractCustomerData.php | 2 +- .../Magento/CustomerGraphQl/Model/Resolver/CreateCustomer.php | 4 +++- .../Magento/CustomerGraphQl/Model/Resolver/UpdateCustomer.php | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php index 542165b49dc1..32813d44b2d4 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php @@ -105,7 +105,7 @@ public function execute(CustomerInterface $customer): array $customerData['group_id'] = null; $customerData['model'] = $customer; $customerData['id'] = null; - + $customerData['date_of_birth'] = $customerData['dob']; return $customerData; } } diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/CreateCustomer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/CreateCustomer.php index 6d33dea35835..c690e11bd494 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/CreateCustomer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/CreateCustomer.php @@ -70,7 +70,9 @@ public function resolve( if (!$this->newsLetterConfig->isActive(ScopeInterface::SCOPE_STORE)) { $args['input']['is_subscribed'] = false; } - + if (isset($args['input']['date_of_birth'])) { + $args['input']['dob'] = $args['input']['date_of_birth']; + } $customer = $this->createCustomerAccount->execute( $args['input'], $context->getExtensionAttributes()->getStore() diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/UpdateCustomer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/UpdateCustomer.php index b2ef03fc40e5..f2b0d0e2a049 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/UpdateCustomer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/UpdateCustomer.php @@ -70,6 +70,9 @@ public function resolve( if (empty($args['input']) || !is_array($args['input'])) { throw new GraphQlInputException(__('"input" value should be specified')); } + if (isset($args['input']['date_of_birth'])) { + $args['input']['dob'] = $args['input']['date_of_birth']; + } $customer = $this->getCustomer->execute($context); $this->updateCustomerAccount->execute( From b21394fa5d4a860476c32b1d678eb577b8ac3c83 Mon Sep 17 00:00:00 2001 From: Mastiuhin Olexandr <mastiuhin.olexandr@transoftgroup.com> Date: Fri, 27 Sep 2019 13:01:50 +0300 Subject: [PATCH 0672/1172] MC-20504: Revert MC-19872 --- .../Initialization/StockDataFilter.php | 28 +- ...inBackorderAllowedAddProductToCartTest.xml | 2 + .../Initialization/StockDataFilterTest.php | 57 +-- .../Model/ResourceModel/Stock/Item.php | 43 +- .../Model/StockStateProvider.php | 33 +- .../Model/System/Config/Backend/Minqty.php | 21 +- .../Unit/Model/StockStateProviderTest.php | 223 ----------- .../Model/ResourceModel/Stock/ItemTest.php | 376 ------------------ .../System/Config/Backend/MinqtyTest.php | 67 ---- 9 files changed, 38 insertions(+), 812 deletions(-) delete mode 100644 app/code/Magento/CatalogInventory/Test/Unit/Model/StockStateProviderTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Stock/ItemTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/CatalogInventory/Model/System/Config/Backend/MinqtyTest.php diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/StockDataFilter.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/StockDataFilter.php index 47324c5b7090..f7e69bc72ea1 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/StockDataFilter.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/StockDataFilter.php @@ -7,7 +7,6 @@ use Magento\CatalogInventory\Api\StockConfigurationInterface; use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\CatalogInventory\Model\Stock; /** * Class StockDataFilter @@ -61,8 +60,8 @@ public function filter(array $stockData) $stockData['qty'] = self::MAX_QTY_VALUE; } - if (isset($stockData['min_qty'])) { - $stockData['min_qty'] = $this->purifyMinQty($stockData['min_qty'], $stockData['backorders']); + if (isset($stockData['min_qty']) && (int)$stockData['min_qty'] < 0) { + $stockData['min_qty'] = 0; } if (!isset($stockData['is_decimal_divided']) || $stockData['is_qty_decimal'] == 0) { @@ -71,27 +70,4 @@ public function filter(array $stockData) return $stockData; } - - /** - * Purifies min_qty. - * - * @param int $minQty - * @param int $backOrders - * @return float - */ - private function purifyMinQty(int $minQty, int $backOrders): float - { - /** - * As described in the documentation if the Backorders Option is disabled - * it is recommended to set the Out Of Stock Threshold to a positive number. - * That's why to clarify the logic to the end user the code below prevent him to set a negative number so such - * a number will turn to zero. - * @see https://docs.magento.com/m2/ce/user_guide/catalog/inventory-backorders.html - */ - if ($backOrders === Stock::BACKORDERS_NO && $minQty < 0) { - $minQty = 0; - } - - return (float)$minQty; - } } diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml index 679cab4159eb..88c524eff387 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminBackorderAllowedAddProductToCartTest.xml @@ -23,11 +23,13 @@ <createData entity="SimpleProductInStockQuantityZero" stepKey="createProduct"/> <!-- Configure Magento to show out of stock products and to allow backorders --> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockEnable.path}} {{CatalogInventoryOptionsShowOutOfStockEnable.value}}" stepKey="setConfigShowOutOfStockTrue"/> <magentoCLI command="config:set {{CatalogInventoryItemOptionsBackordersEnable.path}} {{CatalogInventoryItemOptionsBackordersEnable.value}}" stepKey="setConfigAllowBackordersTrue"/> </before> <after> <!-- Set Magento back to default configuration --> + <magentoCLI command="config:set {{CatalogInventoryOptionsShowOutOfStockDisable.path}} {{CatalogInventoryOptionsShowOutOfStockDisable.value}}" stepKey="setConfigShowOutOfStockFalse"/> <magentoCLI command="config:set {{CatalogInventoryItemOptionsBackordersDisable.path}} {{CatalogInventoryItemOptionsBackordersDisable.value}}" stepKey="setConfigAllowBackordersFalse"/> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> </after> diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/StockDataFilterTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/StockDataFilterTest.php index cb23d0c0a9a2..0214de8120ba 100644 --- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/StockDataFilterTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/StockDataFilterTest.php @@ -6,15 +6,11 @@ namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Initialization; use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter; -use Magento\CatalogInventory\Model\Stock; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\CatalogInventory\Model\Configuration; -use PHPUnit\Framework\TestCase; /** - * StockDataFilter test. + * Class StockDataFilterTest */ -class StockDataFilterTest extends TestCase +class StockDataFilterTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit_Framework_MockObject_MockObject @@ -31,23 +27,17 @@ class StockDataFilterTest extends TestCase */ protected $stockDataFilter; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ + /** @var \PHPUnit_Framework_MockObject_MockObject */ protected $stockConfiguration; - /** - * @inheritdoc - */ protected function setUp() { - $this->scopeConfigMock = $this->createMock(ScopeConfigInterface::class); + $this->scopeConfigMock = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); - $this->scopeConfigMock->method('getValue') - ->will($this->returnValue(1)); + $this->scopeConfigMock->expects($this->any())->method('getValue')->will($this->returnValue(1)); $this->stockConfiguration = $this->createPartialMock( - Configuration::class, + \Magento\CatalogInventory\Model\Configuration::class, ['getManageStock'] ); @@ -55,11 +45,8 @@ protected function setUp() } /** - * Tests filter method. - * * @param array $inputStockData * @param array $outputStockData - * @return void * * @covers \Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter::filter * @dataProvider filterDataProvider @@ -67,7 +54,8 @@ protected function setUp() public function testFilter(array $inputStockData, array $outputStockData) { if (isset($inputStockData['use_config_manage_stock']) && $inputStockData['use_config_manage_stock'] === 1) { - $this->stockConfiguration->method('getManageStock') + $this->stockConfiguration->expects($this->once()) + ->method('getManageStock') ->will($this->returnValue($outputStockData['manage_stock'])); } @@ -105,13 +93,8 @@ public function filterDataProvider() ], ], 'case4' => [ - 'inputStockData' => ['min_qty' => -1, 'backorders' => Stock::BACKORDERS_NO], - 'outputStockData' => [ - 'min_qty' => 0, - 'is_decimal_divided' => 0, - 'use_config_manage_stock' => 0, - 'backorders' => Stock::BACKORDERS_NO, - ], + 'inputStockData' => ['min_qty' => -1], + 'outputStockData' => ['min_qty' => 0, 'is_decimal_divided' => 0, 'use_config_manage_stock' => 0], ], 'case5' => [ 'inputStockData' => ['is_qty_decimal' => 0], @@ -120,25 +103,7 @@ public function filterDataProvider() 'is_decimal_divided' => 0, 'use_config_manage_stock' => 0, ], - ], - 'case6' => [ - 'inputStockData' => ['min_qty' => -1, 'backorders' => Stock::BACKORDERS_YES_NONOTIFY], - 'outputStockData' => [ - 'min_qty' => -1, - 'is_decimal_divided' => 0, - 'use_config_manage_stock' => 0, - 'backorders' => Stock::BACKORDERS_YES_NONOTIFY, - ], - ], - 'case7' => [ - 'inputStockData' => ['min_qty' => -1, 'backorders' => Stock::BACKORDERS_YES_NOTIFY], - 'outputStockData' => [ - 'min_qty' => -1, - 'is_decimal_divided' => 0, - 'use_config_manage_stock' => 0, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - ], - ], + ] ]; } } diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php index 3a214bd8cd7c..edccad60231e 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php @@ -14,7 +14,6 @@ use Magento\Framework\DB\Select; use Magento\Framework\App\ObjectManager; use Magento\Framework\Stdlib\DateTime\DateTime; -use Zend_Db_Expr; /** * Stock item resource model @@ -184,12 +183,16 @@ public function updateSetOutOfStock(int $websiteId) 'is_in_stock = ' . Stock::STOCK_IN_STOCK, '(use_config_manage_stock = 1 AND 1 = ' . $this->stockConfiguration->getManageStock() . ')' . ' OR (use_config_manage_stock = 0 AND manage_stock = 1)', - '(' . $this->getBackordersExpr() .' = 0 AND qty <= ' . $this->getMinQtyExpr() . ')' - . ' OR (' . $this->getBackordersExpr() .' != 0 AND ' - . $this->getMinQtyExpr() . ' != 0 AND qty <= ' . $this->getMinQtyExpr() . ')', + '(use_config_min_qty = 1 AND qty <= ' . $this->stockConfiguration->getMinQty() . ')' + . ' OR (use_config_min_qty = 0 AND qty <= min_qty)', 'product_id IN (' . $select->assemble() . ')', ]; - + $backordersWhere = '(use_config_backorders = 0 AND backorders = ' . Stock::BACKORDERS_NO . ')'; + if (Stock::BACKORDERS_NO == $this->stockConfiguration->getBackorders()) { + $where[] = $backordersWhere . ' OR use_config_backorders = 1'; + } else { + $where[] = $backordersWhere; + } $connection->update($this->getMainTable(), $values, $where); $this->stockIndexerProcessor->markIndexerAsInvalid(); @@ -212,8 +215,8 @@ public function updateSetInStock(int $websiteId) $where = [ 'website_id = ' . $websiteId, 'stock_status_changed_auto = 1', - '(qty > ' . $this->getMinQtyExpr() . ')' - . ' OR (' . $this->getBackordersExpr() . ' != 0 AND ' . $this->getMinQtyExpr() . ' = 0)', // If infinite + '(use_config_min_qty = 1 AND qty > ' . $this->stockConfiguration->getMinQty() . ')' + . ' OR (use_config_min_qty = 0 AND qty > min_qty)', 'product_id IN (' . $select->assemble() . ')', ]; $manageStockWhere = '(use_config_manage_stock = 0 AND manage_stock = 1)'; @@ -301,12 +304,12 @@ public function getBackordersExpr(string $tableAlias = ''): \Zend_Db_Expr } /** - * Get Minimum Sale Quantity Expression. + * Get Minimum Sale Quantity Expression * * @param string $tableAlias - * @return Zend_Db_Expr + * @return \Zend_Db_Expr */ - public function getMinSaleQtyExpr(string $tableAlias = ''): Zend_Db_Expr + public function getMinSaleQtyExpr(string $tableAlias = ''): \Zend_Db_Expr { if ($tableAlias) { $tableAlias .= '.'; @@ -320,26 +323,6 @@ public function getMinSaleQtyExpr(string $tableAlias = ''): Zend_Db_Expr return $itemMinSaleQty; } - /** - * Get Min Qty Expression - * - * @param string $tableAlias - * @return Zend_Db_Expr - */ - public function getMinQtyExpr(string $tableAlias = ''): Zend_Db_Expr - { - if ($tableAlias) { - $tableAlias .= '.'; - } - $itemBackorders = $this->getConnection()->getCheckSql( - $tableAlias . 'use_config_min_qty = 1', - $this->stockConfiguration->getMinQty(), - $tableAlias . 'min_qty' - ); - - return $itemBackorders; - } - /** * Build select for products with types from config * diff --git a/app/code/Magento/CatalogInventory/Model/StockStateProvider.php b/app/code/Magento/CatalogInventory/Model/StockStateProvider.php index 74271cdd97bf..6851b05aa56a 100644 --- a/app/code/Magento/CatalogInventory/Model/StockStateProvider.php +++ b/app/code/Magento/CatalogInventory/Model/StockStateProvider.php @@ -72,31 +72,14 @@ public function __construct( */ public function verifyStock(StockItemInterface $stockItem) { - // Manage stock, but qty is null if ($stockItem->getQty() === null && $stockItem->getManageStock()) { return false; } - - // Backorders are not allowed and qty reached min qty if ($stockItem->getBackorders() == StockItemInterface::BACKORDERS_NO && $stockItem->getQty() <= $stockItem->getMinQty() ) { return false; } - - $backordersAllowed = [Stock::BACKORDERS_YES_NONOTIFY, Stock::BACKORDERS_YES_NOTIFY]; - if (in_array($stockItem->getBackorders(), $backordersAllowed)) { - // Infinite - let it be In stock - if ($stockItem->getMinQty() == 0) { - return true; - } - - // qty reached min qty - let it stand Out Of Stock - if ($stockItem->getQty() <= $stockItem->getMinQty()) { - return false; - } - } - return true; } @@ -262,17 +245,15 @@ public function checkQty(StockItemInterface $stockItem, $qty) if (!$stockItem->getManageStock()) { return true; } - - $backordersAllowed = [Stock::BACKORDERS_YES_NONOTIFY, Stock::BACKORDERS_YES_NOTIFY]; - // Infinite check - if ($stockItem->getMinQty() == 0 && in_array($stockItem->getBackorders(), $backordersAllowed)) { - return true; - } - if ($stockItem->getQty() - $stockItem->getMinQty() - $qty < 0) { - return false; + switch ($stockItem->getBackorders()) { + case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NONOTIFY: + case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NOTIFY: + break; + default: + return false; + } } - return true; } diff --git a/app/code/Magento/CatalogInventory/Model/System/Config/Backend/Minqty.php b/app/code/Magento/CatalogInventory/Model/System/Config/Backend/Minqty.php index 268f1846161d..f49d41b5dd65 100644 --- a/app/code/Magento/CatalogInventory/Model/System/Config/Backend/Minqty.php +++ b/app/code/Magento/CatalogInventory/Model/System/Config/Backend/Minqty.php @@ -6,36 +6,21 @@ namespace Magento\CatalogInventory\Model\System\Config\Backend; -use Magento\CatalogInventory\Model\Stock; - /** - * Minimum product qty backend model. + * Minimum product qty backend model */ class Minqty extends \Magento\Framework\App\Config\Value { /** - * Validate minimum product qty value. + * Validate minimum product qty value * * @return $this */ public function beforeSave() { parent::beforeSave(); - $minQty = (float)$this->getValue(); - - /** - * As described in the documentation if the Backorders Option is disabled - * it is recommended to set the Out Of Stock Threshold to a positive number. - * That's why to clarify the logic to the end user the code below prevent him to set a negative number so such - * a number will turn to zero. - * @see https://docs.magento.com/m2/ce/user_guide/catalog/inventory-backorders.html - */ - if ($this->getFieldsetDataValue("backorders") == Stock::BACKORDERS_NO && $minQty < 0) { - $minQty = 0; - } - + $minQty = (int) $this->getValue() >= 0 ? (int) $this->getValue() : (int) $this->getOldValue(); $this->setValue((string) $minQty); - return $this; } } diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/StockStateProviderTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/StockStateProviderTest.php deleted file mode 100644 index 942d77063a8e..000000000000 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/StockStateProviderTest.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Test\Unit\Model; - -use PHPUnit\Framework\TestCase; -use Magento\CatalogInventory\Model\StockStateProvider; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -use Magento\CatalogInventory\Api\Data\StockItemInterface; -use Magento\CatalogInventory\Model\Stock; - -/** - * StockRegistry test. - */ -class StockStateProviderTest extends TestCase -{ - /** - * @var ObjectManager - */ - private $objectManager; - - /** - * @var StockStateProvider - */ - private $model; - - /** - * @var StockItemInterface|\PHPUnit\Framework\MockObject\MockObject - */ - private $stockItem; - - /** - * @inheritdoc - */ - protected function setUp() - { - $this->objectManager = new ObjectManager($this); - - $this->stockItem = $this->getMockBuilder(StockItemInterface::class) - ->getMock(); - - $this->model = $this->objectManager->getObject(StockStateProvider::class); - } - - /** - * Tests verifyStock method. - * - * @param int $qty - * @param int $backOrders - * @param int $minQty - * @param int $manageStock - * @param int $expected - * - * @return void - * - * @dataProvider stockItemDataProvider - * @covers \Magento\CatalogInventory\Model\StockStateProvider::verifyStock - */ - public function testVerifyStock( - ?int $qty, - ?int $backOrders, - ?int $minQty, - ?int $manageStock, - bool $expected - ): void { - $this->stockItem->method('getQty') - ->willReturn($qty); - $this->stockItem->method('getBackOrders') - ->willReturn($backOrders); - $this->stockItem->method('getMinQty') - ->willReturn($minQty); - $this->stockItem->method('getManageStock') - ->willReturn($manageStock); - - $result = $this->model->verifyStock($this->stockItem); - - self::assertEquals($expected, $result); - } - - /** - * StockItem data provider. - * - * @return array - */ - public function stockItemDataProvider(): array - { - return [ - 'qty_is_null_manage_stock_on' => [ - 'qty' => null, - 'backorders' => null, - 'min_qty' => null, - 'manage_stock' => 1, - 'expected' => false, - ], - 'qty_reached_threshold_without_backorders' => [ - 'qty' => 3, - 'backorders' => Stock::BACKORDERS_NO, - 'min_qty' => 3, - 'manage_stock' => 1, - 'expected' => false, - ], - 'backorders_are_ininite' => [ - 'qty' => -100, - 'backorders' => Stock::BACKORDERS_YES_NONOTIFY, - 'min_qty' => 0, - 'manage_stock' => 1, - 'expected' => true, - ], - 'limited_backorders_and_qty_reached_threshold' => [ - 'qty' => -100, - 'backorders' => Stock::BACKORDERS_YES_NONOTIFY, - 'min_qty' => -100, - 'manage_stock' => 1, - 'expected' => false, - ], - 'qty_not_yet_reached_threshold_1' => [ - 'qty' => -99, - 'backorders' => Stock::BACKORDERS_YES_NONOTIFY, - 'min_qty' => -100, - 'manage_stock' => 1, - 'expected' => true, - ], - 'qty_not_yet_reached_threshold_2' => [ - 'qty' => 1, - 'backorders' => Stock::BACKORDERS_NO, - 'min_qty' => 0, - 'manage_stock' => 1, - 'expected' => true, - ], - ]; - } - - /** - * Tests checkQty method. - * - * @return void - * - * @dataProvider stockItemAndQtyDataProvider - * @covers \Magento\CatalogInventory\Model\StockStateProvider::verifyStock - */ - public function testCheckQty( - bool $manageStock, - int $qty, - int $minQty, - int $backOrders, - int $orderQty, - bool $expected - ): void { - $this->stockItem->method('getManageStock') - ->willReturn($manageStock); - $this->stockItem->method('getQty') - ->willReturn($qty); - $this->stockItem->method('getMinQty') - ->willReturn($minQty); - $this->stockItem->method('getBackOrders') - ->willReturn($backOrders); - - $result = $this->model->checkQty($this->stockItem, $orderQty); - - self::assertEquals($expected, $result); - } - - /** - * StockItem and qty data provider. - * - * @return array - */ - public function stockItemAndQtyDataProvider(): array - { - return [ - 'disabled_manage_stock' => [ - 'manage_stock' => false, - 'qty' => 0, - 'min_qty' => 0, - 'backorders' => 0, - 'order_qty' => 0, - 'expected' => true, - ], - 'infinite_backorders' => [ - 'manage_stock' => true, - 'qty' => -100, - 'min_qty' => 0, - 'backorders' => Stock::BACKORDERS_YES_NONOTIFY, - 'order_qty' => 100, - 'expected' => true, - ], - 'qty_reached_threshold' => [ - 'manage_stock' => true, - 'qty' => -100, - 'min_qty' => -100, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - 'order_qty' => 1, - 'expected' => false, - ], - 'qty_yet_not_reached_threshold' => [ - 'manage_stock' => true, - 'qty' => -100, - 'min_qty' => -100, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - 'order_qty' => 1, - 'expected' => false, - ] - ]; - } - - /** - * Tests checkQty method when check is not applicable. - * - * @return void - */ - public function testCheckQtyWhenCheckIsNotApplicable(): void - { - $model = $this->objectManager->getObject(StockStateProvider::class, ['qtyCheckApplicable' => false]); - - $result = $model->checkQty($this->stockItem, 3); - - self::assertTrue($result); - } -} diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Stock/ItemTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Stock/ItemTest.php deleted file mode 100644 index 460f43d816e3..000000000000 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Stock/ItemTest.php +++ /dev/null @@ -1,376 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Model\ResourceModel\Stock; - -use PHPUnit\Framework\TestCase; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\CatalogInventory\Api\StockItemRepositoryInterface; -use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory; -use Magento\CatalogInventory\Api\Data\StockItemInterface; -use Magento\CatalogInventory\Api\StockConfigurationInterface; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\CatalogInventory\Model\Stock; -use Magento\TestFramework\App\Config; -use Magento\Store\Model\ScopeInterface; -use Magento\CatalogInventory\Model\Configuration; - -/** - * Item test. - * - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - */ -class ItemTest extends TestCase -{ - /** - * @var \Magento\Framework\ObjectManagerInterface - */ - private $objectManager; - - /** - * @var Item - */ - private $stockItemResourceModel; - - /** - * @var ProductRepositoryInterface - */ - private $productRepository; - - /** - * @var StockItemRepositoryInterface - */ - private $stockItemRepository; - - /** - * @var StockItemCriteriaInterfaceFactory - */ - private $stockItemCriteriaFactory; - - /** - * @var StockConfigurationInterface - */ - private $stockConfiguration; - - /** - * @var Config - */ - private $config; - - /** - * Saved Stock Status Item data. - * - * @var array - */ - private $stockStatusData; - - /** - * Saved system config data. - * - * @var array - */ - private $configData; - - /** - * @inheritdoc - */ - protected function setUp() - { - $this->objectManager = Bootstrap::getObjectManager(); - - $this->stockItemResourceModel = $this->objectManager->get(Item::class); - $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); - $this->stockItemRepository = $this->objectManager->get(StockItemRepositoryInterface::class); - $this->stockItemCriteriaFactory = $this->objectManager->get(StockItemCriteriaInterfaceFactory::class); - $this->stockConfiguration = $this->objectManager->get(StockConfigurationInterface::class); - $this->config = $this->objectManager->get(Config::class); - - $this->storeSystemConfig(); - } - - /** - * @inheritdoc - */ - protected function tearDown() - { - $this->restoreSystemConfig(); - } - - /** - * Tests updateSetOutOfStock method. - * - * @return void - * - * @magentoDataFixture Magento/Catalog/_files/product_simple.php - */ - public function testUpdateSetOutOfStock(): void - { - $stockItem = $this->getStockItem(1); - $this->saveStockItemData($stockItem); - $this->storeSystemConfig(); - - foreach ($this->stockStatusVariations() as $variation) { - /** - * Check when Stock Item use it's own configuration of backorders. - */ - $this->configureStockItem($stockItem, $variation); - $this->stockItemResourceModel->updateSetOutOfStock($this->stockConfiguration->getDefaultScopeId()); - $stockItem = $this->getStockItem(1); - - self::assertEquals($variation['is_in_stock'], $stockItem->getIsInStock(), $variation['message']); - $stockItem = $this->resetStockItem($stockItem); - - /** - * Check when Stock Item use system configuration of backorders. - */ - $this->configureStockItemWithSystemConfig($stockItem, $variation); - $this->stockItemResourceModel->updateSetOutOfStock($this->stockConfiguration->getDefaultScopeId()); - $stockItem = $this->getStockItem(1); - - self::assertEquals($variation['is_in_stock'], $stockItem->getIsInStock(), $variation['message']); - $stockItem = $this->resetStockItem($stockItem); - $this->restoreSystemConfig(); - } - } - - /** - * Tests updateSetInOfStock method. - * - * @return void - * - * @magentoDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php - */ - public function testUpdateSetInStock(): void - { - $product = $this->productRepository->get('simple-out-of-stock'); - $stockItem = $this->getStockItem((int)$product->getId()); - $this->saveStockItemData($stockItem); - $this->storeSystemConfig(); - - foreach ($this->stockStatusVariations() as $variation) { - /** - * Check when Stock Item use it's own configuration of backorders. - */ - $stockItem->setStockStatusChangedAutomaticallyFlag(true); - $this->configureStockItem($stockItem, $variation); - $this->stockItemResourceModel->updateSetInStock($this->stockConfiguration->getDefaultScopeId()); - $stockItem = $this->getStockItem((int)$product->getId()); - - self::assertEquals($variation['is_in_stock'], $stockItem->getIsInStock(), $variation['message']); - $stockItem = $this->resetStockItem($stockItem); - - /** - * Check when Stock Item use the system configuration of backorders. - */ - $stockItem->setStockStatusChangedAuto(1); - $this->configureStockItemWithSystemConfig($stockItem, $variation); - $this->stockItemResourceModel->updateSetInStock($this->stockConfiguration->getDefaultScopeId()); - $stockItem = $this->getStockItem((int)$product->getId()); - - self::assertEquals($variation['is_in_stock'], $stockItem->getIsInStock(), $variation['message']); - $stockItem = $this->resetStockItem($stockItem); - $this->restoreSystemConfig(); - } - } - - /** - * Configure backorders feature for Stock Item. - * - * @param StockItemInterface $stockItem - * @param array $config - * @return void - */ - private function configureStockItem(StockItemInterface $stockItem, array $config): void - { - /** - * Configuring Stock Item to use it's own configuration. - */ - $stockItem->setUseConfigBackorders(0); - $stockItem->setUseConfigMinQty(0); - $stockItem->setQty($config['qty']); - $stockItem->setMinQty($config['min_qty']); - $stockItem->setBackorders($config['backorders']); - - $this->stockItemRepository->save($stockItem); - } - - /** - * Configure backorders feature using the system configuration for Stock Item. - * - * @param StockItemInterface $stockItem - * @param array $config - * @return void - */ - private function configureStockItemWithSystemConfig(StockItemInterface $stockItem, array $config): void - { - /** - * Configuring Stock Item to use the system configuration. - */ - $stockItem->setUseConfigBackorders(1); - $stockItem->setUseConfigMinQty(1); - - $this->config->setValue( - Configuration::XML_PATH_BACKORDERS, - $config['backorders'], - ScopeInterface::SCOPE_STORE - ); - $this->config->setValue( - Configuration::XML_PATH_MIN_QTY, - $config['min_qty'], - ScopeInterface::SCOPE_STORE - ); - - $stockItem->setQty($config['qty']); - - $this->stockItemRepository->save($stockItem); - } - - /** - * Stock status variations. - * - * @return array - */ - private function stockStatusVariations(): array - { - return [ - // Quantity has not reached Threshold - [ - 'qty' => 3, - 'min_qty' => 2, - 'backorders' => Stock::BACKORDERS_NO, - 'is_in_stock' => true, - 'message' => "Stock status should be In Stock - v.1", - ], - // Quantity has reached Threshold - [ - 'qty' => 3, - 'min_qty' => 3, - 'backorders' => Stock::BACKORDERS_NO, - 'is_in_stock' => false, - 'message' => "Stock status should be Out of Stock - v.2", - ], - // Infinite backorders - [ - 'qty' => -100, - 'min_qty' => 0, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - 'is_in_stock' => true, - 'message' => "Stock status should be In Stock for infinite backorders - v.3", - ], - // Quantity has not reached Threshold's negative value - [ - 'qty' => -99, - 'min_qty' => -100, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - 'is_in_stock' => true, - 'message' => "Stock status should be In Stock - v.4", - ], - // Quantity has reached Threshold's negative value - [ - 'qty' => -100, - 'min_qty' => -99, - 'backorders' => Stock::BACKORDERS_YES_NOTIFY, - 'is_in_stock' => false, - 'message' => "Stock status should be Out of Stock - v.5", - ], - ]; - } - - /** - * Stores Stock Item values. - * - * @param StockItemInterface $stockItem - * @return void - */ - private function saveStockItemData(StockItemInterface $stockItem): void - { - $this->stockStatusData = $stockItem->getData(); - } - - /** - * Resets Stock Item to previous saved values and prepare for new test variation. - * - * @param StockItemInterface $stockItem - * @return StockItemInterface - */ - private function resetStockItem(StockItemInterface $stockItem): StockItemInterface - { - $stockItem->setData($this->stockStatusData); - - return $this->stockItemRepository->save($stockItem); - } - - /** - * Get Stock Item by product id. - * - * @param int $productId - * @param int|null $scope - * @return StockItemInterface - * @throws NoSuchEntityException - */ - private function getStockItem(int $productId, ?int $scope = null): StockItemInterface - { - $scope = $scope ?? $this->stockConfiguration->getDefaultScopeId(); - $stockItemCriteria = $this->stockItemCriteriaFactory->create(); - $stockItemCriteria->setScopeFilter($scope); - $stockItemCriteria->setProductsFilter([$productId]); - $stockItems = $this->stockItemRepository->getList($stockItemCriteria); - $stockItems = $stockItems->getItems(); - - if (empty($stockItems)) { - throw new NoSuchEntityException(); - } - - $stockItem = reset($stockItems); - - return $stockItem; - } - - /** - * Stores system configuration. - * - * @return void - */ - private function storeSystemConfig(): void - { - /** - * Save system configuration data. - */ - $backorders = $this->config->getValue( - Configuration::XML_PATH_BACKORDERS, - ScopeInterface::SCOPE_STORE - ); - $minQty = $this->config->getValue(Configuration::XML_PATH_MIN_QTY, ScopeInterface::SCOPE_STORE); - $this->configData = [ - 'backorders' => $backorders, - 'min_qty' => $minQty, - ]; - } - - /** - * Restores system configuration. - * - * @return void - */ - private function restoreSystemConfig(): void - { - /** - * Turn back system configuration. - */ - $this->config->setValue( - Configuration::XML_PATH_BACKORDERS, - $this->configData['backorders'], - ScopeInterface::SCOPE_STORE - ); - $this->config->setValue( - Configuration::XML_PATH_MIN_QTY, - $this->configData['min_qty'], - ScopeInterface::SCOPE_STORE - ); - } -} diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/System/Config/Backend/MinqtyTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/System/Config/Backend/MinqtyTest.php deleted file mode 100644 index c053d38fea1f..000000000000 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/System/Config/Backend/MinqtyTest.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ -declare(strict_types=1); - -namespace Magento\CatalogInventory\Model\System\Config\Backend; - -use PHPUnit\Framework\TestCase; -use Magento\TestFramework\Helper\Bootstrap; -use Magento\CatalogInventory\Model\Stock; - -/** - * Minqty test. - */ -class MinqtyTest extends TestCase -{ - /** - * @var Minqty - */ - private $minQtyConfig; - - /** - * @inheritdoc - */ - protected function setUp() - { - $objectManager = Bootstrap::getObjectManager(); - $this->minQtyConfig = $objectManager->create(Minqty::class); - $this->minQtyConfig->setPath('cataloginventory/item_options/min_qty'); - } - - /** - * Tests beforeSave method. - * - * @param string $value - * @param array $fieldSetData - * @param string $expected - * @return void - * - * @dataProvider minQtyConfigDataProvider - */ - public function testBeforeSave(string $value, array $fieldSetData, string $expected): void - { - $this->minQtyConfig->setData('fieldset_data', $fieldSetData); - $this->minQtyConfig->setValue($value); - $this->minQtyConfig->beforeSave(); - $this->assertEquals($expected, $this->minQtyConfig->getValue()); - } - - /** - * Minqty config data provider. - * - * @return array - */ - public function minQtyConfigDataProvider(): array - { - return [ - 'straight' => ['3', ['backorders' => Stock::BACKORDERS_NO], '3'], - 'straight2' => ['3.5', ['backorders' => Stock::BACKORDERS_NO], '3.5'], - 'negative_value_disabled_backorders' => ['-3', ['backorders' => Stock::BACKORDERS_NO], '0'], - 'negative_value_enabled_backorders' => ['-3', ['backorders' => Stock::BACKORDERS_YES_NOTIFY], '-3'], - 'negative_value_enabled_backorders2' => ['-3.05', ['backorders' => Stock::BACKORDERS_YES_NOTIFY], '-3.05'], - ]; - } -} From add665147ca9c1dde66e6b33070a08a38288a15d Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 13:21:09 +0300 Subject: [PATCH 0673/1172] MAGETWO-24676: fixed exception message --- .../Model/Cart/BuyRequest/SuperAttributeDataProvider.php | 2 +- .../ConfigurableProduct/AddConfigurableProductToCartTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php b/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php index 222c81803f23..4a613254ddf8 100644 --- a/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php +++ b/app/code/Magento/ConfigurableProductGraphQl/Model/Cart/BuyRequest/SuperAttributeDataProvider.php @@ -79,7 +79,7 @@ public function execute(array $cartItemData): array } $configurableProductLinks = $parentProduct->getExtensionAttributes()->getConfigurableProductLinks(); if (!in_array($product->getId(), $configurableProductLinks)) { - throw new GraphQlInputException(__('The child product do not belong to the parent product.')); + throw new GraphQlInputException(__('Could not find specified product.')); } $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $this->optionCollection->addProductId((int)$parentProduct->getData($linkField)); diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php index 8767b3e2b904..39b69f86cbe1 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/AddConfigurableProductToCartTest.php @@ -145,7 +145,7 @@ public function testAddMultipleConfigurableProductToCart() * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php * * @expectedException Exception - * @expectedExceptionMessage The child product do not belong to the parent product. + * @expectedExceptionMessage Could not find specified product. */ public function testAddVariationFromAnotherConfigurableProductWithTheSameSuperAttributeToCart() { @@ -173,7 +173,7 @@ public function testAddVariationFromAnotherConfigurableProductWithTheSameSuperAt * @magentoApiDataFixture Magento/Checkout/_files/active_quote.php * * @expectedException Exception - * @expectedExceptionMessage The child product do not belong to the parent product. + * @expectedExceptionMessage Could not find specified product. */ public function testAddVariationFromAnotherConfigurableProductWithDifferentSuperAttributeToCart() { From 3846ddd8b04cdbd027ad8b5625767c3dbbdc4436 Mon Sep 17 00:00:00 2001 From: Vaha <vaha@atwix.com> Date: Fri, 27 Sep 2019 13:48:07 +0300 Subject: [PATCH 0674/1172] magento/magento2# improved getCustomerName method, added prefix, middlename, suffix if configure --- app/code/Magento/Sales/Model/Order.php | 84 +++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php index 48deddb2fe5a..062c51bef9c0 100644 --- a/app/code/Magento/Sales/Model/Order.php +++ b/app/code/Magento/Sales/Model/Order.php @@ -5,8 +5,11 @@ */ namespace Magento\Sales\Model; +use Magento\Config\Model\Config\Source\Nooptreq; use Magento\Directory\Model\Currency; use Magento\Framework\Api\AttributeValueFactory; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Locale\ResolverInterface; @@ -14,6 +17,7 @@ use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Api\Data\OrderStatusHistoryInterface; +use Magento\Sales\Api\OrderItemRepositoryInterface; use Magento\Sales\Model\Order\Payment; use Magento\Sales\Model\Order\ProductOption; use Magento\Sales\Model\ResourceModel\Order\Address\Collection; @@ -24,8 +28,7 @@ use Magento\Sales\Model\ResourceModel\Order\Shipment\Collection as ShipmentCollection; use Magento\Sales\Model\ResourceModel\Order\Shipment\Track\Collection as TrackCollection; use Magento\Sales\Model\ResourceModel\Order\Status\History\Collection as HistoryCollection; -use Magento\Sales\Api\OrderItemRepositoryInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Store\Model\ScopeInterface; /** * Order model @@ -299,6 +302,11 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface */ private $searchCriteriaBuilder; + /** + * @var ScopeConfigInterface; + */ + private $scopeConfig; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -331,6 +339,7 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface * @param ProductOption|null $productOption * @param OrderItemRepositoryInterface $itemRepository * @param SearchCriteriaBuilder $searchCriteriaBuilder + * @param ScopeConfigInterface $scopeConfig * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -364,7 +373,8 @@ public function __construct( ResolverInterface $localeResolver = null, ProductOption $productOption = null, OrderItemRepositoryInterface $itemRepository = null, - SearchCriteriaBuilder $searchCriteriaBuilder = null + SearchCriteriaBuilder $searchCriteriaBuilder = null, + ScopeConfigInterface $scopeConfig = null ) { $this->_storeManager = $storeManager; $this->_orderConfig = $orderConfig; @@ -392,6 +402,7 @@ public function __construct( ->get(OrderItemRepositoryInterface::class); $this->searchCriteriaBuilder = $searchCriteriaBuilder ?: ObjectManager::getInstance() ->get(SearchCriteriaBuilder::class); + $this->scopeConfig = $scopeConfig ?: ObjectManager::getInstance()->get(ScopeConfigInterface::class); parent::__construct( $context, @@ -1111,7 +1122,7 @@ public function addStatusHistoryComment($comment, $status = false) { return $this->addCommentToStatusHistory($comment, $status, false); } - + /** * Add a comment to order status history. * @@ -1965,16 +1976,71 @@ public function getRelatedObjects() * * @return string */ - public function getCustomerName() + public function getCustomerName(): string { - if ($this->getCustomerFirstname()) { - $customerName = $this->getCustomerFirstname() . ' ' . $this->getCustomerLastname(); - } else { - $customerName = (string)__('Guest'); + if (null === $this->getCustomerFirstname()) { + return (string)__('Guest'); + } + + $customerName = ''; + if ($this->isVisibleCustomerPrefix() && strlen($this->getCustomerPrefix())) { + $customerName .= $this->getCustomerPrefix() . ' '; + } + $customerName .= $this->getCustomerFirstname(); + if ($this->isVisibleCustomerMiddlename() && strlen($this->getCustomerMiddlename())) { + $customerName .= ' ' . $this->getCustomerMiddlename(); + } + $customerName .= ' ' . $this->getCustomerLastname(); + if ($this->isVisibleCustomerSuffix() && strlen($this->getCustomerSuffix())) { + $customerName .= ' ' . $this->getCustomerSuffix(); } + return $customerName; } + /** + * Is visible customer middlename + * + * @return bool + */ + private function isVisibleCustomerMiddlename(): bool + { + return $this->scopeConfig->isSetFlag( + 'customer/address/middlename_show', + ScopeInterface::SCOPE_STORE + ); + } + + /** + * Is visible customer prefix + * + * @return bool + */ + private function isVisibleCustomerPrefix(): bool + { + $prefixShowValue = $this->scopeConfig->getValue( + 'customer/address/prefix_show', + ScopeInterface::SCOPE_STORE + ); + + return $prefixShowValue !== Nooptreq::VALUE_NO; + } + + /** + * Is visible customer suffix + * + * @return bool + */ + private function isVisibleCustomerSuffix(): bool + { + $prefixShowValue = $this->scopeConfig->getValue( + 'customer/address/suffix_show', + ScopeInterface::SCOPE_STORE + ); + + return $prefixShowValue !== Nooptreq::VALUE_NO; + } + /** * Add New object to related array * From adb6517d6db8e16671664c0c26b6a9770d872a7f Mon Sep 17 00:00:00 2001 From: Ievgenii Gryshkun <i.gryshkun@gmail.com> Date: Fri, 27 Sep 2019 13:58:17 +0300 Subject: [PATCH 0675/1172] [Customer] Rename dob to date_of_birth #911 --- .../CustomerGraphQl/Model/Customer/ExtractCustomerData.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php index 32813d44b2d4..ac074d543fec 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php @@ -105,7 +105,9 @@ public function execute(CustomerInterface $customer): array $customerData['group_id'] = null; $customerData['model'] = $customer; $customerData['id'] = null; - $customerData['date_of_birth'] = $customerData['dob']; + if (!empty($customerData['dob'])) { + $customerData['date_of_birth'] = $customerData['dob']; + } return $customerData; } } From dfd481d22616708a7e55d7b8757581e90ba4f41c Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Thu, 26 Sep 2019 12:58:06 +0300 Subject: [PATCH 0676/1172] magento/magento2#24043: Better exception handling during cli commands. --- .../Magento/Framework/Console/Cli.php | 11 ++- .../Framework/Console/Test/Unit/CliTest.php | 81 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 lib/internal/Magento/Framework/Console/Test/Unit/CliTest.php diff --git a/lib/internal/Magento/Framework/Console/Cli.php b/lib/internal/Magento/Framework/Console/Cli.php index 34fd6316ce45..6aab9c03ff7b 100644 --- a/lib/internal/Magento/Framework/Console/Cli.php +++ b/lib/internal/Magento/Framework/Console/Cli.php @@ -19,6 +19,7 @@ use Magento\Setup\Application; use Magento\Setup\Console\CompilerPreparation; use Magento\Setup\Model\ObjectManagerProvider; +use Psr\Log\LoggerInterface; use Symfony\Component\Console; use Magento\Framework\Config\ConfigOptionsListConstants; @@ -61,6 +62,11 @@ class Cli extends Console\Application */ private $objectManager; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param string $name the application name * @param string $version the application version @@ -94,6 +100,7 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') parent::__construct($name, $version); $this->serviceManager->setService(\Symfony\Component\Console\Application::class, $this); + $this->logger = $this->objectManager->get(LoggerInterface::class); } /** @@ -107,7 +114,9 @@ public function doRun(Console\Input\InputInterface $input, Console\Output\Output try { $exitCode = parent::doRun($input, $output); } catch (\Exception $e) { - $output->writeln($e->getTraceAsString()); + $errorMessage = $e->getMessage() . PHP_EOL . $e->getTraceAsString(); + $this->logger->error($errorMessage); + $this->initException = $e; } if ($this->initException) { diff --git a/lib/internal/Magento/Framework/Console/Test/Unit/CliTest.php b/lib/internal/Magento/Framework/Console/Test/Unit/CliTest.php new file mode 100644 index 000000000000..6e7bf049c430 --- /dev/null +++ b/lib/internal/Magento/Framework/Console/Test/Unit/CliTest.php @@ -0,0 +1,81 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Console\Test\Unit; + +use Magento\Framework\Console\Cli; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Test for Magento\Framework\Console\Cli class. + */ +class CliTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var Cli + */ + private $cli; + + /** + * @var InputInterface|MockObject + */ + private $inputMock; + + /** + * @var OutputInterface|MockObject + */ + private $outputMock; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->inputMock = $this->getMockBuilder(InputInterface::class) + ->getMockForAbstractClass(); + $this->outputMock = $this->getMockBuilder(OutputInterface::class) + ->getMockForAbstractClass(); + $this->cli = new Cli(); + } + + /** + * Make sure exception message is displayed and trace is logged. + * + * @expectedException \Exception + * @expectedExceptionMessage Test message + */ + public function testDoRunExceptionLogging() + { + $e = new \Exception('Test message'); + $this->inputMock->expects($this->once())->method('getFirstArgument')->willThrowException($e); + $loggerMock = $this->createMock(LoggerInterface::class); + $loggerMock->expects($this->once()) + ->method('error') + ->with($e->getMessage() . PHP_EOL . $e->getTraceAsString()); + $this->injectMock($loggerMock, 'logger'); + + $this->cli->doRun($this->inputMock, $this->outputMock); + } + + /** + * Inject mock to Cli property. + * + * @param MockObject $mockObject + * @param string $propertyName + * @throws \ReflectionException + */ + private function injectMock(MockObject $mockObject, string $propertyName): void + { + $reflection = new \ReflectionClass(Cli::class); + $reflectionProperty = $reflection->getProperty($propertyName); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->cli, $mockObject); + } +} From d440ae92d8a5071e9ed7f2a036e37763b2084c04 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Fri, 27 Sep 2019 17:39:00 +0530 Subject: [PATCH 0677/1172] Fixed swatch-renderer js console error on edit cart product --- .../Magento/Swatches/view/frontend/web/js/swatch-renderer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 a7bafb6bca50..0dcff2277834 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 @@ -1265,7 +1265,9 @@ define([ dataMergeStrategy: this.options.gallerySwitchStrategy }); } - gallery.first(); + if (gallery) { + gallery.first(); + } } else if (justAnImage && justAnImage.img) { context.find('.product-image-photo').attr('src', justAnImage.img); } From 256c7af750f07bac0aca359112c262fc82d1a891 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Fri, 27 Sep 2019 18:12:05 +0530 Subject: [PATCH 0678/1172] add new line before if --- .../Magento/Swatches/view/frontend/web/js/swatch-renderer.js | 1 + 1 file changed, 1 insertion(+) 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 0dcff2277834..bd8994743976 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 @@ -1265,6 +1265,7 @@ define([ dataMergeStrategy: this.options.gallerySwitchStrategy }); } + if (gallery) { gallery.first(); } From 0c41aeaa7f831c534360dee7a7e0518c30df6b05 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 27 Sep 2019 15:35:02 +0400 Subject: [PATCH 0679/1172] MAGETWO-67450: The rate in order is duplicated - Updated automated test script --- .../Test/Mftf/Data/CatalogPriceConfigData.xml | 16 +++++++++ .../Mftf/Data/CurrencyRatesConfigData.xml | 33 +++++++++++++++++++ ...ayWhenChooseThreeAllowedCurrenciesTest.xml | 6 ++-- .../AdminOrderRateDisplayedInOneLineTest.xml | 28 ++++++++-------- 4 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml create mode 100644 app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml new file mode 100644 index 000000000000..a16acbf4c90b --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="CatalogPriceScopeConfigData"> + <data key="path">catalog/price/scope</data> + <data key="value_website">1</data> + <data key="value_global">0</data> + </entity> +</entities> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml new file mode 100644 index 000000000000..5f4e3dc17341 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="SetCurrencyBaseConfig"> + <data key="path">currency/options/base</data> + <data key="value_usd">USD</data> + <data key="value_eur">EUR</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetAllowedCurrenciesConfig"> + <data key="path">currency/options/allow</data> + <data key="value_three_currencies">EUR,USD,RUB</data> + <data key="value_two_currencies">EUR,USD</data> + <data key="value_usd">USD</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetDefaultCurrencyConfig"> + <data key="path">currency/options/default</data> + <data key="value_eur">EUR</data> + <data key="value_usd">USD</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> +</entities> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml index 823e9d1f1557..2cb5ea81e5f3 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml @@ -24,9 +24,9 @@ <!--Create product--> <createData entity="SimpleProduct2" stepKey="createNewProduct"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseUSDWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow EUR,USD,RUB" stepKey="setAllowedCurrencyWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default EUR" stepKey="setCurrencyDefaultUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_three_currencies}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> <!--Delete created product--> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml index 1d96fa1de611..7ac01c079281 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml @@ -24,28 +24,28 @@ <!--Create product--> <createData entity="SimpleProduct2" stepKey="createProduct"/> <!--Set price scope website--> - <magentoCLI command="config:set catalog/price/scope 1" stepKey="setCatalogPriceScopeWebsite"/> + <magentoCLI command="config:set {{CatalogPriceScopeConfigData.path}} {{CatalogPriceScopeConfigData.value_website}}" stepKey="setCatalogPriceScopeWebsite"/> <!--Set Currency options for Default Config--> - <magentoCLI command="config:set currency/options/base EUR" stepKey="setCurrencyBaseEUR"/> - <magentoCLI command="config:set currency/options/allow EUR,USD" stepKey="setAllowedCurrencyEUR"/> - <magentoCLI command="config:set currency/options/default EUR" stepKey="setCurrencyDefaultEUR"/> + <magentoCLI command="config:set {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_eur}}" stepKey="setCurrencyBaseEUR"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_two_currencies}}" stepKey="setAllowedCurrencyEUR"/> + <magentoCLI command="config:set {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEUR"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseEURWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow EUR,USD" stepKey="setAllowedCurrencyEURWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default EUR" stepKey="setCurrencyDefaultEURWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseEURWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_two_currencies}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> <!--Delete created product--> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <!--Reset configurations--> - <magentoCLI command="config:set catalog/price/scope 0" stepKey="setCatalogPriceScopeGlobal"/> - <magentoCLI command="config:set currency/options/base USD" stepKey="setCurrencyBaseUSD"/> - <magentoCLI command="config:set currency/options/default USD" stepKey="setCurrencyDefaultUSD"/> - <magentoCLI command="config:set currency/options/allow USD" stepKey="setAllowedCurrencyUSD"/> + <magentoCLI command="config:set {{CatalogPriceScopeConfigData.path}} {{CatalogPriceScopeConfigData.value_global}}" stepKey="setCatalogPriceScopeGlobal"/> + <magentoCLI command="config:set {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSD"/> + <magentoCLI command="config:set {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_usd}}" stepKey="setCurrencyDefaultUSD"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_usd}}" stepKey="setAllowedCurrencyUSD"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/base USD" stepKey="setCurrencyBaseUSDWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/default USD" stepKey="setCurrencyDefaultUSDWebsites"/> - <magentoCLI command="config:set --scope=websites --scope-code=base currency/options/allow USD" stepKey="setAllowedCurrencyUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_usd}}" stepKey="setCurrencyDefaultUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_usd}}" stepKey="setAllowedCurrencyUSDWebsites"/> <actionGroup ref="logout" stepKey="logout"/> </after> <!--Open created product on Storefront and place for order--> From 3489da5cf2cb98ad9ff758b3a3c8f6783339436b Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 16:57:21 +0300 Subject: [PATCH 0680/1172] GraphQl-972: added support of the Global scope in the config fixture --- .../Annotation/ApiConfigFixture.php | 27 +++++++++++ ...peConfig.php => ApiMutableScopeConfig.php} | 10 +--- .../GraphQl/Catalog/StoreConfigTest.php | 46 +++++++++++++++++++ 3 files changed, 75 insertions(+), 8 deletions(-) rename dev/tests/api-functional/framework/Magento/TestFramework/App/{MutableScopeConfig.php => ApiMutableScopeConfig.php} (90%) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php index a5be49303283..8e6ae6190a6b 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php @@ -10,6 +10,7 @@ use Magento\Config\Model\Config; use Magento\Config\Model\ResourceModel\Config as ConfigResource; use Magento\Config\Model\ResourceModel\Config\Data\CollectionFactory; +use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\TestFramework\Helper\Bootstrap; use Magento\Store\Model\StoreManagerInterface; use PHPUnit\Framework\TestCase; @@ -156,4 +157,30 @@ private function getStoreIdByCode(string $storeCode): int $store = $storeManager->getStore($storeCode); return (int)$store->getId(); } + + /** + * @inheritDoc + */ + protected function _setConfigValue($configPath, $value, $storeCode = false) + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + if ($storeCode === false) { + $objectManager->get( + \Magento\TestFramework\App\ApiMutableScopeConfig::class + )->setValue( + $configPath, + $value, + ScopeConfigInterface::SCOPE_TYPE_DEFAULT + ); + } else { + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\TestFramework\App\ApiMutableScopeConfig::class + )->setValue( + $configPath, + $value, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeCode + ); + } + } } diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/App/MutableScopeConfig.php b/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php similarity index 90% rename from dev/tests/api-functional/framework/Magento/TestFramework/App/MutableScopeConfig.php rename to dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php index efcb5be34e59..63a0ec0f7f48 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/App/MutableScopeConfig.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php @@ -17,7 +17,7 @@ /** * @inheritdoc */ -class MutableScopeConfig implements MutableScopeConfigInterface +class ApiMutableScopeConfig implements MutableScopeConfigInterface { /** * @var Config @@ -56,7 +56,6 @@ public function setValue( /** * Clean app config cache * - * @param string|null $type * @return void */ public function clean() @@ -89,18 +88,13 @@ private function getTestAppConfig() private function persistConfig($path, $value, $scopeType, $scopeCode): void { $pathParts = explode('/', $path); - $store = ''; + $store = 0; if ($scopeType === \Magento\Store\Model\ScopeInterface::SCOPE_STORE) { if ($scopeCode !== null) { $store = ObjectManager::getInstance() ->get(\Magento\Store\Api\StoreRepositoryInterface::class) ->get($scopeCode) ->getId(); - } else { - $store = ObjectManager::getInstance() - ->get(\Magento\Store\Model\StoreManagerInterface::class) - ->getStore() - ->getId(); } } $configData = [ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php index 7a30023c89f7..0982007daaa4 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/StoreConfigTest.php @@ -59,4 +59,50 @@ public function testGetStoreConfig() $this->assertEquals('asc', $response['storeConfig']['catalog_default_sort_by']); $this->assertEquals(2, $response['storeConfig']['root_category_id']); } + + /** + * @magentoApiDataFixture Magento/Store/_files/store.php + * @magentoConfigFixture catalog/seo/product_url_suffix global_test_product_suffix + * @magentoConfigFixture catalog/seo/category_url_suffix global_test_category_suffix + * @magentoConfigFixture catalog/seo/title_separator __ + * @magentoConfigFixture catalog/frontend/list_mode 3 + * @magentoConfigFixture catalog/frontend/grid_per_page_values 16 + * @magentoConfigFixture catalog/frontend/list_per_page_values 8 + * @magentoConfigFixture catalog/frontend/grid_per_page 16 + * @magentoConfigFixture catalog/frontend/list_per_page 8 + * @magentoConfigFixture catalog/frontend/default_sort_by asc + */ + public function testGetStoreConfigGlobal() + { + $query + = <<<QUERY +{ + storeConfig{ + product_url_suffix, + category_url_suffix, + title_separator, + list_mode, + grid_per_page_values, + list_per_page_values, + grid_per_page, + list_per_page, + catalog_default_sort_by, + root_category_id + } +} +QUERY; + $response = $this->graphQlQuery($query); + $this->assertArrayHasKey('storeConfig', $response); + + $this->assertEquals('global_test_product_suffix', $response['storeConfig']['product_url_suffix']); + $this->assertEquals('global_test_category_suffix', $response['storeConfig']['category_url_suffix']); + $this->assertEquals('__', $response['storeConfig']['title_separator']); + $this->assertEquals('3', $response['storeConfig']['list_mode']); + $this->assertEquals('16', $response['storeConfig']['grid_per_page_values']); + $this->assertEquals(16, $response['storeConfig']['grid_per_page']); + $this->assertEquals('8', $response['storeConfig']['list_per_page_values']); + $this->assertEquals(8, $response['storeConfig']['list_per_page']); + $this->assertEquals('asc', $response['storeConfig']['catalog_default_sort_by']); + $this->assertEquals(2, $response['storeConfig']['root_category_id']); + } } From 36ad18af62f3d434b3a08eb6358217ff43cd1bce Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 1 Feb 2019 13:50:24 +0200 Subject: [PATCH 0681/1172] magento/magento2#15775: [Forwardport] Incorrect return type getList() in CustomerRepository. --- .../Model/OperationSearchResults.php | 18 +++++ .../Magento/AsynchronousOperations/etc/di.xml | 2 +- .../Model/CategoryAttributeSearchResults.php | 18 +++++ .../Catalog/Model/CategorySearchResults.php | 18 +++++ .../Model/ProductAttributeSearchResults.php | 18 +++++ .../Catalog/Model/ProductSearchResults.php | 18 +++++ app/code/Magento/Catalog/etc/di.xml | 8 +-- .../Magento/Cms/Model/BlockSearchResults.php | 18 +++++ .../Magento/Cms/Model/PageSearchResults.php | 18 +++++ app/code/Magento/Cms/etc/di.xml | 5 +- .../Customer/Model/AddressSearchResults.php | 18 +++++ .../Customer/Model/CustomerSearchResults.php | 18 +++++ .../Customer/Model/GroupSearchResults.php | 18 +++++ app/code/Magento/Customer/etc/di.xml | 6 +- .../Eav/Model/AttributeGroupSearchResults.php | 18 +++++ .../Eav/Model/AttributeSearchResults.php | 18 +++++ .../Eav/Model/AttributeSetSearchResults.php | 18 +++++ app/code/Magento/Eav/etc/di.xml | 6 +- .../Api/Data/CartSearchResultsInterface.php | 2 + .../Magento/Quote/Model/CartSearchResults.php | 65 +++++++++++++++++++ app/code/Magento/Quote/etc/di.xml | 2 +- .../SalesRule/Model/CouponSearchResult.php | 27 ++++++++ .../SalesRule/Model/RuleSearchResult.php | 27 ++++++++ app/code/Magento/SalesRule/etc/di.xml | 4 +- .../Signifyd/Model/CaseSearchResults.php | 18 +++++ app/code/Magento/Signifyd/etc/di.xml | 2 +- .../Tax/Model/TaxClassSearchResults.php | 18 +++++ .../Tax/Model/TaxRateSearchResults.php | 18 +++++ .../Tax/Model/TaxRuleSearchResults.php | 18 +++++ app/code/Magento/Tax/etc/di.xml | 6 +- .../Ui/Model/BookmarkSearchResults.php | 18 +++++ app/code/Magento/Ui/etc/di.xml | 2 +- .../Vault/Model/PaymentTokenSearchResults.php | 18 +++++ app/code/Magento/Vault/etc/di.xml | 2 +- .../Magento/Framework/Api/SearchResults.php | 3 + .../Framework/Api/SearchResultsInterface.php | 1 + 36 files changed, 489 insertions(+), 23 deletions(-) create mode 100644 app/code/Magento/AsynchronousOperations/Model/OperationSearchResults.php create mode 100644 app/code/Magento/Catalog/Model/CategoryAttributeSearchResults.php create mode 100644 app/code/Magento/Catalog/Model/CategorySearchResults.php create mode 100644 app/code/Magento/Catalog/Model/ProductAttributeSearchResults.php create mode 100644 app/code/Magento/Catalog/Model/ProductSearchResults.php create mode 100644 app/code/Magento/Cms/Model/BlockSearchResults.php create mode 100644 app/code/Magento/Cms/Model/PageSearchResults.php create mode 100644 app/code/Magento/Customer/Model/AddressSearchResults.php create mode 100644 app/code/Magento/Customer/Model/CustomerSearchResults.php create mode 100644 app/code/Magento/Customer/Model/GroupSearchResults.php create mode 100644 app/code/Magento/Eav/Model/AttributeGroupSearchResults.php create mode 100644 app/code/Magento/Eav/Model/AttributeSearchResults.php create mode 100644 app/code/Magento/Eav/Model/AttributeSetSearchResults.php create mode 100644 app/code/Magento/Quote/Model/CartSearchResults.php create mode 100644 app/code/Magento/SalesRule/Model/CouponSearchResult.php create mode 100644 app/code/Magento/SalesRule/Model/RuleSearchResult.php create mode 100644 app/code/Magento/Signifyd/Model/CaseSearchResults.php create mode 100644 app/code/Magento/Tax/Model/TaxClassSearchResults.php create mode 100644 app/code/Magento/Tax/Model/TaxRateSearchResults.php create mode 100644 app/code/Magento/Tax/Model/TaxRuleSearchResults.php create mode 100644 app/code/Magento/Ui/Model/BookmarkSearchResults.php create mode 100644 app/code/Magento/Vault/Model/PaymentTokenSearchResults.php diff --git a/app/code/Magento/AsynchronousOperations/Model/OperationSearchResults.php b/app/code/Magento/AsynchronousOperations/Model/OperationSearchResults.php new file mode 100644 index 000000000000..84f0952a836c --- /dev/null +++ b/app/code/Magento/AsynchronousOperations/Model/OperationSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\AsynchronousOperations\Model; + +use Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with bulk Operation search result. + */ +class OperationSearchResults extends SearchResults implements OperationSearchResultsInterface +{ +} diff --git a/app/code/Magento/AsynchronousOperations/etc/di.xml b/app/code/Magento/AsynchronousOperations/etc/di.xml index 42b62ff8ea37..94a4c56c19ce 100644 --- a/app/code/Magento/AsynchronousOperations/etc/di.xml +++ b/app/code/Magento/AsynchronousOperations/etc/di.xml @@ -16,7 +16,7 @@ <preference for="Magento\AsynchronousOperations\Api\Data\SummaryOperationStatusInterface" type="Magento\AsynchronousOperations\Model\OperationStatus" /> <preference for="Magento\AsynchronousOperations\Api\Data\DetailedBulkOperationsStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Detailed" /> <preference for="Magento\AsynchronousOperations\Api\Data\BulkOperationsStatusInterface" type="Magento\AsynchronousOperations\Model\BulkStatus\Short" /> - <preference for="Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\AsynchronousOperations\Api\Data\OperationSearchResultsInterface" type="Magento\AsynchronousOperations\Model\OperationSearchResults" /> <preference for="Magento\AsynchronousOperations\Api\OperationRepositoryInterface" type="Magento\AsynchronousOperations\Model\OperationRepository" /> <type name="Magento\Framework\EntityManager\MetadataPool"> <arguments> diff --git a/app/code/Magento/Catalog/Model/CategoryAttributeSearchResults.php b/app/code/Magento/Catalog/Model/CategoryAttributeSearchResults.php new file mode 100644 index 000000000000..db1b84ed2777 --- /dev/null +++ b/app/code/Magento/Catalog/Model/CategoryAttributeSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model; + +use Magento\Catalog\Api\Data\CategoryAttributeSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Category Attribute search results. + */ +class CategoryAttributeSearchResults extends SearchResults implements CategoryAttributeSearchResultsInterface +{ +} diff --git a/app/code/Magento/Catalog/Model/CategorySearchResults.php b/app/code/Magento/Catalog/Model/CategorySearchResults.php new file mode 100644 index 000000000000..7590ee4a23ed --- /dev/null +++ b/app/code/Magento/Catalog/Model/CategorySearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model; + +use Magento\Catalog\Api\Data\CategorySearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Category search results. + */ +class CategorySearchResults extends SearchResults implements CategorySearchResultsInterface +{ +} diff --git a/app/code/Magento/Catalog/Model/ProductAttributeSearchResults.php b/app/code/Magento/Catalog/Model/ProductAttributeSearchResults.php new file mode 100644 index 000000000000..776009089b9a --- /dev/null +++ b/app/code/Magento/Catalog/Model/ProductAttributeSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model; + +use Magento\Catalog\Api\Data\ProductAttributeSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Product Attribute search results. + */ +class ProductAttributeSearchResults extends SearchResults implements ProductAttributeSearchResultsInterface +{ +} diff --git a/app/code/Magento/Catalog/Model/ProductSearchResults.php b/app/code/Magento/Catalog/Model/ProductSearchResults.php new file mode 100644 index 000000000000..7aa3b4d961c2 --- /dev/null +++ b/app/code/Magento/Catalog/Model/ProductSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model; + +use Magento\Catalog\Api\Data\ProductSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Product search results. + */ +class ProductSearchResults extends SearchResults implements ProductSearchResultsInterface +{ +} diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 7d2c3699ee2c..5df28f11d185 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -36,16 +36,16 @@ <preference for="Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface" type="Magento\Catalog\Model\ProductAttributeGroupRepository" /> <preference for="Magento\Catalog\Api\ProductAttributeOptionManagementInterface" type="Magento\Catalog\Model\Product\Attribute\OptionManagement" /> <preference for="Magento\Catalog\Api\ProductLinkRepositoryInterface" type="Magento\Catalog\Model\ProductLink\Repository" /> - <preference for="Magento\Catalog\Api\Data\ProductAttributeSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> - <preference for="Magento\Catalog\Api\Data\CategoryAttributeSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> - <preference for="Magento\Catalog\Api\Data\ProductSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Catalog\Api\Data\ProductAttributeSearchResultsInterface" type="Magento\Catalog\Model\ProductAttributeSearchResults" /> + <preference for="Magento\Catalog\Api\Data\CategoryAttributeSearchResultsInterface" type="Magento\Catalog\Model\CategoryAttributeSearchResults" /> + <preference for="Magento\Catalog\Api\Data\ProductSearchResultsInterface" type="Magento\Catalog\Model\ProductSearchResults" /> <preference for="Magento\Catalog\Api\ProductAttributeManagementInterface" type="Magento\Catalog\Model\Product\Attribute\Management" /> <preference for="Magento\Catalog\Api\AttributeSetManagementInterface" type="Magento\Catalog\Model\Product\Attribute\SetManagement" /> <preference for="Magento\Catalog\Api\AttributeSetRepositoryInterface" type="Magento\Catalog\Model\Product\Attribute\SetRepository" /> <preference for="Magento\Catalog\Api\ProductManagementInterface" type="Magento\Catalog\Model\ProductManagement" /> <preference for="Magento\Catalog\Api\AttributeSetFinderInterface" type="Magento\Catalog\Model\Product\Attribute\AttributeSetFinder" /> <preference for="Magento\Catalog\Api\CategoryListInterface" type="Magento\Catalog\Model\CategoryList" /> - <preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Catalog\Model\CategorySearchResults" /> <preference for="Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface" type="Magento\Catalog\Model\Config\Source\Product\Options\Price"/> <preference for="Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterface" type="Magento\Catalog\Model\Indexer\Product\Flat\Table\Builder"/> <preference for="Magento\Catalog\Api\ProductRenderListInterface" type="Magento\Catalog\Model\ProductRenderList"/> diff --git a/app/code/Magento/Cms/Model/BlockSearchResults.php b/app/code/Magento/Cms/Model/BlockSearchResults.php new file mode 100644 index 000000000000..2fa5dbb40139 --- /dev/null +++ b/app/code/Magento/Cms/Model/BlockSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Cms\Model; + +use Magento\Cms\Api\Data\BlockSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Block search results. + */ +class BlockSearchResults extends SearchResults implements BlockSearchResultsInterface +{ +} diff --git a/app/code/Magento/Cms/Model/PageSearchResults.php b/app/code/Magento/Cms/Model/PageSearchResults.php new file mode 100644 index 000000000000..7985e382be27 --- /dev/null +++ b/app/code/Magento/Cms/Model/PageSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Cms\Model; + +use Magento\Cms\Api\Data\PageSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Page search results. + */ +class PageSearchResults extends SearchResults implements PageSearchResultsInterface +{ +} diff --git a/app/code/Magento/Cms/etc/di.xml b/app/code/Magento/Cms/etc/di.xml index b6e13c63302c..a1578ca98aba 100644 --- a/app/code/Magento/Cms/etc/di.xml +++ b/app/code/Magento/Cms/etc/di.xml @@ -7,9 +7,9 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Cms\Api\Data\PageSearchResultsInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\Cms\Model\PageSearchResults" /> <preference for="Magento\Cms\Api\Data\BlockSearchResultsInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\Cms\Model\BlockSearchResults" /> <preference for="Magento\Cms\Api\GetBlockByIdentifierInterface" type="Magento\Cms\Model\GetBlockByIdentifier" /> <preference for="Magento\Cms\Api\GetPageByIdentifierInterface" type="Magento\Cms\Model\GetPageByIdentifier" /> <preference for="Magento\Cms\Api\Data\PageInterface" type="Magento\Cms\Model\Page" /> @@ -234,4 +234,3 @@ </arguments> </type> </config> - diff --git a/app/code/Magento/Customer/Model/AddressSearchResults.php b/app/code/Magento/Customer/Model/AddressSearchResults.php new file mode 100644 index 000000000000..7e83aa8f8d8d --- /dev/null +++ b/app/code/Magento/Customer/Model/AddressSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Model; + +use Magento\Customer\Api\Data\AddressSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Address search results. + */ +class AddressSearchResults extends SearchResults implements AddressSearchResultsInterface +{ +} diff --git a/app/code/Magento/Customer/Model/CustomerSearchResults.php b/app/code/Magento/Customer/Model/CustomerSearchResults.php new file mode 100644 index 000000000000..1d7f0e265641 --- /dev/null +++ b/app/code/Magento/Customer/Model/CustomerSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Model; + +use Magento\Customer\Api\Data\CustomerSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Customer search results. + */ +class CustomerSearchResults extends SearchResults implements CustomerSearchResultsInterface +{ +} diff --git a/app/code/Magento/Customer/Model/GroupSearchResults.php b/app/code/Magento/Customer/Model/GroupSearchResults.php new file mode 100644 index 000000000000..1de4cd078db8 --- /dev/null +++ b/app/code/Magento/Customer/Model/GroupSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Customer\Model; + +use Magento\Customer\Api\Data\GroupSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Customer Groups search results. + */ +class GroupSearchResults extends SearchResults implements GroupSearchResultsInterface +{ +} diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml index a181d6dd217f..4df9e64ced3e 100644 --- a/app/code/Magento/Customer/etc/di.xml +++ b/app/code/Magento/Customer/etc/di.xml @@ -28,11 +28,11 @@ <preference for="Magento\Customer\Api\Data\ValidationResultsInterface" type="Magento\Customer\Model\Data\ValidationResults" /> <preference for="Magento\Customer\Api\Data\GroupSearchResultsInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\Customer\Model\GroupSearchResults" /> <preference for="Magento\Customer\Api\Data\CustomerSearchResultsInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\Customer\Model\CustomerSearchResults" /> <preference for="Magento\Customer\Api\Data\AddressSearchResultsInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\Customer\Model\AddressSearchResults" /> <preference for="Magento\Customer\Api\AccountManagementInterface" type="Magento\Customer\Model\AccountManagement" /> <preference for="Magento\Customer\Api\CustomerMetadataInterface" diff --git a/app/code/Magento/Eav/Model/AttributeGroupSearchResults.php b/app/code/Magento/Eav/Model/AttributeGroupSearchResults.php new file mode 100644 index 000000000000..100d5638a96d --- /dev/null +++ b/app/code/Magento/Eav/Model/AttributeGroupSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Eav\Model; + +use Magento\Eav\Api\Data\AttributeGroupSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Attribute Group search results. + */ +class AttributeGroupSearchResults extends SearchResults implements AttributeGroupSearchResultsInterface +{ +} diff --git a/app/code/Magento/Eav/Model/AttributeSearchResults.php b/app/code/Magento/Eav/Model/AttributeSearchResults.php new file mode 100644 index 000000000000..b82a27bbfea1 --- /dev/null +++ b/app/code/Magento/Eav/Model/AttributeSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Eav\Model; + +use Magento\Eav\Api\Data\AttributeSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Eav Attribute search results. + */ +class AttributeSearchResults extends SearchResults implements AttributeSearchResultsInterface +{ +} diff --git a/app/code/Magento/Eav/Model/AttributeSetSearchResults.php b/app/code/Magento/Eav/Model/AttributeSetSearchResults.php new file mode 100644 index 000000000000..46592efda5a1 --- /dev/null +++ b/app/code/Magento/Eav/Model/AttributeSetSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Eav\Model; + +use Magento\Eav\Api\Data\AttributeSetSearchResultsInterface; +use Magento\Framework\Api\SearchResults; + +/** + * Service Data Object with Attribute Set search results. + */ +class AttributeSetSearchResults extends SearchResults implements AttributeSetSearchResultsInterface +{ +} diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index 8e897b979d2f..f9e3915392b8 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -21,9 +21,9 @@ <preference for="Magento\Eav\Api\AttributeOptionManagementInterface" type="Magento\Eav\Model\Entity\Attribute\OptionManagement" /> <preference for="Magento\Eav\Api\Data\AttributeOptionLabelInterface" type="Magento\Eav\Model\Entity\Attribute\OptionLabel" /> <preference for="Magento\Eav\Api\Data\AttributeValidationRuleInterface" type="Magento\Eav\Model\Entity\Attribute\ValidationRule" /> - <preference for="Magento\Eav\Api\Data\AttributeSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> - <preference for="Magento\Eav\Api\Data\AttributeSetSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> - <preference for="Magento\Eav\Api\Data\AttributeGroupSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Eav\Api\Data\AttributeSearchResultsInterface" type="Magento\Eav\Model\AttributeSearchResults" /> + <preference for="Magento\Eav\Api\Data\AttributeSetSearchResultsInterface" type="Magento\Eav\Model\AttributeSetSearchResults" /> + <preference for="Magento\Eav\Api\Data\AttributeGroupSearchResultsInterface" type="Magento\Eav\Model\AttributeGroupSearchResults" /> <preference for="Magento\Framework\Webapi\CustomAttributeTypeLocatorInterface" type="Magento\Eav\Model\TypeLocator" /> <type name="Magento\Eav\Model\Entity\Attribute\Config"> diff --git a/app/code/Magento/Quote/Api/Data/CartSearchResultsInterface.php b/app/code/Magento/Quote/Api/Data/CartSearchResultsInterface.php index 5da776091f7f..48818e5d253e 100644 --- a/app/code/Magento/Quote/Api/Data/CartSearchResultsInterface.php +++ b/app/code/Magento/Quote/Api/Data/CartSearchResultsInterface.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Quote\Api\Data; /** diff --git a/app/code/Magento/Quote/Model/CartSearchResults.php b/app/code/Magento/Quote/Model/CartSearchResults.php new file mode 100644 index 000000000000..5c505bec121f --- /dev/null +++ b/app/code/Magento/Quote/Model/CartSearchResults.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Quote\Model; + +use Magento\Framework\Api\AbstractSimpleObject; +use Magento\Quote\Api\Data\CartSearchResultsInterface; + +/** + * Service Data Object with Cart search results. + */ +class CartSearchResults extends AbstractSimpleObject implements CartSearchResultsInterface +{ + /** + * @inheritdoc + */ + public function setItems(array $items = null) + { + return $this->setData(self::KEY_ITEMS, $items); + } + + /** + * @inheritdoc + */ + public function getItems() + { + return $this->_get(self::KEY_ITEMS) === null ? [] : $this->_get(self::KEY_ITEMS); + } + + /** + * @inheritdoc + */ + public function getSearchCriteria() + { + return $this->_get(self::KEY_SEARCH_CRITERIA); + } + + /** + * @inheritdoc + */ + public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria) + { + return $this->setData(self::KEY_SEARCH_CRITERIA, $searchCriteria); + } + + /** + * @inheritdoc + */ + public function getTotalCount() + { + return $this->_get(self::KEY_TOTAL_COUNT); + } + + /** + * @inheritdoc + */ + public function setTotalCount($count) + { + return $this->setData(self::KEY_TOTAL_COUNT, $count); + } +} diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml index cd5e62307fdc..f66001e7789c 100644 --- a/app/code/Magento/Quote/etc/di.xml +++ b/app/code/Magento/Quote/etc/di.xml @@ -18,7 +18,7 @@ <preference for="Magento\Quote\Api\Data\CartInterface" type="Magento\Quote\Model\Quote" /> <preference for="Magento\Quote\Api\CartItemRepositoryInterface" type="Magento\Quote\Model\Quote\Item\Repository" /> <preference for="Magento\Quote\Api\CartRepositoryInterface" type="Magento\Quote\Model\QuoteRepository" /> - <preference for="Magento\Quote\Api\Data\CartSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Quote\Api\Data\CartSearchResultsInterface" type="Magento\Quote\Model\CartSearchResults" /> <preference for="Magento\Quote\Api\PaymentMethodManagementInterface" type="Magento\Quote\Model\PaymentMethodManagement" /> <preference for="Magento\Quote\Api\Data\PaymentInterface" type="Magento\Quote\Model\Quote\Payment" /> <preference for="Magento\Quote\Api\CouponManagementInterface" type="Magento\Quote\Model\CouponManagement" /> diff --git a/app/code/Magento/SalesRule/Model/CouponSearchResult.php b/app/code/Magento/SalesRule/Model/CouponSearchResult.php new file mode 100644 index 000000000000..cba57900cf60 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/CouponSearchResult.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesRule\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\SalesRule\Api\Data\CouponSearchResultInterface; + +/** + * Service Data Object with Coupon search results. + * + * @phpcs:ignoreFile + */ +class CouponSearchResult extends SearchResults implements CouponSearchResultInterface +{ + /** + * @inheritdoc + */ + public function setItems(array $items = null) + { + return parent::setItems($items); + } +} diff --git a/app/code/Magento/SalesRule/Model/RuleSearchResult.php b/app/code/Magento/SalesRule/Model/RuleSearchResult.php new file mode 100644 index 000000000000..834b2b575ec2 --- /dev/null +++ b/app/code/Magento/SalesRule/Model/RuleSearchResult.php @@ -0,0 +1,27 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\SalesRule\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\SalesRule\Api\Data\RuleSearchResultInterface; + +/** + * Service Data Object with Sales Rule search results. + * + * @phpcs:ignoreFile + */ +class RuleSearchResult extends SearchResults implements RuleSearchResultInterface +{ + /** + * @inheritdoc + */ + public function setItems(array $items = null) + { + return parent::setItems($items); + } +} diff --git a/app/code/Magento/SalesRule/etc/di.xml b/app/code/Magento/SalesRule/etc/di.xml index a8c350457a5a..30482d7f37ff 100644 --- a/app/code/Magento/SalesRule/etc/di.xml +++ b/app/code/Magento/SalesRule/etc/di.xml @@ -13,7 +13,7 @@ <preference for="Magento\SalesRule\Api\Data\ConditionInterface" type="Magento\SalesRule\Model\Data\Condition" /> <preference for="Magento\SalesRule\Api\Data\RuleSearchResultInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\SalesRule\Model\RuleSearchResult" /> <preference for="Magento\SalesRule\Api\Data\RuleLabelInterface" type="Magento\SalesRule\Model\Data\RuleLabel" /> <preference for="Magento\SalesRule\Api\Data\CouponInterface" @@ -23,7 +23,7 @@ <preference for="Magento\SalesRule\Model\Spi\CouponResourceInterface" type="Magento\SalesRule\Model\ResourceModel\Coupon" /> <preference for="Magento\SalesRule\Api\Data\CouponSearchResultInterface" - type="Magento\Framework\Api\SearchResults" /> + type="Magento\SalesRule\Model\CouponSearchResult" /> <preference for="Magento\SalesRule\Api\Data\CouponGenerationSpecInterface" type="Magento\SalesRule\Model\Data\CouponGenerationSpec" /> <preference for="Magento\SalesRule\Api\Data\CouponMassDeleteResultInterface" diff --git a/app/code/Magento/Signifyd/Model/CaseSearchResults.php b/app/code/Magento/Signifyd/Model/CaseSearchResults.php new file mode 100644 index 000000000000..ff1ab8839f6c --- /dev/null +++ b/app/code/Magento/Signifyd/Model/CaseSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Signifyd\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Signifyd\Api\Data\CaseSearchResultsInterface; + +/** + * Service Data Object with Case entities search results. + */ +class CaseSearchResults extends SearchResults implements CaseSearchResultsInterface +{ +} diff --git a/app/code/Magento/Signifyd/etc/di.xml b/app/code/Magento/Signifyd/etc/di.xml index fd78fff27f61..8e9ea8e4cff9 100644 --- a/app/code/Magento/Signifyd/etc/di.xml +++ b/app/code/Magento/Signifyd/etc/di.xml @@ -9,7 +9,7 @@ <preference for="Magento\Signifyd\Api\Data\CaseInterface" type="Magento\Signifyd\Model\CaseEntity" /> <preference for="Magento\Signifyd\Api\CaseRepositoryInterface" type="Magento\Signifyd\Model\CaseRepository" /> <preference for="Magento\Signifyd\Api\CaseManagementInterface" type="Magento\Signifyd\Model\CaseManagement" /> - <preference for="Magento\Signifyd\Api\Data\CaseSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Signifyd\Api\Data\CaseSearchResultsInterface" type="Magento\Signifyd\Model\CaseSearchResults" /> <preference for="Magento\Signifyd\Api\CaseCreationServiceInterface" type="Magento\Signifyd\Model\CaseServices\CreationService" /> <preference for="Magento\Signifyd\Api\GuaranteeCreationServiceInterface" type="Magento\Signifyd\Model\Guarantee\CreationService" /> <preference for="Magento\Signifyd\Api\GuaranteeCancelingServiceInterface" type="Magento\Signifyd\Model\Guarantee\CancelingService" /> diff --git a/app/code/Magento/Tax/Model/TaxClassSearchResults.php b/app/code/Magento/Tax/Model/TaxClassSearchResults.php new file mode 100644 index 000000000000..4e92fd10a3de --- /dev/null +++ b/app/code/Magento/Tax/Model/TaxClassSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tax\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Tax\Api\Data\TaxClassSearchResultsInterface; + +/** + * Service Data Object with Tax Class search results. + */ +class TaxClassSearchResults extends SearchResults implements TaxClassSearchResultsInterface +{ +} diff --git a/app/code/Magento/Tax/Model/TaxRateSearchResults.php b/app/code/Magento/Tax/Model/TaxRateSearchResults.php new file mode 100644 index 000000000000..80e9b5eaa72f --- /dev/null +++ b/app/code/Magento/Tax/Model/TaxRateSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tax\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Tax\Api\Data\TaxRateSearchResultsInterface; + +/** + * Service Data Object with Tax Rate search results. + */ +class TaxRateSearchResults extends SearchResults implements TaxRateSearchResultsInterface +{ +} diff --git a/app/code/Magento/Tax/Model/TaxRuleSearchResults.php b/app/code/Magento/Tax/Model/TaxRuleSearchResults.php new file mode 100644 index 000000000000..aa70b31ab22a --- /dev/null +++ b/app/code/Magento/Tax/Model/TaxRuleSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Tax\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Tax\Api\Data\TaxRuleSearchResultsInterface; + +/** + * Service Data Object with Tax Rule search results. + */ +class TaxRuleSearchResults extends SearchResults implements TaxRuleSearchResultsInterface +{ +} diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml index 096f8359fadd..a848e32e0f7c 100644 --- a/app/code/Magento/Tax/etc/di.xml +++ b/app/code/Magento/Tax/etc/di.xml @@ -37,8 +37,8 @@ </argument> </arguments> </type> - <preference for="Magento\Tax\Api\Data\TaxRateSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> - <preference for="Magento\Tax\Api\Data\TaxClassSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Tax\Api\Data\TaxRateSearchResultsInterface" type="Magento\Tax\Model\TaxRateSearchResults" /> + <preference for="Magento\Tax\Api\Data\TaxClassSearchResultsInterface" type="Magento\Tax\Model\TaxClassSearchResults" /> <preference for="Magento\Tax\Api\OrderTaxManagementInterface" type="Magento\Tax\Model\Sales\Order\TaxManagement" /> <preference for="Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface" type="Magento\Tax\Model\Sales\Order\Tax" /> <preference for="Magento\Tax\Api\Data\OrderTaxDetailsInterface" type="Magento\Tax\Model\Sales\Order\Details" /> @@ -47,7 +47,7 @@ <preference for="Magento\Tax\Api\TaxClassRepositoryInterface" type="Magento\Tax\Model\TaxClass\Repository" /> <preference for="Magento\Tax\Api\Data\TaxClassInterface" type="Magento\Tax\Model\ClassModel" /> <preference for="Magento\Tax\Api\Data\TaxRuleInterface" type="Magento\Tax\Model\Calculation\Rule" /> - <preference for="Magento\Tax\Api\Data\TaxRuleSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Tax\Api\Data\TaxRuleSearchResultsInterface" type="Magento\Tax\Model\TaxRuleSearchResults" /> <preference for="Magento\Tax\Api\TaxRateManagementInterface" type="Magento\Tax\Model\TaxRateManagement" /> <preference for="Magento\Tax\Api\TaxRateRepositoryInterface" type="Magento\Tax\Model\Calculation\RateRepository" /> <preference for="Magento\Tax\Api\Data\TaxRateTitleInterface" type="Magento\Tax\Model\Calculation\Rate\Title" /> diff --git a/app/code/Magento/Ui/Model/BookmarkSearchResults.php b/app/code/Magento/Ui/Model/BookmarkSearchResults.php new file mode 100644 index 000000000000..2171a5c0084e --- /dev/null +++ b/app/code/Magento/Ui/Model/BookmarkSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Ui\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Ui\Api\Data\BookmarkSearchResultsInterface; + +/** + * Service Data Object with Bookmark search results. + */ +class BookmarkSearchResults extends SearchResults implements BookmarkSearchResultsInterface +{ +} diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml index c029e18addf7..05ace9d556fa 100644 --- a/app/code/Magento/Ui/etc/di.xml +++ b/app/code/Magento/Ui/etc/di.xml @@ -14,7 +14,7 @@ <preference for="Magento\Framework\View\Element\UiComponent\ContextInterface" type="Magento\Framework\View\Element\UiComponent\Context" /> <preference for="Magento\Framework\View\Element\UiComponent\LayoutInterface" type="Magento\Framework\View\Layout\Generic"/> <preference for="Magento\Authorization\Model\UserContextInterface" type="Magento\Authorization\Model\CompositeUserContext"/> - <preference for="Magento\Ui\Api\Data\BookmarkSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Ui\Api\Data\BookmarkSearchResultsInterface" type="Magento\Ui\Model\BookmarkSearchResults" /> <preference for="Magento\Ui\Api\BookmarkRepositoryInterface" type="Magento\Ui\Model\ResourceModel\BookmarkRepository"/> <preference for="Magento\Ui\Api\Data\BookmarkInterface" type="Magento\Ui\Model\Bookmark"/> <preference for="Magento\Ui\Component\Wysiwyg\ConfigInterface" type="Magento\Ui\Component\Wysiwyg\Config"/> diff --git a/app/code/Magento/Vault/Model/PaymentTokenSearchResults.php b/app/code/Magento/Vault/Model/PaymentTokenSearchResults.php new file mode 100644 index 000000000000..39dcf503779b --- /dev/null +++ b/app/code/Magento/Vault/Model/PaymentTokenSearchResults.php @@ -0,0 +1,18 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Vault\Model; + +use Magento\Framework\Api\SearchResults; +use Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface; + +/** + * Service Data Object with Payment Token search results. + */ +class PaymentTokenSearchResults extends SearchResults implements PaymentTokenSearchResultsInterface +{ +} diff --git a/app/code/Magento/Vault/etc/di.xml b/app/code/Magento/Vault/etc/di.xml index 95191e441757..0192a783bd5a 100644 --- a/app/code/Magento/Vault/etc/di.xml +++ b/app/code/Magento/Vault/etc/di.xml @@ -13,7 +13,7 @@ <preference for="Magento\Vault\Api\PaymentTokenRepositoryInterface" type="Magento\Vault\Model\PaymentTokenRepository" /> <preference for="Magento\Vault\Api\PaymentTokenManagementInterface" type="Magento\Vault\Model\PaymentTokenManagement" /> <preference for="Magento\Vault\Api\PaymentMethodListInterface" type="Magento\Vault\Model\PaymentMethodList" /> - <preference for="Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> + <preference for="Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface" type="Magento\Vault\Model\PaymentTokenSearchResults" /> <preference for="Magento\Vault\Model\Ui\TokenUiComponentInterface" type="Magento\Vault\Model\Ui\TokenUiComponent" /> <type name="Magento\Sales\Api\Data\OrderPaymentInterface"> diff --git a/lib/internal/Magento/Framework/Api/SearchResults.php b/lib/internal/Magento/Framework/Api/SearchResults.php index ad58d0a75265..cf1f11463f6a 100644 --- a/lib/internal/Magento/Framework/Api/SearchResults.php +++ b/lib/internal/Magento/Framework/Api/SearchResults.php @@ -3,11 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\Api; /** * SearchResults Service Data Object used for the search service requests + * + * @SuppressWarnings(PHPMD.NumberOfChildren) */ class SearchResults extends AbstractSimpleObject implements SearchResultsInterface { diff --git a/lib/internal/Magento/Framework/Api/SearchResultsInterface.php b/lib/internal/Magento/Framework/Api/SearchResultsInterface.php index d2bc3053b8d6..ba72685a80f4 100644 --- a/lib/internal/Magento/Framework/Api/SearchResultsInterface.php +++ b/lib/internal/Magento/Framework/Api/SearchResultsInterface.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\Api; From 63bd2327cdaba3f75b9d6e955e181f2c4a18a13c Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Fri, 27 Sep 2019 17:08:05 +0300 Subject: [PATCH 0682/1172] GraphQl-972: removed redundant else --- .../Annotation/ApiConfigFixture.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php index 8e6ae6190a6b..8061cb138660 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiConfigFixture.php @@ -172,15 +172,16 @@ protected function _setConfigValue($configPath, $value, $storeCode = false) $value, ScopeConfigInterface::SCOPE_TYPE_DEFAULT ); - } else { - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\TestFramework\App\ApiMutableScopeConfig::class - )->setValue( - $configPath, - $value, - \Magento\Store\Model\ScopeInterface::SCOPE_STORE, - $storeCode - ); + + return; } + \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\TestFramework\App\ApiMutableScopeConfig::class + )->setValue( + $configPath, + $value, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeCode + ); } } From 6bc920a871788aba4ff4e1d2a43743c2411e4475 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 27 Sep 2019 09:32:36 -0500 Subject: [PATCH 0683/1172] MC-20334: Update tests related to SKU field issue in AdvancedSearch --- .../Magento/Catalog/Test/Mftf/Data/ProductData.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 131d89ffd44e..ed436d9926ae 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -559,6 +559,20 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiVirtualProductWithDescriptionAndUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_virtual_product</data> + <data key="type_id">virtual</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Virtual Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-virtual-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="SimpleProductWithNewFromDate" type="product"> <data key="sku" unique="suffix">SimpleProduct</data> <data key="type_id">simple</data> From be1194b19e62a8244a81a18df6e86516ed155e91 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Fri, 27 Sep 2019 20:23:32 +0530 Subject: [PATCH 0684/1172] Resolved issue 24740 --- .../Magento/backend/web/css/source/forms/_fields.less | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index 08aeb35d7adb..525c61e8267a 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -122,7 +122,7 @@ > .admin__field-control { #mix-grid .column(@field-control-grid__column, @field-grid__columns); input[type="checkbox"] { - margin-top: @indent__s; + margin-top: 0; } } @@ -156,7 +156,7 @@ .admin__field { margin-top: 8px; } - } + } } } &.composite-bundle { @@ -307,7 +307,7 @@ .admin__fieldset > & { margin-bottom: 3rem; position: relative; - + &.field-import_file { .input-file { margin-top: 6px; @@ -664,7 +664,7 @@ display: inline-block; } } - + + .admin__field:last-child { width: auto; @@ -700,7 +700,7 @@ width: 100%; } } - & > .admin__field-label { + & > .admin__field-label { text-align: left; } From e2d41dd5b9ca4047524d024fd9bf46ed0d47158e Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Fri, 27 Sep 2019 12:56:55 -0500 Subject: [PATCH 0685/1172] MC-20338: Api-functional tests for Product prices - added test coverage for all configurable and dynamic bundle --- .../GraphQl/Catalog/ProductPriceTest.php | 370 +++++++++++++++++- ...c_bundle_product_with_multiple_options.php | 130 ++++++ ...product_with_multiple_options_rollback.php | 7 + 3 files changed, 491 insertions(+), 16 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php create mode 100644 dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options_rollback.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php index 465c40933401..dc5d5e9313ba 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php @@ -13,13 +13,14 @@ use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; +use Magento\ConfigurableProduct\Api\LinkManagementInterface; +use Magento\ConfigurableProduct\Model\LinkManagement; use Magento\Customer\Model\Group; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; class ProductPriceTest extends GraphQlAbstract { - /** * @magentoApiDataFixture Magento/Catalog/_files/products.php */ @@ -173,6 +174,7 @@ public function testMultipleProductTypes() * Simple products with special price and tier price with % discount * * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testSimpleProductsWithSpecialPriceAndTierPrice() { @@ -181,7 +183,8 @@ public function testSimpleProductsWithSpecialPriceAndTierPrice() /** @var ProductRepositoryInterface $productRepository */ $productRepository = $objectManager->get(ProductRepositoryInterface::class); $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); - /** @var $tpExtensionAttributes */ + + /** @var $tierPriceExtensionAttributesFactory */ $tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); $tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); @@ -323,13 +326,6 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() $productRepository->save($associatedProduct); $this->saveProductTierPrices($associatedProduct, $tierPriceData); } - - //select one of the simple associated products and add a special price - // $associatedProductSku = $groupedProductLinks[0]->getLinkedProductSku(); - /** @var Product $associatedProduct */ -// $associatedProduct = $productRepository->get($associatedProductSku); -// $associatedProduct->setSpecialPrice('95.75'); -// $productRepository->save($associatedProduct); $skus = ['grouped']; $query = $this->getProductQuery($skus); @@ -386,6 +382,7 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() * Check pricing for bundled product with one of bundle items having special price set and no dynamic price type set * * @magentoApiDataFixture Magento/Bundle/_files/product_with_multiple_options_1.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testBundledProductWithSpecialPriceAndTierPrice() { @@ -396,10 +393,25 @@ public function testBundledProductWithSpecialPriceAndTierPrice() /** @var Product $bundled */ $bundled = $productRepository->get($bundledProductSku); $skus = ['bundle-product']; - $query = $this->getProductQuery($skus); $bundled->setSpecialPrice(10); - // Price view set to price_range + + // set the tier price for the bundled product + $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + /** @var $tierPriceExtensionAttributesFactory */ + $tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); + $tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); + $tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2 + ] + ] + )->setExtensionAttributes($tierPriceExtensionAttribute); + $bundled->setTierPrices($tierPrices); + // Price view set to PRICE RANGE $bundled->setPriceView(0); + $productRepository->save($bundled); $bundleRegularPrice = $bundled->getPrice(); /** @var OptionList $optionList */ @@ -411,15 +423,18 @@ public function testBundledProductWithSpecialPriceAndTierPrice() $firstOptionPrice = $bundleProductLinks[0]->getPrice(); $secondOptionPrice = $bundleProductLinks[1]->getPrice(); + //Bundled product with dynamic prices turned OFF + $query = $this->getProductQuery($skus); $result = $this->graphQlQuery($query); $this->assertArrayNotHasKey('errors', $result); $this->assertNotEmpty($result['products']['items']); $product = $result['products']['items'][0]; $this->assertNotEmpty($product['price_range']); + $this->assertNotEmpty($product['price_tiers']); //special price of 10% discount $minRegularPrice = $bundleRegularPrice + $firstOptionPrice ; - //10% discount(caused by special price) of minRegular price + //10% discount(by special price) of minRegular price $minFinalPrice = round($minRegularPrice * 0.1, 2); $maxRegularPrice = $bundleRegularPrice + $secondOptionPrice; $maxFinalPrice = round($maxRegularPrice* 0.1, 2); @@ -451,13 +466,231 @@ public function testBundledProductWithSpecialPriceAndTierPrice() ] ]; $this->assertPrices($expectedPriceRange, $product['price_range']); + $this->assertResponseFields( + $product['price_tiers'], + [ + 0 => [ + 'discount' =>[ + 'amount_off' => 1, + 'percent_off' => 10 + ], + 'final_price' =>['value'=> 9], + 'quantity' => 2 + ] + ] + ); } /** - * Check the pricing for bundled product with one of bundle items having special price set + * Check pricing for bundled product with spl price, tier prcie and dynamic price turned on * - * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php + * @magentoApiDataFixture Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php + */ + public function testBundledWithSpecialPriceAndTierPriceWithDynamicPrice() + { + $bundledProductSku = 'bundle-product'; + $simpleProductSkus= ['simple1', 'simple2']; + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + /** @var Product $bundled */ + $bundled = $productRepository->get($bundledProductSku); + $skus = ['bundle-product']; + + $simple1 = $productRepository->get($simpleProductSkus[0]); + $simple2 = $productRepository->get($simpleProductSkus[1]); + $minRegularPrice = $simple1->getPrice(); + $maxRegularPrice = $simple2->getPrice(); + + //minFinalPrice is 10% of the cheapest simple product in the bundle + $minFinalPrice = round(($simple1->getSpecialPrice())* 0.1, 2); + //special price = 10% is applied on all individual product in the bundle + $maxFinalPrice = round(($simple2->getSpecialPrice())* 0.1, 2); + + $query = $this->getProductQuery($skus); + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + $this->assertNotEmpty($product['price_tiers']); + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => $minRegularPrice + ], + "final_price" => [ + "value" => $minFinalPrice + ], + "discount" => [ + "amount_off" => $minRegularPrice - $minFinalPrice, + "percent_off" => round(($minRegularPrice - $minFinalPrice)*100/$minRegularPrice, 2) + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $maxRegularPrice + ], + "final_price" => [ + "value" => $maxFinalPrice + ], + "discount" => [ + "amount_off" => $maxRegularPrice - $maxFinalPrice, + "percent_off" => round(($maxRegularPrice - $maxFinalPrice)*100/$maxRegularPrice, 2) + ] + ] + ]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + $this->assertResponseFields( + $product['price_tiers'], + [ + 0 => [ + 'discount' =>[ + 'amount_off' => 1, + 'percent_off' => 10 + ], + 'final_price' =>['value'=> 0], + 'quantity' => 2 + ] + ] + ); + } + + /** + * Check pricing for Configurable product with each variants having special price and tier prices + * + * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable_12345.php + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ + public function testConfigurableProductWithVariantsHavingSpecialAndTierPrices() + { + $configurableProductSku ='12345'; + $objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $objectManager->get(ProductRepositoryInterface::class); + /** @var LinkManagementInterface $configurableProductLink */ + $configurableProductLinks = $objectManager->get(LinkManagement::class); + $configurableProductVariants = $configurableProductLinks->getChildren($configurableProductSku); + $tierPriceData = [ + [ + 'customer_group_id' => Group::CUST_GROUP_ALL, + 'percentage_value'=> null, + 'qty'=> 2, + 'value'=> 20 + ] + ]; + foreach ($configurableProductVariants as $configurableProductVariant) { + $configurableProductVariant->setSpecialPrice('25.99'); + $productRepository->save($configurableProductVariant); + $this->saveProductTierPrices($configurableProductVariant, $tierPriceData); + } + $sku = ['12345']; + $query = $this->getQueryConfigurableProductAndVariants($sku); + $result = $this->graphQlQuery($query); + + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']); + $regularPrice = []; + $finalPrice = []; + foreach ($configurableProductVariants as $configurableProductVariant) { + $regularPrice[] = $configurableProductVariant->getPrice(); + $finalPrice[] = $configurableProductVariant->getSpecialPrice(); + } + + $expectedPriceRange = [ + "minimum_price" => [ + "regular_price" => [ + "value" => $configurableProductVariants[0]->getPrice() + ], + "final_price" => [ + "value" => $configurableProductVariants[0]->getSpecialPrice() + ], + "discount" => [ + "amount_off" => ($regularPrice[0] - $finalPrice[0]), + "percent_off" => round(($regularPrice[0] - $finalPrice[0])*100/$regularPrice[0], 2) + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $configurableProductVariants[1]->getPrice() + ], + "final_price" => [ + "value" => $configurableProductVariants[1]->getSpecialPrice() + ], + "discount" => [ + "amount_off" => $regularPrice[1] - $finalPrice[1], + "percent_off" => round(($regularPrice[1] - $finalPrice[1])*100/$regularPrice[1], 2) ] + ] + ]; + $this->assertPrices($expectedPriceRange, $product['price_range']); + //configurable product's tier price is empty + $this->assertEmpty($product['price_tiers']); + $this->assertCount(2, $product['variants']); + + $configurableVariantsInResponse = array_map(null, $product['variants'], $configurableProductVariants); + + foreach ($configurableVariantsInResponse as $key => $configurableVariantPriceData) { + //validate that the tier prices and price range for each configurable variants are not empty + $this->assertNotEmpty($configurableVariantPriceData[0]['product']['price_range']); + $this->assertNotEmpty($configurableVariantPriceData[0]['product']['price_tiers']); + $this->assertResponseFields( + $configurableVariantsInResponse[$key][0]['product']['price_range'], + [ + "minimum_price" => [ + "regular_price" => [ + "value" => $configurableProductVariants[$key]->getPrice() + ], + "final_price" => [ + "value" => round($configurableProductVariants[$key]->getSpecialPrice(), 2) + ], + "discount" => [ + "amount_off" => ($regularPrice[$key] - $finalPrice[$key]), + "percent_off" => round(($regularPrice[$key] - $finalPrice[$key])*100/$regularPrice[$key], 2) + ] + ], + "maximum_price" => [ + "regular_price" => [ + "value" => $configurableProductVariants[$key]->getPrice() + ], + "final_price" => [ + "value" => round($configurableProductVariants[$key]->getSpecialPrice(), 2) + ], + "discount" => [ + "amount_off" => $regularPrice[$key] - $finalPrice[$key], + "percent_off" => round(($regularPrice[$key] - $finalPrice[$key])*100/$regularPrice[$key], 2) + ] + ] + ] + ); + + $this->assertResponseFields( + $configurableVariantsInResponse[$key][0]['product']['price_tiers'], + [ + 0 => [ + 'discount' =>[ + 'amount_off' => $regularPrice[$key] - $tierPriceData[0]['value'], + 'percent_off' => round( + ( + $regularPrice[$key] - $tierPriceData[0]['value'] + ) * 100/$regularPrice[$key], + 2 + ) + ], + 'final_price' =>['value'=> $tierPriceData[0]['value']], + 'quantity' => 2 + ] + ] + ); + } + } + + /** + * Check the pricing for downloadable product type * + * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php */ public function testDownloadableProductWithSpecialPriceAndTierPrices() { @@ -667,6 +900,109 @@ private function getProductQuery(array $skus): string } } } +QUERY; + } + + /** + * Get GraphQl query to fetch Configurable product and its variants by sku + * + * @param array $sku + * @return string + */ + private function getQueryConfigurableProductAndVariants(array $sku): string + { + $stringSku = '"' . implode('","', $sku) . '"'; + return <<<QUERY +{ + products(filter: {sku: {in: [$stringSku]}}, sort: {name: ASC}) { + items { + name + sku + price_range { + minimum_price {regular_price + { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + maximum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + } + } + price_tiers{ + discount{ + amount_off + percent_off + } + final_price{value} + quantity + } + ... on ConfigurableProduct{ + variants{ + product{ + + sku + price_range { + minimum_price {regular_price {value} + final_price { + value + + } + discount { + amount_off + percent_off + } + } + maximum_price { + regular_price { + value + + } + final_price { + value + + } + discount { + amount_off + percent_off + } + } + } + price_tiers{ + discount{ + amount_off + percent_off + } + final_price{value} + quantity + } + + } + } + } + } + } + } + QUERY; } @@ -709,9 +1045,11 @@ private function saveProductTierPrices(ProductInterface $product, array $tierPri $objectManager = Bootstrap::getObjectManager(); $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); foreach ($tierPriceData as $tierPrice) { - $tierPrices[] = $tierPriceFactory->create([ + $tierPrices[] = $tierPriceFactory->create( + [ 'data' => $tierPrice - ]); + ] + ); /** ProductInterface $product */ $product->setTierPrices($tierPrices); $product->save(); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php new file mode 100644 index 000000000000..986342db49cd --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php @@ -0,0 +1,130 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require __DIR__ . '/../../../Magento/Catalog/_files/multiple_products.php'; + +use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; +use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +$productIds = range(10, 12, 1); +foreach ($productIds as $productId) { + /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ + $stockItem = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Item::class); + $stockItem->load($productId, 'product_id'); + + if (!$stockItem->getProductId()) { + $stockItem->setProductId($productId); + } + $stockItem->setUseConfigManageStock(1); + $stockItem->setQty(1000); + $stockItem->setIsQtyDecimal(0); + $stockItem->setIsInStock(1); + $stockItem->save(); +} + +/** @var $product \Magento\Catalog\Model\Product */ +$product = $objectManager->create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) + ->setId(3) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Bundle Product') + ->setSku('bundle-product') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->setPriceView(0) + ->setSkuType(1) + ->setWeightType(1) + ->setPriceType(0) + ->setPrice(10.0) + ->setSpecialPrice(10) + ->setShipmentType(0) + ->setBundleOptionsData( + [ + // Required "Drop-down" option + [ + 'title' => 'Option 1', + 'default_title' => 'Option 1', + 'type' => 'select', + 'required' => 1, + 'delete' => '', + ], + + ] + )->setBundleSelectionsData( + [ + [ + [ + 'product_id' => 10, + 'selection_qty' => 1, + 'selection_price_value' => 2.75, + 'selection_can_change_qty' => 1, + 'delete' => '', + 'option_id' => 1 + ], + [ + 'product_id' => 11, + 'selection_qty' => 1, + 'selection_price_value' => 6.75, + 'selection_can_change_qty' => 1, + 'delete' => '', + 'option_id' => 1 + ] + ] + + ] + ); +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +if ($product->getBundleOptionsData()) { + $options = []; + foreach ($product->getBundleOptionsData() as $key => $optionData) { + if (!(bool)$optionData['delete']) { + $option = $objectManager->create(\Magento\Bundle\Api\Data\OptionInterfaceFactory::class) + ->create(['data' => $optionData]); + $option->setSku($product->getSku()); + $option->setOptionId(null); + + $links = []; + $bundleLinks = $product->getBundleSelectionsData(); + if (!empty($bundleLinks[$key])) { + foreach ($bundleLinks[$key] as $linkData) { + if (!(bool)$linkData['delete']) { + $link = $objectManager->create(\Magento\Bundle\Api\Data\LinkInterfaceFactory::class) + ->create(['data' => $linkData]); + $linkProduct = $productRepository->getById($linkData['product_id']); + $link->setSku($linkProduct->getSku()); + $link->setQty($linkData['selection_qty']); + $link->setPrice($linkData['selection_price_value']); + $links[] = $link; + } + } + $option->setProductLinks($links); + $options[] = $option; + } + } + } + $extension = $product->getExtensionAttributes(); + $extension->setBundleProductOptions($options); + $product->setExtensionAttributes($extension); +} +$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); +/** @var $tierPriceExtensionAttributesFactory */ +$tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); +$tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); +$tierPrices[] = $tierPriceFactory->create( + [ + 'data' => [ + 'customer_group_id' => \Magento\Customer\Model\Group::CUST_GROUP_ALL, + 'qty' => 2 + ] + ] +)->setExtensionAttributes($tierPriceExtensionAttribute); +$product->setTierPrices($tierPrices); +$product->save(); diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options_rollback.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options_rollback.php new file mode 100644 index 000000000000..a17e2604d9d0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options_rollback.php @@ -0,0 +1,7 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require __DIR__ . '/../../../Magento/Bundle/_files/product_with_multiple_options_rollback.php'; From fb126243e52caaeee57ae6405748c09a23a54013 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 27 Sep 2019 13:51:31 -0500 Subject: [PATCH 0686/1172] MC-20244: Pricing :: FPT calculation - expose weee attributes --- .../Model/Resolver/Product/PriceRange.php | 11 ++++--- .../Model/Resolver/FptResolver.php | 31 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index 2607af0ed0ab..a55f11f43268 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -16,6 +16,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Pricing\SaleableInterface; use Magento\Store\Api\Data\StoreInterface; +use Magento\Framework\Pricing\Amount\AmountInterface; /** * Format product's pricing information for price_range field @@ -80,8 +81,9 @@ private function getMinimumProductPrice(SaleableInterface $product, StoreInterfa $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); $regularPrice = $priceProvider->getMinimalRegularPrice($product)->getValue(); $finalPrice = $priceProvider->getMinimalFinalPrice($product)->getValue(); - - return $this->formatPrice($regularPrice, $finalPrice, $store); + $minPriceArray = $this->formatPrice($regularPrice, $finalPrice, $store); + $minPriceArray['model'] = $product; + return $minPriceArray; } /** @@ -96,8 +98,9 @@ private function getMaximumProductPrice(SaleableInterface $product, StoreInterfa $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); $regularPrice = $priceProvider->getMaximalRegularPrice($product)->getValue(); $finalPrice = $priceProvider->getMaximalFinalPrice($product)->getValue(); - - return $this->formatPrice($regularPrice, $finalPrice, $store); + $maxPriceArray = $this->formatPrice($regularPrice, $finalPrice, $store); + $maxPriceArray['model'] = $product; + return $maxPriceArray; } /** diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php index 1e47642aadd1..3a8bc53d308b 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -5,14 +5,29 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Resolver; +namespace Magento\WeeeGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Weee\Helper\Data; class FptResolver implements ResolverInterface { + + /** + * @var Data + */ + private $weeeHelper; + + /** + * @param Data $weeeHelper + */ + public function __construct(Data $weeeHelper) + { + $this->weeeHelper = $weeeHelper; + } + /** * @inheritdoc */ @@ -23,7 +38,19 @@ public function resolve( array $value = null, array $args = null ) { + $fptArray = []; + $product = $value['model']; + $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); + foreach ($attributes as $attribute) { + $fptArray[] = [ + 'amount' => [ + 'value' => $attribute->getData('amount'), + 'currency' => $value['final_price']['currency'], + ], + 'label' => $attribute->getData('name') + ]; + } - return []; + return $fptArray; } } From a24ebcfe8fe147ac6d3651a3b23b82e78604d2a3 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 27 Sep 2019 14:17:10 -0500 Subject: [PATCH 0687/1172] MC-20182: Update AdvancedSearch related MTF tests to Elasticsearch --- .../Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml | 2 +- .../StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml | 2 +- .../Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml | 2 +- .../Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml | 1 + .../Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml index 0ebcf59dae2b..9ad868ff6db7 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByAllParametersTest.xml @@ -19,7 +19,7 @@ <group value="mtf_migrated"/> </annotations> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> - <argument name="productName" value="abc_dfj"/> + <argument name="productName" value="$$createProduct.name$$"/> <argument name="sku" value="abc_dfj"/> <argument name="description" value="adc_Full"/> <argument name="short_description" value="abc_short"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml index 71b6ca064e0c..4d3ba22f7935 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameSkuDescriptionPriceTest.xml @@ -19,7 +19,7 @@ <group value="mtf_migrated"/> </annotations> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> - <argument name="productName" value="abc_dfj"/> + <argument name="productName" value="$$createProduct.name$$"/> <argument name="sku" value="abc_dfj"/> <argument name="description" value="adc_Full"/> <argument name="short_description" value="abc_short"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml index e6020a65cb62..f0b81e08252f 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByNameTest.xml @@ -22,7 +22,7 @@ <createData entity="ABC_123_SimpleProduct" stepKey="createProduct"/> </before> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> - <argument name="productName" value="adc_123"/> + <argument name="productName" value="$$createProduct.name$$"/> </actionGroup> </test> </tests> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml index bf2b2f7bbbee..f875021bd966 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchByPartialNameTest.xml @@ -17,6 +17,7 @@ <severity value="CRITICAL"/> <group value="searchFrontend"/> <group value="mtf_migrated"/> + <group value="SearchEngineMysql"/> </annotations> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> <argument name="productName" value="abc"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml index 16bc36f907a6..c55b3f8b8b7d 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/StorefrontAdvancedSearchEntitySimpleProductTest.xml @@ -35,7 +35,7 @@ <!-- 3. Fill test data in to field(s) 4. Click "Search" button--> <actionGroup ref="StorefrontFillFormAdvancedSearchActionGroup" stepKey="search"> - <argument name="productName" value="abc_dfj"/> + <argument name="productName" value="$$createProduct.name$$"/> <argument name="sku" value="abc_dfj"/> </actionGroup> From c614d21e600246583a4339bb8307631c02cd12b7 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Fri, 27 Sep 2019 15:11:14 -0500 Subject: [PATCH 0688/1172] MC-20337: Update tests related to Checkout, Configurable, Layered Navigation --- .../Mftf/Test/AdminCreateConfigurableProductWithImagesTest.xml | 3 +++ ...torefrontVerifyConfigurableProductLayeredNavigationTest.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithImagesTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithImagesTest.xml index 925e7a890cea..9796c14f5519 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithImagesTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithImagesTest.xml @@ -129,6 +129,9 @@ <!-- Save product --> <actionGroup ref="saveConfigurableProductAddToCurrentAttributeSet" stepKey="saveProduct"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!-- Assert configurable product in category --> <amOnPage url="$$createCategory.name$$.html" stepKey="amOnCategoryPage"/> <waitForPageLoad stepKey="waitForCategoryPageLoad"/> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVerifyConfigurableProductLayeredNavigationTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVerifyConfigurableProductLayeredNavigationTest.xml index bb69122dc0be..182c8c069ab2 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVerifyConfigurableProductLayeredNavigationTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontVerifyConfigurableProductLayeredNavigationTest.xml @@ -135,6 +135,9 @@ <waitForPageLoad stepKey="waitForPageLoad1"/> <see selector="{{AdminCategoryMessagesSection.SuccessMessage}}" userInput="You saved the product." stepKey="messageYouSavedTheProductIsShown"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Open Category in Store Front and select product attribute option from sidebar --> <actionGroup ref="SelectStorefrontSideBarAttributeOption" stepKey="selectStorefrontProductAttributeOption"> <argument name="categoryName" value="$$createCategory.name$$"/> From 9a5c8ff2336216c00045e14cbafaba21d5e2d32d Mon Sep 17 00:00:00 2001 From: Arnob Saha <arnobsh@gmail.com> Date: Mon, 23 Sep 2019 16:22:53 -0500 Subject: [PATCH 0689/1172] MC-20229: Different number of URL rewrites when editing or importing a product - Anchors links on URL Rewrite for categories --- .../Observer/AfterImportDataObserver.php | 106 ++++++++++-------- .../Observer/AfterImportDataObserverTest.php | 69 ++++++++---- ...inUrlRewritesForProductAfterImportTest.xml | 85 ++++++++++++++ .../catalog_import_products_url_rewrite.csv | 2 + .../Model/Import/ProductTest.php | 27 ++--- 5 files changed, 206 insertions(+), 83 deletions(-) create mode 100644 app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml create mode 100644 dev/tests/acceptance/tests/_data/catalog_import_products_url_rewrite.csv diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php index 704b60a8aaf2..b1dfa79373a0 100644 --- a/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php +++ b/app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php @@ -23,7 +23,6 @@ use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\ImportExport\Model\Import as ImportExport; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; @@ -252,7 +251,7 @@ public function execute(Observer $observer) * @throws LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function _populateForUrlGeneration($rowData) + private function _populateForUrlGeneration($rowData) { $newSku = $this->import->getNewSku($rowData[ImportProduct::COL_SKU]); $oldSku = $this->import->getOldSku(); @@ -321,7 +320,7 @@ private function isNeedToPopulateForUrlGeneration($rowData, $newSku, $oldSku): b * @param array $rowData * @return void */ - protected function setStoreToProduct(Product $product, array $rowData) + private function setStoreToProduct(Product $product, array $rowData) { if (!empty($rowData[ImportProduct::COL_STORE]) && ($storeId = $this->import->getStoreIdByCode($rowData[ImportProduct::COL_STORE])) @@ -339,7 +338,7 @@ protected function setStoreToProduct(Product $product, array $rowData) * @param string $storeId * @return $this */ - protected function addProductToImport($product, $storeId) + private function addProductToImport($product, $storeId) { if ($product->getVisibility() == (string)Visibility::getOptionArray()[Visibility::VISIBILITY_NOT_VISIBLE]) { return $this; @@ -357,7 +356,7 @@ protected function addProductToImport($product, $storeId) * @param Product $product * @return $this */ - protected function populateGlobalProduct($product) + private function populateGlobalProduct($product) { foreach ($this->import->getProductWebsites($product->getSku()) as $websiteId) { foreach ($this->websitesToStoreIds[$websiteId] as $storeId) { @@ -376,7 +375,7 @@ protected function populateGlobalProduct($product) * @return UrlRewrite[] * @throws LocalizedException */ - protected function generateUrls() + private function generateUrls() { $mergeDataProvider = clone $this->mergeDataProviderPrototype; $mergeDataProvider->merge($this->canonicalUrlRewriteGenerate()); @@ -398,7 +397,7 @@ protected function generateUrls() * @param int|null $storeId * @return bool */ - protected function isGlobalScope($storeId) + private function isGlobalScope($storeId) { return null === $storeId || $storeId == Store::DEFAULT_STORE_ID; } @@ -408,7 +407,7 @@ protected function isGlobalScope($storeId) * * @return UrlRewrite[] */ - protected function canonicalUrlRewriteGenerate() + private function canonicalUrlRewriteGenerate() { $urls = []; foreach ($this->products as $productId => $productsByStores) { @@ -433,7 +432,7 @@ protected function canonicalUrlRewriteGenerate() * @return UrlRewrite[] * @throws LocalizedException */ - protected function categoriesUrlRewriteGenerate() + private function categoriesUrlRewriteGenerate(): array { $urls = []; foreach ($this->products as $productId => $productsByStores) { @@ -444,17 +443,24 @@ protected function categoriesUrlRewriteGenerate() continue; } $requestPath = $this->productUrlPathGenerator->getUrlPathWithSuffix($product, $storeId, $category); - $urls[] = $this->urlRewriteFactory->create() - ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE) - ->setEntityId($productId) - ->setRequestPath($requestPath) - ->setTargetPath($this->productUrlPathGenerator->getCanonicalUrlPath($product, $category)) - ->setStoreId($storeId) - ->setMetadata(['category_id' => $category->getId()]); + $urls[] = [ + $this->urlRewriteFactory->create() + ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE) + ->setEntityId($productId) + ->setRequestPath($requestPath) + ->setTargetPath($this->productUrlPathGenerator->getCanonicalUrlPath($product, $category)) + ->setStoreId($storeId) + ->setMetadata(['category_id' => $category->getId()]) + ]; + $parentCategoryIds = $category->getAnchorsAbove(); + if ($parentCategoryIds) { + $urls[] = $this->getParentCategoriesUrlRewrites($parentCategoryIds, $storeId, $product); + } } } } - return $urls; + $result = !empty($urls) ? array_merge(...$urls) : []; + return $result; } /** @@ -462,7 +468,7 @@ protected function categoriesUrlRewriteGenerate() * * @return UrlRewrite[] */ - protected function currentUrlRewritesRegenerate() + private function currentUrlRewritesRegenerate() { $currentUrlRewrites = $this->urlFinder->findAllByData( [ @@ -496,7 +502,7 @@ protected function currentUrlRewritesRegenerate() * @param Category $category * @return array */ - protected function generateForAutogenerated($url, $category) + private function generateForAutogenerated($url, $category) { $storeId = $url->getStoreId(); $productId = $url->getEntityId(); @@ -532,7 +538,7 @@ protected function generateForAutogenerated($url, $category) * @param Category $category * @return array */ - protected function generateForCustom($url, $category) + private function generateForCustom($url, $category) { $storeId = $url->getStoreId(); $productId = $url->getEntityId(); @@ -566,7 +572,7 @@ protected function generateForCustom($url, $category) * @param UrlRewrite $url * @return Category|null|bool */ - protected function retrieveCategoryFromMetadata($url) + private function retrieveCategoryFromMetadata($url) { $metadata = $url->getMetadata(); if (isset($metadata['category_id'])) { @@ -576,32 +582,6 @@ protected function retrieveCategoryFromMetadata($url) return null; } - /** - * Check, category suited for url-rewrite generation. - * - * @param Category $category - * @param int $storeId - * @return bool - * @throws NoSuchEntityException - */ - protected function isCategoryProperForGenerating($category, $storeId) - { - if (isset($this->acceptableCategories[$storeId]) && - isset($this->acceptableCategories[$storeId][$category->getId()])) { - return $this->acceptableCategories[$storeId][$category->getId()]; - } - $acceptable = false; - if ($category->getParentId() != Category::TREE_ROOT_ID) { - list(, $rootCategoryId) = $category->getParentIds(); - $acceptable = ($rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId()); - } - if (!isset($this->acceptableCategories[$storeId])) { - $this->acceptableCategories[$storeId] = []; - } - $this->acceptableCategories[$storeId][$category->getId()] = $acceptable; - return $acceptable; - } - /** * Get category by id considering store scope. * @@ -635,4 +615,36 @@ private function isCategoryRewritesEnabled() { return (bool)$this->scopeConfig->getValue('catalog/seo/generate_category_product_rewrites'); } + + /** + * Generate url-rewrite for anchor parent-categories. + * + * @param array $categoryIds + * @param int $storeId + * @param Product $product + * @return array + * @throws LocalizedException + */ + private function getParentCategoriesUrlRewrites(array $categoryIds, int $storeId, Product $product): array + { + $urls = []; + foreach ($categoryIds as $categoryId) { + $category = $this->getCategoryById($categoryId, $storeId); + if ($category->getParentId() == Category::TREE_ROOT_ID) { + continue; + } + $requestPath = $this->productUrlPathGenerator + ->getUrlPathWithSuffix($product, $storeId, $category); + $targetPath = $this->productUrlPathGenerator + ->getCanonicalUrlPath($product, $category); + $urls[] = $this->urlRewriteFactory->create() + ->setEntityType(ProductUrlRewriteGenerator::ENTITY_TYPE) + ->setEntityId($product->getId()) + ->setRequestPath($requestPath) + ->setTargetPath($targetPath) + ->setStoreId($storeId) + ->setMetadata(['category_id' => $category->getId()]); + } + return $urls; + } } diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php index 3984d949332d..94fe6ae8c54d 100644 --- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Observer/AfterImportDataObserverTest.php @@ -153,24 +153,32 @@ class AfterImportDataObserverTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->importProduct = $this->createPartialMock(\Magento\CatalogImportExport\Model\Import\Product::class, [ + $this->importProduct = $this->createPartialMock( + \Magento\CatalogImportExport\Model\Import\Product::class, + [ 'getNewSku', 'getProductCategories', 'getProductWebsites', 'getStoreIdByCode', 'getCategoryProcessor', - ]); - $this->catalogProductFactory = $this->createPartialMock(\Magento\Catalog\Model\ProductFactory::class, [ + ] + ); + $this->catalogProductFactory = $this->createPartialMock( + \Magento\Catalog\Model\ProductFactory::class, + [ 'create', - ]); + ] + ); $this->storeManager = $this ->getMockBuilder( \Magento\Store\Model\StoreManagerInterface::class ) ->disableOriginalConstructor() - ->setMethods([ - 'getWebsite', - ]) + ->setMethods( + [ + 'getWebsite', + ] + ) ->getMockForAbstractClass(); $this->event = $this->createPartialMock(\Magento\Framework\Event::class, ['getAdapter', 'getBunch']); $this->event->expects($this->any())->method('getAdapter')->willReturn($this->importProduct); @@ -202,9 +210,11 @@ protected function setUp() ); $this->urlFinder = $this ->getMockBuilder(\Magento\UrlRewrite\Model\UrlFinderInterface::class) - ->setMethods([ - 'findAllByData', - ]) + ->setMethods( + [ + 'findAllByData', + ] + ) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -269,9 +279,12 @@ public function testAfterImportData() $newSku = [['entity_id' => 'value'], ['entity_id' => 'value3']]; $websiteId = 'websiteId value'; $productsCount = count($this->products); - $websiteMock = $this->createPartialMock(\Magento\Store\Model\Website::class, [ + $websiteMock = $this->createPartialMock( + \Magento\Store\Model\Website::class, + [ 'getStoreIds', - ]); + ] + ); $storeIds = [1, Store::DEFAULT_STORE_ID]; $websiteMock ->expects($this->once()) @@ -315,13 +328,16 @@ public function testAfterImportData() ->expects($this->exactly(1)) ->method('getStoreIdByCode') ->will($this->returnValueMap($map)); - $product = $this->createPartialMock(\Magento\Catalog\Model\Product::class, [ + $product = $this->createPartialMock( + \Magento\Catalog\Model\Product::class, + [ 'getId', 'setId', 'getSku', 'setStoreId', 'getStoreId', - ]); + ] + ); $product ->expects($this->exactly($productsCount)) ->method('setId') @@ -341,17 +357,21 @@ public function testAfterImportData() $product ->expects($this->exactly($productsCount)) ->method('getSku') - ->will($this->onConsecutiveCalls( - $this->products[0]['sku'], - $this->products[1]['sku'] - )); + ->will( + $this->onConsecutiveCalls( + $this->products[0]['sku'], + $this->products[1]['sku'] + ) + ); $product ->expects($this->exactly($productsCount)) ->method('getStoreId') - ->will($this->onConsecutiveCalls( - $this->products[0][ImportProduct::COL_STORE], - $this->products[1][ImportProduct::COL_STORE] - )); + ->will( + $this->onConsecutiveCalls( + $this->products[0][ImportProduct::COL_STORE], + $this->products[1][ImportProduct::COL_STORE] + ) + ); $product ->expects($this->exactly($productsCount)) ->method('setStoreId') @@ -540,7 +560,10 @@ public function testCategoriesUrlRewriteGenerate() ->expects($this->any()) ->method('getId') ->will($this->returnValue($this->categoryId)); - + $category + ->expects($this->any()) + ->method('getAnchorsAbove') + ->willReturn([]); $categoryCollection = $this->getMockBuilder(CategoryCollection::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml new file mode 100644 index 000000000000..a3d3b897ef75 --- /dev/null +++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminUrlRewritesForProductAfterImportTest"> + <annotations> + <features value="Url Rewrite"/> + <stories value="Different number of URL rewrites when editing or importing a product"/> + <title value="Verify the number of URL rewrites when edit or import product"/> + <description value="After importing products to admin verify the number of URL including categories matches"/> + <severity value="MAJOR"/> + <testCaseId value="MC-20229"/> + <group value="urlRewrite"/> + </annotations> + <before> + <comment userInput="Set the configuration for Generate category/product URL Rewrites" stepKey="commentSetURLRewriteConfiguration" /> + <comment userInput="Enable config to generate category/product URL Rewrites " stepKey="commentEnableConfig" /> + <magentoCLI command="config:set catalog/seo/generate_category_product_rewrites 1" stepKey="enableGenerateUrlRewrite"/> + <createData entity="NewRootCategory" stepKey="simpleSubCategory1"> + <field key="parent_id">2</field> + </createData> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory2"> + <requiredEntity createDataKey="simpleSubCategory1"/> + </createData> + <createData entity="SubCategoryWithParent" stepKey="simpleSubCategory3"> + <requiredEntity createDataKey="simpleSubCategory2"/> + </createData> + <comment userInput="Create Simple product 1 and assign it to Category 3 " stepKey="commentCreateSimpleProduct" /> + <createData entity="SimpleProductAfterImport1" stepKey="createSimpleProduct"> + <requiredEntity createDataKey="simpleSubCategory3"/> + </createData> + </before> + <after> + <comment userInput="Delete all products that replaced products in the before block post import " stepKey="commentDeleteAllProducts" /> + <deleteData stepKey="deleteSimpleProduct1" url="/V1/products/SimpleProductForTest1"/> + <deleteData createDataKey="simpleSubCategory3" stepKey="deleteSimpleSubCategory3"/> + <deleteData createDataKey="simpleSubCategory2" stepKey="deleteSimpleSubCategory2"/> + <deleteData createDataKey="simpleSubCategory1" stepKey="deleteSimpleSubCategory1"/> + <comment userInput="Disable config to generate category/product URL Rewrites " stepKey="commentDisableConfig" /> + <magentoCLI command="config:set catalog/seo/generate_category_product_rewrites 0" stepKey="disableGenerateUrlRewrite"/> + <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> + </after> + + <comment userInput="1. Log in to Admin " stepKey="commentAdminLogin" /> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + + <comment userInput="2. Open Marketing - SEO and Search - URL Rewrites " stepKey="commentVerifyUrlRewrite" /> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$.html" stepKey="inputProductName"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$.html)}}" stepKey="seeValue4"/> + + <comment userInput="3. Import products with add/update behavior " stepKey="commentProductImport" /> + <actionGroup ref="AdminImportProductsActionGroup" stepKey="adminImportProducts"> + <argument name="behavior" value="Add/Update"/> + <argument name="importFile" value="catalog_import_products_url_rewrite.csv"/> + <argument name="importNoticeMessage" value="Created: 0, Updated: 1, Deleted: 0"/> + </actionGroup> + + <comment userInput="4. Assert Simple Product1 on grid " stepKey="commentVerifyProduct" /> + <actionGroup ref="AssertProductOnAdminGridActionGroup" stepKey="assertSimpleProduct1OnAdminGrid"> + <argument name="product" value="SimpleProductAfterImport1"/> + </actionGroup> + + <comment userInput="5. Open Marketing - SEO and Search - URL Rewrites" stepKey="commentVerifyURLAfterImport" /> + <amOnPage url="{{AdminUrlRewriteIndexPage.url}}" stepKey="amOnUrlRewriteIndexPage2"/> + <fillField selector="{{AdminUrlRewriteIndexSection.requestPathFilter}}" userInput="$createSimpleProduct.custom_attributes[url_key]$-new.html" stepKey="inputProductName2"/> + <click selector="{{AdminDataGridHeaderSection.applyFilters}}" stepKey="clickSearchButton2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue1"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue2"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue3"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue4"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue5"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue6"/> + <seeElement selector="{{AdminUrlRewriteIndexSection.requestPathColumnValue($simpleSubCategory1.custom_attributes[url_key]$/$simpleSubCategory2.custom_attributes[url_key]$/$simpleSubCategory3.custom_attributes[url_key]$/$createSimpleProduct.custom_attributes[url_key]$-new.html)}}" stepKey="seeInListValue7"/> + </test> +</tests> diff --git a/dev/tests/acceptance/tests/_data/catalog_import_products_url_rewrite.csv b/dev/tests/acceptance/tests/_data/catalog_import_products_url_rewrite.csv new file mode 100644 index 000000000000..95e359ce7a1d --- /dev/null +++ b/dev/tests/acceptance/tests/_data/catalog_import_products_url_rewrite.csv @@ -0,0 +1,2 @@ +sku,url_key +SimpleProductForTest1,SimpleProductAfterImport1-new diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 1b33cd695d06..553242f0daec 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -24,10 +24,10 @@ use Magento\Framework\Filesystem; use Magento\Framework\Registry; use Magento\ImportExport\Model\Import; +use Magento\ImportExport\Model\Import\Source\Csv; use Magento\Store\Model\Store; use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection; use Psr\Log\LoggerInterface; -use Magento\ImportExport\Model\Import\Source\Csv; /** * Class ProductTest @@ -1744,7 +1744,11 @@ public function testUpdateUrlRewritesOnImport() /** @var \Magento\Catalog\Model\Product $product */ $product = $this->objectManager->create(\Magento\Catalog\Model\ProductRepository::class)->get('simple'); - + $listOfProductUrlKeys = [ + sprintf('%s.html', $product->getUrlKey()), + sprintf('men/tops/%s.html', $product->getUrlKey()), + sprintf('men/%s.html', $product->getUrlKey()) + ]; $repUrlRewriteCol = $this->objectManager->create( UrlRewriteCollection::class ); @@ -1754,18 +1758,15 @@ public function testUpdateUrlRewritesOnImport() ->addFieldToFilter('entity_id', ['eq'=> $product->getEntityId()]) ->addFieldToFilter('entity_type', ['eq'=> 'product']) ->load(); + $listOfUrlRewriteIds = $collUrlRewrite->getAllIds(); + $this->assertCount(3, $collUrlRewrite); - $this->assertCount(2, $collUrlRewrite); - - $this->assertEquals( - sprintf('%s.html', $product->getUrlKey()), - $collUrlRewrite->getFirstItem()->getRequestPath() - ); - - $this->assertContains( - sprintf('men/tops/%s.html', $product->getUrlKey()), - $collUrlRewrite->getLastItem()->getRequestPath() - ); + foreach ($listOfUrlRewriteIds as $key => $id) { + $this->assertEquals( + $listOfProductUrlKeys[$key], + $collUrlRewrite->getItemById($id)->getRequestPath() + ); + } } /** From beb1791e2df296e29f2d0350ec282cf2f22d0f46 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Fri, 27 Sep 2019 15:23:30 -0500 Subject: [PATCH 0690/1172] MC-20336: Update tests related to Catalog Search and Swatches --- .../Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml index 08cffcccd520..f93b9ffd83b8 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml @@ -27,6 +27,7 @@ <fillField selector="{{AdminCatalogSearchConfigurationSection.minQueryLength}}" userInput="{{minLength}}" stepKey="setMinQueryLength"/> <!--Scrolling till Category Permissions to make sure the collapse tab for Catalog Search is visible--> <scrollTo selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="scrollToCatalogSearchTab1"/> + <waitForElementVisible selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="waitForElementVisibleWhileScrolling"/> <click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseTab"/> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig"/> <waitForPageLoad stepKey="waitForConfigSaved"/> From 684e8fb52d0db6d20b17128833455cdfa02367a8 Mon Sep 17 00:00:00 2001 From: Alex Taranovsky <firster@atwix.com> Date: Fri, 27 Sep 2019 15:23:50 +0300 Subject: [PATCH 0691/1172] Magento_CurrencySymbol module. Replace replace deprecated message functions --- .../Adminhtml/System/Currency/FetchRates.php | 14 ++-- .../Adminhtml/System/Currency/SaveRates.php | 17 +++-- .../Adminhtml/System/Currencysymbol/Save.php | 8 ++- .../System/Currency/SaveRatesTest.php | 67 +++++++++++++++++++ .../System/Currencysymbol/SaveTest.php | 2 +- 5 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currency/SaveRatesTest.php diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php index 34d24a8b0a7a..a6e29db1e1c4 100644 --- a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php +++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -13,6 +12,9 @@ use Magento\Framework\Controller\ResultFactory; use Magento\CurrencySymbol\Controller\Adminhtml\System\Currency as CurrencyAction; +/** + * Class FetchRates + */ class FetchRates extends CurrencyAction implements HttpGetActionInterface, HttpPostActionInterface { /** @@ -41,20 +43,20 @@ public function execute() } $rates = $importModel->fetchRates(); $errors = $importModel->getMessages(); - if (sizeof($errors) > 0) { + if (count($errors) > 0) { foreach ($errors as $error) { - $this->messageManager->addWarning($error); + $this->messageManager->addWarningMessage($error); } - $this->messageManager->addWarning( + $this->messageManager->addWarningMessage( __('Click "Save" to apply the rates we found.') ); } else { - $this->messageManager->addSuccess(__('Click "Save" to apply the rates we found.')); + $this->messageManager->addSuccessMessage(__('Click "Save" to apply the rates we found.')); } $backendSession->setRates($rates); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php index 8dd6b5e6fac4..f5e1fdbdb0c5 100644 --- a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php +++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -9,6 +8,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +/** + * Class SaveRates + */ class SaveRates extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency implements HttpPostActionInterface { /** @@ -23,12 +25,13 @@ public function execute() try { foreach ($data as $currencyCode => $rate) { foreach ($rate as $currencyTo => $value) { - $value = abs($this->_objectManager->get( - \Magento\Framework\Locale\FormatInterface::class - )->getNumber($value)); + $value = abs( + $this->_objectManager->get(\Magento\Framework\Locale\FormatInterface::class) + ->getNumber($value) + ); $data[$currencyCode][$currencyTo] = $value; if ($value == 0) { - $this->messageManager->addWarning( + $this->messageManager->addWarningMessage( __('Please correct the input data for "%1 => %2" rate.', $currencyCode, $currencyTo) ); } @@ -36,9 +39,9 @@ public function execute() } $this->_objectManager->create(\Magento\Directory\Model\Currency::class)->saveRates($data); - $this->messageManager->addSuccess(__('All valid rates have been saved.')); + $this->messageManager->addSuccessMessage(__('All valid rates have been saved.')); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } } diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php index 703117f34fce..f77976cc9e2f 100644 --- a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php +++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ @@ -8,6 +7,9 @@ use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; +/** + * Class Save + */ class Save extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol implements HttpPostActionInterface { /** @@ -29,9 +31,9 @@ public function execute() try { $this->_objectManager->create(\Magento\CurrencySymbol\Model\System\Currencysymbol::class) ->setCurrencySymbolsData($symbolsDataArray); - $this->messageManager->addSuccess(__('You applied the custom currency symbols.')); + $this->messageManager->addSuccessMessage(__('You applied the custom currency symbols.')); } catch (\Exception $e) { - $this->messageManager->addError($e->getMessage()); + $this->messageManager->addErrorMessage($e->getMessage()); } $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*'))); diff --git a/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currency/SaveRatesTest.php b/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currency/SaveRatesTest.php new file mode 100644 index 000000000000..b561c02c7b36 --- /dev/null +++ b/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currency/SaveRatesTest.php @@ -0,0 +1,67 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CurrencySymbol\Test\Unit\Controller\Adminhtml\System\Currency; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +/** + * Class SaveRatesTest + */ +class SaveRatesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency\SaveRates + */ + protected $action; + + /** + * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $requestMock; + + /** + * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $responseMock; + + /** + * + */ + protected function setUp() + { + $objectManager = new ObjectManager($this); + + $this->requestMock = $this->createMock(\Magento\Framework\App\RequestInterface::class); + + $this->responseMock = $this->createPartialMock( + \Magento\Framework\App\ResponseInterface::class, + ['setRedirect', 'sendResponse'] + ); + + $this->action = $objectManager->getObject( + \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency\SaveRates::class, + [ + 'request' => $this->requestMock, + 'response' => $this->responseMock, + ] + ); + } + + /** + * + */ + public function testWithNullRateExecute() + { + $this->requestMock->expects($this->once()) + ->method('getParam') + ->with('rate') + ->willReturn(null); + + $this->responseMock->expects($this->once())->method('setRedirect'); + + $this->action->execute(); + } +} diff --git a/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currencysymbol/SaveTest.php b/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currencysymbol/SaveTest.php index 0863104a2bf8..06f4294ce639 100644 --- a/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currencysymbol/SaveTest.php +++ b/app/code/Magento/CurrencySymbol/Test/Unit/Controller/Adminhtml/System/Currencysymbol/SaveTest.php @@ -128,7 +128,7 @@ public function testExecute() ->willReturn($this->filterManagerMock); $this->messageManagerMock->expects($this->once()) - ->method('addSuccess') + ->method('addSuccessMessage') ->with(__('You applied the custom currency symbols.')); $this->action->execute(); From b27a5767a5ac6e53b434d2590b5daeeaef2a0cfd Mon Sep 17 00:00:00 2001 From: Ivan Koliadynskyy <i.koliadynskyy@gmail.com> Date: Fri, 27 Sep 2019 15:37:33 +0300 Subject: [PATCH 0692/1172] Fix for CLI Backup doesn't work properly when directory is a symlink #13218 --- lib/internal/Magento/Framework/Backup/Archive/Tar.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Backup/Archive/Tar.php b/lib/internal/Magento/Framework/Backup/Archive/Tar.php index ca8e7caf9884..616952a0404c 100644 --- a/lib/internal/Magento/Framework/Backup/Archive/Tar.php +++ b/lib/internal/Magento/Framework/Backup/Archive/Tar.php @@ -38,9 +38,8 @@ class Tar extends \Magento\Framework\Archive\Tar protected function _createTar($skipRoot = false, $finalize = false) { $path = $this->_getCurrentFile(); - $filesystemIterator = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($path), + new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS), RecursiveIteratorIterator::SELF_FIRST ); @@ -50,6 +49,10 @@ protected function _createTar($skipRoot = false, $finalize = false) ); foreach ($iterator as $item) { + // exclude symlinks to do not get duplicates after follow symlinks in RecursiveDirectoryIterator + if($item->isLink()) { + continue; + } $this->_setCurrentFile($item->getPathname()); $this->_packAndWriteCurrentFile(); } From 777e8b15957f6f2ce4832024cf37014a728693d3 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 27 Sep 2019 16:57:15 -0500 Subject: [PATCH 0693/1172] MC-18403: Pricing :: Product pricing schema - fix schema wording --- .../Magento/CatalogCustomerGraphQl/etc/schema.graphqls | 4 ++-- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls index 84a3d172dab8..17880584bf16 100644 --- a/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogCustomerGraphQl/etc/schema.graphqls @@ -15,8 +15,8 @@ type ProductTierPrices @doc(description: "ProductTierPrices is deprecated and ha } -type TierPrice @doc(description: "TierPrice defines a tier price, which is a price offered based on a particular quantity purchased.") { +type TierPrice @doc(description: "A price based on the quantity purchased.") { final_price: Money @doc(desription: "The price of the product at this tier.") - quantity: Float @doc(description: "The number of items that must be purchased to qualify for this price tier.") + quantity: Float @doc(description: "The minimum number of items that must be purchased to qualify for this price tier.") discount: ProductDiscount @doc(description: "The price discount that this tier represents.") } diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 4d27dfc47aa1..2dce5cfd4a6e 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -41,13 +41,13 @@ enum PriceTypeEnum @doc(description: "This enumeration the price type.") { DYNAMIC } -type ProductPrices @deprecated(reason: "Use PriceRange instead.") @doc(description: "The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { +type ProductPrices @doc(description: "ProductPrices is deprecated, replaced by PriceRange. The ProductPrices object contains the regular price of an item, as well as its minimum and maximum prices. Only composite products, which include bundle, configurable, and grouped products, can contain a minimum and maximum price.") { minimalPrice: Price @deprecated(reason: "Use PriceRange.minimum_price.") @doc(description: "The lowest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the from value.") maximalPrice: Price @deprecated(reason: "Use PriceRange.maximum_price.") @doc(description: "The highest possible final price for all the options defined within a composite product. If you are specifying a price range, this would be the to value.") regularPrice: Price @deprecated(reason: "Use regular_price from PriceRange.minimum_price or PriceRange.maximum_price.") @doc(description: "The base price of a product.") } -type PriceRange @doc(description: "Price range for a product. If the product only has a single price minimum and maximum price will be the same."){ +type PriceRange @doc(description: "Price range for a product. If the product has a single price, the minimum and maximum price will be the same."){ minimum_price: ProductPrice! @doc(description: "The lowest possible price for the product.") maximum_price: ProductPrice @doc(description: "The highest possible price for the product.") } @@ -58,9 +58,9 @@ type ProductPrice @doc(description: "Represents a product price.") { discount: ProductDiscount @doc(description: "The price discount. Represents the difference between the regular and final price.") } -type ProductDiscount @doc(description: "Price discount applied to a product.") { - percent_off: Float @doc(description: "The discount expressed a percent value.") - amount_off: Float @doc(description: "The discount expressed an absolute value.") +type ProductDiscount @doc(description: "A discount applied to a product price.") { + percent_off: Float @doc(description: "The discount expressed a percentage.") + amount_off: Float @doc(description: "The actual value of the discount.") } type ProductLinks implements ProductLinksInterface @doc(description: "ProductLinks is an implementation of ProductLinksInterface.") { From 4bad17ba7651575b420ef6433c901670bd4f2a96 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Fri, 27 Sep 2019 17:17:19 -0500 Subject: [PATCH 0694/1172] MC-20336: Update tests related to Catalog Search and Swatches "Added wait condition to make the page gets loaded till it finishes the text to be filled" --- .../Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml index f93b9ffd83b8..e1c2a7867850 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml @@ -25,9 +25,9 @@ <see userInput="{{MinMaxQueryLength.Hint}}" selector="{{AdminCatalogSearchConfigurationSection.maxQueryLengthHint}}" stepKey="seeHint2"/> <uncheckOption selector="{{AdminCatalogSearchConfigurationSection.minQueryLengthInherit}}" stepKey="uncheckSystemValue"/> <fillField selector="{{AdminCatalogSearchConfigurationSection.minQueryLength}}" userInput="{{minLength}}" stepKey="setMinQueryLength"/> + <waitForPageLoad stepKey="waitForTextToBeFilled"/> <!--Scrolling till Category Permissions to make sure the collapse tab for Catalog Search is visible--> <scrollTo selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="scrollToCatalogSearchTab1"/> - <waitForElementVisible selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="waitForElementVisibleWhileScrolling"/> <click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseTab"/> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig"/> <waitForPageLoad stepKey="waitForConfigSaved"/> From 144b9ee42e937f824a6322a39bd7a26fa631bc39 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 27 Sep 2019 17:24:02 -0500 Subject: [PATCH 0695/1172] MC-20244: Pricing :: FPT calculation - refactor to list individual attributes --- .../Model/Resolver/Product/PriceRange.php | 15 +- .../Magento/Weee/Model/ResourceModel/Tax.php | 85 ++++--- app/code/Magento/Weee/Model/Tax.php | 224 ++++++++++-------- .../Model/Resolver/FptResolver.php | 28 ++- 4 files changed, 209 insertions(+), 143 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index a55f11f43268..9396b1f02b97 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -16,7 +16,6 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Pricing\SaleableInterface; use Magento\Store\Api\Data\StoreInterface; -use Magento\Framework\Pricing\Amount\AmountInterface; /** * Format product's pricing information for price_range field @@ -63,10 +62,16 @@ public function resolve( $product = $value['model']; $product->unsetData('minimal_price'); - return [ - 'minimum_price' => $this->getMinimumProductPrice($product, $store), - 'maximum_price' => $this->getMaximumProductPrice($product, $store) - ]; + $requestedFields = $info->getFieldSelection(10); + $returnArray = []; + + if (isset($requestedFields['minimum_price'])) { + $returnArray['minimum_price'] = $this->getMinimumProductPrice($product, $store); + } + if (isset($requestedFields['maximum_price'])) { + $returnArray['maximum_price'] = $this->getMaximumProductPrice($product, $store); + } + return $returnArray; } /** diff --git a/app/code/Magento/Weee/Model/ResourceModel/Tax.php b/app/code/Magento/Weee/Model/ResourceModel/Tax.php index b097e4a018f2..d10cd244d853 100644 --- a/app/code/Magento/Weee/Model/ResourceModel/Tax.php +++ b/app/code/Magento/Weee/Model/ResourceModel/Tax.php @@ -21,6 +21,11 @@ class Tax extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $dateTime; + /** + * @var array + */ + private $weeeTaxCalculationsByEntityCache = []; + /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Framework\Stdlib\DateTime $dateTime @@ -100,43 +105,57 @@ public function isWeeeInLocation($countryId, $regionId, $websiteId) */ public function fetchWeeeTaxCalculationsByEntity($countryId, $regionId, $websiteId, $storeId, $entityId) { - $attributeSelect = $this->getConnection()->select(); - $attributeSelect->from( - ['eavTable' => $this->getTable('eav_attribute')], - ['eavTable.attribute_code', 'eavTable.attribute_id', 'eavTable.frontend_label'] - )->joinLeft( - ['eavLabel' => $this->getTable('eav_attribute_label')], - 'eavLabel.attribute_id = eavTable.attribute_id and eavLabel.store_id = ' .((int) $storeId), - 'eavLabel.value as label_value' - )->joinInner( - ['weeeTax' => $this->getTable('weee_tax')], - 'weeeTax.attribute_id = eavTable.attribute_id', - 'weeeTax.value as weee_value' - )->where( - 'eavTable.frontend_input = ?', - 'weee' - )->where( - 'weeeTax.website_id IN(?)', - [$websiteId, 0] - )->where( - 'weeeTax.country = ?', - $countryId - )->where( - 'weeeTax.state IN(?)', - [$regionId, 0] - )->where( - 'weeeTax.entity_id = ?', - (int)$entityId + $cacheKey = sprintf( + '%s-%s-%s-%s-%s', + $countryId, + $regionId, + $websiteId, + $storeId, + $entityId ); + if (!isset($this->weeeTaxCalculationsByEntityCache[$cacheKey])) { + $attributeSelect = $this->getConnection()->select(); + $attributeSelect->from( + ['eavTable' => $this->getTable('eav_attribute')], + ['eavTable.attribute_code', 'eavTable.attribute_id', 'eavTable.frontend_label'] + )->joinLeft( + ['eavLabel' => $this->getTable('eav_attribute_label')], + 'eavLabel.attribute_id = eavTable.attribute_id and eavLabel.store_id = ' . ((int)$storeId), + 'eavLabel.value as label_value' + )->joinInner( + ['weeeTax' => $this->getTable('weee_tax')], + 'weeeTax.attribute_id = eavTable.attribute_id', + 'weeeTax.value as weee_value' + )->where( + 'eavTable.frontend_input = ?', + 'weee' + )->where( + 'weeeTax.website_id IN(?)', + [$websiteId, 0] + )->where( + 'weeeTax.country = ?', + $countryId + )->where( + 'weeeTax.state IN(?)', + [$regionId, 0] + )->where( + 'weeeTax.entity_id = ?', + (int)$entityId + ); + - $order = ['weeeTax.state ' . \Magento\Framework\DB\Select::SQL_DESC, - 'weeeTax.website_id ' . \Magento\Framework\DB\Select::SQL_DESC]; - $attributeSelect->order($order); + $order = ['weeeTax.state ' . \Magento\Framework\DB\Select::SQL_DESC, + 'weeeTax.website_id ' . \Magento\Framework\DB\Select::SQL_DESC]; + $attributeSelect->order($order); - $values = $this->getConnection()->fetchAll($attributeSelect); + $values = $this->getConnection()->fetchAll($attributeSelect); - if ($values) { - return $values; + if ($values) { + $this->weeeTaxCalculationsByEntityCache[$cacheKey] = $values; + return $values; + } + } else { + return $this->weeeTaxCalculationsByEntityCache[$cacheKey]; } return []; diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index 941faed0498f..3bc95d6f6f9f 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -88,6 +88,9 @@ class Tax extends \Magento\Framework\Model\AbstractModel */ protected $accountManagement; + /** @var array */ + private $weeAtrributesCache = []; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -247,128 +250,143 @@ public function getProductWeeeAttributes( $calculateTax = null, $round = true ) { + $cacheKey = sprintf( + '%s-%s-%s-%s-%s', + $product->getId(), + $shipping && $shipping->getId() ? $shipping->getId() : '', + $billing && $billing->getId() ? $billing->getId() : '', + $website && $website->getId() ? $website->getId() : $website ? $website : '', + $calculateTax, + $round + ); $result = []; - $websiteId = null; - /** @var \Magento\Store\Model\Store $store */ - $store = null; - if (!$website) { - $store = $product->getStore(); - if ($store) { - $websiteId = $store->getWebsiteId(); + if (isset($this->weeAtrributesCache[$cacheKey])) { + $result = $this->weeAtrributesCache[$cacheKey]; + } else { + $websiteId = null; + /** @var \Magento\Store\Model\Store $store */ + $store = null; + if (!$website) { + $store = $product->getStore(); + if ($store) { + $websiteId = $store->getWebsiteId(); + } + } + if (!$websiteId) { + $websiteObject = $this->_storeManager->getWebsite($website); + $websiteId = $websiteObject->getId(); + $store = $websiteObject->getDefaultGroup()->getDefaultStore(); } - } - if (!$websiteId) { - $websiteObject = $this->_storeManager->getWebsite($website); - $websiteId = $websiteObject->getId(); - $store = $websiteObject->getDefaultGroup()->getDefaultStore(); - } - $allWeee = $this->getWeeeTaxAttributeCodes($store); - if (!$allWeee) { - return $result; - } + $allWeee = $this->getWeeeTaxAttributeCodes($store); + if (!$allWeee) { + return $result; + } - /** @var \Magento\Tax\Model\Calculation $calculator */ - $calculator = $this->_calculationFactory->create(); + /** @var \Magento\Tax\Model\Calculation $calculator */ + $calculator = $this->_calculationFactory->create(); - $customerId = $this->_customerSession->getCustomerId(); - if ($shipping && $shipping->getCountryId()) { - $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId(); - } else { - // if customer logged use it default shipping and billing address - if ($customerId) { - $shipping = $this->accountManagement->getDefaultShippingAddress($customerId); - $billing = $this->accountManagement->getDefaultBillingAddress($customerId); - $customerTaxClass = null; + $customerId = $this->_customerSession->getCustomerId(); + if ($shipping && $shipping->getCountryId()) { + $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId(); } else { - $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress(); - $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress(); - if (!empty($billingAddressArray)) { - $billing = new \Magento\Framework\DataObject($billingAddressArray); - } - if (!empty($shippingAddressArray)) { - $shipping = new \Magento\Framework\DataObject($shippingAddressArray); + // if customer logged use it default shipping and billing address + if ($customerId) { + $shipping = $this->accountManagement->getDefaultShippingAddress($customerId); + $billing = $this->accountManagement->getDefaultBillingAddress($customerId); + $customerTaxClass = null; + } else { + $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress(); + $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress(); + if (!empty($billingAddressArray)) { + $billing = new \Magento\Framework\DataObject($billingAddressArray); + } + if (!empty($shippingAddressArray)) { + $shipping = new \Magento\Framework\DataObject($shippingAddressArray); + } + $customerTaxClass = $this->_customerSession->getCustomerTaxClassId(); } - $customerTaxClass = $this->_customerSession->getCustomerTaxClassId(); } - } - $rateRequest = $calculator->getRateRequest( - $shipping, - $billing, - $customerTaxClass, - $store, - $customerId - ); - $defaultRateRequest = $calculator->getDefaultRateRequest($store); - - $productAttributes = $this->getResource()->fetchWeeeTaxCalculationsByEntity( - $rateRequest->getCountryId(), - $rateRequest->getRegionId(), - $websiteId, - $store->getId(), - $product->getId() - ); + $rateRequest = $calculator->getRateRequest( + $shipping, + $billing, + $customerTaxClass, + $store, + $customerId + ); + $defaultRateRequest = $calculator->getDefaultRateRequest($store); - foreach ($productAttributes as $attribute) { - $value = $attribute['weee_value']; - if ($value) { - $taxAmount = $amount = 0; - $amount = $value; - $amountExclTax = $value; - if ($calculateTax && $this->weeeConfig->isTaxable($store)) { - /** @var \Magento\Tax\Model\Calculation $calculator */ - $defaultPercent = $calculator->getRate( - $defaultRateRequest->setProductClassId($product->getTaxClassId()) - ); - $currentPercent = $calculator->getRate( - $rateRequest->setProductClassId($product->getTaxClassId()) - ); - if ($this->_taxData->priceIncludesTax($store)) { - $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent); - if ($round) { - $amountInclTax = $this->priceCurrency->round($amountInclTax); - } - $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100; - if ($round) { - $taxAmount = $this->priceCurrency->round($taxAmount); - } - $amountExclTax = $amountInclTax - $taxAmount; - } else { - $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest); - if (is_array($appliedRates) && count($appliedRates) > 1) { - $taxAmount = 0; - foreach ($appliedRates as $appliedRate) { - $taxRate = $appliedRate['percent']; - if ($round) { - $taxAmount += $this->priceCurrency->round($value * $taxRate / 100); - } else { - $taxAmount += $value * $taxRate / 100; - } + $productAttributes = $this->getResource()->fetchWeeeTaxCalculationsByEntity( + $rateRequest->getCountryId(), + $rateRequest->getRegionId(), + $websiteId, + $store->getId(), + $product->getId() + ); + + foreach ($productAttributes as $attribute) { + $value = $attribute['weee_value']; + if ($value) { + $taxAmount = $amount = 0; + $amount = $value; + $amountExclTax = $value; + if ($calculateTax && $this->weeeConfig->isTaxable($store)) { + /** @var \Magento\Tax\Model\Calculation $calculator */ + $defaultPercent = $calculator->getRate( + $defaultRateRequest->setProductClassId($product->getTaxClassId()) + ); + $currentPercent = $calculator->getRate( + $rateRequest->setProductClassId($product->getTaxClassId()) + ); + if ($this->_taxData->priceIncludesTax($store)) { + $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent); + if ($round) { + $amountInclTax = $this->priceCurrency->round($amountInclTax); } - } else { + $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100; if ($round) { - $taxAmount = $this->priceCurrency->round( - $value * $currentPercent / 100 - ); + $taxAmount = $this->priceCurrency->round($taxAmount); + } + $amountExclTax = $amountInclTax - $taxAmount; + } else { + $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest); + if (is_array($appliedRates) && count($appliedRates) > 1) { + $taxAmount = 0; + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; + if ($round) { + $taxAmount += $this->priceCurrency->round($value * $taxRate / 100); + } else { + $taxAmount += $value * $taxRate / 100; + } + } } else { - $taxAmount = $value * $currentPercent / 100; + if ($round) { + $taxAmount = $this->priceCurrency->round( + $value * $currentPercent / 100 + ); + } else { + $taxAmount = $value * $currentPercent / 100; + } } } } - } - $one = new \Magento\Framework\DataObject(); - $one->setName( - $attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label']) - ) - ->setAmount($amount) - ->setTaxAmount($taxAmount) - ->setAmountExclTax($amountExclTax) - ->setCode($attribute['attribute_code']); + $one = new \Magento\Framework\DataObject(); + $one->setName( + $attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label']) + ) + ->setAmount($amount) + ->setTaxAmount($taxAmount) + ->setAmountExclTax($amountExclTax) + ->setCode($attribute['attribute_code']); - $result[] = $one; + $result[] = $one; + } } + + $this->weeAtrributesCache[$cacheKey] = $result; } return $result; } diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php index 3a8bc53d308b..c1dd543c5701 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -11,6 +11,9 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Weee\Helper\Data; +use Magento\Framework\Exception\LocalizedException; +use Magento\Tax\Helper\Data as TaxHelper; +use Magento\Store\Api\Data\StoreInterface; class FptResolver implements ResolverInterface { @@ -20,12 +23,19 @@ class FptResolver implements ResolverInterface */ private $weeeHelper; + /** + * @var TaxHelper + */ + private $taxHelper; + /** * @param Data $weeeHelper + * @param TaxHelper $taxHelper */ - public function __construct(Data $weeeHelper) + public function __construct(Data $weeeHelper, TaxHelper $taxHelper) { $this->weeeHelper = $weeeHelper; + $this->taxHelper = $taxHelper; } /** @@ -38,13 +48,27 @@ public function resolve( array $value = null, array $args = null ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } $fptArray = []; $product = $value['model']; + + /** @var StoreInterface $store */ + $store = $context->getExtensionAttributes()->getStore(); + $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); foreach ($attributes as $attribute) { + $displayInclTaxes = $this->taxHelper->getPriceDisplayType($store); + $amount = $attribute->getData('amount'); + if ($displayInclTaxes === 1) { + $amount = $attribute->getData('amount_excl_tax'); + } elseif ($displayInclTaxes === 2) { + $amount = $attribute->getData('amount_excl_tax') + $attribute->getData('tax_amount'); + } $fptArray[] = [ 'amount' => [ - 'value' => $attribute->getData('amount'), + 'value' => $amount, 'currency' => $value['final_price']['currency'], ], 'label' => $attribute->getData('name') From dba05f17c3da8fbbc2bdaeff5fc7ecc604e4ba8b Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Fri, 27 Sep 2019 18:07:17 -0500 Subject: [PATCH 0696/1172] MC-20490: Catalog product list widget doesn't work with custom attribute conditions - fixed --- .../CatalogWidget/Model/Rule/Condition/Product.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php index e5fb20a58aea..ac4f483e0db8 100644 --- a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php +++ b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php @@ -11,6 +11,7 @@ use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Model\ProductCategoryList; +use Magento\Store\Model\Store; /** * Class Product @@ -164,6 +165,8 @@ public function addToCollection($collection) } /** + * Adds Attributes that belong to Global Scope + * * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection * @return $this @@ -200,6 +203,8 @@ protected function addGlobalAttribute( } /** + * Adds Attributes that don't belong to Global Scope + * * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection * @return $this @@ -208,7 +213,7 @@ protected function addNotGlobalAttribute( \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute, \Magento\Catalog\Model\ResourceModel\Product\Collection $collection ) { - $storeId = $this->storeManager->getStore()->getId(); + $storeId = $this->storeManager->getStore()->getId(); $values = $collection->getAllAttributeValues($attribute); $validEntities = []; if ($values) { @@ -218,7 +223,10 @@ protected function addNotGlobalAttribute( $validEntities[] = $entityId; } } else { - if ($this->validateAttribute($storeValues[\Magento\Store\Model\Store::DEFAULT_STORE_ID])) { + if ( + isset($storeValues[Store::DEFAULT_STORE_ID]) && + $this->validateAttribute($storeValues[Store::DEFAULT_STORE_ID]) + ) { $validEntities[] = $entityId; } } From ece34863580bd8ba09cf420759effe7a38c3f076 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Fri, 27 Sep 2019 20:34:08 +0530 Subject: [PATCH 0697/1172] Resolved issue 24708 --- app/code/Magento/Analytics/Model/ExportDataHandler.php | 2 +- .../Analytics/Test/Unit/Model/ExportDataHandlerTest.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Analytics/Model/ExportDataHandler.php b/app/code/Magento/Analytics/Model/ExportDataHandler.php index dc17a548763e..b36ad2398c97 100644 --- a/app/code/Magento/Analytics/Model/ExportDataHandler.php +++ b/app/code/Magento/Analytics/Model/ExportDataHandler.php @@ -89,7 +89,7 @@ public function __construct( public function prepareExportData() { try { - $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP); + $tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR); $this->prepareDirectory($tmpDirectory, $this->getTmpFilesDirRelativePath()); $this->reportWriter->write($tmpDirectory, $this->getTmpFilesDirRelativePath()); diff --git a/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php b/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php index cf00556cfe59..493fe71c9fbf 100644 --- a/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php +++ b/app/code/Magento/Analytics/Test/Unit/Model/ExportDataHandlerTest.php @@ -13,7 +13,7 @@ use Magento\Framework\Archive; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Directory\WriteInterface; -use Magento\Framework\Filesystem\DirectoryList; +use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; class ExportDataHandlerTest extends \PHPUnit\Framework\TestCase @@ -137,7 +137,7 @@ public function testPrepareExportData($isArchiveSourceDirectory) $this->filesystemMock ->expects($this->once()) ->method('getDirectoryWrite') - ->with(DirectoryList::SYS_TMP) + ->with(DirectoryList::VAR_DIR) ->willReturn($this->directoryMock); $this->directoryMock ->expects($this->exactly(4)) @@ -238,7 +238,7 @@ public function testPrepareExportDataWithLocalizedException() $this->filesystemMock ->expects($this->once()) ->method('getDirectoryWrite') - ->with(DirectoryList::SYS_TMP) + ->with(DirectoryList::VAR_DIR) ->willReturn($this->directoryMock); $this->reportWriterMock ->expects($this->once()) From c989fcb8c962b2c97a0bdb5fd4b59c9fdcc63a0a Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Sat, 28 Sep 2019 03:05:58 -0500 Subject: [PATCH 0698/1172] MC-20490: Catalog product list widget doesn't work with custom attribute conditions - static test fixed --- .../CatalogWidget/Model/Rule/Condition/Product.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php index ac4f483e0db8..a712ae91cbfa 100644 --- a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php +++ b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Product.php @@ -107,7 +107,7 @@ function ($attribute) { } /** - * {@inheritdoc} + * @inheritdoc * * @param array &$attributes * @return void @@ -223,8 +223,7 @@ protected function addNotGlobalAttribute( $validEntities[] = $entityId; } } else { - if ( - isset($storeValues[Store::DEFAULT_STORE_ID]) && + if (isset($storeValues[Store::DEFAULT_STORE_ID]) && $this->validateAttribute($storeValues[Store::DEFAULT_STORE_ID]) ) { $validEntities[] = $entityId; @@ -244,7 +243,7 @@ protected function addNotGlobalAttribute( } /** - * {@inheritdoc} + * @inheritdoc * * @return string */ @@ -265,7 +264,7 @@ public function getMappedSqlField() } /** - * {@inheritdoc} + * @inheritdoc * * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection * @return $this From 35ad339af8373cb2280a473f070c57a98da3faee Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Sun, 29 Sep 2019 17:55:34 +0300 Subject: [PATCH 0699/1172] magento/magento2#23295: Reset Password Confirmation Link Email Not Store Scoped For Global Customers --- app/code/Magento/Customer/Model/EmailNotification.php | 2 +- .../Customer/Test/Unit/Model/EmailNotificationTest.php | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/Model/EmailNotification.php b/app/code/Magento/Customer/Model/EmailNotification.php index 573f86247e0c..432317444f4b 100644 --- a/app/code/Magento/Customer/Model/EmailNotification.php +++ b/app/code/Magento/Customer/Model/EmailNotification.php @@ -340,7 +340,7 @@ public function passwordReminder(CustomerInterface $customer) */ public function passwordResetConfirmation(CustomerInterface $customer) { - $storeId = $this->storeManager->getStore()->getId(); + $storeId = $customer->getStoreId(); if (!$storeId) { $storeId = $this->getWebsiteStoreId($customer); } diff --git a/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php b/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php index 318023d8068c..ff83ef62c6aa 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/EmailNotificationTest.php @@ -521,7 +521,7 @@ public function testPasswordResetConfirmation() /** @var CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ $customer = $this->createMock(CustomerInterface::class); - $customer->expects($this->any()) + $customer->expects($this->once()) ->method('getStoreId') ->willReturn($customerStoreId); $customer->expects($this->any()) @@ -539,11 +539,6 @@ public function testPasswordResetConfirmation() ->method('getStore') ->willReturn($this->storeMock); - $this->storeManagerMock->expects($this->at(1)) - ->method('getStore') - ->with($customerStoreId) - ->willReturn($this->storeMock); - $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') ->with($customerId) From a4f6b3c753c5df332be3545a26519581463d89f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Fri, 12 Apr 2019 00:22:20 +0200 Subject: [PATCH 0700/1172] Fix #12256 #13263 - add Serbian Latin language and change language lists to show script --- lib/internal/Magento/Framework/Locale/Config.php | 3 ++- .../Framework/Locale/Test/Unit/ConfigTest.php | 2 +- .../Magento/Framework/Locale/TranslatedLists.php | 12 +++++++++--- lib/internal/Magento/Framework/Setup/Lists.php | 6 +++++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/internal/Magento/Framework/Locale/Config.php b/lib/internal/Magento/Framework/Locale/Config.php index 499c3bd26a3a..f02ba78ccc3e 100644 --- a/lib/internal/Magento/Framework/Locale/Config.php +++ b/lib/internal/Magento/Framework/Locale/Config.php @@ -91,7 +91,8 @@ class Config implements \Magento\Framework\Locale\ConfigInterface 'sk_SK', /*Slovak (Slovakia)*/ 'sl_SI', /*Slovenian (Slovenia)*/ 'sq_AL', /*Albanian (Albania)*/ - 'sr_Cyrl_RS', /*Serbian (Serbia)*/ + 'sr_Cyrl_RS', /*Serbian (Cyrillic, Serbia)*/ + 'sr_Latn_RS', /*Serbian (Latin, Serbia)*/ 'sv_SE', /*Swedish (Sweden)*/ 'sv_FI', /*Swedish (Finland)*/ 'sw_KE', /*Swahili (Kenya)*/ diff --git a/lib/internal/Magento/Framework/Locale/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/Locale/Test/Unit/ConfigTest.php index 5e1dfdc16635..149f6b5e33b6 100644 --- a/lib/internal/Magento/Framework/Locale/Test/Unit/ConfigTest.php +++ b/lib/internal/Magento/Framework/Locale/Test/Unit/ConfigTest.php @@ -15,7 +15,7 @@ class ConfigTest extends \PHPUnit\Framework\TestCase 'es_MX', 'eu_ES', 'es_PE', 'et_EE', 'fa_IR', 'fi_FI', 'fil_PH', 'fr_CA', 'fr_FR', 'gu_IN', 'he_IL', 'hi_IN', 'hr_HR', 'hu_HU', 'id_ID', 'is_IS', 'it_CH', 'it_IT', 'ja_JP', 'ka_GE', 'km_KH', 'ko_KR', 'lo_LA', 'lt_LT', 'lv_LV', 'mk_MK', 'mn_Cyrl_MN', 'ms_Latn_MY', 'nl_NL', 'nb_NO', - 'nn_NO', 'pl_PL', 'pt_BR', 'pt_PT', 'ro_RO', 'ru_RU', 'sk_SK', 'sl_SI', 'sq_AL', 'sr_Cyrl_RS', + 'nn_NO', 'pl_PL', 'pt_BR', 'pt_PT', 'ro_RO', 'ru_RU', 'sk_SK', 'sl_SI', 'sq_AL', 'sr_Cyrl_RS', 'sr_Latn_RS', 'sv_SE', 'sw_KE', 'th_TH', 'tr_TR', 'uk_UA', 'vi_VN', 'zh_Hans_CN', 'zh_Hant_HK', 'zh_Hant_TW', 'es_CL', 'lo_LA', 'es_VE', 'en_IE', ]; diff --git a/lib/internal/Magento/Framework/Locale/TranslatedLists.php b/lib/internal/Magento/Framework/Locale/TranslatedLists.php index 2087564dcec2..e409ca2f0335 100644 --- a/lib/internal/Magento/Framework/Locale/TranslatedLists.php +++ b/lib/internal/Magento/Framework/Locale/TranslatedLists.php @@ -81,17 +81,23 @@ protected function _getOptionLocales($translatedName = false) } $language = \Locale::getPrimaryLanguage($locale); $country = \Locale::getRegion($locale); + $script = \Locale::getScript($locale); + $scriptTranslated = ''; if (!$languages[$language] || !$countries[$country]) { continue; } + if ($script !== '') { + $script = \Locale::getDisplayScript($locale) . ', '; + $scriptTranslated = \Locale::getDisplayScript($locale, $locale) . ', '; + } if ($translatedName) { $label = ucwords(\Locale::getDisplayLanguage($locale, $locale)) - . ' (' . \Locale::getDisplayRegion($locale, $locale) . ') / ' + . ' (' . $scriptTranslated . \Locale::getDisplayRegion($locale, $locale) . ') / ' . $languages[$language] - . ' (' . $countries[$country] . ')'; + . ' (' . $script . $countries[$country] . ')'; } else { $label = $languages[$language] - . ' (' . $countries[$country] . ')'; + . ' (' . $script . $countries[$country] . ')'; } $options[] = ['value' => $locale, 'label' => $label]; } diff --git a/lib/internal/Magento/Framework/Setup/Lists.php b/lib/internal/Magento/Framework/Setup/Lists.php index 1ee5baf28658..995e6dc0823e 100644 --- a/lib/internal/Magento/Framework/Setup/Lists.php +++ b/lib/internal/Magento/Framework/Setup/Lists.php @@ -99,10 +99,14 @@ public function getLocaleList() } $language = \Locale::getPrimaryLanguage($locale); $country = \Locale::getRegion($locale); + $script = \Locale::getScript($locale); if (!$languages[$language] || !$countries[$country]) { continue; } - $list[$locale] = $languages[$language] . ' (' . $countries[$country] . ')'; + if ($script !== '') { + $script = \Locale::getDisplayScript($locale) . ', '; + } + $list[$locale] = $languages[$language] . ' (' . $script . $countries[$country] . ')'; } asort($list); return $list; From 1e6a2991f9ab3feef3baf2e0afdd70894ac9e7e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Sun, 29 Sep 2019 20:50:41 +0200 Subject: [PATCH 0701/1172] Fix #12256 #13263 - static test fix --- lib/internal/Magento/Framework/Setup/Lists.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/internal/Magento/Framework/Setup/Lists.php b/lib/internal/Magento/Framework/Setup/Lists.php index 995e6dc0823e..98c9b6cc0a4b 100644 --- a/lib/internal/Magento/Framework/Setup/Lists.php +++ b/lib/internal/Magento/Framework/Setup/Lists.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\Setup; @@ -12,6 +13,9 @@ use Magento\Framework\Locale\ConfigInterface; use Magento\Framework\Locale\Resolver; +/** + * Retrieves lists of allowed locales and currencies + */ class Lists { /** From 29411feaac256670b5787d61217983fbdd974a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Sun, 29 Sep 2019 23:03:22 +0200 Subject: [PATCH 0702/1172] Fix #12256 #13263 - add unit tests --- .../Locale/Test/Unit/TranslatedListsTest.php | 106 +++++++++++------- .../Framework/Setup/Test/Unit/ListsTest.php | 43 +++---- 2 files changed, 87 insertions(+), 62 deletions(-) diff --git a/lib/internal/Magento/Framework/Locale/Test/Unit/TranslatedListsTest.php b/lib/internal/Magento/Framework/Locale/Test/Unit/TranslatedListsTest.php index 9e247a8e21ac..0d51d6fbda30 100644 --- a/lib/internal/Magento/Framework/Locale/Test/Unit/TranslatedListsTest.php +++ b/lib/internal/Magento/Framework/Locale/Test/Unit/TranslatedListsTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\Locale\Test\Unit; @@ -17,23 +18,62 @@ class TranslatedListsTest extends TestCase /** * @var TranslatedLists */ - protected $listsModel; + private $listsModel; /** - * @var MockObject | ConfigInterface + * @var MockObject | ConfigInterface */ - protected $mockConfig; + private $mockConfig; /** - * @var MockObject | ResolverInterface + * @var MockObject | ResolverInterface */ - protected $mockLocaleResolver; + private $mockLocaleResolver; + + /** + * @var array + */ + private $expectedCurrencies = [ + 'USD', + 'EUR', + 'UAH', + 'GBP', + ]; + + /** + * @var array + */ + private $expectedLocales = [ + 'en_US' => 'English (United States)', + 'en_GB' => 'English (United Kingdom)', + 'uk_UA' => 'Ukrainian (Ukraine)', + 'de_DE' => 'German (Germany)', + 'sr_Cyrl_RS' => 'Serbian (Cyrillic, Serbia)', + 'sr_Latn_RS' => 'Serbian (Latin, Serbia)' + ]; + + /** + * @var array + */ + private $expectedTranslatedLocales = [ + 'en_US' => 'English (United States) / English (United States)', + 'en_GB' => 'English (United Kingdom) / English (United Kingdom)', + 'uk_UA' => 'українська (Україна) / Ukrainian (Ukraine)', + 'de_DE' => 'Deutsch (Deutschland) / German (Germany)', + 'sr_Cyrl_RS' => 'српски (ћирилица, Србија) / Serbian (Cyrillic, Serbia)', + 'sr_Latn_RS' => 'Srpski (latinica, Srbija) / Serbian (Latin, Serbia)' + ]; protected function setUp() { $this->mockConfig = $this->getMockBuilder(ConfigInterface::class) ->disableOriginalConstructor() ->getMock(); + $this->mockConfig->method('getAllowedLocales') + ->willReturn(array_keys($this->expectedLocales)); + $this->mockConfig->method('getAllowedCurrencies') + ->willReturn($this->expectedCurrencies); + $this->mockLocaleResolver = $this->getMockBuilder(ResolverInterface::class) ->disableOriginalConstructor() ->getMock(); @@ -69,12 +109,6 @@ public function testGetOptionAllCurrencies() public function testGetOptionCurrencies() { - $allowedCurrencies = ['USD', 'EUR', 'GBP', 'UAH']; - - $this->mockConfig->expects($this->once()) - ->method('getAllowedCurrencies') - ->willReturn($allowedCurrencies); - $expectedResults = ['USD', 'EUR', 'GBP', 'UAH']; $currencyList = $this->listsModel->getOptionCurrencies(); @@ -134,44 +168,34 @@ public function testGetOptionTimezones() public function testGetOptionLocales() { - $this->setupForOptionLocales(); - - $expectedResults = ['en_US', 'uk_UA', 'de_DE']; - - $list = $this->listsModel->getOptionLocales(); - foreach ($expectedResults as $value) { - $found = false; - foreach ($list as $item) { - $found = $found || ($value == $item['value']); - } - $this->assertTrue($found); - } + $locales = array_intersect( + $this->expectedLocales, + $this->convertOptionLocales($this->listsModel->getOptionLocales()) + ); + $this->assertEquals($this->expectedLocales, $locales); } public function testGetTranslatedOptionLocales() { - $this->setupForOptionLocales(); - - $expectedResults = ['en_US', 'uk_UA', 'de_DE']; - - $list = $this->listsModel->getOptionLocales(); - foreach ($expectedResults as $value) { - $found = false; - foreach ($list as $item) { - $found = $found || ($value == $item['value']); - } - $this->assertTrue($found); - } + $locales = array_intersect( + $this->expectedTranslatedLocales, + $this->convertOptionLocales($this->listsModel->getTranslatedOptionLocales()) + ); + $this->assertEquals($this->expectedTranslatedLocales, $locales); } /** - * Setup for option locales + * @param array $optionLocales + * @return array */ - protected function setupForOptionLocales() + private function convertOptionLocales($optionLocales): array { - $allowedLocales = ['en_US', 'uk_UA', 'de_DE']; - $this->mockConfig->expects($this->once()) - ->method('getAllowedLocales') - ->willReturn($allowedLocales); + $result = []; + + foreach ($optionLocales as $optionLocale) { + $result[$optionLocale['value']] = $optionLocale['label']; + } + + return $result; } } diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/ListsTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/ListsTest.php index a25771b4519f..c9c6dfe6d7dc 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/ListsTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/ListsTest.php @@ -3,27 +3,31 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Framework\Setup\Test\Unit; +use Magento\Framework\Locale\ConfigInterface; use Magento\Framework\Setup\Lists; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\MockObject\MockObject; -class ListsTest extends \PHPUnit\Framework\TestCase +class ListsTest extends TestCase { /** * @var Lists */ - protected $lists; + private $lists; /** - * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ConfigInterface + * @var MockObject|ConfigInterface */ - protected $mockConfig; + private $mockConfig; /** * @var array */ - protected $expectedTimezones = [ + private $expectedTimezones = [ 'Australia/Darwin', 'America/Los_Angeles', 'Europe/Kiev', @@ -33,7 +37,7 @@ class ListsTest extends \PHPUnit\Framework\TestCase /** * @var array */ - protected $expectedCurrencies = [ + private $expectedCurrencies = [ 'USD', 'EUR', 'UAH', @@ -43,23 +47,23 @@ class ListsTest extends \PHPUnit\Framework\TestCase /** * @var array */ - protected $expectedLocales = [ - 'en_US', - 'en_GB', - 'uk_UA', - 'de_DE', + private $expectedLocales = [ + 'en_US' => 'English (United States)', + 'en_GB' => 'English (United Kingdom)', + 'uk_UA' => 'Ukrainian (Ukraine)', + 'de_DE' => 'German (Germany)', + 'sr_Cyrl_RS' => 'Serbian (Cyrillic, Serbia)', + 'sr_Latn_RS' => 'Serbian (Latin, Serbia)' ]; protected function setUp() { - $this->mockConfig = $this->getMockBuilder(\Magento\Framework\Locale\ConfigInterface::class) + $this->mockConfig = $this->getMockBuilder(ConfigInterface::class) ->disableOriginalConstructor() ->getMock(); - $this->mockConfig->expects($this->any()) - ->method('getAllowedLocales') - ->willReturn($this->expectedLocales); - $this->mockConfig->expects($this->any()) - ->method('getAllowedCurrencies') + $this->mockConfig->method('getAllowedLocales') + ->willReturn(array_keys($this->expectedLocales)); + $this->mockConfig->method('getAllowedCurrencies') ->willReturn($this->expectedCurrencies); $this->lists = new Lists($this->mockConfig); @@ -73,13 +77,10 @@ public function testGetTimezoneList() public function testGetLocaleList() { - $locales = array_intersect($this->expectedLocales, array_keys($this->lists->getLocaleList())); + $locales = array_intersect($this->expectedLocales, $this->lists->getLocaleList()); $this->assertEquals($this->expectedLocales, $locales); } - /** - * Test Lists:getCurrencyList() considering allowed currencies config values. - */ public function testGetCurrencyList() { $currencies = array_intersect($this->expectedCurrencies, array_keys($this->lists->getCurrencyList())); From a98d74af53afde3552edf779b59591efc44a6edf Mon Sep 17 00:00:00 2001 From: Raul E Watson <diazwatson@users.noreply.github.com> Date: Sun, 29 Sep 2019 23:31:59 +0100 Subject: [PATCH 0703/1172] Update README.md --- app/code/Magento/BraintreeGraphQl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/BraintreeGraphQl/README.md b/app/code/Magento/BraintreeGraphQl/README.md index 78b527b76360..570f3b767e4e 100644 --- a/app/code/Magento/BraintreeGraphQl/README.md +++ b/app/code/Magento/BraintreeGraphQl/README.md @@ -1,6 +1,6 @@ # Magento_BraintreeGraphQl module -The Magento_BraintreeGraphQl module provides type and resolver for method additional information. +The Magento_BraintreeGraphQl module provides type and resolver information for the GraphQl module to pass payment information data from the client to Magento. ## Extensibility From b82e7486c93fa42e59229f97a3a16ac8ba5670f6 Mon Sep 17 00:00:00 2001 From: Ravi Chandra <ravi.chandra@krishtechnolabs.com> Date: Mon, 30 Sep 2019 14:24:57 +0530 Subject: [PATCH 0704/1172] Add valid mail port validation --- app/code/Magento/Backend/etc/adminhtml/system.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 343ecc0ee3d5..9e4960c12b21 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -323,7 +323,8 @@ </field> <field id="port" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Port (25)</label> - <comment>For Windows server only.</comment> + <validate>validate-digits validate-digits-range digits-range-0-65535</validate> + <comment>Please enter at least 0 and at most 65535 (For Windows server only).</comment> </field> <field id="set_return_path" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Set Return-Path</label> From f05dd7f3daf9967d50ef819fea162e1be821a2d2 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Mon, 30 Sep 2019 12:21:39 +0300 Subject: [PATCH 0705/1172] magento/magento2#24754: Integration tests fix. --- .../System/Currency/FetchRatesTest.php | 25 ++++++++++++++++++- .../System/Currency/SaveRatesTest.php | 15 ++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRatesTest.php b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRatesTest.php index 8e25e5960a4b..15111b27783d 100644 --- a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRatesTest.php @@ -6,11 +6,30 @@ namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency; +use Magento\Framework\Escaper; + /** * Fetch Rates Test */ class FetchRatesTest extends \Magento\TestFramework\TestCase\AbstractBackendController { + /** + * @var Escaper + */ + private $escaper; + + /** + * Initial setup + */ + protected function setUp() + { + $this->escaper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + Escaper::class + ); + + parent::setUp(); + } + /** * Test fetch action without service * @@ -46,7 +65,11 @@ public function testFetchRatesActionWithNonexistentService(): void $this->dispatch('backend/admin/system_currency/fetchRates'); $this->assertSessionMessages( - $this->contains("The import model can't be initialized. Verify the model and try again."), + $this->contains( + $this->escaper->escapeHtml( + "The import model can't be initialized. Verify the model and try again." + ) + ), \Magento\Framework\Message\MessageInterface::TYPE_ERROR ); } diff --git a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php index fefd1a7b250c..536aadd190c0 100644 --- a/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php +++ b/dev/tests/integration/testsuite/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRatesTest.php @@ -3,9 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency; use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Escaper; class SaveRatesTest extends \Magento\TestFramework\TestCase\AbstractBackendController { @@ -13,6 +15,11 @@ class SaveRatesTest extends \Magento\TestFramework\TestCase\AbstractBackendContr /** @var \Magento\Directory\Model\Currency $currencyRate */ protected $currencyRate; + /** + * @var Escaper + */ + private $escaper; + /** * Initial setup */ @@ -21,6 +28,10 @@ protected function setUp() $this->currencyRate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Directory\Model\Currency::class ); + $this->escaper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + Escaper::class + ); + parent::setUp(); } @@ -89,7 +100,9 @@ public function testSaveWithWarningAction() $this->assertSessionMessages( $this->contains( - (string)__('Please correct the input data for "%1 => %2" rate.', $currencyCode, $currencyTo) + $this->escaper->escapeHtml( + (string)__('Please correct the input data for "%1 => %2" rate.', $currencyCode, $currencyTo) + ) ), \Magento\Framework\Message\MessageInterface::TYPE_WARNING ); From 218c16459e07c0b072c2949cae1a9f0b9f0a7754 Mon Sep 17 00:00:00 2001 From: Ivan Koliadynskyy <i.koliadynskyy@gmail.com> Date: Fri, 27 Sep 2019 17:35:07 +0300 Subject: [PATCH 0706/1172] https://github.com/magento/magento2/issues/24716 Not Able to set Rest API oAuth admin token expire in minutes or seconds. #24716 --- app/code/Magento/Integration/Helper/Oauth/Data.php | 12 ++++++------ .../Webapi/Model/Authorization/TokenUserContext.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Integration/Helper/Oauth/Data.php b/app/code/Magento/Integration/Helper/Oauth/Data.php index de074055efa2..5bceec83366e 100644 --- a/app/code/Magento/Integration/Helper/Oauth/Data.php +++ b/app/code/Magento/Integration/Helper/Oauth/Data.php @@ -116,22 +116,22 @@ public function getConsumerPostTimeout() /** * Get customer token lifetime from config. * - * @return int hours + * @return string hours */ public function getCustomerTokenLifetime() { - $hours = (int)$this->_scopeConfig->getValue('oauth/access_token_lifetime/customer'); - return $hours > 0 ? $hours : 0; + $hours = $this->_scopeConfig->getValue('oauth/access_token_lifetime/customer'); + return is_numeric($hours) ? $hours : 0; } /** * Get customer token lifetime from config. * - * @return int hours + * @return string hours */ public function getAdminTokenLifetime() { - $hours = (int)$this->_scopeConfig->getValue('oauth/access_token_lifetime/admin'); - return $hours > 0 ? $hours : 0; + $hours = $this->_scopeConfig->getValue('oauth/access_token_lifetime/admin'); + return is_numeric($hours) ? $hours : 0; } } diff --git a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php index d89513b50c9c..cc8da17e7f52 100644 --- a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php +++ b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php @@ -137,7 +137,7 @@ private function isTokenExpired(Token $token): bool return false; } - if ($this->dateTime->strToTime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { + if ($this->date->timestamp($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { return true; } From c283bba9d737ffc426d2f24fa60b4d9743063aed Mon Sep 17 00:00:00 2001 From: Ivan Koliadynskyy <i.koliadynskyy@gmail.com> Date: Sat, 28 Sep 2019 00:10:18 +0300 Subject: [PATCH 0707/1172] Fix return type in comments --- app/code/Magento/Integration/Helper/Oauth/Data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Integration/Helper/Oauth/Data.php b/app/code/Magento/Integration/Helper/Oauth/Data.php index 5bceec83366e..d14bc0f9355a 100644 --- a/app/code/Magento/Integration/Helper/Oauth/Data.php +++ b/app/code/Magento/Integration/Helper/Oauth/Data.php @@ -116,7 +116,7 @@ public function getConsumerPostTimeout() /** * Get customer token lifetime from config. * - * @return string hours + * @return numeric hours */ public function getCustomerTokenLifetime() { @@ -127,7 +127,7 @@ public function getCustomerTokenLifetime() /** * Get customer token lifetime from config. * - * @return string hours + * @return numeric hours */ public function getAdminTokenLifetime() { From 8d10c41f8e84cb6d6ace926afdc66c572f5b5487 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 30 Sep 2019 13:24:40 +0300 Subject: [PATCH 0708/1172] MAGETWO-67450: The rate in order is duplicated - Fix CR comments --- .../view/adminhtml/templates/order/view/info.phtml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml index 8ada10450c96..825ac8205772 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/info.phtml @@ -9,6 +9,10 @@ */ $order = $block->getOrder(); +$baseCurrencyCode = (string)$order->getBaseCurrencyCode(); +$globalCurrencyCode = (string)$order->getGlobalCurrencyCode(); +$orderCurrencyCode = (string)$order->getOrderCurrencyCode(); + $orderAdminDate = $block->formatDate( $block->getOrderAdminDate($order->getCreatedAt()), \IntlDateFormatter::MEDIUM, @@ -94,15 +98,15 @@ $allowedAddressHtmlTags = ['b', 'br', 'em', 'i', 'li', 'ol', 'p', 'strong', 'sub <td><?= $block->escapeHtml($order->getRemoteIp()); ?><?= $order->getXForwardedFor() ? ' (' . $block->escapeHtml($order->getXForwardedFor()) . ')' : ''; ?></td> </tr> <?php endif; ?> - <?php if ($order->getGlobalCurrencyCode() != $order->getBaseCurrencyCode()) : ?> + <?php if ($globalCurrencyCode !== $baseCurrencyCode) : ?> <tr> - <th><?= $block->escapeHtml(__('%1 / %2 rate:', $order->getGlobalCurrencyCode(), $order->getBaseCurrencyCode())) ?></th> + <th><?= $block->escapeHtml(__('%1 / %2 rate:', $globalCurrencyCode, $baseCurrencyCode)) ?></th> <td><?= $block->escapeHtml($order->getBaseToGlobalRate()) ?></td> </tr> <?php endif; ?> - <?php if ($order->getBaseCurrencyCode() != $order->getOrderCurrencyCode() && $order->getGlobalCurrencyCode() != $order->getOrderCurrencyCode()) : ?> + <?php if ($baseCurrencyCode !== $orderCurrencyCode && $globalCurrencyCode !== $orderCurrencyCode) : ?> <tr> - <th><?= $block->escapeHtml(__('%1 / %2 rate:', $order->getOrderCurrencyCode(), $order->getBaseCurrencyCode())) ?></th> + <th><?= $block->escapeHtml(__('%1 / %2 rate:', $orderCurrencyCode, $baseCurrencyCode)) ?></th> <td><?= $block->escapeHtml($order->getBaseToOrderRate()) ?></td> </tr> <?php endif; ?> From 7a9f956c311af2834f6b263d3e5fb14bde1d7a5a Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Mon, 30 Sep 2019 13:40:00 +0300 Subject: [PATCH 0709/1172] Fix failed static test. --- lib/internal/Magento/Framework/Backup/Archive/Tar.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Backup/Archive/Tar.php b/lib/internal/Magento/Framework/Backup/Archive/Tar.php index 616952a0404c..4ac40c584ee2 100644 --- a/lib/internal/Magento/Framework/Backup/Archive/Tar.php +++ b/lib/internal/Magento/Framework/Backup/Archive/Tar.php @@ -15,6 +15,9 @@ use RecursiveDirectoryIterator; use RecursiveIteratorIterator; +/** + * Class to work with tar archives + */ class Tar extends \Magento\Framework\Archive\Tar { /** @@ -25,8 +28,7 @@ class Tar extends \Magento\Framework\Archive\Tar protected $_skipFiles = []; /** - * Overridden \Magento\Framework\Archive\Tar::_createTar method that does the same actions as it's parent but - * filters files using \Magento\Framework\Backup\Filesystem\Iterator\Filter + * Method same as it's parent but filters files using \Magento\Framework\Backup\Filesystem\Iterator\Filter * * @param bool $skipRoot * @param bool $finalize @@ -50,7 +52,7 @@ protected function _createTar($skipRoot = false, $finalize = false) foreach ($iterator as $item) { // exclude symlinks to do not get duplicates after follow symlinks in RecursiveDirectoryIterator - if($item->isLink()) { + if ($item->isLink()) { continue; } $this->_setCurrentFile($item->getPathname()); From bc86a19ead35b8ee3900f1ed319f0fb4a97c8c6e Mon Sep 17 00:00:00 2001 From: roettigl <l.roettig@techdivision.com> Date: Mon, 30 Sep 2019 12:16:11 +0200 Subject: [PATCH 0710/1172] MC-14871: Update php-amqplib/php-amqplib libary to 2.10.0 --- composer.json | 2 +- composer.lock | 1099 +++++++++++++++++++++---------------------------- 2 files changed, 478 insertions(+), 623 deletions(-) diff --git a/composer.json b/composer.json index fdbfb664c9b1..2510edbfd626 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "wikimedia/less.php": "~1.8.0", "paragonie/sodium_compat": "^1.6", "pelago/emogrifier": "^2.0.0", - "php-amqplib/php-amqplib": "~2.7.0", + "php-amqplib/php-amqplib": "~2.10.0", "phpseclib/mcrypt_compat": "1.0.8", "phpseclib/phpseclib": "2.0.*", "ramsey/uuid": "~3.8.0", diff --git a/composer.lock b/composer.lock index 9d6805ac8be4..e290a720b5cd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "856f519091be654f930aa51de44332a7", + "content-hash": "271b6ffda2898e9717c906f662088380", "packages": [ { "name": "braintree/braintree_php", @@ -201,16 +201,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.2.1", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "33810d865dd06a674130fceb729b2f279dc79e8c" + "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/33810d865dd06a674130fceb729b2f279dc79e8c", - "reference": "33810d865dd06a674130fceb729b2f279dc79e8c", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/10bb96592168a0f8e8f6dcde3532d9fa50b0b527", + "reference": "10bb96592168a0f8e8f6dcde3532d9fa50b0b527", "shasum": "" }, "require": { @@ -253,20 +253,20 @@ "ssl", "tls" ], - "time": "2019-07-31T08:13:16+00:00" + "time": "2019-08-30T08:44:50+00:00" }, { "name": "composer/composer", - "version": "1.8.6", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "19b5f66a0e233eb944f134df34091fe1c5dfcc11" + "reference": "314aa57fdcfc942065996f59fb73a8b3f74f3fa5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/19b5f66a0e233eb944f134df34091fe1c5dfcc11", - "reference": "19b5f66a0e233eb944f134df34091fe1c5dfcc11", + "url": "https://api.github.com/repos/composer/composer/zipball/314aa57fdcfc942065996f59fb73a8b3f74f3fa5", + "reference": "314aa57fdcfc942065996f59fb73a8b3f74f3fa5", "shasum": "" }, "require": { @@ -302,7 +302,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -326,14 +326,14 @@ "homepage": "http://seld.be" } ], - "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", "homepage": "https://getcomposer.org/", "keywords": [ "autoload", "dependency", "package" ], - "time": "2019-06-11T13:03:06+00:00" + "time": "2019-08-02T18:55:33+00:00" }, { "name": "composer/semver", @@ -1110,16 +1110,16 @@ }, { "name": "monolog/monolog", - "version": "1.24.0", + "version": "1.25.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266" + "reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", - "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/70e65a5470a42cfec1a7da00d30edb6e617e8dcf", + "reference": "70e65a5470a42cfec1a7da00d30edb6e617e8dcf", "shasum": "" }, "require": { @@ -1184,7 +1184,7 @@ "logging", "psr-3" ], - "time": "2018-11-05T09:00:11+00:00" + "time": "2019-09-06T13:49:17+00:00" }, { "name": "paragonie/random_compat", @@ -1233,16 +1233,16 @@ }, { "name": "paragonie/sodium_compat", - "version": "v1.10.1", + "version": "v1.11.1", "source": { "type": "git", "url": "https://github.com/paragonie/sodium_compat.git", - "reference": "5115fa44886d1c2785d2f135ef4626db868eac4b" + "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/5115fa44886d1c2785d2f135ef4626db868eac4b", - "reference": "5115fa44886d1c2785d2f135ef4626db868eac4b", + "url": "https://api.github.com/repos/paragonie/sodium_compat/zipball/a9f968bc99485f85f9303a8524c3485a7e87bc15", + "reference": "a9f968bc99485f85f9303a8524c3485a7e87bc15", "shasum": "" }, "require": { @@ -1311,20 +1311,20 @@ "secret-key cryptography", "side-channel resistant" ], - "time": "2019-07-12T16:36:59+00:00" + "time": "2019-09-12T12:05:58+00:00" }, { "name": "pelago/emogrifier", - "version": "v2.1.1", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983" + "reference": "2472bc1c3a2dee8915ecc2256139c6100024332f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8ee7fb5ad772915451ed3415c1992bd3697d4983", - "reference": "8ee7fb5ad772915451ed3415c1992bd3697d4983", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/2472bc1c3a2dee8915ecc2256139c6100024332f", + "reference": "2472bc1c3a2dee8915ecc2256139c6100024332f", "shasum": "" }, "require": { @@ -1342,7 +1342,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1355,16 +1355,6 @@ "MIT" ], "authors": [ - { - "name": "John Reeve", - "email": "jreeve@pelagodesign.com" - }, - { - "name": "Cameron Brooks" - }, - { - "name": "Jaime Prado" - }, { "name": "Oliver Klee", "email": "github@oliverklee.de" @@ -1373,9 +1363,19 @@ "name": "Zoli Szabó", "email": "zoli.szabo+github@gmail.com" }, + { + "name": "John Reeve", + "email": "jreeve@pelagodesign.com" + }, { "name": "Jake Hotson", "email": "jake@qzdesign.co.uk" + }, + { + "name": "Cameron Brooks" + }, + { + "name": "Jaime Prado" } ], "description": "Converts CSS styles into inline style attributes in your HTML code", @@ -1385,43 +1385,41 @@ "email", "pre-processing" ], - "time": "2018-12-10T10:36:30+00:00" + "time": "2019-09-04T16:07:59+00:00" }, { "name": "php-amqplib/php-amqplib", - "version": "v2.7.3", + "version": "v2.10.0", "source": { "type": "git", "url": "https://github.com/php-amqplib/php-amqplib.git", - "reference": "a8ba54bd35b973fc6861e4c2e105f71e9e95f43f" + "reference": "04e5366f032906d5f716890427e425e71307d3a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/a8ba54bd35b973fc6861e4c2e105f71e9e95f43f", - "reference": "a8ba54bd35b973fc6861e4c2e105f71e9e95f43f", + "url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/04e5366f032906d5f716890427e425e71307d3a8", + "reference": "04e5366f032906d5f716890427e425e71307d3a8", "shasum": "" }, "require": { "ext-bcmath": "*", - "ext-mbstring": "*", - "php": ">=5.3.0" + "ext-sockets": "*", + "php": ">=5.6" }, "replace": { "videlalvaro/php-amqplib": "self.version" }, "require-dev": { - "phpdocumentor/phpdocumentor": "^2.9", - "phpunit/phpunit": "^4.8", - "scrutinizer/ocular": "^1.1", + "ext-curl": "*", + "nategood/httpful": "^0.2.20", + "phpdocumentor/phpdocumentor": "dev-master", + "phpunit/phpunit": "^5.7|^6.5|^7.0", "squizlabs/php_codesniffer": "^2.5" }, - "suggest": { - "ext-sockets": "Use AMQPSocketConnection" - }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.10-dev" } }, "autoload": { @@ -1447,6 +1445,11 @@ "name": "Raúl Araya", "email": "nubeiro@gmail.com", "role": "Maintainer" + }, + { + "name": "Luke Bakken", + "email": "luke@bakken.io", + "role": "Maintainer" } ], "description": "Formerly videlalvaro/php-amqplib. This library is a pure PHP implementation of the AMQP protocol. It's been tested against RabbitMQ.", @@ -1456,7 +1459,7 @@ "queue", "rabbitmq" ], - "time": "2018-04-30T03:54:54+00:00" + "time": "2019-08-08T18:28:18+00:00" }, { "name": "phpseclib/mcrypt_compat", @@ -1509,16 +1512,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.21", + "version": "2.0.23", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "9f1287e68b3f283339a9f98f67515dd619e5bf9d" + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/9f1287e68b3f283339a9f98f67515dd619e5bf9d", - "reference": "9f1287e68b3f283339a9f98f67515dd619e5bf9d", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c78eb5058d5bb1a183133c36d4ba5b6675dfa099", + "reference": "c78eb5058d5bb1a183133c36d4ba5b6675dfa099", "shasum": "" }, "require": { @@ -1597,7 +1600,7 @@ "x.509", "x509" ], - "time": "2019-07-12T12:53:49+00:00" + "time": "2019-09-17T03:41:22+00:00" }, { "name": "psr/container", @@ -2079,16 +2082,16 @@ }, { "name": "symfony/css-selector", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d" + "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/105c98bb0c5d8635bea056135304bd8edcc42b4d", - "reference": "105c98bb0c5d8635bea056135304bd8edcc42b4d", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/c6e5e2a00db768c92c3ae131532af4e1acc7bd03", + "reference": "c6e5e2a00db768c92c3ae131532af4e1acc7bd03", "shasum": "" }, "require": { @@ -2128,20 +2131,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2019-01-16T21:53:39+00:00" + "time": "2019-08-20T14:07:54+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "212b020949331b6531250584531363844b34a94e" + "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/212b020949331b6531250584531363844b34a94e", - "reference": "212b020949331b6531250584531363844b34a94e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/429d0a1451d4c9c4abe1959b2986b88794b9b7d2", + "reference": "429d0a1451d4c9c4abe1959b2986b88794b9b7d2", "shasum": "" }, "require": { @@ -2198,7 +2201,7 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2019-06-27T06:42:14+00:00" + "time": "2019-08-26T08:55:16+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2260,16 +2263,16 @@ }, { "name": "symfony/filesystem", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b9896d034463ad6fd2bf17e2bf9418caecd6313d" + "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b9896d034463ad6fd2bf17e2bf9418caecd6313d", - "reference": "b9896d034463ad6fd2bf17e2bf9418caecd6313d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/9abbb7ef96a51f4d7e69627bc6f63307994e4263", + "reference": "9abbb7ef96a51f4d7e69627bc6f63307994e4263", "shasum": "" }, "require": { @@ -2306,20 +2309,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2019-06-23T08:51:25+00:00" + "time": "2019-08-20T14:07:54+00:00" }, { "name": "symfony/finder", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2" + "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9638d41e3729459860bb96f6247ccb61faaa45f2", - "reference": "9638d41e3729459860bb96f6247ccb61faaa45f2", + "url": "https://api.github.com/repos/symfony/finder/zipball/86c1c929f0a4b24812e1eb109262fc3372c8e9f2", + "reference": "86c1c929f0a4b24812e1eb109262fc3372c8e9f2", "shasum": "" }, "require": { @@ -2355,20 +2358,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2019-06-28T13:16:30+00:00" + "time": "2019-08-14T12:26:46+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "82ebae02209c21113908c229e9883c419720738a" + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", - "reference": "82ebae02209c21113908c229e9883c419720738a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", "shasum": "" }, "require": { @@ -2380,7 +2383,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -2396,13 +2399,13 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -2413,20 +2416,20 @@ "polyfill", "portable" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609" + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609", - "reference": "fe5e94c604826c35a32fa832f35bd036b6799609", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", "shasum": "" }, "require": { @@ -2438,7 +2441,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -2472,20 +2475,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/process", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c" + "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/856d35814cf287480465bb7a6c413bb7f5f5e69c", - "reference": "856d35814cf287480465bb7a6c413bb7f5f5e69c", + "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", + "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", "shasum": "" }, "require": { @@ -2521,7 +2524,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-05-30T16:10:05+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "tedivm/jshrink", @@ -2841,16 +2844,16 @@ }, { "name": "zendframework/zend-code", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb" + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/c21db169075c6ec4b342149f446e7b7b724f95eb", - "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/936fa7ad4d53897ea3e3eb41b5b760828246a20b", + "reference": "936fa7ad4d53897ea3e3eb41b5b760828246a20b", "shasum": "" }, "require": { @@ -2858,10 +2861,10 @@ "zendframework/zend-eventmanager": "^2.6 || ^3.0" }, "require-dev": { - "doctrine/annotations": "~1.0", + "doctrine/annotations": "^1.0", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "zendframework/zend-coding-standard": "^1.0.0", + "phpunit/phpunit": "^7.5.15", + "zendframework/zend-coding-standard": "^1.0", "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "suggest": { @@ -2884,13 +2887,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", + "description": "Extensions to the PHP Reflection API, static code scanning, and code generation", "keywords": [ + "ZendFramework", "code", - "zf2" + "zf" ], - "time": "2018-08-13T20:36:59+00:00" + "time": "2019-08-31T14:14:34+00:00" }, { "name": "zendframework/zend-config", @@ -3158,16 +3161,16 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.8.6", + "version": "1.8.7", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "20da13beba0dde8fb648be3cc19765732790f46e" + "reference": "a85e67b86e9b8520d07e6415fcbcb8391b44a75b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e", - "reference": "20da13beba0dde8fb648be3cc19765732790f46e", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/a85e67b86e9b8520d07e6415fcbcb8391b44a75b", + "reference": "a85e67b86e9b8520d07e6415fcbcb8391b44a75b", "shasum": "" }, "require": { @@ -3187,9 +3190,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8.x-dev", - "dev-develop": "1.9.x-dev", - "dev-release-2.0": "2.0.x-dev" + "dev-release-1.8": "1.8.x-dev" } }, "autoload": { @@ -3218,20 +3219,20 @@ "psr", "psr-7" ], - "time": "2018-09-05T19:29:37+00:00" + "time": "2019-08-06T17:53:53+00:00" }, { "name": "zendframework/zend-escaper", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-escaper.git", - "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074" + "reference": "3801caa21b0ca6aca57fa1c42b08d35c395ebd5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/31d8aafae982f9568287cb4dce987e6aff8fd074", - "reference": "31d8aafae982f9568287cb4dce987e6aff8fd074", + "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/3801caa21b0ca6aca57fa1c42b08d35c395ebd5f", + "reference": "3801caa21b0ca6aca57fa1c42b08d35c395ebd5f", "shasum": "" }, "require": { @@ -3263,7 +3264,7 @@ "escaper", "zf" ], - "time": "2018-04-25T15:48:53+00:00" + "time": "2019-09-05T20:03:20+00:00" }, { "name": "zendframework/zend-eventmanager", @@ -3384,16 +3385,16 @@ }, { "name": "zendframework/zend-filter", - "version": "2.9.1", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-filter.git", - "reference": "1c3e6d02f9cd5f6c929c9859498f5efbe216e86f" + "reference": "d78f2cdde1c31975e18b2a0753381ed7b61118ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/1c3e6d02f9cd5f6c929c9859498f5efbe216e86f", - "reference": "1c3e6d02f9cd5f6c929c9859498f5efbe216e86f", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/d78f2cdde1c31975e18b2a0753381ed7b61118ef", + "reference": "d78f2cdde1c31975e18b2a0753381ed7b61118ef", "shasum": "" }, "require": { @@ -3439,13 +3440,13 @@ "license": [ "BSD-3-Clause" ], - "description": "provides a set of commonly needed data filters", + "description": "Programmatically filter and normalize data and files", "keywords": [ "ZendFramework", "filter", "zf" ], - "time": "2018-12-17T16:00:04+00:00" + "time": "2019-08-19T07:08:04+00:00" }, { "name": "zendframework/zend-form", @@ -3645,16 +3646,16 @@ }, { "name": "zendframework/zend-i18n", - "version": "2.9.0", + "version": "2.9.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-i18n.git", - "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f" + "reference": "9233ee8553564a6e45e8311a7173734ba4e5db9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/6d69af5a04e1a4de7250043cb1322f077a0cdb7f", - "reference": "6d69af5a04e1a4de7250043cb1322f077a0cdb7f", + "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/9233ee8553564a6e45e8311a7173734ba4e5db9b", + "reference": "9233ee8553564a6e45e8311a7173734ba4e5db9b", "shasum": "" }, "require": { @@ -3662,7 +3663,7 @@ "zendframework/zend-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.16", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-config": "^2.6", @@ -3709,20 +3710,20 @@ "i18n", "zf" ], - "time": "2018-05-16T16:39:13+00:00" + "time": "2019-09-26T11:54:57+00:00" }, { "name": "zendframework/zend-inputfilter", - "version": "2.10.0", + "version": "2.10.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-inputfilter.git", - "reference": "4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c" + "reference": "1f44a2e9bc394a71638b43bc7024b572fa65410e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c", - "reference": "4f52b71ec9cef3a06e3bba8f5c2124e94055ec0c", + "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/1f44a2e9bc394a71638b43bc7024b572fa65410e", + "reference": "1f44a2e9bc394a71638b43bc7024b572fa65410e", "shasum": "" }, "require": { @@ -3733,7 +3734,7 @@ "zendframework/zend-validator": "^2.11" }, "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.15", "psr/http-message": "^1.0", "zendframework/zend-coding-standard": "~1.0.0" }, @@ -3766,7 +3767,7 @@ "inputfilter", "zf" ], - "time": "2019-01-30T16:58:51+00:00" + "time": "2019-08-28T19:45:32+00:00" }, { "name": "zendframework/zend-json", @@ -3825,16 +3826,16 @@ }, { "name": "zendframework/zend-loader", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/zendframework/zend-loader.git", - "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c" + "reference": "91da574d29b58547385b2298c020b257310898c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/78f11749ea340f6ca316bca5958eef80b38f9b6c", - "reference": "78f11749ea340f6ca316bca5958eef80b38f9b6c", + "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/91da574d29b58547385b2298c020b257310898c6", + "reference": "91da574d29b58547385b2298c020b257310898c6", "shasum": "" }, "require": { @@ -3866,20 +3867,20 @@ "loader", "zf" ], - "time": "2018-04-30T15:20:54+00:00" + "time": "2019-09-04T19:38:14+00:00" }, { "name": "zendframework/zend-log", - "version": "2.10.0", + "version": "2.11.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-log.git", - "reference": "9cec3b092acb39963659c2f32441cccc56b3f430" + "reference": "cb278772afdacb1924342248a069330977625ae6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-log/zipball/9cec3b092acb39963659c2f32441cccc56b3f430", - "reference": "9cec3b092acb39963659c2f32441cccc56b3f430", + "url": "https://api.github.com/repos/zendframework/zend-log/zipball/cb278772afdacb1924342248a069330977625ae6", + "reference": "cb278772afdacb1924342248a069330977625ae6", "shasum": "" }, "require": { @@ -3892,8 +3893,8 @@ "psr/log-implementation": "1.0.0" }, "require-dev": { - "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": "^5.7.15 || ^6.0.8", + "mikey179/vfsstream": "^1.6.7", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.15", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.6", "zendframework/zend-escaper": "^2.5", @@ -3904,7 +3905,6 @@ "suggest": { "ext-mongo": "mongo extension to use Mongo writer", "ext-mongodb": "mongodb extension to use MongoDB writer", - "zendframework/zend-console": "Zend\\Console component to use the RequestID log processor", "zendframework/zend-db": "Zend\\Db component to use the database log writer", "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML log formatter", "zendframework/zend-mail": "Zend\\Mail component to use the email log writer", @@ -3913,8 +3913,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "2.11.x-dev" + "dev-master": "2.11.x-dev", + "dev-develop": "2.12.x-dev" }, "zf": { "component": "Zend\\Log", @@ -3930,14 +3930,14 @@ "license": [ "BSD-3-Clause" ], - "description": "component for general purpose logging", - "homepage": "https://github.com/zendframework/zend-log", + "description": "Robust, composite logger with filtering, formatting, and PSR-3 support", "keywords": [ + "ZendFramework", "log", "logging", - "zf2" + "zf" ], - "time": "2018-04-09T21:59:51+00:00" + "time": "2019-08-23T21:28:18+00:00" }, { "name": "zendframework/zend-mail", @@ -4464,28 +4464,28 @@ }, { "name": "zendframework/zend-session", - "version": "2.8.5", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-session.git", - "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b" + "reference": "0a0c7ae4d8be608e30ecff714c86164ccca19ca3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-session/zipball/2cfd90e1a2f6b066b9f908599251d8f64f07021b", - "reference": "2cfd90e1a2f6b066b9f908599251d8f64f07021b", + "url": "https://api.github.com/repos/zendframework/zend-session/zipball/0a0c7ae4d8be608e30ecff714c86164ccca19ca3", + "reference": "0a0c7ae4d8be608e30ecff714c86164ccca19ca3", "shasum": "" }, "require": { "php": "^5.6 || ^7.0", "zendframework/zend-eventmanager": "^2.6.2 || ^3.0", - "zendframework/zend-stdlib": "^2.7 || ^3.0" + "zendframework/zend-stdlib": "^3.2.1" }, "require-dev": { "container-interop/container-interop": "^1.1", "mongodb/mongodb": "^1.0.1", "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", - "phpunit/phpunit": "^5.7.5 || >=6.0.13 <6.5.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.16", "zendframework/zend-cache": "^2.6.1", "zendframework/zend-coding-standard": "~1.0.0", "zendframework/zend-db": "^2.7", @@ -4504,8 +4504,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev", - "dev-develop": "2.9-dev" + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" }, "zf": { "component": "Zend\\Session", @@ -4521,13 +4521,13 @@ "license": [ "BSD-3-Clause" ], - "description": "manage and preserve session data, a logical complement of cookie data, across multiple page requests by the same client", + "description": "Object-oriented interface to PHP sessions and storage", "keywords": [ "ZendFramework", "session", "zf" ], - "time": "2018-02-22T16:33:54+00:00" + "time": "2019-09-20T12:50:51+00:00" }, { "name": "zendframework/zend-soap", @@ -4938,25 +4938,26 @@ }, { "name": "allure-framework/allure-php-api", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", - "url": "https://github.com/allure-framework/allure-php-adapter-api.git", - "reference": "a462a0da121681577033e13c123b6cc4e89cdc64" + "url": "https://github.com/allure-framework/allure-php-commons.git", + "reference": "c7a675823ad75b8e02ddc364baae21668e7c4e88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/allure-framework/allure-php-adapter-api/zipball/a462a0da121681577033e13c123b6cc4e89cdc64", - "reference": "a462a0da121681577033e13c123b6cc4e89cdc64", + "url": "https://api.github.com/repos/allure-framework/allure-php-commons/zipball/c7a675823ad75b8e02ddc364baae21668e7c4e88", + "reference": "c7a675823ad75b8e02ddc364baae21668e7c4e88", "shasum": "" }, "require": { - "jms/serializer": ">=0.16.0", - "moontoast/math": ">=1.1.0", + "jms/serializer": "^0.16.0", "php": ">=5.4.0", - "phpunit/phpunit": ">=4.0.0", - "ramsey/uuid": ">=3.0.0", - "symfony/http-foundation": ">=2.0" + "ramsey/uuid": "^3.0.0", + "symfony/http-foundation": "^2.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0.0" }, "type": "library", "autoload": { @@ -4986,7 +4987,7 @@ "php", "report" ], - "time": "2016-12-07T12:15:46+00:00" + "time": "2018-05-25T14:02:11+00:00" }, { "name": "allure-framework/allure-phpunit", @@ -5021,8 +5022,8 @@ "authors": [ { "name": "Ivan Krutov", - "email": "vania-pooh@yandex-team.ru", - "role": "Developer" + "role": "Developer", + "email": "vania-pooh@yandex-team.ru" } ], "description": "A PHPUnit adapter for Allure report.", @@ -5283,16 +5284,16 @@ }, { "name": "codeception/phpunit-wrapper", - "version": "6.6.1", + "version": "6.7.0", "source": { "type": "git", "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c" + "reference": "93f59e028826464eac086052fa226e58967f6907" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c", - "reference": "d0da25a98bcebeb15d97c2ad3b2de6166b6e7a0c", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/93f59e028826464eac086052fa226e58967f6907", + "reference": "93f59e028826464eac086052fa226e58967f6907", "shasum": "" }, "require": { @@ -5325,7 +5326,7 @@ } ], "description": "PHPUnit classes used by Codeception", - "time": "2019-02-26T20:47:39+00:00" + "time": "2019-08-18T15:43:35+00:00" }, { "name": "codeception/stub", @@ -6030,16 +6031,16 @@ }, { "name": "doctrine/annotations", - "version": "v1.6.1", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24" + "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/53120e0eb10355388d6ccbe462f1fea34ddadb24", - "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/fa4c4e861e809d6a1103bd620cce63ed91aedfeb", + "reference": "fa4c4e861e809d6a1103bd620cce63ed91aedfeb", "shasum": "" }, "require": { @@ -6048,12 +6049,12 @@ }, "require-dev": { "doctrine/cache": "1.*", - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^7.5@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6.x-dev" + "dev-master": "1.7.x-dev" } }, "autoload": { @@ -6066,6 +6067,10 @@ "MIT" ], "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -6074,10 +6079,6 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, { "name": "Jonathan Wage", "email": "jonwage@gmail.com" @@ -6094,7 +6095,7 @@ "docblock", "parser" ], - "time": "2019-03-25T19:12:02+00:00" + "time": "2019-08-08T18:11:40+00:00" }, { "name": "doctrine/cache", @@ -6171,76 +6172,6 @@ ], "time": "2018-08-21T18:01:43+00:00" }, - { - "name": "doctrine/collections", - "version": "v1.6.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/c5e0bc17b1620e97c968ac409acbff28b8b850be", - "reference": "c5e0bc17b1620e97c968ac409acbff28b8b850be", - "shasum": "" - }, - "require": { - "php": "^7.1.3" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan-shim": "^0.9.2", - "phpunit/phpunit": "^7.0", - "vimeo/psalm": "^3.2.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", - "homepage": "https://www.doctrine-project.org/projects/collections.html", - "keywords": [ - "array", - "collections", - "iterators", - "php" - ], - "time": "2019-06-09T13:48:14+00:00" - }, { "name": "doctrine/inflector", "version": "v1.1.0", @@ -6424,52 +6355,6 @@ ], "time": "2019-06-08T11:03:04+00:00" }, - { - "name": "epfremme/swagger-php", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/epfremmer/swagger-php.git", - "reference": "eee28a442b7e6220391ec953d3c9b936354f23bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/epfremmer/swagger-php/zipball/eee28a442b7e6220391ec953d3c9b936354f23bc", - "reference": "eee28a442b7e6220391ec953d3c9b936354f23bc", - "shasum": "" - }, - "require": { - "doctrine/annotations": "^1.2", - "doctrine/collections": "^1.3", - "jms/serializer": "^1.1", - "php": ">=5.5", - "phpoption/phpoption": "^1.1", - "symfony/yaml": "^2.7|^3.1" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "~4.8|~5.0", - "satooshi/php-coveralls": "^1.0" - }, - "type": "package", - "autoload": { - "psr-4": { - "Epfremme\\Swagger\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Edward Pfremmer", - "email": "epfremme@nerdery.com" - } - ], - "description": "Library for parsing swagger documentation into PHP entities for use in testing and code generation", - "time": "2016-09-26T17:24:17+00:00" - }, { "name": "facebook/webdriver", "version": "1.7.1", @@ -6573,16 +6458,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.14.4", + "version": "v2.14.6", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "69ccf81f3c968be18d646918db94ab88ddf3594f" + "reference": "8d18a8bb180e2acde1c8031db09aefb9b73f6127" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/69ccf81f3c968be18d646918db94ab88ddf3594f", - "reference": "69ccf81f3c968be18d646918db94ab88ddf3594f", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/8d18a8bb180e2acde1c8031db09aefb9b73f6127", + "reference": "8d18a8bb180e2acde1c8031db09aefb9b73f6127", "shasum": "" }, "require": { @@ -6612,9 +6497,10 @@ "php-cs-fixer/accessible-object": "^1.0", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1", - "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1", - "phpunitgoodpractices/traits": "^1.8", - "symfony/phpunit-bridge": "^4.3" + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1", + "phpunitgoodpractices/traits": "^1.5.1", + "symfony/phpunit-bridge": "^4.0", + "symfony/yaml": "^3.0 || ^4.0" }, "suggest": { "ext-mbstring": "For handling non-UTF8 characters in cache signature.", @@ -6647,17 +6533,17 @@ "MIT" ], "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" } ], "description": "A tool to automatically fix PHP code style", - "time": "2019-06-01T10:29:34+00:00" + "time": "2019-08-31T12:47:52+00:00" }, { "name": "fzaninotto/faker", @@ -6804,6 +6690,48 @@ "description": "Expands internal property references in a yaml file.", "time": "2017-12-16T16:06:03+00:00" }, + { + "name": "ircmaxell/password-compat", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/ircmaxell/password_compat.git", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", + "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "autoload": { + "files": [ + "lib/password.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthony Ferrara", + "email": "ircmaxell@php.net", + "homepage": "http://blog.ircmaxell.com" + } + ], + "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", + "homepage": "https://github.com/ircmaxell/password_compat", + "keywords": [ + "hashing", + "password" + ], + "time": "2014-11-20T16:49:30+00:00" + }, { "name": "jms/metadata", "version": "1.7.0", @@ -6896,56 +6824,44 @@ }, { "name": "jms/serializer", - "version": "1.14.0", + "version": "0.16.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/serializer.git", - "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca" + "reference": "c8a171357ca92b6706e395c757f334902d430ea9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", - "reference": "ee96d57024af9a7716d56fcbe3aa94b3d030f3ca", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/c8a171357ca92b6706e395c757f334902d430ea9", + "reference": "c8a171357ca92b6706e395c757f334902d430ea9", "shasum": "" }, "require": { - "doctrine/annotations": "^1.0", - "doctrine/instantiator": "^1.0.3", - "jms/metadata": "^1.3", + "doctrine/annotations": "1.*", + "jms/metadata": "~1.1", "jms/parser-lib": "1.*", - "php": "^5.5|^7.0", - "phpcollection/phpcollection": "~0.1", - "phpoption/phpoption": "^1.1" - }, - "conflict": { - "twig/twig": "<1.12" + "php": ">=5.3.2", + "phpcollection/phpcollection": "~0.1" }, "require-dev": { "doctrine/orm": "~2.1", - "doctrine/phpcr-odm": "^1.3|^2.0", - "ext-pdo_sqlite": "*", - "jackalope/jackalope-doctrine-dbal": "^1.1.5", - "phpunit/phpunit": "^4.8|^5.0", + "doctrine/phpcr-odm": "~1.0.1", + "jackalope/jackalope-doctrine-dbal": "1.0.*", "propel/propel1": "~1.7", - "psr/container": "^1.0", - "symfony/dependency-injection": "^2.7|^3.3|^4.0", - "symfony/expression-language": "^2.6|^3.0", - "symfony/filesystem": "^2.1", - "symfony/form": "~2.1|^3.0", - "symfony/translation": "^2.1|^3.0", - "symfony/validator": "^2.2|^3.0", - "symfony/yaml": "^2.1|^3.0", - "twig/twig": "~1.12|~2.0" + "symfony/filesystem": "2.*", + "symfony/form": "~2.1", + "symfony/translation": "~2.0", + "symfony/validator": "~2.0", + "symfony/yaml": "2.*", + "twig/twig": ">=1.8,<2.0-dev" }, "suggest": { - "doctrine/cache": "Required if you like to use cache functionality.", - "doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.", "symfony/yaml": "Required if you'd like to serialize data to YAML format." }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.14-dev" + "dev-master": "0.15-dev" } }, "autoload": { @@ -6955,16 +6871,14 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache2" ], "authors": [ { - "name": "Asmir Mustafic", - "email": "goetas@gmail.com" - }, - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh", + "role": "Developer of wrapped JMSSerializerBundle" } ], "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.", @@ -6976,7 +6890,7 @@ "serialization", "xml" ], - "time": "2019-04-17T08:12:16+00:00" + "time": "2014-03-18T08:39:00+00:00" }, { "name": "league/container", @@ -7303,23 +7217,23 @@ }, { "name": "mikey179/vfsstream", - "version": "v1.6.6", + "version": "v1.6.7", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "095238a0711c974ae5b4ebf4c4534a23f3f6c99d" + "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/095238a0711c974ae5b4ebf4c4534a23f3f6c99d", - "reference": "095238a0711c974ae5b4ebf4c4534a23f3f6c99d", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", + "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "~4.5" + "phpunit/phpunit": "^4.5|^5.0" }, "type": "library", "extra": { @@ -7345,56 +7259,7 @@ ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", - "time": "2019-04-08T13:54:32+00:00" - }, - { - "name": "moontoast/math", - "version": "1.1.2", - "source": { - "type": "git", - "url": "https://github.com/ramsey/moontoast-math.git", - "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/moontoast-math/zipball/c2792a25df5cad4ff3d760dd37078fc5b6fccc79", - "reference": "c2792a25df5cad4ff3d760dd37078fc5b6fccc79", - "shasum": "" - }, - "require": { - "ext-bcmath": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-parallel-lint": "^0.9.0", - "phpunit/phpunit": "^4.7|>=5.0 <5.4", - "satooshi/php-coveralls": "^0.6.1", - "squizlabs/php_codesniffer": "^2.3" - }, - "type": "library", - "autoload": { - "psr-4": { - "Moontoast\\Math\\": "src/Moontoast/Math/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" - } - ], - "description": "A mathematics library, providing functionality for large numbers", - "homepage": "https://github.com/ramsey/moontoast-math", - "keywords": [ - "bcmath", - "math" - ], - "time": "2017-02-16T16:54:46+00:00" + "time": "2019-08-01T01:38:37+00:00" }, { "name": "mustache/mustache", @@ -7444,16 +7309,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.1", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", - "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { @@ -7488,7 +7353,7 @@ "object", "object graph" ], - "time": "2019-04-07T13:18:21+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "pdepend/pdepend", @@ -7568,18 +7433,18 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "role": "Developer", + "email": "arne@blankerts.de" }, { "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "role": "Developer", + "email": "sebastian@phpeople.de" }, { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "role": "Developer", + "email": "sebastian@phpunit.de" } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", @@ -7615,18 +7480,18 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "role": "Developer", + "email": "arne@blankerts.de" }, { "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" + "role": "Developer", + "email": "sebastian@phpeople.de" }, { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" + "role": "Developer", + "email": "sebastian@phpunit.de" } ], "description": "Library for handling version information and constraints", @@ -7733,35 +7598,33 @@ }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -7783,30 +7646,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.1", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", - "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -7834,41 +7697,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-04-30T17:48:53+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -7881,7 +7743,8 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpmd/phpmd", @@ -8114,8 +7977,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", @@ -8162,8 +8025,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "role": "lead", + "email": "sb@sebastian-bergmann.de" } ], "description": "FilterIterator implementation that filters files based on a list of suffixes.", @@ -8204,8 +8067,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Simple template engine.", @@ -8253,8 +8116,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" + "role": "lead", + "email": "sb@sebastian-bergmann.de" } ], "description": "Utility class for timing", @@ -8764,16 +8627,16 @@ }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -8800,6 +8663,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -8808,17 +8675,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -8827,7 +8690,7 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/finder-facade", @@ -8860,8 +8723,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", @@ -9191,8 +9054,8 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "role": "lead", + "email": "sebastian@phpunit.de" } ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", @@ -9252,16 +9115,16 @@ }, { "name": "symfony/browser-kit", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "a29dd02a1f3f81b9a15c7730cc3226718ddb55ca" + "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a29dd02a1f3f81b9a15c7730cc3226718ddb55ca", - "reference": "a29dd02a1f3f81b9a15c7730cc3226718ddb55ca", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9e5dddb637b13db82e35695a8603fe6e118cc119", + "reference": "9e5dddb637b13db82e35695a8603fe6e118cc119", "shasum": "" }, "require": { @@ -9307,20 +9170,20 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2019-06-11T15:41:59+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/config", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a17a2aea43950ce83a0603ed301bac362eb86870" + "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a17a2aea43950ce83a0603ed301bac362eb86870", - "reference": "a17a2aea43950ce83a0603ed301bac362eb86870", + "url": "https://api.github.com/repos/symfony/config/zipball/07d49c0f823e0bc367c6d84e35b61419188a5ece", + "reference": "07d49c0f823e0bc367c6d84e35b61419188a5ece", "shasum": "" }, "require": { @@ -9371,26 +9234,26 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2019-07-18T10:34:59+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "9ad1b83d474ae17156f6914cb81ffe77aeac3a9b" + "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/9ad1b83d474ae17156f6914cb81ffe77aeac3a9b", - "reference": "9ad1b83d474ae17156f6914cb81ffe77aeac3a9b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d3ad14b66ac773ba6123622eb9b5b010165fe3d9", + "reference": "d3ad14b66ac773ba6123622eb9b5b010165fe3d9", "shasum": "" }, "require": { "php": "^7.1.3", "psr/container": "^1.0", - "symfony/service-contracts": "^1.1.2" + "symfony/service-contracts": "^1.1.6" }, "conflict": { "symfony/config": "<4.3", @@ -9444,20 +9307,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2019-07-26T07:03:43+00:00" + "time": "2019-08-26T16:27:33+00:00" }, { "name": "symfony/dom-crawler", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "291397232a2eefb3347eaab9170409981eaad0e2" + "reference": "cc686552948d627528c0e2e759186dff67c2610e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291397232a2eefb3347eaab9170409981eaad0e2", - "reference": "291397232a2eefb3347eaab9170409981eaad0e2", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/cc686552948d627528c0e2e759186dff67c2610e", + "reference": "cc686552948d627528c0e2e759186dff67c2610e", "shasum": "" }, "require": { @@ -9505,35 +9368,35 @@ ], "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", - "time": "2019-06-13T11:03:18+00:00" + "time": "2019-08-26T08:26:39+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.3.3", + "version": "v2.8.50", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "8b778ee0c27731105fbf1535f51793ad1ae0ba2b" + "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8b778ee0c27731105fbf1535f51793ad1ae0ba2b", - "reference": "8b778ee0c27731105fbf1535f51793ad1ae0ba2b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/746f8d3638bf46ee8b202e62f2b214c3d61fb06a", + "reference": "746f8d3638bf46ee8b202e62f2b214c3d61fb06a", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/mime": "^4.3", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php54": "~1.0", + "symfony/polyfill-php55": "~1.0" }, "require-dev": { - "predis/predis": "~1.0", - "symfony/expression-language": "~3.4|~4.0" + "symfony/expression-language": "~2.4|~3.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -9560,30 +9423,24 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-07-23T11:21:36+00:00" + "time": "2019-04-16T10:00:53+00:00" }, { - "name": "symfony/mime", - "version": "v4.3.3", + "name": "symfony/options-resolver", + "version": "v4.3.4", "source": { "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "6b7148029b1dd5eda1502064f06d01357b7b2d8b" + "url": "https://github.com/symfony/options-resolver.git", + "reference": "81c2e120522a42f623233968244baebd6b36cb6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/6b7148029b1dd5eda1502064f06d01357b7b2d8b", - "reference": "6b7148029b1dd5eda1502064f06d01357b7b2d8b", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/81c2e120522a42f623233968244baebd6b36cb6a", + "reference": "81c2e120522a42f623233968244baebd6b36cb6a", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" - }, - "require-dev": { - "egulias/email-validator": "^2.0", - "symfony/dependency-injection": "~3.4|^4.1" + "php": "^7.1.3" }, "type": "library", "extra": { @@ -9593,7 +9450,7 @@ }, "autoload": { "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Component\\OptionsResolver\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -9613,43 +9470,47 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A library to manipulate MIME messages", + "description": "Symfony OptionsResolver Component", "homepage": "https://symfony.com", "keywords": [ - "mime", - "mime-type" + "config", + "configuration", + "options" ], - "time": "2019-07-19T16:21:19+00:00" + "time": "2019-08-08T09:29:19+00:00" }, { - "name": "symfony/options-resolver", - "version": "v4.3.3", + "name": "symfony/polyfill-php54", + "version": "v1.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "40762ead607c8f792ee4516881369ffa553fee6f" + "url": "https://github.com/symfony/polyfill-php54.git", + "reference": "a043bcced870214922fbb4bf22679d431ec0296a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/40762ead607c8f792ee4516881369ffa553fee6f", - "reference": "40762ead607c8f792ee4516881369ffa553fee6f", + "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/a043bcced870214922fbb4bf22679d431ec0296a", + "reference": "a043bcced870214922fbb4bf22679d431ec0296a", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "1.12-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" + "Symfony\\Polyfill\\Php54\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -9658,54 +9519,51 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony OptionsResolver Component", + "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ - "config", - "configuration", - "options" + "compatibility", + "polyfill", + "portable", + "shim" ], - "time": "2019-06-13T11:01:17+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.11.0", + "name": "symfony/polyfill-php55", + "version": "v1.12.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af" + "url": "https://github.com/symfony/polyfill-php55.git", + "reference": "548bb39407e78e54f785b4e18c7e0d5d9e493265" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c766e95bec706cdd89903b1eda8afab7d7a6b7af", - "reference": "c766e95bec706cdd89903b1eda8afab7d7a6b7af", + "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/548bb39407e78e54f785b4e18c7e0d5d9e493265", + "reference": "548bb39407e78e54f785b4e18c7e0d5d9e493265", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.9" - }, - "suggest": { - "ext-intl": "For best performance" + "ircmaxell/password-compat": "~1.0", + "php": ">=5.3.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "1.12-dev" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" + "Symfony\\Polyfill\\Php55\\": "" }, "files": [ "bootstrap.php" @@ -9717,38 +9575,36 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "idn", - "intl", "polyfill", "portable", "shim" ], - "time": "2019-03-04T13:44:35+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-php70", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "bc4858fb611bda58719124ca079baff854149c89" + "reference": "54b4c428a0054e254223797d2713c31e08610831" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/bc4858fb611bda58719124ca079baff854149c89", - "reference": "bc4858fb611bda58719124ca079baff854149c89", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/54b4c428a0054e254223797d2713c31e08610831", + "reference": "54b4c428a0054e254223797d2713c31e08610831", "shasum": "" }, "require": { @@ -9758,7 +9614,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -9794,20 +9650,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.11.0", + "version": "v1.12.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c" + "reference": "04ce3335667451138df4307d6a9b61565560199e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/ab50dcf166d5f577978419edd37aa2bb8eabce0c", - "reference": "ab50dcf166d5f577978419edd37aa2bb8eabce0c", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", + "reference": "04ce3335667451138df4307d6a9b61565560199e", "shasum": "" }, "require": { @@ -9816,7 +9672,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11-dev" + "dev-master": "1.12-dev" } }, "autoload": { @@ -9849,20 +9705,20 @@ "portable", "shim" ], - "time": "2019-02-06T07:57:58+00:00" + "time": "2019-08-06T08:03:45+00:00" }, { "name": "symfony/service-contracts", - "version": "v1.1.5", + "version": "v1.1.6", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d" + "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d", - "reference": "f391a00de78ec7ec8cf5cdcdae59ec7b883edb8d", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", "shasum": "" }, "require": { @@ -9907,20 +9763,20 @@ "interoperability", "standards" ], - "time": "2019-06-13T11:15:36+00:00" + "time": "2019-08-20T14:44:19+00:00" }, { "name": "symfony/stopwatch", - "version": "v4.3.3", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "6b100e9309e8979cf1978ac1778eb155c1f7d93b" + "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6b100e9309e8979cf1978ac1778eb155c1f7d93b", - "reference": "6b100e9309e8979cf1978ac1778eb155c1f7d93b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/1e4ff456bd625be5032fac9be4294e60442e9b71", + "reference": "1e4ff456bd625be5032fac9be4294e60442e9b71", "shasum": "" }, "require": { @@ -9957,24 +9813,24 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2019-05-27T08:16:38+00:00" + "time": "2019-08-07T11:52:19+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.30", + "version": "v4.3.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b" + "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/051d045c684148060ebfc9affb7e3f5e0899d40b", - "reference": "051d045c684148060ebfc9affb7e3f5e0899d40b", + "url": "https://api.github.com/repos/symfony/yaml/zipball/5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", + "reference": "5a0b7c32dc3ec56fd4abae8a4a71b0cf05013686", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": "^7.1.3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -9989,7 +9845,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -10016,7 +9872,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-07-24T13:01:31+00:00" + "time": "2019-08-20T14:27:59+00:00" }, { "name": "theseer/fdomdocument", @@ -10050,8 +9906,8 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "lead" + "role": "lead", + "email": "arne@blankerts.de" } ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", @@ -10091,8 +9947,8 @@ "authors": [ { "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" + "role": "Developer", + "email": "arne@blankerts.de" } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", @@ -10151,16 +10007,16 @@ }, { "name": "webmozart/assert", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", - "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { @@ -10168,8 +10024,7 @@ "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -10198,7 +10053,7 @@ "check", "validate" ], - "time": "2018-12-25T11:19:39+00:00" + "time": "2019-08-24T08:43:50+00:00" }, { "name": "weew/helpers-array", From ea68f57e55b07c8418a8f709d87f9ed059e54aed Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 30 Sep 2019 16:03:28 +0400 Subject: [PATCH 0711/1172] MC-18215: Error message while creating shipping label - Updated automated test script --- app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml | 1 - .../Mftf/Data/{FexExConfigData.xml => FedExConfigData.xml} | 0 .../Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml | 4 ++-- 3 files changed, 2 insertions(+), 3 deletions(-) rename app/code/Magento/Fedex/Test/Mftf/Data/{FexExConfigData.xml => FedExConfigData.xml} (100%) diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml index 986369f4ebc6..4d7a39b3246e 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml @@ -291,7 +291,6 @@ <data key="company">Magento</data> <array key="street"> <item>Augsburger Strabe 41</item> - <item>Augsburger Strabe 42</item> </array> <data key="city">Berlin</data> <data key="country_id">DE</data> diff --git a/app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml b/app/code/Magento/Fedex/Test/Mftf/Data/FedExConfigData.xml similarity index 100% rename from app/code/Magento/Fedex/Test/Mftf/Data/FexExConfigData.xml rename to app/code/Magento/Fedex/Test/Mftf/Data/FedExConfigData.xml diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml index 4b4654abb2bf..e50d484df27c 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml @@ -42,14 +42,14 @@ <magentoCLI command="config:set {{AdminGeneralSetCityConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.city}}" stepKey="setStoreInformationCity"/> <magentoCLI command="config:set {{AdminGeneralSetPostcodeConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.postcode}}" stepKey="setStoreInformationPostcode"/> <magentoCLI command="config:set {{AdminGeneralSetStreetAddressConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[0]}}'" stepKey="setStoreInformationStreetAddress"/> - <magentoCLI command="config:set {{AdminGeneralSetStreetAddress2ConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[1]}}'" stepKey="setStoreInformationStreetAddress2"/> + <magentoCLI command="config:set {{AdminGeneralSetStreetAddress2ConfigData.path}} '{{US_Address_California.street[0]}}'" stepKey="setStoreInformationStreetAddress2"/> <magentoCLI command="config:set {{AdminGeneralSetVatNumberConfigData.path}} {{AdminGeneralSetVatNumberConfigData.value}}" stepKey="setStoreInformationVatNumber"/> <!--Set Shipping settings origin data--> <magentoCLI command="config:set {{AdminShippingSettingsOriginCountryConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.country_id}}" stepKey="setOriginCountry"/> <magentoCLI command="config:set {{AdminShippingSettingsOriginCityConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.city}}" stepKey="setOriginCity"/> <magentoCLI command="config:set {{AdminShippingSettingsOriginZipCodeConfigData.path}} {{DE_Address_Berlin_Not_Default_Address.postcode}}" stepKey="setOriginZipCode"/> <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddressConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[0]}}'" stepKey="setOriginStreetAddress"/> - <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddress2ConfigData.path}} '{{DE_Address_Berlin_Not_Default_Address.street[1]}}'" stepKey="setOriginStreetAddress2"/> + <magentoCLI command="config:set {{AdminShippingSettingsOriginStreetAddress2ConfigData.path}} '{{US_Address_California.street[0]}}'" stepKey="setOriginStreetAddress2"/> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> From e1948fcaaa06c8cf412a9d45904d9fa335eaec2a Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Fri, 27 Sep 2019 14:12:50 -0500 Subject: [PATCH 0712/1172] MC-20394: [Magento Cloud] Redirect URL is getting cut off after 3 slashes - Fix redirect to base URL --- .../Plugin/RequestPreprocessor.php | 7 +- .../Plugin/RequestPreprocessorTest.php | 198 +++++++++++++++++- 2 files changed, 193 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php index 5df50581792c..de2da5442382 100644 --- a/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php +++ b/app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php @@ -5,6 +5,9 @@ */ namespace Magento\Store\App\FrontController\Plugin; +/** + * Class RequestPreprocessor + */ class RequestPreprocessor { /** @@ -52,6 +55,7 @@ public function __construct( /** * Auto-redirect to base url (without SID) if the requested url doesn't match it. + * * By default this feature is enabled in configuration. * * @param \Magento\Framework\App\FrontController $subject @@ -72,10 +76,11 @@ public function aroundDispatch( $this->_storeManager->getStore()->isCurrentlySecure() ); if ($baseUrl) { + // phpcs:disable Magento2.Functions.DiscouragedFunction $uri = parse_url($baseUrl); if (!$this->getBaseUrlChecker()->execute($uri, $request)) { $redirectUrl = $this->_url->getRedirectUrl( - $this->_url->getUrl(ltrim($request->getPathInfo(), '/'), ['_nosid' => true]) + $this->_url->getDirectUrl(ltrim($request->getPathInfo(), '/'), ['_nosid' => true]) ); $redirectCode = (int)$this->_scopeConfig->getValue( 'web/url/redirect_to_base', diff --git a/dev/tests/integration/testsuite/Magento/Store/App/FrontController/Plugin/RequestPreprocessorTest.php b/dev/tests/integration/testsuite/Magento/Store/App/FrontController/Plugin/RequestPreprocessorTest.php index 0e158821f180..a1a99ecd32b8 100644 --- a/dev/tests/integration/testsuite/Magento/Store/App/FrontController/Plugin/RequestPreprocessorTest.php +++ b/dev/tests/integration/testsuite/Magento/Store/App/FrontController/Plugin/RequestPreprocessorTest.php @@ -14,7 +14,7 @@ use Zend\Stdlib\Parameters; /** - * Class RequestPreprocessorTest @covers \Magento\Store\App\FrontController\Plugin\RequestPreprocessor. + * Tests \Magento\Store\App\FrontController\Plugin\RequestPreprocessor. */ class RequestPreprocessorTest extends \Magento\TestFramework\TestCase\AbstractController { @@ -24,6 +24,28 @@ class RequestPreprocessorTest extends \Magento\TestFramework\TestCase\AbstractCo * @var string */ private $baseUrl; + /** + * @var array; + */ + private $config; + + /** + * @inheritDoc + */ + protected function setUp() + { + parent::setUp(); + $this->config = []; + } + + /** + * @inheritDoc + */ + protected function tearDown() + { + $this->setConfig($this->config); + parent::tearDown(); + } /** * Test non-secure POST request is redirected right away on completely secure frontend. @@ -62,6 +84,115 @@ public function testHttpsPassSecureLoginPost() $this->setFrontendCompletelySecureRollback(); } + /** + * Test auto redirect to base URL + * + * @param array $config + * @param string $requestUrl + * @param string $redirectUrl + * @dataProvider autoRedirectToBaseURLDataProvider + */ + public function testAutoRedirectToBaseURL(array $config, string $requestUrl, string $redirectUrl) + { + $request = [ + 'REQUEST_SCHEME' => parse_url($requestUrl, PHP_URL_SCHEME), + 'SERVER_NAME' => parse_url($requestUrl, PHP_URL_HOST), + 'SCRIPT_NAME' => '/index.php', + 'SCRIPT_FILENAME' => 'index.php', + 'REQUEST_URI' => parse_url($requestUrl, PHP_URL_PATH), + ]; + $this->setConfig($config); + $this->setServer($request); + $app = $this->_objectManager->create(\Magento\Framework\App\Http::class, ['_request' => $this->getRequest()]); + $this->_response = $app->launch(); + $this->assertRedirect($this->equalTo($redirectUrl)); + } + + /** + * @return array + */ + public function autoRedirectToBaseURLDataProvider(): array + { + $baseConfig = [ + 'web/unsecure/base_url' => 'http://magento.com/us/', + 'web/session/use_frontend_sid' => 0, + 'web/seo/use_rewrites' => 1, + ]; + + return [ + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c/d/e.html', + 'redirectUrl' => 'http://magento.com/us/a/b/c/d/e.html' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c/d.html', + 'redirectUrl' => 'http://magento.com/us/a/b/c/d.html' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c.html', + 'redirectUrl' => 'http://magento.com/us/a/b/c.html' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b.html', + 'redirectUrl' => 'http://magento.com/us/a/b.html' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a.html', + 'redirectUrl' => 'http://magento.com/us/a.html' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c/d/e', + 'redirectUrl' => 'http://magento.com/us/a/b/c/d/e' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c/d', + 'redirectUrl' => 'http://magento.com/us/a/b/c/d' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b/c', + 'redirectUrl' => 'http://magento.com/us/a/b/c' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a/b', + 'redirectUrl' => 'http://magento.com/us/a/b' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/a', + 'redirectUrl' => 'http://magento.com/us/a' + ], + [ + 'config' => $baseConfig, + 'request' => 'http://magento.com/', + 'redirectUrl' => 'http://magento.com/us/' + ], + [ + 'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]), + 'request' => 'http://magento.com/', + 'redirectUrl' => 'http://magento.com/us/index.php/' + ], + [ + 'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]), + 'request' => 'http://magento.com/a/b/c/d.html', + 'redirectUrl' => 'http://magento.com/us/index.php/a/b/c/d.html' + ], + [ + 'config' => array_merge($baseConfig, ['web/seo/use_rewrites' => 0]), + 'request' => 'http://magento.com/a/b/c/d', + 'redirectUrl' => 'http://magento.com/us/index.php/a/b/c/d' + ], + ]; + } + /** * Assert response is redirect with https protocol. * @@ -83,22 +214,26 @@ private function assertResponseRedirect(Response $response, string $redirectUrl) */ private function prepareRequest(bool $isSecure = false) { - $post = new Parameters([ - 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(), - 'login' => [ - 'username' => 'customer@example.com', - 'password' => 'password' + $post = new Parameters( + [ + 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(), + 'login' => [ + 'username' => 'customer@example.com', + 'password' => 'password' + ] ] - ]); + ); $request = $this->getRequest(); $request->setMethod(\Magento\TestFramework\Request::METHOD_POST); $request->setRequestUri('customer/account/loginPost/'); $request->setPost($post); if ($isSecure) { - $server = new Parameters([ - 'HTTPS' => 'on', - 'SERVER_PORT' => 443 - ]); + $server = new Parameters( + [ + 'HTTPS' => 'on', + 'SERVER_PORT' => 443 + ] + ); $request->setServer($server); } @@ -151,4 +286,45 @@ private function setFrontendCompletelySecureRollback() $reinitibleConfig = $this->_objectManager->create(ReinitableConfigInterface::class); $reinitibleConfig->reinit(); } + + private function setConfig(array $config): void + { + foreach ($config as $path => $value) { + $model = $this->_objectManager->create(Value::class); + $model->load($path, 'path'); + if (!isset($this->config[$path])) { + $this->config[$path] = $model->getValue(); + } + if (!$model->getPath()) { + $model->setPath($path); + } + if ($value !== null) { + $model->setValue($value); + $model->save(); + } elseif ($model->getId()) { + $model->delete(); + } + } + $this->_objectManager->create(ReinitableConfigInterface::class)->reinit(); + } + + private function setServer(array $server) + { + $request = $this->getRequest(); + $properties = [ + 'baseUrl', + 'basePath', + 'requestUri', + 'originalPathInfo', + 'pathInfo', + ]; + $reflection = new \ReflectionClass($request); + + foreach ($properties as $name) { + $property = $reflection->getProperty($name); + $property->setAccessible(true); + $property->setValue($request, null); + } + $request->setServer(new Parameters($server)); + } } From a73b832be92f3628363d7a4e6db5d4dc6a36e8cf Mon Sep 17 00:00:00 2001 From: Nazar Klovanych <nazarn96@gmail.com> Date: Mon, 30 Sep 2019 16:59:46 +0300 Subject: [PATCH 0713/1172] Cover changes with unit test. --- .../Indexer/ProductPriceIndexFilterTest.php | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/ProductPriceIndexFilterTest.php diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/ProductPriceIndexFilterTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/ProductPriceIndexFilterTest.php new file mode 100644 index 000000000000..46f4e0f26f37 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/ProductPriceIndexFilterTest.php @@ -0,0 +1,121 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogInventory\Test\Unit\Model\Indexer; + +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Model\Indexer\ProductPriceIndexFilter; +use Magento\CatalogInventory\Model\ResourceModel\Stock\Item; +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\DB\Query\Generator; +use PHPUnit\Framework\MockObject\MockObject; +use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure; + +/** + * Product Price filter test, to ensure that product id's filtered. + */ +class ProductPriceIndexFilterTest extends \PHPUnit\Framework\TestCase +{ + + /** + * @var MockObject|StockConfigurationInterface $stockConfiguration + */ + private $stockConfiguration; + + /** + * @var MockObject|Item $item + */ + private $item; + + /** + * @var MockObject|ResourceConnection $resourceCnnection + */ + private $resourceCnnection; + + /** + * @var MockObject|Generator $generator + */ + private $generator; + + /** + * @var ProductPriceIndexFilter $productPriceIndexFilter + */ + private $productPriceIndexFilter; + + /** + * @inheritDoc + */ + protected function setUp() + { + $this->stockConfiguration = $this->createMock(StockConfigurationInterface::class); + $this->item = $this->createMock(Item::class); + $this->resourceCnnection = $this->createMock(ResourceConnection::class); + $this->generator = $this->createMock(Generator::class); + + $this->productPriceIndexFilter = new ProductPriceIndexFilter( + $this->stockConfiguration, + $this->item, + $this->resourceCnnection, + 'indexer', + $this->generator, + 100 + ); + } + + /** + * Test to ensure that Modify Price method uses entityIds, + */ + public function testModifyPrice() + { + $entityIds = [1, 2, 3]; + $indexTableStructure = $this->createMock(IndexTableStructure::class); + $connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class); + $this->resourceCnnection->expects($this->once())->method('getConnection')->willReturn($connectionMock); + $selectMock = $this->createMock(\Magento\Framework\DB\Select::class); + $connectionMock->expects($this->once())->method('select')->willReturn($selectMock); + $selectMock->expects($this->at(2)) + ->method('where') + ->with('stock_item.product_id in (?)', $entityIds) + ->willReturn($selectMock); + $this->generator->expects($this->once()) + ->method('generate') + ->will( + $this->returnCallback( + $this->getBatchIteratorCallback($selectMock, 5) + ) + ); + + $fetchStmtMock = $this->createPartialMock(\Zend_Db_Statement_Pdo::class, ['fetchAll']); + $fetchStmtMock->expects($this->any()) + ->method('fetchAll') + ->will($this->returnValue([['product_id' => 1]])); + $connectionMock->expects($this->any())->method('query')->will($this->returnValue($fetchStmtMock)); + $this->productPriceIndexFilter->modifyPrice($indexTableStructure, $entityIds); + } + + /** + * Returns batches. + * + * @param MockObject $selectMock + * @param int $batchCount + * @return \Closure + */ + private function getBatchIteratorCallback(MockObject $selectMock, int $batchCount): \Closure + { + $iteratorCallback = function () use ($batchCount, $selectMock): array { + $result = []; + $count = $batchCount; + while ($count) { + $count--; + $result[$count] = $selectMock; + } + + return $result; + }; + + return $iteratorCallback; + } +} From 6b2e747aa6b5acf9d4ce559b274344fc755f1491 Mon Sep 17 00:00:00 2001 From: Raul E Watson <diazwatson@users.noreply.github.com> Date: Mon, 30 Sep 2019 15:26:35 +0100 Subject: [PATCH 0714/1172] Update app/code/Magento/BraintreeGraphQl/README.md Co-Authored-By: Jeff Matthews <matthews.jeffery@gmail.com> --- app/code/Magento/BraintreeGraphQl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/BraintreeGraphQl/README.md b/app/code/Magento/BraintreeGraphQl/README.md index 570f3b767e4e..4e8eecc93a92 100644 --- a/app/code/Magento/BraintreeGraphQl/README.md +++ b/app/code/Magento/BraintreeGraphQl/README.md @@ -1,6 +1,6 @@ # Magento_BraintreeGraphQl module -The Magento_BraintreeGraphQl module provides type and resolver information for the GraphQl module to pass payment information data from the client to Magento. +The Magento_BraintreeGraphQl module provides type and resolver information for the GraphQL module to pass payment information data from the client to Magento. ## Extensibility From 20d35fb7881c44446ba2c21d4630522f80f388c3 Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Mon, 30 Sep 2019 10:23:18 -0500 Subject: [PATCH 0715/1172] MC-20336: Update tests related to Catalog Search and Swatches "Reverting previous changes committed in e41a8166b2b48cdd88444ba4d2a9935d04fde2f8 as they fail in both mainline and elastic search branch" --- .../Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml | 3 --- .../Test/Mftf/Section/CatalogSearchAdminConfigSection.xml | 1 - 2 files changed, 4 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml index e1c2a7867850..a6e3dfd7eaad 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminSetMinimalQueryLengthActionGroup.xml @@ -25,9 +25,6 @@ <see userInput="{{MinMaxQueryLength.Hint}}" selector="{{AdminCatalogSearchConfigurationSection.maxQueryLengthHint}}" stepKey="seeHint2"/> <uncheckOption selector="{{AdminCatalogSearchConfigurationSection.minQueryLengthInherit}}" stepKey="uncheckSystemValue"/> <fillField selector="{{AdminCatalogSearchConfigurationSection.minQueryLength}}" userInput="{{minLength}}" stepKey="setMinQueryLength"/> - <waitForPageLoad stepKey="waitForTextToBeFilled"/> - <!--Scrolling till Category Permissions to make sure the collapse tab for Catalog Search is visible--> - <scrollTo selector="{{AdminCatalogSearchConfigurationSection.categoryPermissions}}" stepKey="scrollToCatalogSearchTab1"/> <click selector="{{AdminCatalogSearchConfigurationSection.catalogSearchTab}}" stepKey="collapseTab"/> <click selector="{{ContentManagementSection.Save}}" stepKey="saveConfig"/> <waitForPageLoad stepKey="waitForConfigSaved"/> diff --git a/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml index ff4c0fead0ee..e82ad4670f9b 100644 --- a/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml +++ b/app/code/Magento/Config/Test/Mftf/Section/CatalogSearchAdminConfigSection.xml @@ -7,7 +7,6 @@ --> <sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> <section name="AdminCatalogSearchConfigurationSection"> - <element name="categoryPermissions" type="button" selector="#catalog_magento_catalogpermissions-head"/> <element name="catalogSearchTab" type="button" selector="#catalog_search-head"/> <element name="checkIfCatalogSearchTabExpand" type="button" selector="#catalog_search-head:not(.open)"/> <element name="searchEngineDefaultSystemValue" type="checkbox" selector="#catalog_search_engine_inherit"/> From 6252d2c7176d02bd12df0c0685920e39b7873bd5 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 30 Sep 2019 10:51:07 -0500 Subject: [PATCH 0716/1172] MC-19247: Broken translations with advanced bundling - Update comment; --- .../Magento/Translation/view/base/templates/translate.phtml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Translation/view/base/templates/translate.phtml b/app/code/Magento/Translation/view/base/templates/translate.phtml index 844b16024f15..4c257eb76843 100644 --- a/app/code/Magento/Translation/view/base/templates/translate.phtml +++ b/app/code/Magento/Translation/view/base/templates/translate.phtml @@ -6,7 +6,10 @@ /** @var \Magento\Translation\Block\Js $block */ ?> -<!--Now dictionary file is inserted into html head for frontend in Magento/Translation/view/base/templates/dictionary.phtml--> +<!-- + For frontend area dictionary file is inserted into html head in Magento/Translation/view/base/templates/dictionary.phtml + Same translation mechanism should be introduced for admin area in 2.4 version. +--> <?php if ($block->dictionaryEnabled()) : ?> <script> require.config({ From 052c0357f7e42b6a589edd1b62919a0852cc09ef Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Mon, 30 Sep 2019 19:14:22 +0300 Subject: [PATCH 0717/1172] Improve test coverage for Magento\AuthorizenetGraphQl\Model\AuthorizenetDataProvider Cover exceptions: - `Required parameter "opaque_data_value" for "authorizenet_acceptjs" is missing.` - `Required parameter "cc_last_4" for "authorizenet_acceptjs" is missing.` Signed-off-by: Tomash Khamlai <tomash.khamlai@gmail.com> --- .../Customer/SetPaymentMethodTest.php | 86 +++++++++++++++++-- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php index 5f70cf4fd668..2df6fb97b702 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php @@ -139,7 +139,7 @@ public function testSetPaymentInvalidInput(\Closure $getMutationClosure, string $this->expectExceptionMessage($expectedMessage); $this->graphQlMutation($setPaymentMutation, [], '', $this->getHeaderMap()); } - + /** * Data provider for testSetPaymentInvalidInput * @@ -156,9 +156,25 @@ function (string $maskedQuoteId) { ], [ function (string $maskedQuoteId) { - return $this->getInvalidAcceptJsInput($maskedQuoteId); + return $this->getEmptyAcceptJsInput($maskedQuoteId); + }, + 'for "authorizenet_acceptjs" is missing.', + ], + [ + function (string $maskedQuoteId) { + return $this->getMissingCcLastFourAcceptJsInput( + $maskedQuoteId, + static::VALID_DESCRIPTOR, + static::VALID_NONCE + ); + }, + 'parameter "cc_last_4" for "authorizenet_acceptjs" is missing', + ], + [ + function (string $maskedQuoteId) { + return $this->getMissingOpaqueDataValueAcceptJsInput($maskedQuoteId, static::VALID_DESCRIPTOR); }, - 'for "authorizenet_acceptjs" is missing.' + 'parameter "opaque_data_value" for "authorizenet_acceptjs" is missing', ], ]; } @@ -190,12 +206,12 @@ private function getInvalidSetPaymentMutation(string $maskedQuoteId): string } /** - * Get setPaymentMethodOnCart missing require additional data properties + * Get setPaymentMethodOnCart missing required additional data properties * * @param string $maskedQuoteId * @return string */ - private function getInvalidAcceptJsInput(string $maskedQuoteId): string + private function getEmptyAcceptJsInput(string $maskedQuoteId): string { return <<<QUERY mutation { @@ -216,6 +232,66 @@ private function getInvalidAcceptJsInput(string $maskedQuoteId): string QUERY; } + /** + * Get setPaymentMethodOnCart missing required additional data properties + * + * @param string $maskedQuoteId + * @return string + */ + private function getMissingCcLastFourAcceptJsInput(string $maskedQuoteId, string $descriptor, string $nonce): string + { + return <<<QUERY +mutation { + setPaymentMethodOnCart(input:{ + cart_id:"{$maskedQuoteId}" + payment_method:{ + code:"authorizenet_acceptjs" + authorizenet_acceptjs:{ + opaque_data_descriptor: "{$descriptor}" + opaque_data_value: "{$nonce}" + } + } + }) { + cart { + selected_payment_method { + code + } + } + } +} +QUERY; + } + + /** + * Get setPaymentMethodOnCart missing required additional data properties + * + * @param string $maskedQuoteId + * @return string + */ + private function getMissingOpaqueDataValueAcceptJsInput(string $maskedQuoteId, string $descriptor): string + { + return <<<QUERY +mutation { + setPaymentMethodOnCart(input:{ + cart_id:"{$maskedQuoteId}" + payment_method:{ + code:"authorizenet_acceptjs" + authorizenet_acceptjs:{ + opaque_data_descriptor: "{$descriptor}" + cc_last_4: 1111 + } + } + }) { + cart { + selected_payment_method { + code + } + } + } +} +QUERY; + } + private function assertPlaceOrderResponse(array $response, string $reservedOrderId): void { self::assertArrayHasKey('placeOrder', $response); From 13ca551d457546c5b9e2d95ddefd66fb3eead53d Mon Sep 17 00:00:00 2001 From: Valerii Naida <vnayda@adobe.com> Date: Mon, 30 Sep 2019 11:41:54 -0500 Subject: [PATCH 0718/1172] #async-import/issues/207: Provide the ability to check errors in WebAPI tests in a single approach for different adapters (SOAP/REST) --- .../TestFramework/TestCase/WebapiAbstract.php | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php index 9ad051b686d4..eecca0a396a0 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php @@ -7,6 +7,7 @@ use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Filesystem; +use Magento\Framework\Webapi\Exception as WebapiException; use Magento\Webapi\Model\Soap\Fault; use Magento\TestFramework\Helper\Bootstrap; @@ -671,6 +672,12 @@ protected function _checkWrappedErrors($expectedWrappedErrors, $errorDetails) */ private function getActualWrappedErrors(\stdClass $errorNode) { + if (!isset($errorNode->parameters)) { + return [ + 'message' => $errorNode->message, + ]; + } + $actualParameters = []; $parameterNode = $errorNode->parameters->parameter; if (is_array($parameterNode)) { @@ -686,4 +693,40 @@ private function getActualWrappedErrors(\stdClass $errorNode) 'params' => $actualParameters, ]; } + + /** + * @param array $serviceInfo + * @param array $data + * @param array $expectedErrorData + * @return void + * @throws \Exception + */ + protected function assertWebApiCallErrors(array $serviceInfo, array $data, array $expectedErrorData) + { + try { + $this->_webApiCall($serviceInfo, $data); + $this->fail('Expected throwing exception'); + } catch (\Exception $e) { + if (TESTS_WEB_API_ADAPTER === self::ADAPTER_REST) { + self::assertEquals($expectedErrorData, $this->processRestExceptionResult($e)); + self::assertEquals(WebapiException::HTTP_BAD_REQUEST, $e->getCode()); + } elseif (TESTS_WEB_API_ADAPTER === self::ADAPTER_SOAP) { + $this->assertInstanceOf('SoapFault', $e); + $expectedWrappedErrors = []; + foreach ($expectedErrorData['errors'] as $error) { + // @see \Magento\TestFramework\TestCase\WebapiAbstract::getActualWrappedErrors() + $expectedWrappedError = [ + 'message' => $error['message'], + ]; + if (isset($error['parameters'])) { + $expectedWrappedError['params'] = $error['parameters']; + } + $expectedWrappedErrors[] = $expectedWrappedError; + } + $this->checkSoapFault($e, $expectedErrorData['message'], 'env:Sender', [], $expectedWrappedErrors); + } else { + throw $e; + } + } + } } From 63184a77cb09398d70028cc96b826ed2e6811c1b Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Mon, 30 Sep 2019 12:34:39 -0500 Subject: [PATCH 0719/1172] MC-19247: Broken translations with advanced bundling - Update comment; --- dev/tests/js/jasmine/tests/lib/mage/translate.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js index 22be0fbbaa32..dc6c6ce7eb96 100644 --- a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js +++ b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js @@ -9,6 +9,7 @@ define([ ], function ($) { 'use strict'; + // be careful with test variation order as one variation can affect another one describe('Test for mage/translate jQuery plugin', function () { it('works with one string as parameter', function () { $.mage.translate.add('Hello World!'); From 86c1ea30e244db83c4884ec2b421037bea72a099 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 30 Sep 2019 12:42:09 -0500 Subject: [PATCH 0720/1172] MC-20338: Api-functional tests for Product prices - fixed CR comments --- .../GraphQl/Catalog/ProductPriceTest.php | 191 +++++++++--------- ...c_bundle_product_with_multiple_options.php | 2 +- 2 files changed, 91 insertions(+), 102 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php index dc5d5e9313ba..af237f1bd6fb 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php @@ -7,7 +7,6 @@ namespace Magento\GraphQl\Catalog; -use Magento\Bundle\Model\Product\OptionList; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\Data\ProductTierPriceExtensionFactory; use Magento\Catalog\Api\Data\ProductTierPriceInterfaceFactory; @@ -16,11 +15,25 @@ use Magento\ConfigurableProduct\Api\LinkManagementInterface; use Magento\ConfigurableProduct\Model\LinkManagement; use Magento\Customer\Model\Group; +use Magento\Framework\ObjectManager\ObjectManager; use Magento\TestFramework\Helper\Bootstrap; use Magento\TestFramework\TestCase\GraphQlAbstract; class ProductPriceTest extends GraphQlAbstract { + /** @var ObjectManager $objectManager */ + private $objectManager; + + /** @var ProductRepositoryInterface $productRepository */ + private $productRepository; + + protected function setUp() :void + { + $this->objectManager = Bootstrap::getObjectManager(); + /** @var ProductRepositoryInterface $productRepository */ + $this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + } + /** * @magentoApiDataFixture Magento/Catalog/_files/products.php */ @@ -28,7 +41,6 @@ public function testProductWithSinglePrice() { $skus = ['simple']; $query = $this->getProductQuery($skus); - $result = $this->graphQlQuery($query); $this->assertArrayNotHasKey('errors', $result); @@ -67,7 +79,7 @@ public function testProductWithSinglePrice() } /** - * Pricing for Simple, Grouped and Configurable products + * Pricing for Simple, Grouped and Configurable products with no special or tier prices configured * * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable_12345.php * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped_with_simple.php @@ -179,13 +191,10 @@ public function testMultipleProductTypes() public function testSimpleProductsWithSpecialPriceAndTierPrice() { $skus = ["simple1", "simple2"]; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); - $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + $tierPriceFactory = $this->objectManager->get(ProductTierPriceInterfaceFactory::class); /** @var $tierPriceExtensionAttributesFactory */ - $tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); + $tierPriceExtensionAttributesFactory = $this->objectManager->create(ProductTierPriceExtensionFactory::class); $tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); $tierPrices[] = $tierPriceFactory->create( @@ -198,9 +207,9 @@ public function testSimpleProductsWithSpecialPriceAndTierPrice() )->setExtensionAttributes($tierPriceExtensionAttribute); foreach ($skus as $sku) { /** @var Product $simpleProduct */ - $simpleProduct = $productRepository->get($sku); + $simpleProduct = $this->productRepository->get($sku); $simpleProduct->setTierPrices($tierPrices); - $productRepository->save($simpleProduct); + $this->productRepository->save($simpleProduct); } $query = $this->getProductQuery($skus); $result = $this->graphQlQuery($query); @@ -301,13 +310,9 @@ public function testSimpleProductsWithSpecialPriceAndTierPrice() public function testGroupedProductsWithSpecialPriceAndTierPrices() { $groupedProductSku = 'grouped'; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); - $grouped = $productRepository->get($groupedProductSku); + $grouped = $this->productRepository->get($groupedProductSku); //get the associated products $groupedProductLinks = $grouped->getProductLinks(); - $associatedProductSkus = []; $tierPriceData = [ [ 'customer_group_id' => Group::CUST_GROUP_ALL, @@ -316,51 +321,50 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() 'value'=> 87 ] ]; + $associatedProductSkus = []; foreach ($groupedProductLinks as $groupedProductLink) { - $associatedProductSkus[] = $groupedProductLink ->getLinkedProductSku(); + $associatedProductSkus[] = $groupedProductLink->getLinkedProductSku(); } - $associatedProduct = []; + foreach ($associatedProductSkus as $associatedProductSku) { - $associatedProduct = $productRepository->get($associatedProductSku); + $associatedProduct = $this->productRepository->get($associatedProductSku); $associatedProduct->setSpecialPrice('95.75'); - $productRepository->save($associatedProduct); + $this->productRepository->save($associatedProduct); $this->saveProductTierPrices($associatedProduct, $tierPriceData); } $skus = ['grouped']; $query = $this->getProductQuery($skus); - $result = $this->graphQlQuery($query); $this->assertArrayNotHasKey('errors', $result); $this->assertNotEmpty($result['products']['items']); $product = $result['products']['items'][0]; $this->assertNotEmpty($product['price_range']); - $discountAmount = $associatedProduct->getPrice() - $associatedProduct->getSpecialPrice(); - $percentageDiscount = $discountAmount; $expectedPriceRange = [ "minimum_price" => [ "regular_price" => [ - "value" => $associatedProduct->getPrice() + "value" => 100 ], "final_price" => [ - "value" => $associatedProduct->getSpecialPrice() + "value" => 95.75 ], "discount" => [ - "amount_off" => $discountAmount, - "percent_off" => $percentageDiscount + "amount_off" => 100 - 95.75, + //difference between original and final over original price + "percent_off" => (100 - 95.75)*100/100 ] ], "maximum_price" => [ "regular_price" => [ - "value" => $associatedProduct->getPrice() + "value" => 100 ], "final_price" => [ - "value" => $associatedProduct->getSpecialPrice() + "value" => 95.75 ], "discount" => [ - "amount_off" => $discountAmount, - "percent_off" => $percentageDiscount + "amount_off" => 100 - 95.75, + "percent_off" => (100 - 95.75)*100/100 ] ] ]; @@ -371,7 +375,7 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() foreach ($groupedProductLinks as $groupedProductLink) { $groupedProductLink->getExtensionAttributes()->setQty(3); } - $productRepository->save($grouped); + $this->productRepository->save($grouped); $result = $this->graphQlQuery($query); $product = $result['products']['items'][0]; $this->assertPrices($expectedPriceRange, $product['price_range']); @@ -379,7 +383,7 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() } /** - * Check pricing for bundled product with one of bundle items having special price set and no dynamic price type set + * Check pricing for bundled product with one item having special price set and dynamic price turned off * * @magentoApiDataFixture Magento/Bundle/_files/product_with_multiple_options_1.php * @SuppressWarnings(PHPMD.ExcessiveMethodLength) @@ -387,18 +391,15 @@ public function testGroupedProductsWithSpecialPriceAndTierPrices() public function testBundledProductWithSpecialPriceAndTierPrice() { $bundledProductSku = 'bundle-product'; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); /** @var Product $bundled */ - $bundled = $productRepository->get($bundledProductSku); + $bundled = $this->productRepository->get($bundledProductSku); $skus = ['bundle-product']; $bundled->setSpecialPrice(10); // set the tier price for the bundled product - $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + $tierPriceFactory = $this->objectManager->get(ProductTierPriceInterfaceFactory::class); /** @var $tierPriceExtensionAttributesFactory */ - $tierPriceExtensionAttributesFactory = $objectManager->create(ProductTierPriceExtensionFactory::class); + $tierPriceExtensionAttributesFactory = $this->objectManager->create(ProductTierPriceExtensionFactory::class); $tierPriceExtensionAttribute = $tierPriceExtensionAttributesFactory->create()->setPercentageValue(10); $tierPrices[] = $tierPriceFactory->create( [ @@ -409,19 +410,9 @@ public function testBundledProductWithSpecialPriceAndTierPrice() ] )->setExtensionAttributes($tierPriceExtensionAttribute); $bundled->setTierPrices($tierPrices); - // Price view set to PRICE RANGE + // Set Price view to PRICE RANGE $bundled->setPriceView(0); - - $productRepository->save($bundled); - $bundleRegularPrice = $bundled->getPrice(); - /** @var OptionList $optionList */ - $optionList = $objectManager->get(\Magento\Bundle\Model\Product\OptionList::class); - $options = $optionList->getItems($bundled); - $option = $options[0]; - /** @var \Magento\Bundle\Api\Data\LinkInterface $bundleProductLinks */ - $bundleProductLinks = $option->getProductLinks(); - $firstOptionPrice = $bundleProductLinks[0]->getPrice(); - $secondOptionPrice = $bundleProductLinks[1]->getPrice(); + $this->productRepository->save($bundled); //Bundled product with dynamic prices turned OFF $query = $this->getProductQuery($skus); @@ -432,10 +423,14 @@ public function testBundledProductWithSpecialPriceAndTierPrice() $this->assertNotEmpty($product['price_range']); $this->assertNotEmpty($product['price_tiers']); - //special price of 10% discount + $bundleRegularPrice = 10; + $firstOptionPrice = 2.75; + $secondOptionPrice = 6.75; + $minRegularPrice = $bundleRegularPrice + $firstOptionPrice ; - //10% discount(by special price) of minRegular price + //Apply special price of 10% on minRegular price $minFinalPrice = round($minRegularPrice * 0.1, 2); + $maxRegularPrice = $bundleRegularPrice + $secondOptionPrice; $maxFinalPrice = round($maxRegularPrice* 0.1, 2); @@ -482,39 +477,30 @@ public function testBundledProductWithSpecialPriceAndTierPrice() } /** - * Check pricing for bundled product with spl price, tier prcie and dynamic price turned on + * Check pricing for bundled product with spl price, tier price with dynamic price turned on * * @magentoApiDataFixture Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php */ public function testBundledWithSpecialPriceAndTierPriceWithDynamicPrice() { - $bundledProductSku = 'bundle-product'; - $simpleProductSkus= ['simple1', 'simple2']; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); - /** @var Product $bundled */ - $bundled = $productRepository->get($bundledProductSku); $skus = ['bundle-product']; - - $simple1 = $productRepository->get($simpleProductSkus[0]); - $simple2 = $productRepository->get($simpleProductSkus[1]); - $minRegularPrice = $simple1->getPrice(); - $maxRegularPrice = $simple2->getPrice(); - - //minFinalPrice is 10% of the cheapest simple product in the bundle - $minFinalPrice = round(($simple1->getSpecialPrice())* 0.1, 2); - //special price = 10% is applied on all individual product in the bundle - $maxFinalPrice = round(($simple2->getSpecialPrice())* 0.1, 2); - $query = $this->getProductQuery($skus); $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); $this->assertNotEmpty($result['products']['items']); $product = $result['products']['items'][0]; $this->assertNotEmpty($product['price_range']); $this->assertNotEmpty($product['price_tiers']); + $minRegularPrice = 10; + $maxRegularPrice = 20; + + //Apply 10% special price on the cheapest simple product in bundle + $minFinalPrice = round(5.99 * 0.1, 2); + //Apply 10% special price on the expensive product in bundle + $maxFinalPrice = round(15.99 * 0.1, 2); + $expectedPriceRange = [ "minimum_price" => [ "regular_price" => [ @@ -566,11 +552,8 @@ public function testBundledWithSpecialPriceAndTierPriceWithDynamicPrice() public function testConfigurableProductWithVariantsHavingSpecialAndTierPrices() { $configurableProductSku ='12345'; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); /** @var LinkManagementInterface $configurableProductLink */ - $configurableProductLinks = $objectManager->get(LinkManagement::class); + $configurableProductLinks = $this->objectManager->get(LinkManagement::class); $configurableProductVariants = $configurableProductLinks->getChildren($configurableProductSku); $tierPriceData = [ [ @@ -582,7 +565,7 @@ public function testConfigurableProductWithVariantsHavingSpecialAndTierPrices() ]; foreach ($configurableProductVariants as $configurableProductVariant) { $configurableProductVariant->setSpecialPrice('25.99'); - $productRepository->save($configurableProductVariant); + $this->productRepository->save($configurableProductVariant); $this->saveProductTierPrices($configurableProductVariant, $tierPriceData); } $sku = ['12345']; @@ -599,30 +582,40 @@ public function testConfigurableProductWithVariantsHavingSpecialAndTierPrices() $regularPrice[] = $configurableProductVariant->getPrice(); $finalPrice[] = $configurableProductVariant->getSpecialPrice(); } + $regularPriceCheapestVariant = 30; + $specialPrice = 25.99; + $regularPriceExpensiveVariant = 40; $expectedPriceRange = [ "minimum_price" => [ "regular_price" => [ - "value" => $configurableProductVariants[0]->getPrice() + "value" => $regularPriceCheapestVariant ], "final_price" => [ - "value" => $configurableProductVariants[0]->getSpecialPrice() + "value" => $specialPrice ], "discount" => [ - "amount_off" => ($regularPrice[0] - $finalPrice[0]), - "percent_off" => round(($regularPrice[0] - $finalPrice[0])*100/$regularPrice[0], 2) + "amount_off" => $regularPriceCheapestVariant - $specialPrice, + "percent_off" => round( + ($regularPriceCheapestVariant - $specialPrice)*100/$regularPriceCheapestVariant, + 2 + ) ] ], "maximum_price" => [ "regular_price" => [ - "value" => $configurableProductVariants[1]->getPrice() + "value" => $regularPriceExpensiveVariant ], "final_price" => [ - "value" => $configurableProductVariants[1]->getSpecialPrice() + "value" => $specialPrice ], "discount" => [ - "amount_off" => $regularPrice[1] - $finalPrice[1], - "percent_off" => round(($regularPrice[1] - $finalPrice[1])*100/$regularPrice[1], 2) ] + "amount_off" => $regularPriceExpensiveVariant - $specialPrice, + "percent_off" => round( + ($regularPriceExpensiveVariant - $specialPrice)*100/$regularPriceExpensiveVariant, + 2 + ) + ] ] ]; $this->assertPrices($expectedPriceRange, $product['price_range']); @@ -695,14 +688,11 @@ public function testConfigurableProductWithVariantsHavingSpecialAndTierPrices() public function testDownloadableProductWithSpecialPriceAndTierPrices() { $downloadableProductSku = 'downloadable-product'; - $objectManager = Bootstrap::getObjectManager(); - /** @var ProductRepositoryInterface $productRepository */ - $productRepository = $objectManager->get(ProductRepositoryInterface::class); /** @var Product $downloadableProduct */ - $downloadableProduct = $productRepository->get($downloadableProductSku); + $downloadableProduct = $this->productRepository->get($downloadableProductSku); //setting the special price for the product $downloadableProduct->setSpecialPrice('5.75'); - $productRepository->save($downloadableProduct); + $this->productRepository->save($downloadableProduct); //setting the tier price data for the product $tierPriceData = [ [ @@ -722,32 +712,31 @@ public function testDownloadableProductWithSpecialPriceAndTierPrices() $product = $result['products']['items'][0]; $this->assertNotEmpty($product['price_range']); $this->assertNotEmpty($product['price_tiers']); - $discountAmount = $downloadableProduct->getPrice() - $downloadableProduct->getSpecialPrice(); - $percentageDiscount = ($discountAmount/$downloadableProduct->getPrice())*100; $expectedPriceRange = [ "minimum_price" => [ "regular_price" => [ - "value" => $downloadableProduct->getPrice() + "value" => 10 ], "final_price" => [ - "value" => $downloadableProduct->getSpecialPrice() + "value" => 5.75 ], "discount" => [ - "amount_off" => $discountAmount, - "percent_off" => $percentageDiscount + "amount_off" => 4.25, + //discount amount over regular price value + "percent_off" => (4.25/10)*100 ] ], "maximum_price" => [ "regular_price" => [ - "value" => $downloadableProduct->getPrice() + "value" => 10 ], "final_price" => [ - "value" => $downloadableProduct->getSpecialPrice() + "value" => 5.75 ], "discount" => [ - "amount_off" => $discountAmount, - "percent_off" => $percentageDiscount + "amount_off" => 4.25, + "percent_off" => (4.25/10)*100 ] ] ]; @@ -757,6 +746,7 @@ public function testDownloadableProductWithSpecialPriceAndTierPrices() [ 0 => [ 'discount' =>[ + //regualr price - tier price value 'amount_off' => 3, 'percent_off' => 30 ], @@ -1042,8 +1032,7 @@ private function assertPrices($expectedPrices, $actualPrices, $currency = 'USD') private function saveProductTierPrices(ProductInterface $product, array $tierPriceData) { $tierPrices =[]; - $objectManager = Bootstrap::getObjectManager(); - $tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class); + $tierPriceFactory = $this->objectManager->get(ProductTierPriceInterfaceFactory::class); foreach ($tierPriceData as $tierPrice) { $tierPrices[] = $tierPriceFactory->create( [ diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php index 986342db49cd..ee8c117037c1 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php @@ -11,7 +11,7 @@ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); -$productIds = range(10, 12, 1); +$productIds = [10, 11, 12]; foreach ($productIds as $productId) { /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */ $stockItem = $objectManager->create(\Magento\CatalogInventory\Model\Stock\Item::class); From 0b1bf759074ecedf8d5556465bb394aba841468f Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Mon, 30 Sep 2019 13:26:37 -0500 Subject: [PATCH 0721/1172] MC-20338: Api-functional tests for Product prices - fixed indentation --- .../_files/dynamic_bundle_product_with_multiple_options.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php index ee8c117037c1..c00fd2435a9f 100644 --- a/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php +++ b/dev/tests/integration/testsuite/Magento/Bundle/_files/dynamic_bundle_product_with_multiple_options.php @@ -77,8 +77,7 @@ 'option_id' => 1 ] ] - - ] + ] ); $productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); From 0bda8d0248923c9409e76fe4378667e26f030a86 Mon Sep 17 00:00:00 2001 From: Ivan Koliadynskyy <i.koliadynskyy@gmail.com> Date: Mon, 30 Sep 2019 22:05:40 +0300 Subject: [PATCH 0722/1172] Minor updates for resolving errors on tests run --- .../Webapi/Model/Authorization/TokenUserContext.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php index cc8da17e7f52..5c54c8b8660d 100644 --- a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php +++ b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php @@ -99,7 +99,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getUserId() { @@ -108,7 +108,7 @@ public function getUserId() } /** - * {@inheritdoc} + * @inheritdoc */ public function getUserType() { @@ -137,7 +137,7 @@ private function isTokenExpired(Token $token): bool return false; } - if ($this->date->timestamp($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { + if (strtotime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { return true; } @@ -187,6 +187,8 @@ protected function processRequest() } /** + * Set user data based on user type received from token data. + * * @param Token $token * @return void */ From 44569d5a84805be70fae9a9bc1a09033e500682a Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Mon, 30 Sep 2019 14:12:04 -0500 Subject: [PATCH 0723/1172] magento/magento2#22228: Suppress PHPCS violations in test --- .../Catalog/DeepNestedCategoriesAndProductsTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index e2f16e06d8b9..cace8267b5c2 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -69,12 +69,14 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void $productIdsFromCategory = $category->getProductCollection()->getAllIds(); foreach ($productIdsFromCategory as $productId) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $resolvedCategoryIds = array_merge( $resolvedCategoryIds, $productRepository->getById($productId)->getCategoryIds() ); } + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $resolvedCategoryIds = array_merge($resolvedCategoryIds, [$baseCategoryId]); foreach ($resolvedCategoryIds as $categoryId) { $category = $categoryRepository->get($categoryId); @@ -88,9 +90,11 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void $uniqueCategoryIds = array_unique($resolvedCategoryIds); $expectedCacheTags = ['cat_c', 'cat_p', 'FPC']; foreach ($uniqueProductIds as $uniqueProductId) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $expectedCacheTags = array_merge($expectedCacheTags, ['cat_p_' . $uniqueProductId]); } foreach ($uniqueCategoryIds as $uniqueCategoryId) { + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $expectedCacheTags = array_merge($expectedCacheTags, ['cat_c_' . $uniqueCategoryId]); } From f15b76fcf0342b2b320037b5f913ba274f4f3d6d Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Mon, 30 Sep 2019 14:29:15 -0500 Subject: [PATCH 0724/1172] Minor changes --- .../Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php index e6a51beedbfb..524261bd88e6 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php @@ -17,8 +17,6 @@ use Magento\Framework\DB\Select; use Magento\Framework\Json\EncoderInterface; use Magento\Quote\Model\Quote; -use function count; -use function is_array; /** * Grid widget massaction block From 0669c8806a8ea388e1a5f192e1aac9049cd7ba3c Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Mon, 30 Sep 2019 14:44:46 -0500 Subject: [PATCH 0725/1172] MC-20337: Update tests related to Checkout, Configurable, Layered Navigation --- .../Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml index c599a6a23f19..e8d6434dabd3 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductLongSkuTest.xml @@ -87,6 +87,9 @@ <see selector="{{AdminProductFormConfigurationsSection.currentVariationsSkuCells}}" userInput="LongSku-$$getConfigAttributeOption2.label$$" stepKey="seeChildProductSku2"/> <see selector="{{AdminProductFormConfigurationsSection.currentVariationsPriceCells}}" userInput="{{ProductWithLongNameSku.price}}" stepKey="seeConfigurationsPrice"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Assert storefront category list page--> <amOnPage url="/" stepKey="amOnStorefront"/> <waitForPageLoad stepKey="waitForStorefrontLoad"/> From c15e194a9c5395d6cc703813feea8ed6efc4f6d5 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Mon, 30 Sep 2019 15:28:18 -0500 Subject: [PATCH 0726/1172] MAGETWO-99043: Shipping Methods Don't Load In IE11 --- .../frontend/web/js/model/address-converter.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js index 9b20a782c38d..c114b795a80b 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js @@ -9,8 +9,9 @@ define([ 'jquery', 'Magento_Checkout/js/model/new-customer-address', 'Magento_Customer/js/customer-data', - 'mage/utils/objects' -], function ($, address, customerData, mageUtils) { + 'mage/utils/objects', + 'underscore' +], function ($, address, customerData, mageUtils, _) { 'use strict'; var countryData = customerData.get('directory-data'); @@ -59,13 +60,15 @@ define([ delete addressData['region_id']; if (addressData['custom_attributes']) { - addressData['custom_attributes'] = Object.entries(addressData['custom_attributes']) - .map(function (customAttribute) { + addressData['custom_attributes'] = _.map( + addressData['custom_attributes'], + function (value, key) { return { - 'attribute_code': customAttribute[0], - 'value': customAttribute[1] + 'attribute_code': key, + 'value': value }; - }); + } + ); } return address(addressData); From 9a9622247fcf4aa3e49c1857999693064b82b045 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Mon, 30 Sep 2019 15:40:20 -0500 Subject: [PATCH 0727/1172] magento/magento2#24773: Suppressed PHPCS code style violations --- app/code/Magento/Analytics/Model/ExportDataHandler.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Analytics/Model/ExportDataHandler.php b/app/code/Magento/Analytics/Model/ExportDataHandler.php index b36ad2398c97..72a8e4ea0034 100644 --- a/app/code/Magento/Analytics/Model/ExportDataHandler.php +++ b/app/code/Magento/Analytics/Model/ExportDataHandler.php @@ -157,7 +157,9 @@ private function prepareDirectory(WriteInterface $directory, $path) private function prepareFileDirectory(WriteInterface $directory, $path) { $directory->delete($path); + // phpcs:ignore Magento2.Functions.DiscouragedFunction if (dirname($path) !== '.') { + // phpcs:ignore Magento2.Functions.DiscouragedFunction $directory->create(dirname($path)); } @@ -176,6 +178,7 @@ private function pack($source, $destination) $this->archive->pack( $source, $destination, + // phpcs:ignore Magento2.Functions.DiscouragedFunction is_dir($source) ?: false ); From 989058cfd23241174b9e6c5e0adca88d42d37d21 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Mon, 30 Sep 2019 15:46:02 -0500 Subject: [PATCH 0728/1172] magento/magento2#22228: Suppress PHPCS violations in test --- .../Controller/Catalog/DeepNestedCategoriesAndProductsTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php index cace8267b5c2..6228feae37c1 100644 --- a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/DeepNestedCategoriesAndProductsTest.php @@ -80,6 +80,7 @@ public function testDispatchForCacheHeadersOnDeepNestedQueries(): void $resolvedCategoryIds = array_merge($resolvedCategoryIds, [$baseCategoryId]); foreach ($resolvedCategoryIds as $categoryId) { $category = $categoryRepository->get($categoryId); + // phpcs:ignore Magento2.Performance.ForeachArrayMerge $productIdsFromCategory= array_merge( $productIdsFromCategory, $category->getProductCollection()->getAllIds() From 3b3531a5bb06135e807bcf589a2a209094342dfe Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Mon, 30 Sep 2019 16:04:02 -0500 Subject: [PATCH 0729/1172] MC-20536: Make remaining failed MTF tests running with MySQL only --- .../InjectableTests/elastic_search.xml | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/elastic_search.xml diff --git a/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/elastic_search.xml b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/elastic_search.xml new file mode 100644 index 000000000000..614115151833 --- /dev/null +++ b/dev/tests/functional/testsuites/Magento/Mtf/TestSuite/InjectableTests/elastic_search.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="../../../../../vendor/magento/mtf/Magento/Mtf/TestRunner/etc/testRunner.xsd"> + <rule scope="testcase"> + <deny> + <tag group="stable" value="no" /> + <tag group="to_maintain" value="yes" /> + <tag group="mftf_migrated" value="yes" /> + </deny> + </rule> + <rule scope="testsuite"> + <deny> + <module value="Magento_Setup" strict="1" /> + <module value="Magento_SampleData" strict="1" /> + </deny> + </rule> + <rule scope="variation"> + <deny> + <tag group="test_type" value="3rd_party_test, 3rd_party_test_single_flow, mysql_search" /> + <tag group="stable" value="no" /> + <tag group="mftf_migrated" value="yes" /> + <tag group="to_maintain" value="yes" /> + </deny> + </rule> +</config> From f70fd6827e42ee759e668deaaed093e284fa2cb4 Mon Sep 17 00:00:00 2001 From: vital_sery <vital_sery@epam.com> Date: Tue, 1 Oct 2019 09:05:10 +0300 Subject: [PATCH 0730/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Integration test for MC-11299 --- .../Sales/Model/Order/ShipmentTest.php | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php index c52450d413ad..11499a024b44 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php +++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/ShipmentTest.php @@ -155,7 +155,6 @@ private function getOrder(string $incrementId): OrderInterface */ public function testGetTracksCollection() { - $trackCount = 1; $order = $this->getOrder('100000001'); $items = []; foreach ($order->getItems() as $item) { @@ -197,25 +196,10 @@ public function testGetTracksCollection() $this->shipmentRepository->save($secondOrderShipment); $secondShipmentTrackCollection = $secondOrderShipment->getTracksCollection(); - $shipmentId = $shipment->getId(); - $shipmentTrackIds = $shipmentTracksCollection->getColumnValues('parent_id'); - foreach ($shipmentTrackIds as $trackShipmentId) { - self::assertEquals($shipmentId, $trackShipmentId); - } - self::assertCount($trackCount, $shipmentTrackIds); - - $secondShipmentId = $secondOrderShipment->getId(); - $secondShipmentTrackIds = $secondShipmentTrackCollection->getColumnValues('parent_id'); - foreach ($secondShipmentTrackIds as $trackShipmentId) { - self::assertEquals($secondShipmentId, $trackShipmentId); - } - self::assertCount($trackCount, $secondShipmentTrackIds); - - self::assertEmpty( - array_intersect( - $shipmentTracksCollection->getColumnValues('id'), - $secondShipmentTrackCollection->getColumnValues('id') - ) + self::assertEquals($shipmentTracksCollection->getColumnValues('id'), [$track->getEntityId()]); + self::assertEquals( + $secondShipmentTrackCollection->getColumnValues('id'), + [$secondShipmentTrack->getEntityId()] ); } } From 520d8f18788abfd81d190ebd0944d2ba9b986ee5 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Tue, 1 Oct 2019 13:55:03 +0530 Subject: [PATCH 0731/1172] Fixed inconsistent capitalization of heading --- .../Email/Test/Mftf/ActionGroup/EmailTemplateActionGroup.xml | 2 +- app/code/Magento/Email/i18n/en_US.csv | 2 +- .../Magento/Email/view/adminhtml/templates/template/edit.phtml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Email/Test/Mftf/ActionGroup/EmailTemplateActionGroup.xml b/app/code/Magento/Email/Test/Mftf/ActionGroup/EmailTemplateActionGroup.xml index 1155930dd75e..3b99ade32e6c 100644 --- a/app/code/Magento/Email/Test/Mftf/ActionGroup/EmailTemplateActionGroup.xml +++ b/app/code/Magento/Email/Test/Mftf/ActionGroup/EmailTemplateActionGroup.xml @@ -21,7 +21,7 @@ <amOnPage url="{{AdminEmailTemplateIndexPage.url}}" stepKey="navigateToEmailTemplatePage"/> <!--Click "Add New Template" button--> <click selector="{{AdminMainActionsSection.add}}" stepKey="clickAddNewTemplateButton"/> - <!--Select value for "Template" drop-down menu in "Load default template" tab--> + <!--Select value for "Template" drop-down menu in "Load Default Template" tab--> <selectOption selector="{{AdminEmailTemplateEditSection.templateDropDown}}" userInput="Registry Update" stepKey="selectValueFromTemplateDropDown"/> <!--Fill in required fields in "Template Information" tab and click "Save Template" button--> <click selector="{{AdminEmailTemplateEditSection.loadTemplateButton}}" stepKey="clickLoadTemplateButton"/> diff --git a/app/code/Magento/Email/i18n/en_US.csv b/app/code/Magento/Email/i18n/en_US.csv index 8eed4b5c662b..412660d90d46 100644 --- a/app/code/Magento/Email/i18n/en_US.csv +++ b/app/code/Magento/Email/i18n/en_US.csv @@ -72,7 +72,7 @@ City,City "We're sorry, an error has occurred while generating this content.","We're sorry, an error has occurred while generating this content." "Invalid sender data","Invalid sender data" Title,Title -"Load default template","Load default template" +"Load Default Template","Load Default Template" Template,Template "Are you sure you want to strip tags?","Are you sure you want to strip tags?" "Are you sure you want to delete this template?","Are you sure you want to delete this template?" diff --git a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml index 1f236a21a730..82b09f109558 100644 --- a/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml +++ b/app/code/Magento/Email/view/adminhtml/templates/template/edit.phtml @@ -12,7 +12,7 @@ use Magento\Framework\App\TemplateTypesInterface; <form action="<?= $block->escapeUrl($block->getLoadUrl()) ?>" method="post" id="email_template_load_form"> <?= $block->getBlockHtml('formkey') ?> <fieldset class="admin__fieldset form-inline"> - <legend class="admin__legend"><span><?= $block->escapeHtml(__('Load default template')) ?></span></legend><br> + <legend class="admin__legend"><span><?= $block->escapeHtml(__('Load Default Template')) ?></span></legend><br> <div class="admin__field"> <label class="admin__field-label" for="template_select"><?= $block->escapeHtml(__('Template')) ?></label> <div class="admin__field-control"> From a6cec0ae32858439c2812ca32e4711be44e7a8a2 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Tue, 1 Oct 2019 12:15:01 +0300 Subject: [PATCH 0732/1172] magento/magento2#23452: Static test fix. --- .../Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php index 524261bd88e6..79597e07be76 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php @@ -21,6 +21,7 @@ /** * Grid widget massaction block * + * phpcs:disable Magento2.Classes.AbstractApi * @api * @method Quote setHideFormElement(boolean $value) Hide Form element to prevent IE errors * @method boolean getHideFormElement() From 9517396a09a8eea3db0533a54beb1e7836402cc8 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Mon, 30 Sep 2019 17:28:23 +0400 Subject: [PATCH 0733/1172] MAGETWO-67450: The rate in order is duplicated - Updated automated test script --- .../Test/Mftf/Data/CatalogPriceConfigData.xml | 9 +++-- .../Mftf/Data/CurrencyRatesConfigData.xml | 40 ++++++++++++++----- .../Test/Mftf/Page/AdminCurrencyRatesPage.xml | 2 +- ...ayWhenChooseThreeAllowedCurrenciesTest.xml | 6 +-- .../AdminOrderRateDisplayedInOneLineTest.xml | 28 ++++++------- 5 files changed, 54 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml index a16acbf4c90b..50ce7f2da18c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogPriceConfigData.xml @@ -8,9 +8,12 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="CatalogPriceScopeConfigData"> + <entity name="CatalogPriceScopeWebsiteConfigData"> <data key="path">catalog/price/scope</data> - <data key="value_website">1</data> - <data key="value_global">0</data> + <data key="value">1</data> + </entity> + <entity name="CatalogPriceScopeGlobalConfigData"> + <data key="path">catalog/price/scope</data> + <data key="value">0</data> </entity> </entities> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml index 5f4e3dc17341..b7b6bc8690bd 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml @@ -8,25 +8,45 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="SetCurrencyBaseConfig"> + <entity name="SetCurrencyUSDBaseConfig"> <data key="path">currency/options/base</data> - <data key="value_usd">USD</data> - <data key="value_eur">EUR</data> + <data key="value">USD</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> - <entity name="SetAllowedCurrenciesConfig"> + <entity name="SetCurrencyEURBaseConfig"> + <data key="path">currency/options/base</data> + <data key="value">EUR</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetAllowedCurrenciesConfigForThree"> + <data key="path">currency/options/allow</data> + <data key="value">EUR,USD,RUB</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetAllowedCurrenciesConfigForTwo"> <data key="path">currency/options/allow</data> - <data key="value_three_currencies">EUR,USD,RUB</data> - <data key="value_two_currencies">EUR,USD</data> - <data key="value_usd">USD</data> + <data key="value">EUR,USD</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetAllowedCurrenciesConfigForOne"> + <data key="path">currency/options/allow</data> + <data key="value">USD</data> + <data key="scope">websites</data> + <data key="scope_code">base</data> + </entity> + <entity name="SetDefaultCurrencyEURConfig"> + <data key="path">currency/options/default</data> + <data key="value">EUR</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> - <entity name="SetDefaultCurrencyConfig"> + <entity name="SetDefaultCurrencyUSDConfig"> <data key="path">currency/options/default</data> - <data key="value_eur">EUR</data> - <data key="value_usd">USD</data> + <data key="value">USD</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml index 7cfb177ecec3..d31dd71d474b 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Page/AdminCurrencyRatesPage.xml @@ -8,7 +8,7 @@ <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> - <page name="AdminCurrencyRatesPage" url="admin/system_currency/" area="admin" module="Currency"> + <page name="AdminCurrencyRatesPage" url="admin/system_currency/" area="admin" module="CurrencySymbol"> <section name="AdminCurrencyRatesSection"/> </page> </pages> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml index 2cb5ea81e5f3..fb71777b086d 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml @@ -24,9 +24,9 @@ <!--Create product--> <createData entity="SimpleProduct2" stepKey="createNewProduct"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSDWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_three_currencies}}" stepKey="setAllowedCurrencyWebsites"/> - <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEURWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForThree.scope}} --scope-code={{SetAllowedCurrenciesConfigForThree.scope_code}} {{SetAllowedCurrenciesConfigForThree.path}} {{SetAllowedCurrenciesConfigForThree.value}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyEURConfig.scope}} --scope-code={{SetDefaultCurrencyEURConfig.scope_code}} {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> <!--Delete created product--> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml index 7ac01c079281..514d4c5d54f8 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml @@ -24,28 +24,28 @@ <!--Create product--> <createData entity="SimpleProduct2" stepKey="createProduct"/> <!--Set price scope website--> - <magentoCLI command="config:set {{CatalogPriceScopeConfigData.path}} {{CatalogPriceScopeConfigData.value_website}}" stepKey="setCatalogPriceScopeWebsite"/> + <magentoCLI command="config:set {{CatalogPriceScopeWebsiteConfigData.path}} {{CatalogPriceScopeWebsiteConfigData.value}}" stepKey="setCatalogPriceScopeWebsite"/> <!--Set Currency options for Default Config--> - <magentoCLI command="config:set {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_eur}}" stepKey="setCurrencyBaseEUR"/> - <magentoCLI command="config:set {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_two_currencies}}" stepKey="setAllowedCurrencyEUR"/> - <magentoCLI command="config:set {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEUR"/> + <magentoCLI command="config:set {{SetCurrencyEURBaseConfig.path}} {{SetCurrencyEURBaseConfig.value}}" stepKey="setCurrencyBaseEUR"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForTwo.path}} {{SetAllowedCurrenciesConfigForTwo.value}}" stepKey="setAllowedCurrencyEUR"/> + <magentoCLI command="config:set {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEUR"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseEURWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_two_currencies}}" stepKey="setAllowedCurrencyWebsites"/> - <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_eur}}" stepKey="setCurrencyDefaultEURWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseEURWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForTwo.scope}} --scope-code={{SetAllowedCurrenciesConfigForTwo.scope_code}} {{SetAllowedCurrenciesConfigForTwo.path}} {{SetAllowedCurrenciesConfigForTwo.value}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyEURConfig.scope}} --scope-code={{SetDefaultCurrencyEURConfig.scope_code}} {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> <!--Delete created product--> <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <!--Reset configurations--> - <magentoCLI command="config:set {{CatalogPriceScopeConfigData.path}} {{CatalogPriceScopeConfigData.value_global}}" stepKey="setCatalogPriceScopeGlobal"/> - <magentoCLI command="config:set {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSD"/> - <magentoCLI command="config:set {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_usd}}" stepKey="setCurrencyDefaultUSD"/> - <magentoCLI command="config:set {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_usd}}" stepKey="setAllowedCurrencyUSD"/> + <magentoCLI command="config:set {{CatalogPriceScopeGlobalConfigData.path}} {{CatalogPriceScopeGlobalConfigData.value}}" stepKey="setCatalogPriceScopeGlobal"/> + <magentoCLI command="config:set {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSD"/> + <magentoCLI command="config:set {{SetDefaultCurrencyUSDConfig.path}} {{SetDefaultCurrencyUSDConfig.value}}" stepKey="setCurrencyDefaultUSD"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForOne.path}} {{SetAllowedCurrenciesConfigForOne.value}}" stepKey="setAllowedCurrencyUSD"/> <!--Set Currency options for Website--> - <magentoCLI command="config:set --scope={{SetCurrencyBaseConfig.scope}} --scope-code={{SetCurrencyBaseConfig.scope_code}} {{SetCurrencyBaseConfig.path}} {{SetCurrencyBaseConfig.value_usd}}" stepKey="setCurrencyBaseUSDWebsites"/> - <magentoCLI command="config:set --scope={{SetDefaultCurrencyConfig.scope}} --scope-code={{SetDefaultCurrencyConfig.scope_code}} {{SetDefaultCurrencyConfig.path}} {{SetDefaultCurrencyConfig.value_usd}}" stepKey="setCurrencyDefaultUSDWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfig.scope}} --scope-code={{SetAllowedCurrenciesConfig.scope_code}} {{SetAllowedCurrenciesConfig.path}} {{SetAllowedCurrenciesConfig.value_usd}}" stepKey="setAllowedCurrencyUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetDefaultCurrencyUSDConfig.scope}} --scope-code={{SetDefaultCurrencyUSDConfig.scope_code}} {{SetDefaultCurrencyUSDConfig.path}} {{SetDefaultCurrencyUSDConfig.value}}" stepKey="setCurrencyDefaultUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForOne.scope}} --scope-code={{SetAllowedCurrenciesConfigForOne.scope_code}} {{SetAllowedCurrenciesConfigForOne.path}} {{SetAllowedCurrenciesConfigForOne.value}}" stepKey="setAllowedCurrencyUSDWebsites"/> <actionGroup ref="logout" stepKey="logout"/> </after> <!--Open created product on Storefront and place for order--> From abf0643f78bdca338dad4e46b1aeb9c046d0afc6 Mon Sep 17 00:00:00 2001 From: Lena Orobei <oorobei@magento.com> Date: Tue, 1 Oct 2019 13:59:36 +0300 Subject: [PATCH 0734/1172] magento/graphql-ce#976: Improve test coverage for Magento\AuthorizenetGraphQl\Model\AuthorizenetDataProvider - code style fix --- .../AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php index 2df6fb97b702..c16454d99ddb 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/AuthorizenetAcceptjs/Customer/SetPaymentMethodTest.php @@ -139,7 +139,7 @@ public function testSetPaymentInvalidInput(\Closure $getMutationClosure, string $this->expectExceptionMessage($expectedMessage); $this->graphQlMutation($setPaymentMutation, [], '', $this->getHeaderMap()); } - + /** * Data provider for testSetPaymentInvalidInput * From f8f6abe8fcda42ef4cd1eb18d665f657fd3e6df7 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 11 Jun 2019 16:57:55 +0300 Subject: [PATCH 0735/1172] MC-16455: Admin user with permission for 1 store can manage categories - Add fix --- .../Ui/view/base/web/js/form/element/ui-select.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js index 5667ce5d71d8..d66b0619b5e2 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js @@ -568,8 +568,10 @@ define([ * Remove element from selected array */ removeSelected: function (value, data, event) { - event ? event.stopPropagation() : false; - this.value.remove(value); + if (! this.disabled()) { + event ? event.stopPropagation() : false; + this.value.remove(value); + } }, /** @@ -661,7 +663,9 @@ define([ * @returns {Object} Chainable */ toggleListVisible: function () { - this.listVisible(!this.listVisible()); + if (! this.disabled()) { + this.listVisible(!this.listVisible()); + } return this; }, From e55816b1131aaed94a80ba5539df40176d5558f8 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 1 Oct 2019 14:13:43 +0300 Subject: [PATCH 0736/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix merge conflict with 2.3-develop --- .../Ui/DataProvider/Product/Form/Modifier/Categories.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index 5f1907344ce8..f62aacfce8e8 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -234,6 +234,7 @@ protected function customizeCategoriesField(array $meta) $fieldCode = 'category_ids'; $elementPath = $this->arrayManager->findPath($fieldCode, $meta, null, 'children'); $containerPath = $this->arrayManager->findPath(static::CONTAINER_PREFIX . $fieldCode, $meta, null, 'children'); + $fieldIsDisabled = $this->locator->getProduct()->isLockedAttribute($fieldCode); if (!$elementPath) { return $meta; @@ -250,7 +251,6 @@ protected function customizeCategoriesField(array $meta) 'componentType' => 'container', 'component' => 'Magento_Ui/js/form/components/group', 'scopeLabel' => __('[GLOBAL]'), - 'disabled' => $this->locator->getProduct()->isLockedAttribute($fieldCode), ], ], ], @@ -268,6 +268,7 @@ protected function customizeCategoriesField(array $meta) 'levelsVisibility' => '1', 'elementTmpl' => 'ui/grid/filters/elements/ui-select', 'options' => $this->getCategoriesTree(), + 'disabled' => $fieldIsDisabled, 'listens' => [ 'index=create_category:responseData' => 'setParsed', 'newOption' => 'toggleOptionSelected' @@ -315,6 +316,7 @@ protected function customizeCategoriesField(array $meta) 'displayArea' => 'insideGroup', 'sortOrder' => 20, 'dataScope' => $fieldCode, + 'disabled' => $fieldIsDisabled, ], ], ] From 49addf9963749e61a860a2db6b192291cab0b3ba Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 13 Jun 2019 16:03:13 +0300 Subject: [PATCH 0737/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix statics - Fix unit tests --- .../Magento/Ui/view/base/web/js/form/element/ui-select.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js index d66b0619b5e2..9d38067d332f 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js @@ -568,7 +568,7 @@ define([ * Remove element from selected array */ removeSelected: function (value, data, event) { - if (! this.disabled()) { + if (!this.disabled()) { event ? event.stopPropagation() : false; this.value.remove(value); } @@ -663,7 +663,7 @@ define([ * @returns {Object} Chainable */ toggleListVisible: function () { - if (! this.disabled()) { + if (!this.disabled()) { this.listVisible(!this.listVisible()); } From 5e070035e0b45a85a349181e4a0fa9b433c21dbe Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Mon, 5 Aug 2019 20:52:49 +0300 Subject: [PATCH 0738/1172] MC-16455: Admin user with permission for 1 store can manage categories - Make category page as read only for restricted-admin role --- .../Catalog/Model/Category/DataProvider.php | 77 +++++++++++-------- .../Product/Form/Modifier/Categories.php | 5 +- .../Ui/Component/Form/Element/Wysiwyg.php | 7 +- .../view/base/web/js/form/components/group.js | 18 +++++ 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index c96b2aae3605..c22ecd25512d 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -3,6 +3,8 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Catalog\Model\Category; use Magento\Catalog\Api\Data\CategoryInterface; @@ -20,6 +22,7 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Filesystem; use Magento\Framework\Stdlib\ArrayManager; +use Magento\Framework\Stdlib\ArrayUtils; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; use Magento\Ui\Component\Form\Field; @@ -28,10 +31,9 @@ use Magento\Framework\AuthorizationInterface; /** - * Class DataProvider + * Category form data provider. * * @api - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @SuppressWarnings(PHPMD.TooManyFields) * @since 101.0.0 @@ -52,6 +54,7 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider /** * EAV attribute properties to fetch from meta storage + * * @var array * @since 101.0.0 */ @@ -143,6 +146,11 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider */ private $arrayManager; + /** + * @var ArrayUtils + */ + private $arrayUtils; + /** * @var Filesystem */ @@ -154,8 +162,6 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider private $auth; /** - * DataProvider constructor - * * @param string $name * @param string $primaryFieldName * @param string $requestFieldName @@ -186,7 +192,8 @@ public function __construct( array $meta = [], array $data = [], PoolInterface $pool = null, - ?AuthorizationInterface $auth = null + ?AuthorizationInterface $auth = null, + ?ArrayUtils $arrayUtils = null ) { $this->eavValidationRules = $eavValidationRules; $this->collection = $categoryCollectionFactory->create(); @@ -197,6 +204,7 @@ public function __construct( $this->request = $request; $this->categoryFactory = $categoryFactory; $this->auth = $auth ?? ObjectManager::getInstance()->get(AuthorizationInterface::class); + $this->arrayUtils = $arrayUtils ?? ObjectManager::getInstance()->get(ArrayUtils::class); parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data, $pool); } @@ -205,7 +213,7 @@ public function __construct( * @inheritdoc * @since 101.1.0 */ - public function getMeta() + public function getMeta(): array { $meta = parent::getMeta(); $meta = $this->prepareMeta($meta); @@ -226,7 +234,7 @@ public function getMeta() * @param array $meta * @return array */ - private function addUseDefaultValueCheckbox(Category $category, array $meta) + private function addUseDefaultValueCheckbox(Category $category, array $meta): array { /** @var EavAttributeInterface $attribute */ foreach ($category->getAttributes() as $attribute) { @@ -264,10 +272,7 @@ private function addUseDefaultValueCheckbox(Category $category, array $meta) } /** - * Prepare meta data - * - * @param array $meta - * @return array + * @inheritDoc * @since 101.0.0 */ public function prepareMeta($meta) @@ -290,7 +295,7 @@ public function prepareMeta($meta) * @param array $fieldsMeta * @return array */ - private function prepareFieldsMeta($fieldsMap, $fieldsMeta) + private function prepareFieldsMeta(array $fieldsMap, array $fieldsMeta): array { $canEditDesign = $this->auth->isAllowed('Magento_Catalog::edit_category_design'); @@ -313,12 +318,10 @@ private function prepareFieldsMeta($fieldsMap, $fieldsMeta) } /** - * Get data - * - * @return array + * @inheritDoc * @since 101.0.0 */ - public function getData() + public function getData(): array { if (isset($this->loadedData)) { return $this->loadedData; @@ -350,6 +353,7 @@ public function getAttributesMeta(Type $entityType) { $meta = []; $attributes = $entityType->getAttributeCollection(); + $fields = $this->getFields(); /* @var EavAttribute $attribute */ foreach ($attributes as $attribute) { $code = $attribute->getAttributeCode(); @@ -374,6 +378,13 @@ public function getAttributesMeta(Type $entityType) $meta[$code]['scopeLabel'] = $this->getScopeLabel($attribute); $meta[$code]['componentType'] = Field::NAME; + + // disable fields + $attributeIsLocked = $this->getCurrentCategory()->isLockedAttribute($code); + $meta[$code]['disabled'] = $attributeIsLocked; + if (array_search('use_config.' . $code, $fields, true) && $meta[$code]['disabled']) { + $meta['use_config.' . $code]['disabled'] = true; + } } $result = []; @@ -394,7 +405,7 @@ public function getAttributesMeta(Type $entityType) * @return array * @since 101.0.0 */ - protected function addUseConfigSettings($categoryData) + protected function addUseConfigSettings($categoryData): array { foreach ($this->elementsWithUseConfigSetting as $elementsWithUseConfigSetting) { if (!isset($categoryData['use_config'][$elementsWithUseConfigSetting])) { @@ -419,7 +430,7 @@ protected function addUseConfigSettings($categoryData) * @deprecated 101.1.0 * @since 101.0.0 */ - protected function addUseDefaultSettings($category, $categoryData) + protected function addUseDefaultSettings($category, $categoryData): array { if ($category->getExistsStoreValueFlag('url_key') || $category->getStoreId() === Store::DEFAULT_STORE_ID @@ -493,7 +504,7 @@ public function getScopeLabel(EavAttribute $attribute) * @return array * @since 101.0.0 */ - protected function filterFields($categoryData) + protected function filterFields($categoryData): array { return array_diff_key($categoryData, array_flip($this->ignoreFields)); } @@ -505,7 +516,7 @@ protected function filterFields($categoryData) * @param array $categoryData * @return array */ - private function convertValues($category, $categoryData) + private function convertValues($category, $categoryData): array { foreach ($category->getAttributes() as $attributeCode => $attribute) { if (!isset($categoryData[$attributeCode])) { @@ -541,10 +552,7 @@ private function convertValues($category, $categoryData) } /** - * Category's fields default values - * - * @param array $result - * @return array + * @inheritDoc * @since 101.0.0 */ public function getDefaultMetaData($result) @@ -558,9 +566,7 @@ public function getDefaultMetaData($result) } /** - * List of fields groups and fields. - * - * @return array + * @inheritDoc * @since 101.0.0 */ protected function getFieldsMap() @@ -616,13 +622,24 @@ protected function getFieldsMap() ]; } + /** + * Return list of fields names. + * + * @return array + */ + private function getFields(): array + { + $fieldsMap = $this->getFieldsMap(); + return $this->arrayUtils->flatten($fieldsMap); + } + /** * Retrieve scope overridden value * * @return ScopeOverriddenValue * @deprecated 101.1.0 */ - private function getScopeOverriddenValue() + private function getScopeOverriddenValue(): ScopeOverriddenValue { if (null === $this->scopeOverriddenValue) { $this->scopeOverriddenValue = \Magento\Framework\App\ObjectManager::getInstance()->get( @@ -639,7 +656,7 @@ private function getScopeOverriddenValue() * @return ArrayManager * @deprecated 101.1.0 */ - private function getArrayManager() + private function getArrayManager(): ArrayManager { if (null === $this->arrayManager) { $this->arrayManager = \Magento\Framework\App\ObjectManager::getInstance()->get( @@ -657,7 +674,7 @@ private function getArrayManager() * * @deprecated 101.1.0 */ - private function getFileInfo() + private function getFileInfo(): FileInfo { if ($this->fileInfo === null) { $this->fileInfo = ObjectManager::getInstance()->get(FileInfo::class); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index f62aacfce8e8..3580ba2b467e 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -23,7 +23,6 @@ * Data provider for categories field of product page * * @api - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 101.0.0 */ @@ -120,7 +119,7 @@ public function __construct( * @return CacheInterface * @deprecated 101.0.3 */ - private function getCacheManager() + private function getCacheManager(): CacheInterface { if (!$this->cacheManager) { $this->cacheManager = ObjectManager::getInstance() @@ -148,7 +147,7 @@ public function modifyMeta(array $meta) * * @return bool */ - private function isAllowed() + private function isAllowed(): bool { return $this->authorization->isAllowed('Magento_Catalog::categories'); } diff --git a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php index d39d2dc3cd93..869df80159b8 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php +++ b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php @@ -3,12 +3,13 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\Ui\Component\Form\Element; use Magento\Framework\Data\Form\Element\Editor; use Magento\Framework\Data\Form; use Magento\Framework\Data\FormFactory; -use Magento\Framework\DataObject; use Magento\Framework\View\Element\UiComponent\ContextInterface; use Magento\Ui\Component\Wysiwyg\ConfigInterface; @@ -51,6 +52,10 @@ public function __construct( array $config = [] ) { $wysiwygConfigData = isset($config['wysiwygConfigData']) ? $config['wysiwygConfigData'] : []; + if ($config['disabled'] === true) { + $config['wysiwygConfigData']['settings']['readonly'] = 1; + } + $this->form = $formFactory->create(); $wysiwygId = $context->getNamespace() . '_' . $data['name']; $this->editor = $this->form->addField( 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 8c5950f7e2fa..f74bf3f5e919 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 @@ -36,6 +36,24 @@ define([ return this; }, + /** + * @inheritdoc + */ + initElement: function (elem) { + this._super(); + + if (this.disabled) { + try { + elem.disabled(true); + } + catch (e) { + + } + } + + return this; + }, + /** * Calls initObservable of parent class. * Defines observable properties of instance. From 8a627e00b5dd681d67404de1589e89b538e9183e Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 6 Aug 2019 21:39:51 +0300 Subject: [PATCH 0739/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix unit and static tests failures. --- .../Catalog/Model/Category/DataProvider.php | 13 +++++++------ .../Unit/Model/Category/DataProviderTest.php | 18 +++++++++++++++++- .../Product/Form/Modifier/Categories.php | 4 ++-- .../Ui/Component/Form/Element/Wysiwyg.php | 2 +- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index c22ecd25512d..af517448e2ef 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -162,9 +162,9 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider private $auth; /** - * @param string $name - * @param string $primaryFieldName - * @param string $requestFieldName + * @param $name + * @param $primaryFieldName + * @param $requestFieldName * @param EavValidationRules $eavValidationRules * @param CategoryCollectionFactory $categoryCollectionFactory * @param StoreManagerInterface $storeManager @@ -176,7 +176,8 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider * @param array $data * @param PoolInterface|null $pool * @param AuthorizationInterface|null $auth - * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @param ArrayUtils|null $arrayUtils + * @throws \Magento\Framework\Exception\LocalizedException */ public function __construct( $name, @@ -321,7 +322,7 @@ private function prepareFieldsMeta(array $fieldsMap, array $fieldsMeta): array * @inheritDoc * @since 101.0.0 */ - public function getData(): array + public function getData() { if (isset($this->loadedData)) { return $this->loadedData; @@ -382,7 +383,7 @@ public function getAttributesMeta(Type $entityType) // disable fields $attributeIsLocked = $this->getCurrentCategory()->isLockedAttribute($code); $meta[$code]['disabled'] = $attributeIsLocked; - if (array_search('use_config.' . $code, $fields, true) && $meta[$code]['disabled']) { + if (array_search('use_config.' . $code, $fields) && $meta[$code]['disabled']) { $meta['use_config.' . $code]['disabled'] = true; } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php index 8f3aa66e57c5..1511a930dd02 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php @@ -17,6 +17,7 @@ use Magento\Store\Model\StoreManagerInterface; use Magento\Ui\DataProvider\EavValidationRules; use Magento\Ui\DataProvider\Modifier\PoolInterface; +use Magento\Framework\Stdlib\ArrayUtils; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -78,6 +79,14 @@ class DataProviderTest extends \PHPUnit\Framework\TestCase */ private $modifierPool; + /** + * @var ArrayUtils|\PHPUnit_Framework_MockObject_MockObject + */ + private $arrayUtils; + + /** + * @inheritDoc + */ protected function setUp() { $this->eavValidationRules = $this->getMockBuilder(EavValidationRules::class) @@ -128,6 +137,10 @@ protected function setUp() ->getMock(); $this->modifierPool = $this->getMockBuilder(PoolInterface::class)->getMockForAbstractClass(); + + $this->arrayUtils = $this->getMockBuilder(ArrayUtils::class) + ->setMethods(['flatten']) + ->disableOriginalConstructor()->getMock(); } /** @@ -157,7 +170,8 @@ private function getModel() 'eavConfig' => $this->eavConfig, 'request' => $this->request, 'categoryFactory' => $this->categoryFactory, - 'pool' => $this->modifierPool + 'pool' => $this->modifierPool, + 'arrayUtils' => $this->arrayUtils ] ); @@ -331,6 +345,8 @@ public function testGetData() public function testGetMetaWithoutParentInheritanceResolving() { + $this->arrayUtils->expects($this->atLeastOnce())->method('flatten')->willReturn([1,3,3]); + $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index 3580ba2b467e..c395fc49ac07 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -149,7 +149,7 @@ public function modifyMeta(array $meta) */ private function isAllowed(): bool { - return $this->authorization->isAllowed('Magento_Catalog::categories'); + return (bool) $this->authorization->isAllowed('Magento_Catalog::categories'); } /** @@ -291,6 +291,7 @@ protected function customizeCategoriesField(array $meta) 'formElement' => 'container', 'additionalClasses' => 'admin__field-small', 'componentType' => 'container', + 'disabled' => $fieldIsDisabled, 'component' => 'Magento_Ui/js/form/components/button', 'template' => 'ui/form/components/button/container', 'actions' => [ @@ -315,7 +316,6 @@ protected function customizeCategoriesField(array $meta) 'displayArea' => 'insideGroup', 'sortOrder' => 20, 'dataScope' => $fieldCode, - 'disabled' => $fieldIsDisabled, ], ], ] diff --git a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php index 869df80159b8..7005afbad44d 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php +++ b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php @@ -52,7 +52,7 @@ public function __construct( array $config = [] ) { $wysiwygConfigData = isset($config['wysiwygConfigData']) ? $config['wysiwygConfigData'] : []; - if ($config['disabled'] === true) { + if (isset($config['disabled']) && $config['disabled'] === true) { $config['wysiwygConfigData']['settings']['readonly'] = 1; } From 74826150ee086441c31614d56719fcfad40defb3 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 6 Aug 2019 22:07:54 +0300 Subject: [PATCH 0740/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix static tests failures. --- .../Catalog/Model/Category/DataProvider.php | 10 ++++++---- .../Unit/Model/Category/DataProviderTest.php | 20 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index af517448e2ef..392d0b64f821 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -162,9 +162,9 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider private $auth; /** - * @param $name - * @param $primaryFieldName - * @param $requestFieldName + * @param string $name + * @param string $primaryFieldName + * @param string $requestFieldName * @param EavValidationRules $eavValidationRules * @param CategoryCollectionFactory $categoryCollectionFactory * @param StoreManagerInterface $storeManager @@ -178,6 +178,7 @@ class DataProvider extends \Magento\Ui\DataProvider\ModifierPoolDataProvider * @param AuthorizationInterface|null $auth * @param ArrayUtils|null $arrayUtils * @throws \Magento\Framework\Exception\LocalizedException + * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( $name, @@ -383,7 +384,8 @@ public function getAttributesMeta(Type $entityType) // disable fields $attributeIsLocked = $this->getCurrentCategory()->isLockedAttribute($code); $meta[$code]['disabled'] = $attributeIsLocked; - if (array_search('use_config.' . $code, $fields) && $meta[$code]['disabled']) { + $hasUseConfigField = (bool) array_search('use_config.' . $code, $fields, true); + if ($hasUseConfigField && $meta[$code]['disabled']) { $meta['use_config.' . $code]['disabled'] = true; } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php index 1511a930dd02..da5809a0f481 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php @@ -220,10 +220,12 @@ public function testGetDataNoFileExists() ->getMock(); $categoryMock->expects($this->exactly(2)) ->method('getData') - ->willReturnMap([ - ['', null, $categoryData], - ['image', null, $categoryData['image']], - ]); + ->willReturnMap( + [ + ['', null, $categoryData], + ['image', null, $categoryData['image']], + ] + ); $categoryMock->expects($this->any()) ->method('getExistsStoreValueFlag') ->with('url_key') @@ -294,10 +296,12 @@ public function testGetData() ->getMock(); $categoryMock->expects($this->exactly(2)) ->method('getData') - ->willReturnMap([ - ['', null, $categoryData], - ['image', null, $categoryData['image']], - ]); + ->willReturnMap( + [ + ['', null, $categoryData], + ['image', null, $categoryData['image']], + ] + ); $categoryMock->expects($this->any()) ->method('getExistsStoreValueFlag') ->with('url_key') From bf8d4306dc888dcffc4ce207e79d823901e2778a Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 8 Aug 2019 20:27:40 +0300 Subject: [PATCH 0741/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix integration test. --- .../Magento/Catalog/Model/Category/DataProvider.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index 392d0b64f821..21a7bfa98bf9 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -356,6 +356,7 @@ public function getAttributesMeta(Type $entityType) $meta = []; $attributes = $entityType->getAttributeCollection(); $fields = $this->getFields(); + $category = $this->getCurrentCategory(); /* @var EavAttribute $attribute */ foreach ($attributes as $attribute) { $code = $attribute->getAttributeCode(); @@ -382,11 +383,13 @@ public function getAttributesMeta(Type $entityType) $meta[$code]['componentType'] = Field::NAME; // disable fields - $attributeIsLocked = $this->getCurrentCategory()->isLockedAttribute($code); - $meta[$code]['disabled'] = $attributeIsLocked; - $hasUseConfigField = (bool) array_search('use_config.' . $code, $fields, true); - if ($hasUseConfigField && $meta[$code]['disabled']) { - $meta['use_config.' . $code]['disabled'] = true; + if ($category) { + $attributeIsLocked = $category->isLockedAttribute($code); + $meta[$code]['disabled'] = $attributeIsLocked; + $hasUseConfigField = (bool) array_search('use_config.' . $code, $fields, true); + if ($hasUseConfigField && $meta[$code]['disabled']) { + $meta['use_config.' . $code]['disabled'] = true; + } } } From 7ea4c6ce306f41683c5a7cb25879df6ca231f068 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Fri, 9 Aug 2019 14:53:17 +0300 Subject: [PATCH 0742/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix unit tests failures. --- .../Catalog/Test/Unit/Model/Category/DataProviderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php index da5809a0f481..4c3450d555f1 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/DataProviderTest.php @@ -354,7 +354,7 @@ public function testGetMetaWithoutParentInheritanceResolving() $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) ->disableOriginalConstructor() ->getMock(); - $this->registry->expects($this->once()) + $this->registry->expects($this->atLeastOnce()) ->method('registry') ->with('category') ->willReturn($categoryMock); From 92bd66feaf498dff4e97f3aae366f9f228354790 Mon Sep 17 00:00:00 2001 From: Lena Orobei <oorobei@magento.com> Date: Tue, 1 Oct 2019 14:53:20 +0300 Subject: [PATCH 0743/1172] magento/graphql-ce#882: [PayPal] Rename PaypalExpressToken type --- app/code/Magento/PaypalGraphQl/etc/schema.graphqls | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/PaypalGraphQl/etc/schema.graphqls b/app/code/Magento/PaypalGraphQl/etc/schema.graphqls index 45ebb0d7871f..b8f14eec70d1 100644 --- a/app/code/Magento/PaypalGraphQl/etc/schema.graphqls +++ b/app/code/Magento/PaypalGraphQl/etc/schema.graphqls @@ -20,9 +20,9 @@ input PaypalExpressTokenInput @doc(description: "Defines the attributes required express_button: Boolean @doc(description: "Indicates whether the buyer selected the quick checkout button. The default value is false") } -type PaypalExpressToken @doc(description: "Deprecated: use type PaypalExpressTokenOutput instead") { - token: String @deprecated(reason: "Use field `token` of type PaypalExpressTokenOutput instead") @doc(description:"The token returned by PayPal") - paypal_urls: PaypalExpressUrlList @deprecated(reason: "Use field `PaypalExpressUrlList` of type PaypalExpressTokenOutput instead") @doc(description:"A set of URLs that allow the buyer to authorize payment and adjust checkout details") +type PaypalExpressToken @doc(description: "Deprecated: use type `PaypalExpressTokenOutput` instead") { + token: String @deprecated(reason: "Use field `token` of type `PaypalExpressTokenOutput` instead") @doc(description:"The token returned by PayPal") + paypal_urls: PaypalExpressUrlList @deprecated(reason: "Use field `paypal_urls` of type `PaypalExpressTokenOutput` instead") @doc(description:"A set of URLs that allow the buyer to authorize payment and adjust checkout details") } type PaypalExpressTokenOutput @doc(description: "Contains the token returned by PayPal and a set of URLs that allow the buyer to authorize payment and adjust checkout details. Applies to Express Checkout and Payments Standard payment methods.") { From 27945bcd7e2adffe5818cd76ba4a365bbaf79f8a Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Tue, 10 Sep 2019 13:05:07 +0400 Subject: [PATCH 0744/1172] MC-16455: Admin user with permission for 1 store can manage categories - Added automation test script. --- .../Section/AdminCategoryProductsSection.xml | 1 + ...oriesByUserWithPermissionFor1StoreTest.xml | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsSection.xml index e9ff40f98bb1..8a993a74a58d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsSection.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryProductsSection.xml @@ -11,5 +11,6 @@ <section name="AdminCategoryProductsSection"> <element name="sectionHeader" type="button" selector="div[data-index='assign_products']" timeout="30"/> <element name="addProducts" type="button" selector="#catalog_category_add_product_tabs" timeout="30"/> + <element name="addProductsDisabled" type="button" selector="#catalog_category_add_product_tabs[disabled]" timeout="30"/> </section> </sections> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml new file mode 100644 index 000000000000..8dd4597b0b96 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminManageCategoriesByUserWithPermissionFor1StoreTest"> + <annotations> + <features value="Catalog"/> + <stories value="user role"/> + <title value="Ability to manage categories by admin user with permission for 1 store"/> + <description value="Ability to manage categories by admin user with permission for 1 store"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-19264"/> + <group value="Catalog"/> + </annotations> + <before> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!--Create new store and store view--> + <comment userInput="Create new store and store view" stepKey="createStoreAndStoreView"/> + <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createStore1"> + <argument name="website" value="Main Website"/> + <argument name="storeGroupName" value="{{SecondStoreGroupUnique.name}}"/> + <argument name="storeGroupCode" value="{{SecondStoreGroupUnique.code}}"/> + </actionGroup> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreViewA"/> + <!--Create simple category and product--> + <comment userInput="Create simple product and category" stepKey="createCategoryAndProduct"/> + <createData entity="_defaultCategory" stepKey="createCategory"/> + <createData entity="ApiSimpleProduct" stepKey="createProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!--Create restricted user role--> + <actionGroup ref="AdminAddNewUserRoleWithCustomRoleScopes" stepKey="createLimitedRole"> + <argument name="role" value="restrictedRole"/> + <argument name="customWebsiteName" value="{{SecondStoreGroupUnique.name}}"/> + </actionGroup> + <!--Create admin user with restricted role--> + <comment userInput="Create admin user with restricted role" stepKey="createUserWithRestrictedRole"/> + <actionGroup ref="AdminCreateUserWithRoleActionGroup" stepKey="createRestrictedAdmin"> + <argument name="role" value="restrictedRole"/> + <argument name="user" value="Admin3"/> + </actionGroup> + </before> + <after> + <!--Delete product and category--> + <comment userInput="Delete product and category" stepKey="deleteProdAndCategory"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> + <actionGroup ref="logout" stepKey="logout"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + <!-- Delete User--> + <comment userInput="Delete User" stepKey="deleteUser"/> + <actionGroup ref="AdminDeleteCreatedUserActionGroup" stepKey="deleteLimitedUser"> + <argument name="user" value="Admin3"/> + </actionGroup> + <!--Delete users roles--> + <comment userInput="Delete users roles" stepKey="deleteUserRole"/> + <actionGroup ref="AdminDeleteUserRoleWithSpecifiedPermissionActionGroup" stepKey="deleteRestrictedRole"> + <argument name="role" value="restrictedRole"/> + </actionGroup> + <!--Delete store view--> + <comment userInput="Delete store view" stepKey="deleteStoreView"/> + <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteFirstStoreView"> + <argument name="customStore" value="customStore"/> + </actionGroup> + </after> + <!--Login as restricted user--> + <comment userInput="Login as restricted user" stepKey="loginAsRestrictedUser"/> + <actionGroup ref="logout" stepKey="logout"/> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"> + <argument name="adminUser" value="Admin3"/> + </actionGroup> + <!--Open Product page--> + <comment userInput="openProductPage" stepKey="openProdPage"/> + <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="visitAdminProductPage"/> + <waitForPageLoad stepKey="waitForPageLoad"/> + <!--Check that ability to manage category is disabled--> + <comment userInput="Check that ability to manage category is disabled" stepKey="checkAbilityToManageCategory"/> + <grabAttributeFrom userInput="class" selector="{{AdminProductFormSection.categoriesDropdown}}" stepKey="grabAttributeFromInput"/> + <assertContains expectedType="string" expected="disabled" actual="$grabAttributeFromInput" stepKey="assertCategoryIsDisabled"/> + <!--Go to created category page--> + <comment userInput="Go to created category page" stepKey="visitAdminCategoryPage"/> + <actionGroup ref="goToAdminCategoryPageById" stepKey="goToAdminCategoryPage0"> + <argument name="id" value="$$createCategory.id$$"/> + </actionGroup> + <!--Expand products in category tab--> + <comment userInput="Expand products in category tab" stepKey="expandProductsInCategoryTab"/> + <conditionalClick selector="{{AdminCategoryProductsSection.sectionHeader}}" dependentSelector="{{AdminCategoryProductsSection.matchByRule}}" visible="false" stepKey="openProductsInCategoryTab"/> + <!--Check that the ability to add product is disabled--> + <comment userInput="Check that the ability to add product is disabled" stepKey="checkAbilityToAddProduct"/> + <seeElement selector="{{AdminCategoryProductsSection.addProductsDisabled}}" stepKey="checkAbilityToAddProductIsDisabled"/> + </test> +</tests> From ccbdcc522bcc1255f1cc7a437b7d2701403893e1 Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Tue, 10 Sep 2019 14:18:54 +0400 Subject: [PATCH 0745/1172] MC-16455: Admin user with permission for 1 store can manage categories - Updated automation test script. --- .../AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml index 8dd4597b0b96..cfb41fed61de 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml @@ -16,6 +16,7 @@ <description value="Ability to manage categories by admin user with permission for 1 store"/> <severity value="CRITICAL"/> <testCaseId value="MC-19264"/> + <useCaseId value="MC-16455"/> <group value="Catalog"/> </annotations> <before> @@ -27,7 +28,7 @@ <argument name="storeGroupName" value="{{SecondStoreGroupUnique.name}}"/> <argument name="storeGroupCode" value="{{SecondStoreGroupUnique.code}}"/> </actionGroup> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreViewA"/> + <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView"/> <!--Create simple category and product--> <comment userInput="Create simple product and category" stepKey="createCategoryAndProduct"/> <createData entity="_defaultCategory" stepKey="createCategory"/> From 35328a82dc8265f6c299ab958e50979ee4df0797 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Wed, 11 Sep 2019 17:31:47 +0300 Subject: [PATCH 0746/1172] MC-16455: Admin user with permission for 1 store can manage categories - CSV test errors fixed. --- .../Catalog/Model/Category/DataProvider.php | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/Catalog/Model/Category/DataProvider.php b/app/code/Magento/Catalog/Model/Category/DataProvider.php index 21a7bfa98bf9..eeb4c082ff51 100644 --- a/app/code/Magento/Catalog/Model/Category/DataProvider.php +++ b/app/code/Magento/Catalog/Model/Category/DataProvider.php @@ -215,7 +215,7 @@ public function __construct( * @inheritdoc * @since 101.1.0 */ - public function getMeta(): array + public function getMeta() { $meta = parent::getMeta(); $meta = $this->prepareMeta($meta); @@ -274,7 +274,10 @@ private function addUseDefaultValueCheckbox(Category $category, array $meta): ar } /** - * @inheritDoc + * Prepare meta data + * + * @param array $meta + * @return array * @since 101.0.0 */ public function prepareMeta($meta) @@ -320,7 +323,9 @@ private function prepareFieldsMeta(array $fieldsMap, array $fieldsMeta): array } /** - * @inheritDoc + * Get data + * + * @return array * @since 101.0.0 */ public function getData() @@ -411,7 +416,7 @@ public function getAttributesMeta(Type $entityType) * @return array * @since 101.0.0 */ - protected function addUseConfigSettings($categoryData): array + protected function addUseConfigSettings($categoryData) { foreach ($this->elementsWithUseConfigSetting as $elementsWithUseConfigSetting) { if (!isset($categoryData['use_config'][$elementsWithUseConfigSetting])) { @@ -436,7 +441,7 @@ protected function addUseConfigSettings($categoryData): array * @deprecated 101.1.0 * @since 101.0.0 */ - protected function addUseDefaultSettings($category, $categoryData): array + protected function addUseDefaultSettings($category, $categoryData) { if ($category->getExistsStoreValueFlag('url_key') || $category->getStoreId() === Store::DEFAULT_STORE_ID @@ -510,7 +515,7 @@ public function getScopeLabel(EavAttribute $attribute) * @return array * @since 101.0.0 */ - protected function filterFields($categoryData): array + protected function filterFields($categoryData) { return array_diff_key($categoryData, array_flip($this->ignoreFields)); } @@ -558,7 +563,10 @@ private function convertValues($category, $categoryData): array } /** - * @inheritDoc + * Category's fields default values + * + * @param array $result + * @return array * @since 101.0.0 */ public function getDefaultMetaData($result) @@ -572,7 +580,9 @@ public function getDefaultMetaData($result) } /** - * @inheritDoc + * List of fields groups and fields. + * + * @return array * @since 101.0.0 */ protected function getFieldsMap() From f37537b4d23d04d338beee7e515b0514b6dd297c Mon Sep 17 00:00:00 2001 From: Lilit Sargsyan <lilit_sargsyan@epam.com> Date: Thu, 12 Sep 2019 16:20:39 +0400 Subject: [PATCH 0747/1172] MC-16455: Admin user with permission for 1 store can manage categories - Moved test to ee. --- ...oriesByUserWithPermissionFor1StoreTest.xml | 99 ------------------- 1 file changed, 99 deletions(-) delete mode 100644 app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml deleted file mode 100644 index cfb41fed61de..000000000000 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminManageCategoriesByUserWithPermissionFor1StoreTest.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminManageCategoriesByUserWithPermissionFor1StoreTest"> - <annotations> - <features value="Catalog"/> - <stories value="user role"/> - <title value="Ability to manage categories by admin user with permission for 1 store"/> - <description value="Ability to manage categories by admin user with permission for 1 store"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-19264"/> - <useCaseId value="MC-16455"/> - <group value="Catalog"/> - </annotations> - <before> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <!--Create new store and store view--> - <comment userInput="Create new store and store view" stepKey="createStoreAndStoreView"/> - <actionGroup ref="AdminCreateNewStoreGroupActionGroup" stepKey="createStore1"> - <argument name="website" value="Main Website"/> - <argument name="storeGroupName" value="{{SecondStoreGroupUnique.name}}"/> - <argument name="storeGroupCode" value="{{SecondStoreGroupUnique.code}}"/> - </actionGroup> - <actionGroup ref="AdminCreateStoreViewActionGroup" stepKey="createStoreView"/> - <!--Create simple category and product--> - <comment userInput="Create simple product and category" stepKey="createCategoryAndProduct"/> - <createData entity="_defaultCategory" stepKey="createCategory"/> - <createData entity="ApiSimpleProduct" stepKey="createProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - <!--Create restricted user role--> - <actionGroup ref="AdminAddNewUserRoleWithCustomRoleScopes" stepKey="createLimitedRole"> - <argument name="role" value="restrictedRole"/> - <argument name="customWebsiteName" value="{{SecondStoreGroupUnique.name}}"/> - </actionGroup> - <!--Create admin user with restricted role--> - <comment userInput="Create admin user with restricted role" stepKey="createUserWithRestrictedRole"/> - <actionGroup ref="AdminCreateUserWithRoleActionGroup" stepKey="createRestrictedAdmin"> - <argument name="role" value="restrictedRole"/> - <argument name="user" value="Admin3"/> - </actionGroup> - </before> - <after> - <!--Delete product and category--> - <comment userInput="Delete product and category" stepKey="deleteProdAndCategory"/> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> - <actionGroup ref="logout" stepKey="logout"/> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <!-- Delete User--> - <comment userInput="Delete User" stepKey="deleteUser"/> - <actionGroup ref="AdminDeleteCreatedUserActionGroup" stepKey="deleteLimitedUser"> - <argument name="user" value="Admin3"/> - </actionGroup> - <!--Delete users roles--> - <comment userInput="Delete users roles" stepKey="deleteUserRole"/> - <actionGroup ref="AdminDeleteUserRoleWithSpecifiedPermissionActionGroup" stepKey="deleteRestrictedRole"> - <argument name="role" value="restrictedRole"/> - </actionGroup> - <!--Delete store view--> - <comment userInput="Delete store view" stepKey="deleteStoreView"/> - <actionGroup ref="AdminDeleteStoreViewActionGroup" stepKey="deleteFirstStoreView"> - <argument name="customStore" value="customStore"/> - </actionGroup> - </after> - <!--Login as restricted user--> - <comment userInput="Login as restricted user" stepKey="loginAsRestrictedUser"/> - <actionGroup ref="logout" stepKey="logout"/> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"> - <argument name="adminUser" value="Admin3"/> - </actionGroup> - <!--Open Product page--> - <comment userInput="openProductPage" stepKey="openProdPage"/> - <amOnPage url="{{AdminProductEditPage.url($$createProduct.id$$)}}" stepKey="visitAdminProductPage"/> - <waitForPageLoad stepKey="waitForPageLoad"/> - <!--Check that ability to manage category is disabled--> - <comment userInput="Check that ability to manage category is disabled" stepKey="checkAbilityToManageCategory"/> - <grabAttributeFrom userInput="class" selector="{{AdminProductFormSection.categoriesDropdown}}" stepKey="grabAttributeFromInput"/> - <assertContains expectedType="string" expected="disabled" actual="$grabAttributeFromInput" stepKey="assertCategoryIsDisabled"/> - <!--Go to created category page--> - <comment userInput="Go to created category page" stepKey="visitAdminCategoryPage"/> - <actionGroup ref="goToAdminCategoryPageById" stepKey="goToAdminCategoryPage0"> - <argument name="id" value="$$createCategory.id$$"/> - </actionGroup> - <!--Expand products in category tab--> - <comment userInput="Expand products in category tab" stepKey="expandProductsInCategoryTab"/> - <conditionalClick selector="{{AdminCategoryProductsSection.sectionHeader}}" dependentSelector="{{AdminCategoryProductsSection.matchByRule}}" visible="false" stepKey="openProductsInCategoryTab"/> - <!--Check that the ability to add product is disabled--> - <comment userInput="Check that the ability to add product is disabled" stepKey="checkAbilityToAddProduct"/> - <seeElement selector="{{AdminCategoryProductsSection.addProductsDisabled}}" stepKey="checkAbilityToAddProductIsDisabled"/> - </test> -</tests> From 0f6773d9e7b27260bd6d7c6327bb9ed3f1f20f3c Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Thu, 26 Sep 2019 20:43:12 +0300 Subject: [PATCH 0748/1172] MC-16455: Admin user with permission for 1 store can manage categories - Fix CR comments --- .../Product/Form/Modifier/Categories.php | 1 + .../Ui/Component/Form/Element/Wysiwyg.php | 4 ---- .../view/base/web/js/form/components/group.js | 18 ------------------ .../view/base/web/js/form/element/ui-select.js | 10 +++------- .../backend/web/css/source/forms/_fields.less | 13 +++++++++---- 5 files changed, 13 insertions(+), 33 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index c395fc49ac07..72d078a26b57 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -265,6 +265,7 @@ protected function customizeCategoriesField(array $meta) 'chipsEnabled' => true, 'disableLabel' => true, 'levelsVisibility' => '1', + 'disabled' => $fieldIsDisabled, 'elementTmpl' => 'ui/grid/filters/elements/ui-select', 'options' => $this->getCategoriesTree(), 'disabled' => $fieldIsDisabled, diff --git a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php index 7005afbad44d..040c27d4939e 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php +++ b/app/code/Magento/Ui/Component/Form/Element/Wysiwyg.php @@ -3,7 +3,6 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types=1); namespace Magento\Ui\Component\Form\Element; @@ -52,9 +51,6 @@ public function __construct( array $config = [] ) { $wysiwygConfigData = isset($config['wysiwygConfigData']) ? $config['wysiwygConfigData'] : []; - if (isset($config['disabled']) && $config['disabled'] === true) { - $config['wysiwygConfigData']['settings']['readonly'] = 1; - } $this->form = $formFactory->create(); $wysiwygId = $context->getNamespace() . '_' . $data['name']; 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 f74bf3f5e919..8c5950f7e2fa 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 @@ -36,24 +36,6 @@ define([ return this; }, - /** - * @inheritdoc - */ - initElement: function (elem) { - this._super(); - - if (this.disabled) { - try { - elem.disabled(true); - } - catch (e) { - - } - } - - return this; - }, - /** * Calls initObservable of parent class. * Defines observable properties of instance. diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js index 9d38067d332f..5667ce5d71d8 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js +++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js @@ -568,10 +568,8 @@ define([ * Remove element from selected array */ removeSelected: function (value, data, event) { - if (!this.disabled()) { - event ? event.stopPropagation() : false; - this.value.remove(value); - } + event ? event.stopPropagation() : false; + this.value.remove(value); }, /** @@ -663,9 +661,7 @@ define([ * @returns {Object} Chainable */ toggleListVisible: function () { - if (!this.disabled()) { - this.listVisible(!this.listVisible()); - } + this.listVisible(!this.listVisible()); return this; }, diff --git a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less index 08aeb35d7adb..51402692075e 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/forms/_fields.less @@ -156,7 +156,7 @@ .admin__field { margin-top: 8px; } - } + } } } &.composite-bundle { @@ -307,7 +307,7 @@ .admin__fieldset > & { margin-bottom: 3rem; position: relative; - + &.field-import_file { .input-file { margin-top: 6px; @@ -361,6 +361,11 @@ cursor: inherit; opacity: 1; outline: inherit; + .admin__action-multiselect-wrap { + .admin__action-multiselect { + .__form-control-pattern__disabled(); + } + } } &._hidden { @@ -664,7 +669,7 @@ display: inline-block; } } - + + .admin__field:last-child { width: auto; @@ -700,7 +705,7 @@ width: 100%; } } - & > .admin__field-label { + & > .admin__field-label { text-align: left; } From 62c3d35e3b70260071168e0f5ab9076a5da3fa46 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Fri, 27 Sep 2019 12:41:48 +0300 Subject: [PATCH 0749/1172] MC-16455: Admin user with permission for 1 store can manage categories - Unit test errors fix - Health index test errors fix --- .../Product/Form/Modifier/CategoriesTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php index 932b09f7df9c..bceafee0f82a 100644 --- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php @@ -10,7 +10,6 @@ use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory; use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection; -use Magento\Framework\App\CacheInterface; use Magento\Framework\DB\Helper as DbHelper; use Magento\Framework\UrlInterface; use Magento\Store\Model\Store; @@ -161,7 +160,14 @@ public function testModifyMetaLocked($locked) ->willReturnArgument(2); $modifyMeta = $this->createModel()->modifyMeta($meta); - $this->assertEquals($locked, $modifyMeta['arguments']['data']['config']['disabled']); + $this->assertEquals( + $locked, + $modifyMeta['children']['category_ids']['arguments']['data']['config']['disabled'] + ); + $this->assertEquals( + $locked, + $modifyMeta['children']['create_category_button']['arguments']['data']['config']['disabled'] + ); } /** From f52ba88cf0ba26ae8b30eb6257a80dd2afb9958c Mon Sep 17 00:00:00 2001 From: Lena Orobei <oorobei@magento.com> Date: Tue, 1 Oct 2019 15:19:18 +0300 Subject: [PATCH 0750/1172] magento/graphql-ce#911: [Customer] Rename dob to date_of_birth --- .../CustomerGraphQl/Model/Customer/ExtractCustomerData.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php index ac074d543fec..c62a93180964 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/ExtractCustomerData.php @@ -101,10 +101,13 @@ public function execute(CustomerInterface $customer): array } } $customerData = array_merge($customerData, $customAttributes); - //Field is deprecated and should not be exposed on storefront. + //Fields are deprecated and should not be exposed on storefront. $customerData['group_id'] = null; - $customerData['model'] = $customer; $customerData['id'] = null; + + $customerData['model'] = $customer; + + //'dob' is deprecated, 'date_of_birth' is used instead. if (!empty($customerData['dob'])) { $customerData['date_of_birth'] = $customerData['dob']; } From ab04d7e7a79aa2ac15075243cc450a38baea3f74 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Tue, 1 Oct 2019 13:51:06 +0300 Subject: [PATCH 0751/1172] magento/magento2#23452: Added unit test. --- .../Unit/Block/Widget/Grid/MassactionTest.php | 73 ++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/MassactionTest.php b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/MassactionTest.php index e62b73f39241..51411ce04aac 100644 --- a/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/MassactionTest.php +++ b/app/code/Magento/Backend/Test/Unit/Block/Widget/Grid/MassactionTest.php @@ -4,14 +4,19 @@ * See COPYING.txt for license details. */ -/** - * Test class for \Magento\Backend\Block\Widget\Grid\Massaction - */ namespace Magento\Backend\Test\Unit\Block\Widget\Grid; use Magento\Backend\Block\Widget\Grid\Massaction\VisibilityCheckerInterface as VisibilityChecker; use Magento\Framework\Authorization; +use Magento\Framework\Data\Collection\AbstractDb as Collection; +use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\Framework\DB\Select; +/** + * Test class for \Magento\Backend\Block\Widget\Grid\Massaction + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class MassactionTest extends \PHPUnit\Framework\TestCase { /** @@ -54,6 +59,21 @@ class MassactionTest extends \PHPUnit\Framework\TestCase */ private $visibilityCheckerMock; + /** + * @var Collection|\PHPUnit\Framework\MockObject\MockObject + */ + private $gridCollectionMock; + + /** + * @var Select|\PHPUnit\Framework\MockObject\MockObject + */ + private $gridCollectionSelectMock; + + /** + * @var AdapterInterface|\PHPUnit\Framework\MockObject\MockObject + */ + private $connectionMock; + protected function setUp() { $this->_gridMock = $this->getMockBuilder(\Magento\Backend\Block\Widget\Grid::class) @@ -97,6 +117,18 @@ protected function setUp() ->setMethods(['isAllowed']) ->getMock(); + $this->gridCollectionMock = $this->createMock(Collection::class); + $this->gridCollectionSelectMock = $this->createMock(Select::class); + $this->connectionMock = $this->createMock(AdapterInterface::class); + + $this->gridCollectionMock->expects($this->any()) + ->method('getSelect') + ->willReturn($this->gridCollectionSelectMock); + + $this->gridCollectionMock->expects($this->any()) + ->method('getConnection') + ->willReturn($this->connectionMock); + $arguments = [ 'layout' => $this->_layoutMock, 'request' => $this->_requestMock, @@ -269,6 +301,41 @@ public function testGetGridIdsJsonWithoutUseSelectAll() $this->assertEmpty($this->_block->getGridIdsJson()); } + /** + * Test for getGridIdsJson when select all functionality flag set to true. + */ + public function testGetGridIdsJsonWithUseSelectAll() + { + $this->_block->setUseSelectAll(true); + + $this->_gridMock->expects($this->once()) + ->method('getCollection') + ->willReturn($this->gridCollectionMock); + + $this->gridCollectionSelectMock->expects($this->exactly(4)) + ->method('reset') + ->withConsecutive( + [Select::ORDER], + [Select::LIMIT_COUNT], + [Select::LIMIT_OFFSET], + [Select::COLUMNS] + ); + + $this->gridCollectionSelectMock->expects($this->once()) + ->method('columns') + ->with('test_id'); + + $this->connectionMock->expects($this->once()) + ->method('fetchCol') + ->with($this->gridCollectionSelectMock) + ->willReturn([1, 2, 3]); + + $this->assertEquals( + '1,2,3', + $this->_block->getGridIdsJson() + ); + } + /** * @param string $itemId * @param array|\Magento\Framework\DataObject $item From 2a29bec42aca484288b08460e478100eb4d75f47 Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Mon, 30 Sep 2019 17:18:24 -0500 Subject: [PATCH 0752/1172] MC-20622: Email sent from admin order edit includes incorrect static file paths - Fix unable to set local though \Magento\Backend\Model\Locale\Resolver::setLocale() --- .../Magento/Backend/Model/Locale/Resolver.php | 6 ++- .../Backend/Model/Locale/ResolverTest.php | 45 ++++++++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Backend/Model/Locale/Resolver.php b/app/code/Magento/Backend/Model/Locale/Resolver.php index b9be471cd599..9086e2af83e2 100644 --- a/app/code/Magento/Backend/Model/Locale/Resolver.php +++ b/app/code/Magento/Backend/Model/Locale/Resolver.php @@ -7,8 +7,10 @@ /** * Backend locale model + * * @api * @since 100.0.2 + * @SuppressWarnings(PHPMD.CookieAndSessionMisuse) */ class Resolver extends \Magento\Framework\Locale\Resolver { @@ -40,7 +42,7 @@ class Resolver extends \Magento\Framework\Locale\Resolver * @param Manager $localeManager * @param \Magento\Framework\App\RequestInterface $request * @param \Magento\Framework\Validator\Locale $localeValidator - * @param null $locale + * @param string|null $locale * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -76,7 +78,7 @@ public function setLocale($locale = null) $sessionLocale = $this->_session->getSessionLocale(); $userLocale = $this->_localeManager->getUserInterfaceLocale(); - $localeCodes = array_filter([$forceLocale, $sessionLocale, $userLocale]); + $localeCodes = array_filter([$forceLocale, $locale, $sessionLocale, $userLocale]); if (count($localeCodes)) { $locale = reset($localeCodes); diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php index 88662a65c742..a930244238ef 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Locale/ResolverTest.php @@ -20,6 +20,9 @@ class ResolverTest extends \PHPUnit\Framework\TestCase */ protected $_model; + /** + * {@inheritDoc} + */ protected function setUp() { parent::setUp(); @@ -29,7 +32,7 @@ protected function setUp() } /** - * @covers \Magento\Backend\Model\Locale\Resolver::setLocale + * Tests setLocale() with default locale */ public function testSetLocaleWithDefaultLocale() { @@ -37,7 +40,7 @@ public function testSetLocaleWithDefaultLocale() } /** - * @covers \Magento\Backend\Model\Locale\Resolver::setLocale + * Tests setLocale() with interface locale */ public function testSetLocaleWithBaseInterfaceLocale() { @@ -55,7 +58,7 @@ public function testSetLocaleWithBaseInterfaceLocale() } /** - * @covers \Magento\Backend\Model\Locale\Resolver::setLocale + * Tests setLocale() with session locale */ public function testSetLocaleWithSessionLocale() { @@ -68,7 +71,7 @@ public function testSetLocaleWithSessionLocale() } /** - * @covers \Magento\Backend\Model\Locale\Resolver::setLocale + * Tests setLocale() with post parameter */ public function testSetLocaleWithRequestLocale() { @@ -78,13 +81,45 @@ public function testSetLocaleWithRequestLocale() $this->_checkSetLocale('de_DE'); } + /** + * Tests setLocale() with parameter + * + * @param string|null $localeParam + * @param string|null $localeRequestParam + * @param string $localeExpected + * @dataProvider setLocaleWithParameterDataProvider + */ + public function testSetLocaleWithParameter( + ?string $localeParam, + ?string $localeRequestParam, + string $localeExpected + ) { + $request = Bootstrap::getObjectManager() + ->get(\Magento\Framework\App\RequestInterface::class); + $request->setPostValue(['locale' => $localeRequestParam]); + $this->_model->setLocale($localeParam); + $this->assertEquals($localeExpected, $this->_model->getLocale()); + } + + /** + * @return array + */ + public function setLocaleWithParameterDataProvider(): array + { + return [ + ['ko_KR', 'ja_JP', 'ja_JP'], + ['ko_KR', null, 'ko_KR'], + [null, 'ja_JP', 'ja_JP'], + ]; + } + /** * Check set locale * * @param string $localeCodeToCheck * @return void */ - protected function _checkSetLocale($localeCodeToCheck) + private function _checkSetLocale($localeCodeToCheck) { $this->_model->setLocale(); $localeCode = $this->_model->getLocale(); From ad5682cda9d265a44dc6203d07b5a61aff2fbdc1 Mon Sep 17 00:00:00 2001 From: Mykola Orlenko <mo@integer-net.de> Date: Tue, 1 Oct 2019 16:03:44 +0200 Subject: [PATCH 0753/1172] [BUGFIX] DesignTheme should be initialized before all images --- .../Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php index 4fcb87ab1396..9fadb22bb15d 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Listing/Collector/Image.php @@ -107,6 +107,7 @@ public function collect(ProductInterface $product, ProductRenderInterface $produ $images = []; /** @var ThemeInterface $currentTheme */ $currentTheme = $this->design->getDesignTheme(); + $this->design->setDesignTheme($currentTheme); foreach ($this->imageCodes as $imageCode) { /** @var ImageInterface $image */ @@ -135,7 +136,6 @@ public function collect(ProductInterface $product, ProductRenderInterface $produ $images[] = $image; } - $this->design->setDesignTheme($currentTheme); $productRender->setImages($images); } From f3bc78e8d41f9bd915e21ec87e8e57432fb04c58 Mon Sep 17 00:00:00 2001 From: Yauhen_Lyskavets <yauhen_lyskavets@epam.com> Date: Tue, 1 Oct 2019 17:22:29 +0300 Subject: [PATCH 0754/1172] MC-16455: Admin user with permission for 1 store can manage categories - Static tests errors fix --- .../Ui/DataProvider/Product/Form/Modifier/Categories.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php index 72d078a26b57..c4ca5eca8e88 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php @@ -268,7 +268,6 @@ protected function customizeCategoriesField(array $meta) 'disabled' => $fieldIsDisabled, 'elementTmpl' => 'ui/grid/filters/elements/ui-select', 'options' => $this->getCategoriesTree(), - 'disabled' => $fieldIsDisabled, 'listens' => [ 'index=create_category:responseData' => 'setParsed', 'newOption' => 'toggleOptionSelected' @@ -322,11 +321,7 @@ protected function customizeCategoriesField(array $meta) ] ]; } - $meta = $this->arrayManager->merge( - $containerPath, - $meta, - $value - ); + $meta = $this->arrayManager->merge($containerPath, $meta, $value); return $meta; } From 424321e5a055e256d21d0764660c658c827f0369 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Tue, 1 Oct 2019 11:54:22 +0300 Subject: [PATCH 0755/1172] MAGETWO-65232: Product name does not display special characters properly - Escape html output --- .../Product/Modifier/Attributes.php | 64 +++++++++++++++++++ app/code/Magento/Catalog/etc/adminhtml/di.xml | 19 +++++- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/Attributes.php diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/Attributes.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/Attributes.php new file mode 100644 index 000000000000..01aaa6f8e062 --- /dev/null +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Modifier/Attributes.php @@ -0,0 +1,64 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Ui\DataProvider\Product\Modifier; + +use Magento\Framework\Escaper; +use Magento\Ui\DataProvider\Modifier\ModifierInterface; + +/** + * Modify product listing attributes + */ +class Attributes implements ModifierInterface +{ + /** + * @var Escaper + */ + private $escaper; + + /** + * @var array + */ + private $escapeAttributes; + + /** + * @param Escaper $escaper + * @param array $escapeAttributes + */ + public function __construct( + Escaper $escaper, + array $escapeAttributes = [] + ) { + $this->escaper = $escaper; + $this->escapeAttributes = $escapeAttributes; + } + + /** + * @inheritdoc + */ + public function modifyData(array $data) + { + if (!empty($data) && !empty($this->escapeAttributes)) { + foreach ($data['items'] as &$item) { + foreach ($this->escapeAttributes as $escapeAttribute) { + if (isset($item[$escapeAttribute])) { + $item[$escapeAttribute] = $this->escaper->escapeHtml($item[$escapeAttribute]); + } + } + } + } + return $data; + } + + /** + * @inheritdoc + */ + public function modifyMeta(array $meta) + { + return $meta; + } +} diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml index c04cfb2dce00..b3c9230b3cfc 100644 --- a/app/code/Magento/Catalog/etc/adminhtml/di.xml +++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml @@ -166,7 +166,24 @@ <argument name="pool" xsi:type="object">Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool</argument> </arguments> </type> - <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Listing\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"/> + <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Listing\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool"> + <arguments> + <argument name="modifiers" xsi:type="array"> + <item name="attributes" xsi:type="array"> + <item name="class" xsi:type="string">Magento\Catalog\Ui\DataProvider\Product\Modifier\Attributes</item> + <item name="sortOrder" xsi:type="number">10</item> + </item> + </argument> + </arguments> + </virtualType> + <type name="Magento\Catalog\Ui\DataProvider\Product\Modifier\Attributes"> + <arguments> + <argument name="escapeAttributes" xsi:type="array"> + <item name="name" xsi:type="string">name</item> + <item name="sku" xsi:type="string">sku</item> + </argument> + </arguments> + </type> <type name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions"> <arguments> <argument name="scopeName" xsi:type="string">product_form.product_form</argument> From 86f3fdbabbfd5437a6811bad07c9d04d59370aaf Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 1 Oct 2019 10:25:31 -0500 Subject: [PATCH 0756/1172] MC-20536: Make remaining failed MTF tests running with MySQL only --- .../Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml | 6 ++++++ ...tAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml | 2 ++ 2 files changed, 8 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml index 0d1925ef538a..02d3051ae1a8 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml @@ -154,6 +154,8 @@ <after> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChildProduct1" before="delete"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChildProduct2" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchConfigurableByDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByDescriptionTest"> @@ -228,6 +230,8 @@ <after> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChildProduct1" before="delete"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChildProduct2" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchConfigurableByShortDescriptionTest" extends="AdvanceCatalogSearchSimpleProductByShortDescriptionTest"> @@ -302,6 +306,8 @@ <after> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChildProduct1" before="delete"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChildProduct2" before="delete"/> </after> </test> </tests> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml index 8a7d7d5394ee..a8e982475253 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontAdvanceCatalogSearchConfigurableBySkuWithHyphenTest.xml @@ -81,6 +81,8 @@ <after> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChildProduct1" before="delete"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChildProduct2" before="delete"/> </after> </test> </tests> From 076295d4069e83b47f38c726cf25e1bb1efa805c Mon Sep 17 00:00:00 2001 From: Krishna Abothu <abothu@adobe.com> Date: Tue, 1 Oct 2019 11:16:18 -0500 Subject: [PATCH 0757/1172] MC-20644: Update MFTF test failures for Catalog Rules and Sales Modules --- .../Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml index 1ad736ade37f..4310d412d1c9 100644 --- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml +++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCorrectnessInvoicedItemInBundleProductTest.xml @@ -55,6 +55,9 @@ <amOnPage url="{{AdminProductEditPage.url($$createBundleProduct.id$$)}}" stepKey="goToProductEditPage"/> <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + <!--Run re-index task--> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <!--Go to bundle product page--> <amOnPage url="{{StorefrontProductPage.url($$createCategory.name$$)}}" stepKey="navigateToBundleProductPage"/> From 2c926f032a4f1197b9aa6f52d4abeddc6e511e97 Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Tue, 1 Oct 2019 11:57:22 -0500 Subject: [PATCH 0758/1172] MC-15986: Category Filtering - added new schema changes from approved proposal --- .../Magento/CatalogGraphQl/etc/schema.graphqls | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 24a2123ff60f..66e6fb68728f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -12,9 +12,11 @@ type Query { @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Products") @doc(description: "The products query searches for products that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\Identity") category ( id: Int @doc(description: "Id of the category.") - filter: CategoryFilterInput @doc(description: "Identifies which Category inputs to search for and return."), ): CategoryTree - @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") + @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @deprecated(reason: "Use 'categoryList' query instead of 'category' query") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") + categoryList( + filters: CategoryFilterInput @doc(description: "Identifies which Category filter inputs to search for and return.") + ): [CategoryList] @doc(description: "Categories filter.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryList") } type Price @doc(description: "The Price object defines the price of a product as well as any tax-related adjustments.") { @@ -278,10 +280,11 @@ input ProductAttributeFilterInput @doc(description: "ProductAttributeFilterInput category_id: FilterEqualTypeInput @doc(description: "Filter product by category id") } -input CategoryFilterInput @doc(description: "CategoryFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { - id: FilterEqualTypeInput @doc(description: "Filter by category ID that uniquely identifies and filters the category."), - url_key: FilterEqualTypeInput @doc(description: "Filter by the part of the URL that identifies the category"), - name: FilterEqualTypeInput @doc(description: "Filter by the display name of the category.") +input CategoryFilterInput @doc(description: "CategoryFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") +{ + ids: FilterEqualTypeInput @doc(description: "Filter by category ID that uniquely identifies and filters the category.") + url_key: FilterEqualTypeInput @doc(description: "Filter by the part of the URL that identifies the category") + name: FilterMatchTypeInput @doc(description: "Filter by the display name of the category.") } input ProductFilterInput @doc(description: "ProductFilterInput is deprecated, use @ProductAttributeFilterInput instead. ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { From 003bb8715a2e48c74a32842450908344a8f35cf4 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 1 Oct 2019 11:58:55 -0500 Subject: [PATCH 0759/1172] MC-19248: Add static test to prevent regressing mage-init directive fixes made in the phtml files --- .../Magento/Test/Legacy/PhtmlTemplateTest.php | 82 +++++++++++++++++++ .../data_mage_init/whitelist.php | 13 +++ 2 files changed, 95 insertions(+) create mode 100644 dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php index 5c342614f94f..47f9b033363d 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php @@ -7,6 +7,8 @@ */ namespace Magento\Test\Legacy; +use Magento\Framework\Component\ComponentRegistrar; + /** * Static test for phtml template files. */ @@ -105,4 +107,84 @@ function ($file) { \Magento\Framework\App\Utility\Files::init()->getPhtmlFiles() ); } + + public function testJsComponentsAreProperlyInitializedInDataMageInitAttribute() + { + $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); + $invoker( + /** + * JS components in data-mage-init attributes should be initialized not in php. + * JS components should be initialized in templates for them to be properly statically analyzed for bundling. + * + * @param string $file + */ + function ($file) { + $whiteList = $this->getWhiteList(); + if (!in_array($file, $whiteList, true) + && (strpos($file, '/view/frontend/templates/') !== false + || strpos($file, '/view/base/templates/') !== false) + ) { + self::assertNotRegExp( + '/data-mage-init=(?:\'|")(?!\s*{\s*"[^"]+")/', + file_get_contents($file), + 'Please do not initialize JS component in php. Do it in template.' + ); + } + }, + \Magento\Framework\App\Utility\Files::init()->getPhtmlFiles() + ); + } + + /** + * @return array + */ + private function getWhiteList() + { + $whiteListFiles = []; + $componentRegistrar = new ComponentRegistrar(); + foreach ($this->getFilesData('data_mage_init/whitelist.php') as $fileInfo) { + $whiteListFiles[] = $componentRegistrar->getPath(ComponentRegistrar::MODULE, $fileInfo[0]) + . DIRECTORY_SEPARATOR . $fileInfo[1]; + } + return $whiteListFiles; + } + + /** + * @param string $filePattern + * @return array + */ + private function getFilesData($filePattern) + { + $result = []; + foreach (glob(__DIR__ . '/_files/initialize_javascript/' . $filePattern) as $file) { + $fileData = include $file; + $result = array_merge($result, $fileData); + } + return $result; + } + + public function testJsComponentsAreProperlyInitializedInXMagentoInitAttribute() + { + $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); + $invoker( + /** + * JS components in x-magento-init attributes should be initialized not in php. + * JS components should be initialized in templates for them to be properly statically analyzed for bundling. + * + * @param string $file + */ + function ($file) { + if (strpos($file, '/view/frontend/templates/') !== false + || strpos($file, '/view/base/templates/') !== false + ) { + self::assertNotRegExp( + '@x-magento-init.>(?!\s*+{\s*"[^"]+"\s*:\s*{\s*"[\w/-]+")@i', + file_get_contents($file), + 'Please do not initialize JS component in php. Do it in template.' + ); + } + }, + \Magento\Framework\App\Utility\Files::init()->getPhtmlFiles() + ); + } } diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php new file mode 100644 index 000000000000..ab55bc3eae92 --- /dev/null +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +/** + * List of templates with data-mage-init attribute where JS component is not correctly called. + * + * JS component is initialized in php here. These templates cannot be refactored easily. + */ +return [ + ['Magento_Braintree', 'view/frontend/templates/paypal/button_shopping_cart.phtml'] +]; From 2b0558bf9922a32e904e12cae67ea944569eebe7 Mon Sep 17 00:00:00 2001 From: Joan He <johe@magento.com> Date: Tue, 1 Oct 2019 12:08:15 -0500 Subject: [PATCH 0760/1172] MC-20555: Add "Search Engine" parameter in Jenkins build --- .../Magento/TestModuleCatalogSearch/etc/module.xml | 14 ++++++++++++++ .../TestModuleCatalogSearch/registration.php | 12 ++++++++++++ .../Magento/TestModuleCatalogSearch/etc/module.xml | 14 ++++++++++++++ .../TestModuleCatalogSearch/registration.php | 12 ++++++++++++ 4 files changed, 52 insertions(+) create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/etc/module.xml create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/registration.php create mode 100644 dev/tests/integration/_files/Magento/TestModuleCatalogSearch/etc/module.xml create mode 100644 dev/tests/integration/_files/Magento/TestModuleCatalogSearch/registration.php diff --git a/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/etc/module.xml new file mode 100644 index 000000000000..bae0739d237e --- /dev/null +++ b/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/etc/module.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_TestModuleCatalogSearch"> + <sequence> + <module name="Magento_CatalogSearch"/> + </sequence> + </module> +</config> diff --git a/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/registration.php b/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/registration.php new file mode 100644 index 000000000000..78fb97a9e113 --- /dev/null +++ b/dev/tests/api-functional/_files/Magento/TestModuleCatalogSearch/registration.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Component\ComponentRegistrar; + +$registrar = new ComponentRegistrar(); +if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleCatalogSearch') === null) { + ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleCatalogSearch', __DIR__); +} diff --git a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/etc/module.xml b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/etc/module.xml new file mode 100644 index 000000000000..bae0739d237e --- /dev/null +++ b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/etc/module.xml @@ -0,0 +1,14 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> + <module name="Magento_TestModuleCatalogSearch"> + <sequence> + <module name="Magento_CatalogSearch"/> + </sequence> + </module> +</config> diff --git a/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/registration.php b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/registration.php new file mode 100644 index 000000000000..78fb97a9e113 --- /dev/null +++ b/dev/tests/integration/_files/Magento/TestModuleCatalogSearch/registration.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +use Magento\Framework\Component\ComponentRegistrar; + +$registrar = new ComponentRegistrar(); +if ($registrar->getPath(ComponentRegistrar::MODULE, 'Magento_TestModuleCatalogSearch') === null) { + ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_TestModuleCatalogSearch', __DIR__); +} From 6d642f83ad5551d5adc52930a227e66b87ddf480 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Tue, 1 Oct 2019 12:56:27 -0500 Subject: [PATCH 0761/1172] MC-18783: IE11 Checkout Error; Indefinite loading; Cant complete check out - overridden window clearTimeout function should take a parameter --- .../view/frontend/web/js/view/payment/list-mixin.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/PaypalCaptcha/view/frontend/web/js/view/payment/list-mixin.js b/app/code/Magento/PaypalCaptcha/view/frontend/web/js/view/payment/list-mixin.js index 60172f696e9e..8abd57cc6913 100644 --- a/app/code/Magento/PaypalCaptcha/view/frontend/web/js/view/payment/list-mixin.js +++ b/app/code/Magento/PaypalCaptcha/view/frontend/web/js/view/payment/list-mixin.js @@ -34,14 +34,16 @@ define([ /** * Overrides default window.clearTimeout() to catch errors from iframe and reload Captcha. + * + * @param {Number} timeoutID */ - clearTimeout: function () { + clearTimeout: function (timeoutID) { var captcha = captchaList.getCaptchaByFormId(this.formId); if (captcha !== null) { captcha.refresh(); } - clearTimeout(); + clearTimeout(timeoutID); } }; From 33772d26cf4afa7c2436023d6fa1fbfa0a88b055 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 1 Oct 2019 13:15:08 -0500 Subject: [PATCH 0762/1172] MC-20536: Make remaining failed MTF tests running with MySQL only --- .../Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml index 02d3051ae1a8..037028030927 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdvanceCatalogSearchConfigurableTest.xml @@ -80,6 +80,8 @@ <after> <deleteData createDataKey="simple1Handle" stepKey="deleteSimple1" before="deleteSimple2"/> <deleteData createDataKey="simple2Handle" stepKey="deleteSimple2" before="delete"/> + <deleteData createDataKey="childProductHandle1" stepKey="deleteChildProduct1" before="delete"/> + <deleteData createDataKey="childProductHandle2" stepKey="deleteChildProduct2" before="delete"/> </after> </test> <test name="AdvanceCatalogSearchConfigurableBySkuTest" extends="AdvanceCatalogSearchSimpleProductBySkuTest"> From 6879694ef4735ae2e6e15986660af05a4b047098 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Tue, 1 Oct 2019 13:41:01 -0500 Subject: [PATCH 0763/1172] MC-20536: Make remaining failed MTF tests running with MySQL only --- .../LayeredNavigation/Test/TestCase/FilterProductListTest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml index 72b89916a08d..48129ef28749 100644 --- a/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml +++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/TestCase/FilterProductListTest.xml @@ -94,6 +94,7 @@ <constraint name="Magento\LayeredNavigation\Test\Constraint\AssertFilterProductList" /> </variation> <variation name="FilterProductListTestVariation4" summary="Use sorting category filter when layered navigation is applied" ticketId="MAGETWO-42701"> + <data name="tag" xsi:type="string">test_type:mysql_search</data> <data name="configData" xsi:type="string">layered_navigation_manual_range_10</data> <data name="runReindex" xsi:type="boolean">true</data> <data name="category/dataset" xsi:type="string">default_anchor_subcategory</data> From 26ea9edb082e63c915588ce2cd8df5049b4ea91f Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Tue, 1 Oct 2019 14:37:29 -0500 Subject: [PATCH 0764/1172] MC-19248: Add static test to prevent regressing mage-init directive fixes made in the phtml files - Fix unit tests; --- .../Magento/Test/Legacy/PhtmlTemplateTest.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php index 47f9b033363d..f9630fd8cc05 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/PhtmlTemplateTest.php @@ -112,12 +112,12 @@ public function testJsComponentsAreProperlyInitializedInDataMageInitAttribute() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * JS components in data-mage-init attributes should be initialized not in php. - * JS components should be initialized in templates for them to be properly statically analyzed for bundling. - * - * @param string $file - */ + /** + * JS components in data-mage-init attributes should be initialized not in php. + * JS components should be initialized in templates for them to be properly statically analyzed for bundling. + * + * @param string $file + */ function ($file) { $whiteList = $this->getWhiteList(); if (!in_array($file, $whiteList, true) @@ -167,12 +167,12 @@ public function testJsComponentsAreProperlyInitializedInXMagentoInitAttribute() { $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this); $invoker( - /** - * JS components in x-magento-init attributes should be initialized not in php. - * JS components should be initialized in templates for them to be properly statically analyzed for bundling. - * - * @param string $file - */ + /** + * JS components in x-magento-init attributes should be initialized not in php. + * JS components should be initialized in templates for them to be properly statically analyzed for bundling. + * + * @param string $file + */ function ($file) { if (strpos($file, '/view/frontend/templates/') !== false || strpos($file, '/view/base/templates/') !== false From 854a9d6d8b3e46aee985901d2acf4300fa513c42 Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Tue, 1 Oct 2019 15:05:21 -0500 Subject: [PATCH 0765/1172] MC-15986: Category Filtering - added change to the query in schema --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 66e6fb68728f..5e8f5590bbd3 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -16,7 +16,7 @@ type Query { @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @deprecated(reason: "Use 'categoryList' query instead of 'category' query") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") categoryList( filters: CategoryFilterInput @doc(description: "Identifies which Category filter inputs to search for and return.") - ): [CategoryList] @doc(description: "Categories filter.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryList") + ): [CategoryTree] @doc(description: "Categories filter.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryList") } type Price @doc(description: "The Price object defines the price of a product as well as any tax-related adjustments.") { From a9dcf1354fb18cfb819aaff4d3f7b0adc38a8e43 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 1 Oct 2019 15:17:15 -0500 Subject: [PATCH 0766/1172] MC-20244: Pricing :: FPT calculation - add fpt display settings --- .../Model/Resolver/FptResolver.php | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php index c1dd543c5701..5d1abe00a267 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -51,30 +51,39 @@ public function resolve( if (!isset($value['model'])) { throw new LocalizedException(__('"model" value should be specified')); } + $fptArray = []; $product = $value['model']; /** @var StoreInterface $store */ $store = $context->getExtensionAttributes()->getStore(); - $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); - foreach ($attributes as $attribute) { - $displayInclTaxes = $this->taxHelper->getPriceDisplayType($store); - $amount = $attribute->getData('amount'); - if ($displayInclTaxes === 1) { - $amount = $attribute->getData('amount_excl_tax'); - } elseif ($displayInclTaxes === 2) { - $amount = $attribute->getData('amount_excl_tax') + $attribute->getData('tax_amount'); - } - $fptArray[] = [ - 'amount' => [ - 'value' => $amount, - 'currency' => $value['final_price']['currency'], + + if (!$this->weeeHelper->isEnabled($store)) { + return $fptArray; + } + + + if ($this->weeeHelper->isDisplayInclDesc($store) || $this->weeeHelper->isDisplayExclDescIncl($store)) { + $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); + foreach ($attributes as $attribute) { + $displayInclTaxes = $this->taxHelper->getPriceDisplayType($store); + $amount = $attribute->getData('amount'); + //add display mode for WEE to not return WEE if excluded + if ($displayInclTaxes === 1) { + $amount = $attribute->getData('amount_excl_tax'); + } elseif ($displayInclTaxes === 2) { + $amount = $attribute->getData('amount_excl_tax') + $attribute->getData('tax_amount'); + } + $fptArray[] = [ + 'amount' => [ + 'value' => $amount, + 'currency' => $value['final_price']['currency'], ], 'label' => $attribute->getData('name') - ]; + ]; + } } - return $fptArray; } } From 671d4bd099e6b597812eb087ba83fcc6e1fc1b7c Mon Sep 17 00:00:00 2001 From: Oleksandr Dubovyk <odubovyk@magento.com> Date: Tue, 1 Oct 2019 15:41:11 -0500 Subject: [PATCH 0767/1172] MC-20709: [On PREM] Checkboxes inside widgets are not fully clickable in admin - fixed --- .../Magento/backend/Magento_Banner/web/css/source/_module.less | 1 + 1 file changed, 1 insertion(+) diff --git a/app/design/adminhtml/Magento/backend/Magento_Banner/web/css/source/_module.less b/app/design/adminhtml/Magento/backend/Magento_Banner/web/css/source/_module.less index d9e2cfdd66bf..dd67220db12d 100644 --- a/app/design/adminhtml/Magento/backend/Magento_Banner/web/css/source/_module.less +++ b/app/design/adminhtml/Magento/backend/Magento_Banner/web/css/source/_module.less @@ -24,6 +24,7 @@ input[type='checkbox'].banner-content-checkbox { } .adminhtml-widget_instance-edit, +.adminhtml-cms_page-edit, .adminhtml-banner-edit { .admin__fieldset { .admin__field-control { From f52d0fac70114ccba75dd9c06f70af8a865c086a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Tue, 1 Oct 2019 22:42:50 +0200 Subject: [PATCH 0768/1172] Fix #13278 - Wrong return type in Salesrule Module RuleInterface.php --- .../SalesRule/Api/Data/RuleInterface.php | 24 +++++++++-------- .../Magento/SalesRule/Model/Data/Rule.php | 27 +++++++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/app/code/Magento/SalesRule/Api/Data/RuleInterface.php b/app/code/Magento/SalesRule/Api/Data/RuleInterface.php index 34341e16cfb6..b811289798e3 100644 --- a/app/code/Magento/SalesRule/Api/Data/RuleInterface.php +++ b/app/code/Magento/SalesRule/Api/Data/RuleInterface.php @@ -5,13 +5,15 @@ */ namespace Magento\SalesRule\Api\Data; +use Magento\Framework\Api\ExtensibleDataInterface; + /** * Interface RuleInterface * * @api * @since 100.0.2 */ -interface RuleInterface extends \Magento\Framework\Api\ExtensibleDataInterface +interface RuleInterface extends ExtensibleDataInterface { const FREE_SHIPPING_NONE = 'NONE'; const FREE_SHIPPING_MATCHING_ITEMS_ONLY = 'MATCHING_ITEMS_ONLY'; @@ -59,14 +61,14 @@ public function setName($name); /** * Get display label * - * @return \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null + * @return RuleLabelInterface[]|null */ public function getStoreLabels(); /** * Set display label * - * @param \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null $storeLabels + * @param RuleLabelInterface[]|null $storeLabels * @return $this */ public function setStoreLabels(array $storeLabels = null); @@ -173,21 +175,21 @@ public function getIsActive(); * Set whether the coupon is active * * @param bool $isActive - * @return bool + * @return $this */ public function setIsActive($isActive); /** * Get condition for the rule * - * @return \Magento\SalesRule\Api\Data\ConditionInterface|null + * @return ConditionInterface|null */ public function getCondition(); /** * Set condition for the rule * - * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $condition + * @param ConditionInterface|null $condition * @return $this */ public function setCondition(ConditionInterface $condition = null); @@ -195,14 +197,14 @@ public function setCondition(ConditionInterface $condition = null); /** * Get action condition * - * @return \Magento\SalesRule\Api\Data\ConditionInterface|null + * @return ConditionInterface|null */ public function getActionCondition(); /** * Set action condition * - * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $actionCondition + * @param ConditionInterface|null $actionCondition * @return $this */ public function setActionCondition(ConditionInterface $actionCondition = null); @@ -436,15 +438,15 @@ public function setSimpleFreeShipping($simpleFreeShipping); /** * Retrieve existing extension attributes object or create a new one. * - * @return \Magento\SalesRule\Api\Data\RuleExtensionInterface|null + * @return RuleExtensionInterface|null */ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param \Magento\SalesRule\Api\Data\RuleExtensionInterface $extensionAttributes + * @param RuleExtensionInterface $extensionAttributes * @return $this */ - public function setExtensionAttributes(\Magento\SalesRule\Api\Data\RuleExtensionInterface $extensionAttributes); + public function setExtensionAttributes(RuleExtensionInterface $extensionAttributes); } diff --git a/app/code/Magento/SalesRule/Model/Data/Rule.php b/app/code/Magento/SalesRule/Model/Data/Rule.php index 58520831c016..869822ab917c 100644 --- a/app/code/Magento/SalesRule/Model/Data/Rule.php +++ b/app/code/Magento/SalesRule/Model/Data/Rule.php @@ -5,10 +5,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace Magento\SalesRule\Model\Data; +use Magento\Framework\Api\AbstractExtensibleObject; use Magento\SalesRule\Api\Data\ConditionInterface; +use Magento\SalesRule\Api\Data\RuleExtensionInterface; use Magento\SalesRule\Api\Data\RuleInterface; +use Magento\SalesRule\Api\Data\RuleLabelInterface; /** * Class Rule @@ -16,7 +21,7 @@ * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @codeCoverageIgnore */ -class Rule extends \Magento\Framework\Api\AbstractExtensibleObject implements RuleInterface +class Rule extends AbstractExtensibleObject implements RuleInterface { const KEY_RULE_ID = 'rule_id'; const KEY_NAME = 'name'; @@ -187,7 +192,7 @@ public function getIsActive() * Set whether the coupon is active * * @param bool $isActive - * @return bool + * @return $this */ public function setIsActive($isActive) { @@ -197,7 +202,7 @@ public function setIsActive($isActive) /** * Get condition for the rule * - * @return \Magento\SalesRule\Api\Data\ConditionInterface|null + * @return ConditionInterface|null */ public function getCondition() { @@ -207,7 +212,7 @@ public function getCondition() /** * Set condition for the rule * - * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $condition + * @param ConditionInterface|null $condition * @return $this */ public function setCondition(ConditionInterface $condition = null) @@ -218,7 +223,7 @@ public function setCondition(ConditionInterface $condition = null) /** * Get action condition * - * @return \Magento\SalesRule\Api\Data\ConditionInterface|null + * @return ConditionInterface|null */ public function getActionCondition() { @@ -228,7 +233,7 @@ public function getActionCondition() /** * Set action condition * - * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $actionCondition + * @param ConditionInterface|null $actionCondition * @return $this */ public function setActionCondition(ConditionInterface $actionCondition = null) @@ -283,7 +288,7 @@ public function setIsAdvanced($isAdvanced) /** * Get display label * - * @return \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null + * @return RuleLabelInterface[]|null */ public function getStoreLabels() { @@ -293,7 +298,7 @@ public function getStoreLabels() /** * Set display label * - * @param \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null $storeLabels + * @param RuleLabelInterface[]|null $storeLabels * @return $this */ public function setStoreLabels(array $storeLabels = null) @@ -622,7 +627,7 @@ public function setSimpleFreeShipping($simpleFreeShipping) /** * @inheritdoc * - * @return \Magento\SalesRule\Api\Data\RuleExtensionInterface|null + * @return RuleExtensionInterface|null */ public function getExtensionAttributes() { @@ -632,11 +637,11 @@ public function getExtensionAttributes() /** * @inheritdoc * - * @param \Magento\SalesRule\Api\Data\RuleExtensionInterface $extensionAttributes + * @param RuleExtensionInterface $extensionAttributes * @return $this */ public function setExtensionAttributes( - \Magento\SalesRule\Api\Data\RuleExtensionInterface $extensionAttributes + RuleExtensionInterface $extensionAttributes ) { return $this->_setExtensionAttributes($extensionAttributes); } From 1ad0e32b021ae1d980bf8461ece3b03b7d80d7d7 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 1 Oct 2019 16:56:05 -0500 Subject: [PATCH 0769/1172] MC-20244: Pricing :: FPT calculation - removing display settings form resolver - fixing a bug with the old weee schema --- .../WeeeGraphQl/Model/Resolver/FptResolver.php | 14 +++++--------- app/code/Magento/WeeeGraphQl/composer.json | 1 + app/code/Magento/WeeeGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php index 5d1abe00a267..be98e19cfe65 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -14,6 +14,7 @@ use Magento\Framework\Exception\LocalizedException; use Magento\Tax\Helper\Data as TaxHelper; use Magento\Store\Api\Data\StoreInterface; +use Magento\Tax\Model\Config; class FptResolver implements ResolverInterface { @@ -58,21 +59,15 @@ public function resolve( /** @var StoreInterface $store */ $store = $context->getExtensionAttributes()->getStore(); - - if (!$this->weeeHelper->isEnabled($store)) { - return $fptArray; - } - - - if ($this->weeeHelper->isDisplayInclDesc($store) || $this->weeeHelper->isDisplayExclDescIncl($store)) { + if ($this->weeeHelper->isEnabled($store)) { $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); foreach ($attributes as $attribute) { $displayInclTaxes = $this->taxHelper->getPriceDisplayType($store); $amount = $attribute->getData('amount'); //add display mode for WEE to not return WEE if excluded - if ($displayInclTaxes === 1) { + if ($displayInclTaxes === Config::DISPLAY_TYPE_EXCLUDING_TAX) { $amount = $attribute->getData('amount_excl_tax'); - } elseif ($displayInclTaxes === 2) { + } elseif ($displayInclTaxes === Config::DISPLAY_TYPE_INCLUDING_TAX) { $amount = $attribute->getData('amount_excl_tax') + $attribute->getData('tax_amount'); } $fptArray[] = [ @@ -84,6 +79,7 @@ public function resolve( ]; } } + return $fptArray; } } diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index 0bf303f789a7..6d868d4f960a 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -7,6 +7,7 @@ "magento/framework": "*" }, "suggest": { + "magento/module-tax": "*", "magento/module-weee": "*", "magento/module-catalog-graph-ql": "*" }, diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 4a5067125758..9e7e3e19e42b 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -3,7 +3,7 @@ enum PriceAdjustmentCodesEnum { WEEE - WEEETAX + WEEE_TAX } type ProductPrice { From fb8d6fdba2f8f509aa88050f0b037035161c5d35 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 1 Oct 2019 17:08:35 -0500 Subject: [PATCH 0770/1172] MC-20244: Pricing :: FPT calculation - add description --- app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php index be98e19cfe65..44c16a499a40 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php @@ -16,6 +16,9 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Tax\Model\Config; +/** + * Resolver for FixedProductTax object that retrieves an array of FPT attributes with prices + */ class FptResolver implements ResolverInterface { From a102fd36ebac329080697bffb488f8c127da7efa Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Tue, 1 Oct 2019 17:12:12 -0500 Subject: [PATCH 0771/1172] MC-20244: Pricing :: FPT calculation - update composer --- app/code/Magento/WeeeGraphQl/composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index 6d868d4f960a..03c3d0d91819 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -7,6 +7,7 @@ "magento/framework": "*" }, "suggest": { + "magento/module-store": "*", "magento/module-tax": "*", "magento/module-weee": "*", "magento/module-catalog-graph-ql": "*" From fc5ff1266c548e09af2e6fc3db4d2c469aecf55c Mon Sep 17 00:00:00 2001 From: Ivan Koliadynskyy <i.koliadynskyy@gmail.com> Date: Wed, 2 Oct 2019 10:26:43 +0300 Subject: [PATCH 0772/1172] Reverted change for time compression to use \Magento\Framework\Stdlib\DateTime::strToTime instead of php strtotime. Updated helpers to get token expire time to check if value is positive before response. --- app/code/Magento/Integration/Helper/Oauth/Data.php | 4 ++-- .../Magento/Webapi/Model/Authorization/TokenUserContext.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Integration/Helper/Oauth/Data.php b/app/code/Magento/Integration/Helper/Oauth/Data.php index d14bc0f9355a..93fab35c1f40 100644 --- a/app/code/Magento/Integration/Helper/Oauth/Data.php +++ b/app/code/Magento/Integration/Helper/Oauth/Data.php @@ -121,7 +121,7 @@ public function getConsumerPostTimeout() public function getCustomerTokenLifetime() { $hours = $this->_scopeConfig->getValue('oauth/access_token_lifetime/customer'); - return is_numeric($hours) ? $hours : 0; + return is_numeric($hours) && $hours > 0 ? $hours : 0; } /** @@ -132,6 +132,6 @@ public function getCustomerTokenLifetime() public function getAdminTokenLifetime() { $hours = $this->_scopeConfig->getValue('oauth/access_token_lifetime/admin'); - return is_numeric($hours) ? $hours : 0; + return is_numeric($hours) && $hours > 0 ? $hours : 0; } } diff --git a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php index 5c54c8b8660d..8dcaabda93aa 100644 --- a/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php +++ b/app/code/Magento/Webapi/Model/Authorization/TokenUserContext.php @@ -137,7 +137,7 @@ private function isTokenExpired(Token $token): bool return false; } - if (strtotime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { + if ($this->dateTime->strToTime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) { return true; } From 1c32a7141dad359c31f2c2708294b53cec5cadbd Mon Sep 17 00:00:00 2001 From: natalia <natalia_marozava@epam.com> Date: Tue, 1 Oct 2019 20:26:59 +0300 Subject: [PATCH 0773/1172] MC-18821: Increase test coverage for Catalog functional area - Fixed MC-6354 test --- .../frontend/web/js/swatch-renderer.test.js | 66 ++++++++++--------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js index f7248f71d303..bf0ff3466c52 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.test.js @@ -9,8 +9,10 @@ define([ ], function ($, SwatchRenderer) { 'use strict'; - describe('Testing SwatchRenderer Widget', function () { + describe('Testing "_RenderSwatchOptions" method of SwatchRenderer Widget', function () { var widget, + html, + optionConfig, attribute, optionId = 2, swathImageHeight = '60', @@ -22,11 +24,21 @@ define([ widget = new SwatchRenderer(); attribute = { id: 1, - options: [{id: optionId}] + options: [{ + id: optionId + }] }; widget.options = { - classes: {optionClass: "swatch-option"}, - jsonSwatchConfig: {1: {2: {type: 2}}}, + classes: { + optionClass: 'swatch-option' + }, + jsonSwatchConfig: { + 1: { + 2: { + type: 2 + } + } + }, jsonSwatchImageSizeConfig: { swatchImage: { width: swathImageWidth, @@ -38,39 +50,31 @@ define([ } } }; + optionConfig = widget.options.jsonSwatchConfig[attribute.id]; + html = $(widget._RenderSwatchOptions(attribute, 'option-label-control-id-1'))[0]; }); - describe('"_RenderSwatchOptions" method', function () { - var html, - optionConfig; - - beforeEach(function () { - optionConfig = widget.options.jsonSwatchConfig[attribute.id]; - html = $(widget._RenderSwatchOptions(attribute, 'option-label-control-id-1'))[0]; - }); - - it('check if swatch config has attribute id', function () { - expect(widget.options.jsonSwatchConfig.hasOwnProperty(attribute.id)).toEqual(true); - }); + it('check if swatch config has attribute id', function () { + expect(widget.options.jsonSwatchConfig.hasOwnProperty(attribute.id)).toEqual(true); + }); - it('check if option config has option id', function () { - expect(optionConfig.hasOwnProperty(optionId)).toEqual(true); - }); + it('check if option config has option id', function () { + expect(optionConfig.hasOwnProperty(optionId)).toEqual(true); + }); - it('check swatch thumbnail image height attribute', function () { - expect(html.hasAttribute('thumb-height')).toBe(true); - expect(html.getAttribute('thumb-height')).toEqual(swathThumbImageHeight); - }); + it('check swatch thumbnail image height attribute', function () { + expect(html.hasAttribute('thumb-height')).toBe(true); + expect(html.getAttribute('thumb-height')).toEqual(swathThumbImageHeight); + }); - it('check swatch thumbnail image width attribute', function () { - expect(html.hasAttribute('thumb-width')).toBe(true); - expect(html.getAttribute('thumb-width')).toEqual(swathThumbImageWidth); - }); + it('check swatch thumbnail image width attribute', function () { + expect(html.hasAttribute('thumb-width')).toBe(true); + expect(html.getAttribute('thumb-width')).toEqual(swathThumbImageWidth); + }); - it('check swatch image styles', function () { - expect(html.style.height).toEqual(swathImageHeight + 'px'); - expect(html.style.width).toEqual(swathImageWidth + 'px'); - }); + it('check swatch image styles', function () { + expect(html.style.height).toEqual(swathImageHeight + 'px'); + expect(html.style.width).toEqual(swathImageWidth + 'px'); }); }); }); From 033efa82980fe4ece72e272e7c6266c9f54f55c4 Mon Sep 17 00:00:00 2001 From: Max Romanov <maxromanov4669@gmail.com> Date: Wed, 2 Oct 2019 11:08:08 +0300 Subject: [PATCH 0774/1172] fix https://github.com/magento/magento2/issues/24452 --- .../view/adminhtml/templates/catalog/category/tree.phtml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml index 6b63a20134df..d6340330df8e 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/tree.phtml @@ -507,8 +507,13 @@ })(jQuery); this.closeModal(); } - }] - + }], + keyEventHandlers: { + enterKey: function (event) { + this.buttons[1].click(); + event.preventDefault(); + } + } }).trigger('openModal'); } From 9c2cd28efe3dc67348ca6bedb0f592683ba93ffd Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 2 Oct 2019 11:12:44 +0300 Subject: [PATCH 0775/1172] Adding the tracking number client validation --- .../Block/Adminhtml/Order/Tracking/View.php | 2 +- .../templates/order/tracking/view.phtml | 132 ++++++++++-------- 2 files changed, 72 insertions(+), 62 deletions(-) diff --git a/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php b/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php index 356483c9a5dd..9772ddcaeb9a 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php @@ -43,7 +43,7 @@ public function __construct( */ protected function _prepareLayout() { - $onclick = "submitAndReloadArea($('shipment_tracking_info').parentNode, '" . $this->getSubmitUrl() . "')"; + $onclick = "saveTrackingInfo($('shipment_tracking_info').parentNode, '" . $this->getSubmitUrl() . "')"; $this->addChild( 'save_button', \Magento\Backend\Block\Widget\Button::class, diff --git a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking/view.phtml b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking/view.phtml index 67587f19774c..afeecf5cdcb8 100644 --- a/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking/view.phtml +++ b/app/code/Magento/Shipping/view/adminhtml/templates/order/tracking/view.phtml @@ -9,76 +9,85 @@ ?> <?php /** @var $block Magento\Shipping\Block\Adminhtml\Order\Tracking\View */ ?> <div class="admin__control-table-wrapper"> - <table class="data-table admin__control-table" id="shipment_tracking_info"> - <thead> - <tr class="headings"> - <th class="col-carrier"><?= $block->escapeHtml(__('Carrier')) ?></th> - <th class="col-title"><?= $block->escapeHtml(__('Title')) ?></th> - <th class="col-number"><?= $block->escapeHtml(__('Number')) ?></th> - <th class="col-delete last"><?= $block->escapeHtml(__('Action')) ?></th> - </tr> - </thead> - <tfoot> - <tr> - <td class="col-carrier"> - <select name="carrier" - class="select admin__control-select" - onchange="selectCarrier(this)"> - <?php foreach ($block->getCarriers() as $_code => $_name) : ?> - <option value="<?= $block->escapeHtmlAttr($_code) ?>"><?= $block->escapeHtml($_name) ?></option> - <?php endforeach; ?> - </select> - </td> - <td class="col-title"> - <input class="input-text admin__control-text" - type="text" - id="tracking_title" - name="title" - value="" /> - </td> - <td class="col-number"> - <input class="input-text admin__control-text" - type="text" - id="tracking_number" - name="number" - value="" /> - </td> - <td class="col-delete last"><?= $block->getSaveButtonHtml() ?></td> - </tr> - </tfoot> - <?php if ($_tracks = $block->getShipment()->getAllTracks()) : ?> - <tbody> - <?php $i = 0; foreach ($_tracks as $_track) :$i++ ?> - <tr class="<?= /* @noEscape */ ($i%2 == 0) ? 'even' : 'odd' ?>"> - <td class="col-carrier"> - <?= $block->escapeHtml($block->getCarrierTitle($_track->getCarrierCode())) ?> - </td> - <td class="col-title"><?= $block->escapeHtml($_track->getTitle()) ?></td> - <td class="col-number"> - <?php if ($_track->isCustom()) : ?> - <?= $block->escapeHtml($_track->getNumber()) ?> - <?php else : ?> - <a href="#" onclick="popWin('<?= $block->escapeJs($block->escapeUrl($this->helper(Magento\Shipping\Helper\Data::class)->getTrackingPopupUrlBySalesModel($_track))) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')"><?= $block->escapeHtml($_track->getNumber()) ?></a> - <div id="shipment_tracking_info_response_<?= (int) $_track->getId() ?>"></div> - <?php endif; ?> - </td> - <td class="col-delete last"><button class="action-delete" type="button" onclick="deleteTrackingNumber('<?= $block->escapeJs($block->escapeUrl($block->getRemoveUrl($_track))) ?>'); return false;"><span><?= $block->escapeHtml(__('Delete')) ?></span></button></td> - </tr> - <?php endforeach; ?> - </tbody> - <?php endif; ?> - </table> + <form id="tracking-shipping-form" data-mage-init='{"validation": {}}'> + <table class="data-table admin__control-table" id="shipment_tracking_info"> + <thead> + <tr class="headings"> + <th class="col-carrier"><?= $block->escapeHtml(__('Carrier')) ?></th> + <th class="col-title"><?= $block->escapeHtml(__('Title')) ?></th> + <th class="col-number"><?= $block->escapeHtml(__('Number')) ?></th> + <th class="col-delete last"><?= $block->escapeHtml(__('Action')) ?></th> + </tr> + </thead> + <tfoot> + <tr> + <td class="col-carrier"> + <select name="carrier" + class="select admin__control-select" + onchange="selectCarrier(this)"> + <?php foreach ($block->getCarriers() as $_code => $_name) : ?> + <option value="<?= $block->escapeHtmlAttr($_code) ?>"><?= $block->escapeHtml($_name) ?></option> + <?php endforeach; ?> + </select> + </td> + <td class="col-title"> + <input class="input-text admin__control-text" + type="text" + id="tracking_title" + name="title" + value="" /> + </td> + <td class="col-number"> + <input class="input-text admin__control-text required-entry" + type="text" + id="tracking_number" + name="number" + value="" /> + </td> + <td class="col-delete last"><?= $block->getSaveButtonHtml() ?></td> + </tr> + </tfoot> + <?php if ($_tracks = $block->getShipment()->getAllTracks()) : ?> + <tbody> + <?php $i = 0; foreach ($_tracks as $_track) :$i++ ?> + <tr class="<?= /* @noEscape */ ($i%2 == 0) ? 'even' : 'odd' ?>"> + <td class="col-carrier"> + <?= $block->escapeHtml($block->getCarrierTitle($_track->getCarrierCode())) ?> + </td> + <td class="col-title"><?= $block->escapeHtml($_track->getTitle()) ?></td> + <td class="col-number"> + <?php if ($_track->isCustom()) : ?> + <?= $block->escapeHtml($_track->getNumber()) ?> + <?php else : ?> + <a href="#" onclick="popWin('<?= $block->escapeJs($block->escapeUrl($this->helper(Magento\Shipping\Helper\Data::class)->getTrackingPopupUrlBySalesModel($_track))) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')"><?= $block->escapeHtml($_track->getNumber()) ?></a> + <div id="shipment_tracking_info_response_<?= (int) $_track->getId() ?>"></div> + <?php endif; ?> + </td> + <td class="col-delete last"><button class="action-delete" type="button" onclick="deleteTrackingNumber('<?= $block->escapeJs($block->escapeUrl($block->getRemoveUrl($_track))) ?>'); return false;"><span><?= $block->escapeHtml(__('Delete')) ?></span></button></td> + </tr> + <?php endforeach; ?> + </tbody> + <?php endif; ?> + </table> + </form> </div> <script> -require(['prototype'], function(){ - +require(['prototype', 'jquery'], function(prototype, $j) { //<![CDATA[ function selectCarrier(elem) { var option = elem.options[elem.selectedIndex]; $('tracking_title').value = option.value && option.value != 'custom' ? option.text : ''; } +function saveTrackingInfo(node, url) { + var form = $j('#tracking-shipping-form'); + + if (form.validation() && form.validation('isValid')) { + submitAndReloadArea(node, url); + } +} + function deleteTrackingNumber(url) { if (confirm('<?= $block->escapeJs($block->escapeHtml(__('Are you sure?'))) ?>')) { submitAndReloadArea($('shipment_tracking_info').parentNode, url) @@ -87,6 +96,7 @@ function deleteTrackingNumber(url) { window.selectCarrier = selectCarrier; window.deleteTrackingNumber = deleteTrackingNumber; +window.saveTrackingInfo = saveTrackingInfo; //]]> }); From c381ae817a62bad16f32c07ed5e098bb4a8c4ae7 Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Wed, 2 Oct 2019 13:16:32 +0300 Subject: [PATCH 0776/1172] Cover changes with mftf tests --- ...ryAndLeavingRegionSelectUnselectedTest.xml | 44 +++++++++++++++++++ ...kEditDefaultShippingAddressActionGroup.xml | 19 ++++++++ 2 files changed, 63 insertions(+) create mode 100644 app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRegionUpdatesAfterChangingCountryAndLeavingRegionSelectUnselectedTest.xml create mode 100644 app/code/Magento/Customer/Test/Mftf/ActionGroup/StoreFrontClickEditDefaultShippingAddressActionGroup.xml diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRegionUpdatesAfterChangingCountryAndLeavingRegionSelectUnselectedTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRegionUpdatesAfterChangingCountryAndLeavingRegionSelectUnselectedTest.xml new file mode 100644 index 000000000000..44bfe81b40dc --- /dev/null +++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontRegionUpdatesAfterChangingCountryAndLeavingRegionSelectUnselectedTest.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="StorefrontRegionUpdatesAfterChangingCountryAndLeavingRegionSelectUnselectedTest"> + <annotations> + <features value="Checkout"/> + <stories value="Region updates after changing country "/> + <title value="Region updates after changing country "/> + <description value="Region dupdates after changing country and leaving region select unselected"/> + <severity value="CRITICAL"/> + <testCaseId value="https://github.com/magento/magento2/issues/23460"/> + <group value="checkout"/> + </annotations> + <before> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + </before> + <after> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + </after> + + <!-- Login to storefront from customer --> + <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginCustomer"> + <argument name="Customer" value="$$createCustomer$$"/> + </actionGroup> + + <actionGroup ref="StorefrontOpenMyAccountPageActionGroup" stepKey="goToMyAccountPage"/> + + <actionGroup ref="StorefrontCustomerGoToSidebarMenu" stepKey="goToAddressBookPage"> + <argument name="menu" value="Address Book"/> + </actionGroup> + <actionGroup ref="StoreFrontClickEditDefaultShippingAddressActionGroup" stepKey="clickEditAddress"/> + <selectOption selector="{{StorefrontCustomerAddressFormSection.country}}" userInput="{{updateCustomerFranceAddress.country}}" stepKey="selectCountry"/> + <actionGroup ref="AdminSaveCustomerAddressActionGroup" stepKey="saveAddress"/> + + <see selector="{{StorefrontCustomerAddressesSection.defaultShippingAddress}}" userInput="{{updateCustomerFranceAddress.country}}" stepKey="seeAssertCustomerDefaultShippingAddressCountry"/> + </test> +</tests> diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/StoreFrontClickEditDefaultShippingAddressActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StoreFrontClickEditDefaultShippingAddressActionGroup.xml new file mode 100644 index 000000000000..36c62a887c18 --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/StoreFrontClickEditDefaultShippingAddressActionGroup.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> + <!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + --> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> +<actionGroup name="StoreFrontClickEditDefaultShippingAddressActionGroup"> + <annotations> + <description>Click on the edit default shipping address link.</description> + </annotations> + + <click stepKey="ClickEditDefaultShippingAddress" selector="{{StorefrontCustomerAddressesSection.editDefaultShippingAddress}}"/> + <waitForPageLoad stepKey="waitForStorefrontSignInPageLoad"/> +</actionGroup> +</actionGroups> From a6984616d135603f6f6c8cb52f6082630450f115 Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 2 Oct 2019 13:33:49 +0400 Subject: [PATCH 0777/1172] MAGETWO-67450: The rate in order is duplicated - Updated automated test script --- .../Test/Mftf/Data/CurrencyRatesConfigData.xml | 12 ++++++------ ...teDisplayWhenChooseThreeAllowedCurrenciesTest.xml | 2 +- .../Test/AdminOrderRateDisplayedInOneLineTest.xml | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml index b7b6bc8690bd..6194287dd058 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Data/CurrencyRatesConfigData.xml @@ -20,21 +20,21 @@ <data key="scope">websites</data> <data key="scope_code">base</data> </entity> - <entity name="SetAllowedCurrenciesConfigForThree"> + <entity name="SetAllowedCurrenciesConfigForUSD"> <data key="path">currency/options/allow</data> - <data key="value">EUR,USD,RUB</data> + <data key="value">USD</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> - <entity name="SetAllowedCurrenciesConfigForTwo"> + <entity name="SetAllowedCurrenciesConfigForEUR"> <data key="path">currency/options/allow</data> - <data key="value">EUR,USD</data> + <data key="value">EUR</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> - <entity name="SetAllowedCurrenciesConfigForOne"> + <entity name="SetAllowedCurrenciesConfigForRUB"> <data key="path">currency/options/allow</data> - <data key="value">USD</data> + <data key="value">RUB</data> <data key="scope">websites</data> <data key="scope_code">base</data> </entity> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml index fb71777b086d..26fbfd394be6 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayWhenChooseThreeAllowedCurrenciesTest.xml @@ -25,7 +25,7 @@ <createData entity="SimpleProduct2" stepKey="createNewProduct"/> <!--Set Currency options for Website--> <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSDWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForThree.scope}} --scope-code={{SetAllowedCurrenciesConfigForThree.scope_code}} {{SetAllowedCurrenciesConfigForThree.path}} {{SetAllowedCurrenciesConfigForThree.value}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForUSD.scope}} --scope-code={{SetAllowedCurrenciesConfigForUSD.scope_code}} {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}},{{SetAllowedCurrenciesConfigForEUR.value}},{{SetAllowedCurrenciesConfigForRUB.value}}" stepKey="setAllowedCurrencyWebsitesEURandRUBandUSD"/> <magentoCLI command="config:set --scope={{SetDefaultCurrencyEURConfig.scope}} --scope-code={{SetDefaultCurrencyEURConfig.scope_code}} {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> diff --git a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml index 514d4c5d54f8..dc6bdf3db542 100644 --- a/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml +++ b/app/code/Magento/CurrencySymbol/Test/Mftf/Test/AdminOrderRateDisplayedInOneLineTest.xml @@ -27,11 +27,11 @@ <magentoCLI command="config:set {{CatalogPriceScopeWebsiteConfigData.path}} {{CatalogPriceScopeWebsiteConfigData.value}}" stepKey="setCatalogPriceScopeWebsite"/> <!--Set Currency options for Default Config--> <magentoCLI command="config:set {{SetCurrencyEURBaseConfig.path}} {{SetCurrencyEURBaseConfig.value}}" stepKey="setCurrencyBaseEUR"/> - <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForTwo.path}} {{SetAllowedCurrenciesConfigForTwo.value}}" stepKey="setAllowedCurrencyEUR"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}},{{SetAllowedCurrenciesConfigForEUR.value}}" stepKey="setAllowedCurrencyEURandUSD"/> <magentoCLI command="config:set {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEUR"/> <!--Set Currency options for Website--> <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseEURWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForTwo.scope}} --scope-code={{SetAllowedCurrenciesConfigForTwo.scope_code}} {{SetAllowedCurrenciesConfigForTwo.path}} {{SetAllowedCurrenciesConfigForTwo.value}}" stepKey="setAllowedCurrencyWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForUSD.scope}} --scope-code={{SetAllowedCurrenciesConfigForUSD.scope_code}} {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}},{{SetAllowedCurrenciesConfigForEUR.value}}" stepKey="setAllowedCurrencyWebsitesForEURandUSD"/> <magentoCLI command="config:set --scope={{SetDefaultCurrencyEURConfig.scope}} --scope-code={{SetDefaultCurrencyEURConfig.scope_code}} {{SetDefaultCurrencyEURConfig.path}} {{SetDefaultCurrencyEURConfig.value}}" stepKey="setCurrencyDefaultEURWebsites"/> </before> <after> @@ -41,11 +41,11 @@ <magentoCLI command="config:set {{CatalogPriceScopeGlobalConfigData.path}} {{CatalogPriceScopeGlobalConfigData.value}}" stepKey="setCatalogPriceScopeGlobal"/> <magentoCLI command="config:set {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSD"/> <magentoCLI command="config:set {{SetDefaultCurrencyUSDConfig.path}} {{SetDefaultCurrencyUSDConfig.value}}" stepKey="setCurrencyDefaultUSD"/> - <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForOne.path}} {{SetAllowedCurrenciesConfigForOne.value}}" stepKey="setAllowedCurrencyUSD"/> + <magentoCLI command="config:set {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}}" stepKey="setAllowedCurrencyUSD"/> <!--Set Currency options for Website--> <magentoCLI command="config:set --scope={{SetCurrencyUSDBaseConfig.scope}} --scope-code={{SetCurrencyUSDBaseConfig.scope_code}} {{SetCurrencyUSDBaseConfig.path}} {{SetCurrencyUSDBaseConfig.value}}" stepKey="setCurrencyBaseUSDWebsites"/> <magentoCLI command="config:set --scope={{SetDefaultCurrencyUSDConfig.scope}} --scope-code={{SetDefaultCurrencyUSDConfig.scope_code}} {{SetDefaultCurrencyUSDConfig.path}} {{SetDefaultCurrencyUSDConfig.value}}" stepKey="setCurrencyDefaultUSDWebsites"/> - <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForOne.scope}} --scope-code={{SetAllowedCurrenciesConfigForOne.scope_code}} {{SetAllowedCurrenciesConfigForOne.path}} {{SetAllowedCurrenciesConfigForOne.value}}" stepKey="setAllowedCurrencyUSDWebsites"/> + <magentoCLI command="config:set --scope={{SetAllowedCurrenciesConfigForUSD.scope}} --scope-code={{SetAllowedCurrenciesConfigForUSD.scope_code}} {{SetAllowedCurrenciesConfigForUSD.path}} {{SetAllowedCurrenciesConfigForUSD.value}}" stepKey="setAllowedCurrencyUSDWebsites"/> <actionGroup ref="logout" stepKey="logout"/> </after> <!--Open created product on Storefront and place for order--> From 9598e577c0f5091390fd72e14dccdc3bada0792d Mon Sep 17 00:00:00 2001 From: Nazarn96 <nazarn96@gmail.com> Date: Wed, 2 Oct 2019 14:19:39 +0300 Subject: [PATCH 0778/1172] Static test fix. --- .../TestFramework/TestCase/WebapiAbstract.php | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php index eecca0a396a0..6400a61b3ef3 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php @@ -103,9 +103,11 @@ abstract class WebapiAbstract extends \PHPUnit\Framework\TestCase /** * Initialize fixture namespaces. + * //phpcs:disable */ public static function setUpBeforeClass() { + //phpcs:enable parent::setUpBeforeClass(); self::_setFixtureNamespace(); } @@ -114,9 +116,11 @@ public static function setUpBeforeClass() * Run garbage collector for cleaning memory * * @return void + * //phpcs:disable */ public static function tearDownAfterClass() { + //phpcs:enable //clear garbage in memory gc_collect_cycles(); @@ -134,8 +138,7 @@ public static function tearDownAfterClass() } /** - * Call safe delete for models which added to delete list - * Restore config values changed during the test + * Call safe delete for models which added to delete list, Restore config values changed during the test * * @return void */ @@ -179,6 +182,8 @@ protected function _webApiCall( /** * Mark test to be executed for SOAP adapter only. + * + * @param ?string $message */ protected function _markTestAsSoapOnly($message = null) { @@ -189,6 +194,8 @@ protected function _markTestAsSoapOnly($message = null) /** * Mark test to be executed for REST adapter only. + * + * @param ?string $message */ protected function _markTestAsRestOnly($message = null) { @@ -204,9 +211,11 @@ protected function _markTestAsRestOnly($message = null) * @param mixed $fixture * @param int $tearDown * @return void + * //phpcs:disable */ public static function setFixture($key, $fixture, $tearDown = self::AUTO_TEAR_DOWN_AFTER_METHOD) { + //phpcs:enable $fixturesNamespace = self::_getFixtureNamespace(); if (!isset(self::$_fixtures[$fixturesNamespace])) { self::$_fixtures[$fixturesNamespace] = []; @@ -232,9 +241,11 @@ public static function setFixture($key, $fixture, $tearDown = self::AUTO_TEAR_DO * * @param string $key * @return mixed + * //phpcs:disable */ public static function getFixture($key) { + //phpcs:enable $fixturesNamespace = self::_getFixtureNamespace(); if (array_key_exists($key, self::$_fixtures[$fixturesNamespace])) { return self::$_fixtures[$fixturesNamespace][$key]; @@ -248,9 +259,11 @@ public static function getFixture($key) * @param \Magento\Framework\Model\AbstractModel $model * @param bool $secure * @return \Magento\TestFramework\TestCase\WebapiAbstract + * //phpcs:disable */ public static function callModelDelete($model, $secure = false) { + //phpcs:enable if ($model instanceof \Magento\Framework\Model\AbstractModel && $model->getId()) { if ($secure) { self::_enableSecureArea(); @@ -301,9 +314,11 @@ protected function _getWebApiAdapter($webApiAdapterCode) * Set fixtures namespace * * @throws \RuntimeException + * //phpcs:disable */ protected static function _setFixtureNamespace() { + //phpcs:enable if (self::$_fixturesNamespace !== null) { throw new \RuntimeException('Fixture namespace is already set.'); } @@ -312,9 +327,11 @@ protected static function _setFixtureNamespace() /** * Unset fixtures namespace + * //phpcs:disable */ protected static function _unsetFixtureNamespace() { + //phpcs:enable $fixturesNamespace = self::_getFixtureNamespace(); unset(self::$_fixtures[$fixturesNamespace]); self::$_fixturesNamespace = null; @@ -325,9 +342,12 @@ protected static function _unsetFixtureNamespace() * * @throws \RuntimeException * @return string + * //phpcs:disable */ protected static function _getFixtureNamespace() { + //phpcs:enable + $fixtureNamespace = self::$_fixturesNamespace; if ($fixtureNamespace === null) { throw new \RuntimeException('Fixture namespace must be set.'); @@ -340,9 +360,12 @@ protected static function _getFixtureNamespace() * * @param bool $flag * @return void + * //phpcs:disable */ protected static function _enableSecureArea($flag = true) { + //phpcs:enable + /** @var $objectManager \Magento\TestFramework\ObjectManager */ $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -389,9 +412,11 @@ protected function _assertMessagesEqual($expectedMessages, $receivedMessages) * Delete array of fixtures * * @param array $fixtures + * //phpcs:disable */ protected static function _deleteFixtures($fixtures) { + //phpcs:enable foreach ($fixtures as $fixture) { self::deleteFixture($fixture, true); } @@ -403,9 +428,11 @@ protected static function _deleteFixtures($fixtures) * @param string $key * @param bool $secure * @return void + * //phpcs:disable */ public static function deleteFixture($key, $secure = false) { + //phpcs:enable $fixturesNamespace = self::_getFixtureNamespace(); if (array_key_exists($key, self::$_fixtures[$fixturesNamespace])) { self::callModelDelete(self::$_fixtures[$fixturesNamespace][$key], $secure); @@ -457,11 +484,11 @@ protected function _cleanAppConfigCache() /** * Update application config data * - * @param string $path Config path with the form "section/group/node" - * @param string|int|null $value Value of config item - * @param bool $cleanAppCache If TRUE application cache will be refreshed - * @param bool $updateLocalConfig If TRUE local config object will be updated too - * @param bool $restore If TRUE config value will be restored after test run + * @param string $path Config path with the form "section/group/node" + * @param string|int|null $value Value of config item + * @param bool $cleanAppCache If TRUE application cache will be refreshed + * @param bool $updateLocalConfig If TRUE local config object will be updated too + * @param bool $restore If TRUE config value will be restored after test run * @return \Magento\TestFramework\TestCase\WebapiAbstract * @throws \RuntimeException */ @@ -521,6 +548,8 @@ protected function _restoreAppConfig() } /** + * Process rest exception result. + * * @param \Exception $e * @return array * <pre> ex. @@ -667,6 +696,8 @@ protected function _checkWrappedErrors($expectedWrappedErrors, $errorDetails) } /** + * Get actual wrapped errors. + * * @param \stdClass $errorNode * @return array */ @@ -695,6 +726,8 @@ private function getActualWrappedErrors(\stdClass $errorNode) } /** + * Assert webapi errors. + * * @param array $serviceInfo * @param array $data * @param array $expectedErrorData From cb53e902a28e00f1f78fb443ac5cd4b220699878 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 2 Oct 2019 14:40:37 +0300 Subject: [PATCH 0779/1172] Fixing static tests --- .../Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php b/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php index 9772ddcaeb9a..55eecfa00d6d 100644 --- a/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php +++ b/app/code/Magento/Shipping/Block/Adminhtml/Order/Tracking/View.php @@ -86,7 +86,10 @@ public function getRemoveUrl($track) } /** + * Get carrier title + * * @param string $code + * * @return \Magento\Framework\Phrase|string|bool */ public function getCarrierTitle($code) From 735177a8c3feb9d8534a14115d7a1f2a7e0a6e56 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Wed, 2 Oct 2019 15:34:19 +0300 Subject: [PATCH 0780/1172] MC-18821: Increase test coverage for Catalog functional area - Revert duplicating of automation test for MC-13641 --- .../Suite/MagentoDeveloperModeTestSuite.xml | 20 ---- ...TabForSwatchProductAtributeActionGroup.xml | 8 -- .../Mftf/Section/AdminManageSwatchSection.xml | 1 - ...fProductWithCustomProductAttributeTest.xml | 92 ------------------- 4 files changed, 121 deletions(-) delete mode 100644 app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml delete mode 100644 app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml diff --git a/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml b/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml deleted file mode 100644 index 76dd6995c751..000000000000 --- a/app/code/Magento/Deploy/Test/Mftf/Suite/MagentoDeveloperModeTestSuite.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Suite/etc/suiteSchema.xsd"> - <suite name="MagentoDeveloperModeTestSuite"> - <before> - <magentoCLI command="deploy:mode:set developer" stepKey="enableDeveloperMode"/> - </before> - <after> - <magentoCLI command="deploy:mode:set production" stepKey="enableProductionMode"/> - </after> - <include> - <group name="developer_mode_only"/> - </include> - </suite> -</suites> diff --git a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml index 879487d93a65..05ab5a53468a 100644 --- a/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml +++ b/app/code/Magento/Swatches/Test/Mftf/ActionGroup/AdminEditPropertiesTabForSwatchProductAtributeActionGroup.xml @@ -20,14 +20,6 @@ <fillField selector="{{AdminNewAttributePanel.lastVisualSwatchOptionAdminValue}}" userInput="{{swatchOption.admin_label}}" stepKey="fillAdminLabel"/> <fillField selector="{{AdminNewAttributePanel.lastVisualSwatchOptionDefaultStoreValue}}" userInput="{{swatchOption.default_label}}" stepKey="fillDefaultStoreLabel"/> </actionGroup> - <actionGroup name="AdminAddPreviewImageSwatchOption"> - <arguments> - <argument name="image" type="entity" defaultValue="MagentoLogo"/> - <argument name="index" type="string" defaultValue="1"/> - </arguments> - <click selector="{{AdminManageSwatchSection.nthUploadFile(index)}}" stepKey="clickUploadFile"/> - <attachFile selector="{{AdminManageSwatchSection.file}}" userInput="{{image.file}}" stepKey="attachFile"/> - </actionGroup> <!--You are on ProductAttributePage--> <!--Select value for option "Update Product Preview Image"--> diff --git a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml index 899a032488c5..c3ef0a7324bf 100644 --- a/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml +++ b/app/code/Magento/Swatches/Test/Mftf/Section/AdminManageSwatchSection.xml @@ -21,7 +21,6 @@ <element name="swatchAdminDescriptionByIndex" type="input" selector="input[name='optiontext[value][option_{{index}}][0]']" parameterized="true"/> <element name="nthChooseColor" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.colorpicker_handler" parameterized="true"/> <element name="nthUploadFile" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) .swatch_row_name.btn_choose_file_upload" parameterized="true"/> - <element name="file" type="input" selector="input[name='datafile']"/> <element name="nthDelete" type="button" selector="#swatch-visual-options-panel table tbody tr:nth-of-type({{var}}) button.delete-option" parameterized="true"/> <element name="deleteBtn" type="button" selector="#manage-options-panel:nth-of-type({{var}}) button.delete-option" parameterized="true"/> </section> diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml deleted file mode 100644 index b91acdf5d723..000000000000 --- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminSaveConfProductWithCustomProductAttributeTest.xml +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - /** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ ---> - -<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> - <test name="AdminSaveConfProductWithCustomProductAttributeTest"> - <annotations> - <features value="Swatches"/> - <stories value="Configurable product with swatch attribute"/> - <title value="Saving configurable product with custom product attribute (images as swatches)"/> - <description value="Saving configurable product with custom product attribute (images as swatches)"/> - <severity value="CRITICAL"/> - <testCaseId value="MC-13641"/> - <useCaseId value="MC-10968"/> - <group value="developer_mode_only"/> - <group value="Swatches"/> - </annotations> - <before> - <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <!--Create configurable product--> - <createData entity="SimpleSubCategory" stepKey="createCategory"/> - <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> - <requiredEntity createDataKey="createCategory"/> - </createData> - </before> - <after> - <!--Delete created data--> - <deleteData createDataKey="createConfigProduct" stepKey="deleteProduct"/> - <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> - <actionGroup ref="AdminOpenProductIndexPageActionGroup" stepKey="navigateToProductIndexPage"/> - <actionGroup ref="deleteProductsIfTheyExist" stepKey="deleteAllProducts"/> - <actionGroup ref="deleteProductAttribute" stepKey="deleteAttribute"> - <argument name="ProductAttribute" value="VisualSwatchProductAttribute"/> - </actionGroup> - <actionGroup ref="logout" stepKey="logout"/> - </after> - <!--Create Visual swatch with preview image--> - <amOnPage url="{{ProductAttributePage.url}}" stepKey="goToNewProductAttributePage"/> - <actionGroup ref="AdminFillProductAttributePropertiesActionGroup" stepKey="fillProductAttributeProperties"> - <argument name="attributeName" value="{{VisualSwatchProductAttribute.attribute_code}}"/> - <argument name="attributeType" value="{{VisualSwatchProductAttribute.frontend_input}}"/> - </actionGroup> - <!--Add first option--> - <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addFirstSwatchOptionAndFillFields"> - <argument name="swatchOption" value="visualSwatchOption1"/> - </actionGroup> - <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSFirstSwatch"> - <argument name="index" value="0"/> - </actionGroup> - <actionGroup ref="AdminAddPreviewImageSwatchOption" stepKey="addFirstOptionImage"> - <argument name="image" value="MagentoLogo"/> - <argument name="index" value="1"/> - </actionGroup> - <!--Add second option--> - <actionGroup ref="AdminAddSwatchOptionAndFillFieldsActionGroup" stepKey="addSecondSwatchOptionAndFillFields"> - <argument name="swatchOption" value="visualSwatchOption2"/> - </actionGroup> - <actionGroup ref="openSwatchMenuByIndex" stepKey="clickSecondSwatch"> - <argument name="index" value="1"/> - </actionGroup> - <actionGroup ref="AdminAddPreviewImageSwatchOption" stepKey="addSecondOptionImage"> - <argument name="image" value="MagentoLogo"/> - <argument name="index" value="2"/> - </actionGroup> - <actionGroup ref="AdminSwitchScopeForProductAttributeActionGroup" stepKey="switchScopeForProductAttribute"/> - <actionGroup ref="ClickSaveButtonActionGroup" stepKey="clickSaveAttribute"> - <argument name="message" value="You saved the product attribute."/> - </actionGroup> - <!--Create configurations for product--> - <amOnPage url="{{AdminProductEditPage.url($$createConfigProduct.id$$)}}" stepKey="goToProductEditPage"/> - <waitForPageLoad stepKey="waitForProductPageLoad"/> - <actionGroup ref="StartCreateConfigurationsForAttribute" stepKey="createConfigurations"> - <argument name="attributeCode" value="{{VisualSwatchProductAttribute.attribute_code}}"/> - </actionGroup> - <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionOne"> - <argument name="image" value="TestImageAdobe"/> - <argument name="frontend_label" value="{{VisualSwatchProductAttribute.attribute_code}}"/> - <argument name="label" value="{{visualSwatchOption1.default_label}}"/> - </actionGroup> - <actionGroup ref="addUniqueImageToConfigurableProductOption" stepKey="addImageToConfigurableProductOptionTwo"> - <argument name="image" value="ImageUpload3"/> - <argument name="frontend_label" value="{{VisualSwatchProductAttribute.attribute_code}}"/> - <argument name="label" value="{{visualSwatchOption2.default_label}}"/> - </actionGroup> - <actionGroup ref="GenerateAndSaveConfiguredProductAfterSettingOptions" stepKey="saveProductForm"/> - </test> -</tests> From f3bba70b003decd6e9ec5d635e47d81554c5c627 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Wed, 2 Oct 2019 16:13:50 +0300 Subject: [PATCH 0781/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Fix annotation for unit test that was created for the ticket MC-6387. --- .../Authorizenet/Test/Unit/Model/DirectpostTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php index 50cf7e86e8fc..a1547a056346 100644 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php +++ b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); namespace Magento\Authorizenet\Test\Unit\Model; @@ -306,7 +307,9 @@ public function dataProviderCaptureWithInvalidAmount() } /** - * @@expectedException \Magento\Framework\Exception\LocalizedException + * Test capture has parent transaction id. + * + * @expectedException \Magento\Framework\Exception\LocalizedException */ public function testCaptureHasParentTransactionId() { @@ -550,13 +553,10 @@ public function checkResponseCodeSuccessDataProvider() /** * Checks response failures behaviour. * - * @param int $responseCode - * @param int $failuresHandlerCalls * @return void - * * @expectedException \Magento\Framework\Exception\LocalizedException */ - public function testCheckResponseCodeFailureDefault(): void + public function testCheckResponseCodeFailureDefault() { $responseCode = 999999; $this->responseMock->expects($this->once())->method('getXResponseCode')->willReturn($responseCode); From d3be7818f589193d5350d4c9d4e03453ffbdf4ab Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Wed, 2 Oct 2019 17:35:06 +0400 Subject: [PATCH 0782/1172] MC-18215: Error message while creating shipping label - Updated automated test script --- .../Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml | 0 .../Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml | 2 +- .../Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename app/code/Magento/{Backend => Customer}/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml (100%) diff --git a/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml similarity index 100% rename from app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml rename to app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml diff --git a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml index e50d484df27c..91a76383babd 100644 --- a/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml +++ b/app/code/Magento/Fedex/Test/Mftf/Test/AdminCreatingShippingLabelTest.xml @@ -114,7 +114,7 @@ <actionGroup ref="goToShipmentIntoOrder" stepKey="goToShipmentIntoOrder"/> <checkOption selector="{{AdminShipmentTotalSection.createShippingLabel}}" stepKey="checkCreateShippingLabel"/> <click selector="{{AdminShipmentMainActionsSection.submitShipment}}" stepKey="clickSubmitShipment"/> - <actionGroup ref="AdminShipmentCreatePackageActionGroup" stepKey="createPackage"> + <actionGroup ref="AdminShipmentCreateShippingLabelActionGroup" stepKey="createPackage"> <argument name="productName" value="$$createProduct.name$$"/> </actionGroup> <actionGroup ref="AdminGoToShipmentTabActionGroup" stepKey="goToShipmentTab"/> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml index d160f95e2a9c..631db885ab3d 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminShipmentActionGroup.xml @@ -62,7 +62,7 @@ <seeInCurrentUrl url="{{AdminOrderDetailsPage.url}}" stepKey="seeViewOrderPageShipping"/> <see selector="{{AdminOrderDetailsMessagesSection.successMessage}}" userInput="The shipment has been created." stepKey="seeShipmentCreateSuccess"/> </actionGroup> - <actionGroup name="AdminShipmentCreatePackageActionGroup"> + <actionGroup name="AdminShipmentCreateShippingLabelActionGroup"> <arguments> <argument name="productName" type="string" defaultValue="{{SimpleProduct.name}}"/> </arguments> From 7c5e7178abdb799062b67230589e4b7c70f8213c Mon Sep 17 00:00:00 2001 From: Max Souza <max@trezo.com.br> Date: Wed, 2 Oct 2019 10:49:48 -0300 Subject: [PATCH 0783/1172] Fix url for back button on multishipping new shipping address --- .../Multishipping/Controller/Checkout/Address/NewShipping.php | 2 +- .../Test/Unit/Controller/Checkout/Address/NewShippingTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php index c86caec733a1..c656b3af1447 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php @@ -35,7 +35,7 @@ public function execute() if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) { $addressForm->setBackUrl($this->_url->getUrl('*/checkout/addresses')); } else { - $addressForm->setBackUrl($this->_url->getUrl('*/cart/')); + $addressForm->setBackUrl($this->_url->getUrl('checkout/cart/')); } } $this->_view->renderLayout(); diff --git a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/Address/NewShippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/Address/NewShippingTest.php index 9ffef2832a6b..42715d026e9e 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/Address/NewShippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/Address/NewShippingTest.php @@ -170,7 +170,7 @@ public function executeDataProvider() { return [ 'shipping_address_exists' => ['*/checkout/addresses', 'shipping_address', 'back/address'], - 'shipping_address_not_exist' => ['*/cart/', null, 'back/cart'] + 'shipping_address_not_exist' => ['checkout/cart/', null, 'back/cart'] ]; } From d0687d1d68dee57f217495be062e8603b7ed0a59 Mon Sep 17 00:00:00 2001 From: Andrey Legayev <andrey@ven.com> Date: Wed, 2 Oct 2019 17:10:51 +0300 Subject: [PATCH 0784/1172] Static Content Deploy - Sort JS Translations to have them in the same order on every build We've faced an issue on BitBucket Pipelines: every build had own unique order of JS translations. We couldn't see the real diff between builds because of it. Simple alphabetical sorting of translations resolves this issue. --- app/code/Magento/Translation/Model/Js/DataProvider.php | 2 ++ .../Translation/Test/Unit/Model/Js/DataProviderTest.php | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Translation/Model/Js/DataProvider.php b/app/code/Magento/Translation/Model/Js/DataProvider.php index 7aad7c765bcd..ae388239bc53 100644 --- a/app/code/Magento/Translation/Model/Js/DataProvider.php +++ b/app/code/Magento/Translation/Model/Js/DataProvider.php @@ -120,6 +120,8 @@ public function getData($themePath) } } + ksort($dictionary); + return $dictionary; } diff --git a/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php b/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php index 021709bdda1f..3ebbaf3f6721 100644 --- a/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php +++ b/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php @@ -90,7 +90,7 @@ public function testGetData() $themePath = 'blank'; $areaCode = 'adminhtml'; - $filePaths = [['path1'], ['path2'], ['path3'], ['path4']]; + $filePaths = [['path1'], ['path2'], ['path4'], ['path3']]; $jsFilesMap = [ ['base', $themePath, '*', '*', [$filePaths[0]]], @@ -111,8 +111,8 @@ public function testGetData() $contentsMap = [ 'content1$.mage.__("hello1")content1', 'content2$.mage.__("hello2")content2', + 'content2$.mage.__("hello4")content4', // this value should be last after running data provider 'content2$.mage.__("hello3")content3', - 'content2$.mage.__("hello4")content4' ]; $translateMap = [ @@ -147,7 +147,10 @@ public function testGetData() ->method('render') ->willReturnMap($translateMap); - $this->assertEquals($expectedResult, $this->model->getData($themePath)); + $actualResult = $this->model->getData($themePath); + $this->assertEquals($expectedResult, $actualResult); + $this->assertEquals(json_encode($expectedResult), json_encode($actualResult), + "Translations should be sorted by key"); } /** From b52dc0cf8ae48ce91fbd6d9da2f9a45aa4c5961a Mon Sep 17 00:00:00 2001 From: Andrey Legayev <andrey@ven.com> Date: Wed, 2 Oct 2019 17:41:34 +0300 Subject: [PATCH 0785/1172] Fix code style --- .../Translation/Test/Unit/Model/Js/DataProviderTest.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php b/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php index 3ebbaf3f6721..b5bfbbc29a60 100644 --- a/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php +++ b/app/code/Magento/Translation/Test/Unit/Model/Js/DataProviderTest.php @@ -149,8 +149,11 @@ public function testGetData() $actualResult = $this->model->getData($themePath); $this->assertEquals($expectedResult, $actualResult); - $this->assertEquals(json_encode($expectedResult), json_encode($actualResult), - "Translations should be sorted by key"); + $this->assertEquals( + json_encode($expectedResult), + json_encode($actualResult), + "Translations should be sorted by key" + ); } /** From 224fa3d53dfed3d1e0181bd35394e7a6afd4ba16 Mon Sep 17 00:00:00 2001 From: eduard13 <e.chitoraga@atwix.com> Date: Wed, 2 Oct 2019 17:45:56 +0300 Subject: [PATCH 0786/1172] Covering the CaptchaValidator by Unit Tests --- .../Test/Unit/Model/CaptchaValidatorTest.php | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 app/code/Magento/SendFriend/Test/Unit/Model/CaptchaValidatorTest.php diff --git a/app/code/Magento/SendFriend/Test/Unit/Model/CaptchaValidatorTest.php b/app/code/Magento/SendFriend/Test/Unit/Model/CaptchaValidatorTest.php new file mode 100644 index 000000000000..22377897e564 --- /dev/null +++ b/app/code/Magento/SendFriend/Test/Unit/Model/CaptchaValidatorTest.php @@ -0,0 +1,161 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +declare(strict_types=1); + +namespace Magento\SendFriend\Test\Unit\Model; + +use Magento\Authorization\Model\UserContextInterface; +use Magento\Captcha\Helper\Data; +use Magento\Captcha\Model\DefaultModel; +use Magento\Captcha\Observer\CaptchaStringResolver; +use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Framework\App\RequestInterface; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\SendFriend\Model\CaptchaValidator; +use PHPUnit\Framework\TestCase; +use PHPUnit_Framework_MockObject_MockObject; + +/** + * Test CaptchaValidatorTest + */ +class CaptchaValidatorTest extends TestCase +{ + const FORM_ID = 'product_sendtofriend_form'; + + /** + * @var CaptchaValidator + */ + private $model; + + /** + * @var CaptchaStringResolver|PHPUnit_Framework_MockObject_MockObject + */ + private $captchaStringResolverMock; + + /** + * @var UserContextInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $currentUserMock; + + /** + * @var CustomerRepositoryInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $customerRepositoryMock; + + /** + * @var Data|PHPUnit_Framework_MockObject_MockObject + */ + private $captchaHelperMock; + + /** + * @var DefaultModel|PHPUnit_Framework_MockObject_MockObject + */ + private $captchaMock; + + /** + * @var RequestInterface|PHPUnit_Framework_MockObject_MockObject + */ + private $requestMock; + + /** + * Set Up + */ + protected function setUp() + { + $objectManager = new ObjectManager($this); + + $this->captchaHelperMock = $this->createMock(Data::class); + $this->captchaStringResolverMock = $this->createMock(CaptchaStringResolver::class); + $this->currentUserMock = $this->getMockBuilder(UserContextInterface::class) + ->getMockForAbstractClass(); + $this->customerRepositoryMock = $this->createMock(CustomerRepositoryInterface::class); + $this->captchaMock = $this->createMock(DefaultModel::class); + $this->requestMock = $this->getMockBuilder(RequestInterface::class)->getMock(); + + $this->model = $objectManager->getObject( + CaptchaValidator::class, + [ + 'captchaHelper' => $this->captchaHelperMock, + 'captchaStringResolver' => $this->captchaStringResolverMock, + 'currentUser' => $this->currentUserMock, + 'customerRepository' => $this->customerRepositoryMock, + ] + ); + } + + /** + * Testing the captcha validation before sending the email + * + * @dataProvider captchaProvider + * + * @param bool $captchaIsRequired + * @param bool $captchaWordIsValid + * + * @throws LocalizedException + * @throws NoSuchEntityException + */ + public function testCaptchaValidationOnSend(bool $captchaIsRequired, bool $captchaWordIsValid) + { + $word = 'test-word'; + $this->captchaHelperMock->expects($this->once())->method('getCaptcha')->with(static::FORM_ID) + ->will($this->returnValue($this->captchaMock)); + $this->captchaMock->expects($this->once())->method('isRequired') + ->will($this->returnValue($captchaIsRequired)); + + if ($captchaIsRequired) { + $this->captchaStringResolverMock->expects($this->once())->method('resolve') + ->with($this->requestMock, static::FORM_ID)->will($this->returnValue($word)); + $this->captchaMock->expects($this->once())->method('isCorrect')->with($word) + ->will($this->returnValue($captchaWordIsValid)); + } + + $this->model->validateSending($this->requestMock); + } + + /** + * Testing the wrong used word for captcha + * + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Incorrect CAPTCHA + */ + public function testWrongCaptcha() + { + $word = 'test-word'; + $captchaIsRequired = true; + $captchaWordIsCorrect = false; + $this->captchaHelperMock->expects($this->once())->method('getCaptcha')->with(static::FORM_ID) + ->will($this->returnValue($this->captchaMock)); + $this->captchaMock->expects($this->once())->method('isRequired') + ->will($this->returnValue($captchaIsRequired)); + $this->captchaStringResolverMock->expects($this->any())->method('resolve') + ->with($this->requestMock, static::FORM_ID)->will($this->returnValue($word)); + $this->captchaMock->expects($this->any())->method('isCorrect')->with($word) + ->will($this->returnValue($captchaWordIsCorrect)); + + $this->model->validateSending($this->requestMock); + } + + /** + * Providing captcha settings + * + * @return array + */ + public function captchaProvider(): array + { + return [ + [ + true, + true + ], [ + false, + false + ] + ]; + } +} From 56adedddf6fa8680c298d3967f67171783582725 Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Wed, 2 Oct 2019 11:53:26 -0300 Subject: [PATCH 0787/1172] Unit tests --- .../Address/CollectTotalsObserverTest.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/app/code/Magento/Quote/Test/Unit/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php b/app/code/Magento/Quote/Test/Unit/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php index 4ea067c9be8f..a590c8aa891a 100644 --- a/app/code/Magento/Quote/Test/Unit/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php +++ b/app/code/Magento/Quote/Test/Unit/Observer/Frontend/Quote/Address/CollectTotalsObserverTest.php @@ -314,6 +314,43 @@ public function testDispatchWithCustomerCountryInEU() $this->model->execute($this->observerMock); } + public function testDispatchWithAddressCustomerVatIdAndCountryId() + { + $customerCountryCode = "BE"; + $customerVat = "123123123"; + $defaultShipping = 1; + + $customerAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $customerAddress->expects($this->any()) + ->method("getVatId") + ->willReturn($customerVat); + + $customerAddress->expects($this->any()) + ->method("getCountryId") + ->willReturn($customerCountryCode); + + $this->addressRepository->expects($this->once()) + ->method("getById") + ->with($defaultShipping) + ->willReturn($customerAddress); + + $this->customerMock->expects($this->atLeastOnce()) + ->method("getDefaultShipping") + ->willReturn($defaultShipping); + + $this->vatValidatorMock->expects($this->once()) + ->method('isEnabled') + ->with($this->quoteAddressMock, $this->storeId) + ->will($this->returnValue(true)); + + $this->customerVatMock->expects($this->once()) + ->method('isCountryInEU') + ->with($customerCountryCode) + ->willReturn(true); + + $this->model->execute($this->observerMock); + } + public function testDispatchWithEmptyShippingAddress() { $customerCountryCode = "DE"; From a528841c676f188824ca30479ca3e1d801b729c4 Mon Sep 17 00:00:00 2001 From: Max Souza <max@trezo.com.br> Date: Wed, 2 Oct 2019 11:53:34 -0300 Subject: [PATCH 0788/1172] Fix annotations --- .../Controller/Checkout/Address/NewShipping.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php index c656b3af1447..1f14b52da42c 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php @@ -1,11 +1,14 @@ <?php /** - * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Multishipping\Controller\Checkout\Address; +/** + * Class NewShipping + * @package Magento\Multishipping\Controller\Checkout\Address + */ class NewShipping extends \Magento\Multishipping\Controller\Checkout\Address { /** From 8d0b4c436e654a1f24a91640e6827fa882441619 Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 2 Oct 2019 10:18:38 -0500 Subject: [PATCH 0789/1172] MC-20358: Create New MFTF Suites for MySQL/Elasticsearch Specific Functionality * Removing after block from Elasticsearch suite --- .../Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml index 81debdb0d448..d612f5bd17a2 100644 --- a/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml +++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Suite/SearchEngineElasticsearchSuite.xml @@ -12,11 +12,7 @@ <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> - <after> - <magentoCLI stepKey="setSearchEngineToMysql" command="config:set {{SearchEngineMysqlConfigData.path}} {{SearchEngineMysqlConfigData.value}}"/> - <magentoCLI command="indexer:reindex" stepKey="reindex"/> - <magentoCLI command="cache:flush" stepKey="flushCache"/> - </after> + <after></after> <include> <group name="SearchEngineElasticsearch" /> </include> From 76a6cf1f4513050367a1dc24003c4cf91607094a Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Wed, 2 Oct 2019 10:25:52 -0500 Subject: [PATCH 0790/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage Adding skipped notation back, till cicd vault integration is complete. --- .../Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml index fea1cf3966b9..6adba94e9689 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/StorefrontPaypalSmartButtonInCheckoutPageTest.xml @@ -16,6 +16,9 @@ <description value="Users are able to place order using Paypal Smart Button"/> <severity value="CRITICAL"/> <testCaseId value="MC-13690"/> + <skip> + <issueId value="DEVOPS-3311"/> + </skip> <group value="paypal"/> </annotations> <before> From b64a485793d81b0734539e27a0c049b765186991 Mon Sep 17 00:00:00 2001 From: Vitaliy Boyko <v.boyko@atwix.com> Date: Wed, 2 Oct 2019 18:40:52 +0300 Subject: [PATCH 0791/1172] GraphQl-972: static fix --- .../Magento/TestFramework/App/ApiMutableScopeConfig.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php b/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php index 63a0ec0f7f48..fa0cebece9a9 100644 --- a/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php +++ b/dev/tests/api-functional/framework/Magento/TestFramework/App/ApiMutableScopeConfig.php @@ -89,13 +89,12 @@ private function persistConfig($path, $value, $scopeType, $scopeCode): void { $pathParts = explode('/', $path); $store = 0; - if ($scopeType === \Magento\Store\Model\ScopeInterface::SCOPE_STORE) { - if ($scopeCode !== null) { - $store = ObjectManager::getInstance() + if ($scopeType === \Magento\Store\Model\ScopeInterface::SCOPE_STORE + && $scopeCode !== null) { + $store = ObjectManager::getInstance() ->get(\Magento\Store\Api\StoreRepositoryInterface::class) ->get($scopeCode) ->getId(); - } } $configData = [ 'section' => $pathParts[0], From 88532ef5e2cd5b580250793c39f7b1ae32e93815 Mon Sep 17 00:00:00 2001 From: Max Souza <max@trezo.com.br> Date: Wed, 2 Oct 2019 12:49:36 -0300 Subject: [PATCH 0792/1172] Fix line blank --- .../Multishipping/Controller/Checkout/Address/NewShipping.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php index 1f14b52da42c..3e2b5eec52fc 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php @@ -6,6 +6,8 @@ namespace Magento\Multishipping\Controller\Checkout\Address; /** + * New Shipping + * * Class NewShipping * @package Magento\Multishipping\Controller\Checkout\Address */ From c416cbf8e8154a9061fa16e980f0e79ca7549128 Mon Sep 17 00:00:00 2001 From: Dmytro Poperechnyy <dpoperechnyy@magento.com> Date: Wed, 2 Oct 2019 10:54:37 -0500 Subject: [PATCH 0793/1172] MC-19248: Add static test to prevent regressing mage-init directive fixes made in the phtml files - Fix BIC changes; --- .../_files/initialize_javascript/data_mage_init/whitelist.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php index ab55bc3eae92..a77b7b28864e 100644 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/initialize_javascript/data_mage_init/whitelist.php @@ -6,7 +6,8 @@ /** * List of templates with data-mage-init attribute where JS component is not correctly called. * - * JS component is initialized in php here. These templates cannot be refactored easily. + * JS component is initialized in php here. These templates cannot be refactored easily. This list consists of + * module name and template path within module. */ return [ ['Magento_Braintree', 'view/frontend/templates/paypal/button_shopping_cart.phtml'] From 867925dc92a51fc711275a51bc77b794fe190e0f Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Wed, 2 Oct 2019 11:23:30 -0500 Subject: [PATCH 0794/1172] Fixed docblock type hint --- app/code/Magento/Integration/Helper/Oauth/Data.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Integration/Helper/Oauth/Data.php b/app/code/Magento/Integration/Helper/Oauth/Data.php index 93fab35c1f40..107583a9e70a 100644 --- a/app/code/Magento/Integration/Helper/Oauth/Data.php +++ b/app/code/Magento/Integration/Helper/Oauth/Data.php @@ -116,7 +116,7 @@ public function getConsumerPostTimeout() /** * Get customer token lifetime from config. * - * @return numeric hours + * @return float hours */ public function getCustomerTokenLifetime() { @@ -127,7 +127,7 @@ public function getCustomerTokenLifetime() /** * Get customer token lifetime from config. * - * @return numeric hours + * @return float hours */ public function getAdminTokenLifetime() { From ecb2249fd67ce4d489e81c131349191c7256268b Mon Sep 17 00:00:00 2001 From: Max Souza <max@trezo.com.br> Date: Wed, 2 Oct 2019 13:28:32 -0300 Subject: [PATCH 0795/1172] Fix annotations --- .../Multishipping/Controller/Checkout/Address/NewShipping.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php index 3e2b5eec52fc..a484dfbf1797 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php @@ -6,9 +6,8 @@ namespace Magento\Multishipping\Controller\Checkout\Address; /** - * New Shipping - * * Class NewShipping + * * @package Magento\Multishipping\Controller\Checkout\Address */ class NewShipping extends \Magento\Multishipping\Controller\Checkout\Address From 0c102bb6ed2f5511e364d9bcd38b243343c17a2b Mon Sep 17 00:00:00 2001 From: Mahesh Singh <mahesh721@webkul.com> Date: Wed, 2 Oct 2019 22:35:11 +0530 Subject: [PATCH 0796/1172] Fixed #24722 with suggestion --- .../AdvancedPricingImportExport/Model/Export/AdvancedPricing.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php b/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php index 31b99bf71d11..39009e5c7b4e 100644 --- a/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php +++ b/app/code/Magento/AdvancedPricingImportExport/Model/Export/AdvancedPricing.php @@ -216,6 +216,7 @@ public function export() if ($entityCollection->count() == 0) { break; } + $entityCollection->clear(); $exportData = $this->getExportData(); foreach ($exportData as $dataRow) { $writer->writeRow($dataRow); From fded460ee1bc92156ff479e29115fe06fbbaffaa Mon Sep 17 00:00:00 2001 From: Max Souza <max@trezo.com.br> Date: Wed, 2 Oct 2019 15:18:05 -0300 Subject: [PATCH 0797/1172] Implements HttpGetActionInterface --- .../Controller/Checkout/Address/NewShipping.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php index a484dfbf1797..38a30c1ee49e 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php +++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php @@ -5,12 +5,15 @@ */ namespace Magento\Multishipping\Controller\Checkout\Address; +use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface; +use Magento\Multishipping\Controller\Checkout\Address; + /** * Class NewShipping * - * @package Magento\Multishipping\Controller\Checkout\Address + * @package Address */ -class NewShipping extends \Magento\Multishipping\Controller\Checkout\Address +class NewShipping extends Address implements HttpGetActionInterface { /** * Create New Shipping address Form From 41e73b35294e7f60f855888363dc9918b02027ab Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Wed, 2 Oct 2019 15:49:17 -0300 Subject: [PATCH 0798/1172] Added cdata to comment --- app/code/Magento/Backend/etc/adminhtml/system.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 343ecc0ee3d5..261229d2db63 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -481,7 +481,7 @@ <field id="base_url" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Base URL</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>Specify URL or {{base_url}} placeholder.</comment> + <comment><![CDATA[Specify URL or {{base_url}} placeholder.]]></comment> </field> <field id="base_link_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Base Link URL</label> @@ -505,7 +505,7 @@ <field id="base_url" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Secure Base URL</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>Specify URL or {{base_url}}, or {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[Specify URL or {{base_url}}, or {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="base_link_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Secure Base Link URL</label> From fa63035141c04b706fe0570cfc9bb5b83fca62fb Mon Sep 17 00:00:00 2001 From: Andrew Molina <amolina@adobe.com> Date: Wed, 2 Oct 2019 14:27:22 -0500 Subject: [PATCH 0799/1172] MC-21435: Migrate failed QuickSearch related MFTF tests to SearchEngineMysqlSuite --- .../Test/Mftf/Test/MinimalQueryLengthForCatalogSearchTest.xml | 1 + .../CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml | 3 +++ .../Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml | 1 + .../LayeredNavigation/Test/Mftf/Test/ShopByButtonInMobile.xml | 1 + 4 files changed, 6 insertions(+) diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/MinimalQueryLengthForCatalogSearchTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/MinimalQueryLengthForCatalogSearchTest.xml index b6417e12a6db..89269a1ad0d9 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/MinimalQueryLengthForCatalogSearchTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/MinimalQueryLengthForCatalogSearchTest.xml @@ -18,6 +18,7 @@ <testCaseId value="MC-6325"/> <useCaseId value="MAGETWO-58764"/> <group value="CatalogSearch"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="ApiCategory" stepKey="createCategory"/> diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml index 19db201e91f4..b283c5bfe70d 100644 --- a/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml +++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/SearchEntityResultsTest.xml @@ -124,6 +124,7 @@ <severity value="MAJOR"/> <testCaseId value="MC-15034"/> <group value="CatalogSearch"/> + <group value="SearchEngineMysql"/> <group value="mtf_migrated"/> </annotations> <executeJS function="var s = '$createSimpleProduct.name$'; var ret=s.substring(0,3); return ret;" stepKey="getFirstThreeLetters" before="searchStorefront"/> @@ -160,6 +161,7 @@ <severity value="MAJOR"/> <testCaseId value="MC-14796"/> <group value="CatalogSearch"/> + <group value="SearchEngineMysql"/> <group value="mtf_migrated"/> </annotations> <before> @@ -242,6 +244,7 @@ <severity value="MAJOR"/> <testCaseId value="MC-14797"/> <group value="CatalogSearch"/> + <group value="SearchEngineMysql"/> <group value="mtf_migrated"/> </annotations> <before> diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml index 1075f79aef18..d5b76888fccc 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml @@ -17,6 +17,7 @@ <severity value="MAJOR"/> <testCaseId value="MC-249"/> <group value="ConfigurableProduct"/> + <group value="SearchEngineMysql"/> </annotations> <before> <!-- TODO: This should be converted to an actionGroup once MQE-993 is fixed. --> diff --git a/app/code/Magento/LayeredNavigation/Test/Mftf/Test/ShopByButtonInMobile.xml b/app/code/Magento/LayeredNavigation/Test/Mftf/Test/ShopByButtonInMobile.xml index 721942f58f7c..6d182d0b7a5e 100644 --- a/app/code/Magento/LayeredNavigation/Test/Mftf/Test/ShopByButtonInMobile.xml +++ b/app/code/Magento/LayeredNavigation/Test/Mftf/Test/ShopByButtonInMobile.xml @@ -17,6 +17,7 @@ <severity value="CRITICAL"/> <testCaseId value="MC-6092"/> <group value="LayeredNavigation"/> + <group value="SearchEngineMysql"/> </annotations> <before> <createData entity="productDropDownAttribute" stepKey="attribute"/> From f54bd5f3ccfbfa6eab8a9a6f0ed9f8d089589cfb Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 2 Oct 2019 14:46:46 -0500 Subject: [PATCH 0800/1172] MC-20244: Pricing :: FPT calculation - fix static failures --- .../CatalogGraphQl/etc/schema.graphqls | 10 ++++----- .../Magento/Weee/Model/ResourceModel/Tax.php | 9 ++++---- app/code/Magento/Weee/Model/Tax.php | 21 +++++++++++++++---- .../{FptResolver.php => FixedProductTax.php} | 3 +-- app/code/Magento/WeeeGraphQl/composer.json | 8 +++---- .../Magento/WeeeGraphQl/etc/schema.graphqls | 8 +++---- 6 files changed, 36 insertions(+), 23 deletions(-) rename app/code/Magento/WeeeGraphQl/Model/Resolver/{FptResolver.php => FixedProductTax.php} (98%) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index e70b64e7f97d..0ec29369a85a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -21,16 +21,16 @@ type Price @doc(description: "Price is deprecated, replaced by ProductPrice. The adjustments: [PriceAdjustment] @deprecated(reason: "Price is deprecated, use ProductPrice.") @doc(description: "An array that provides information about tax, weee, or weee_tax adjustments.") } -type PriceAdjustment @doc(description: "The PricedAdjustment object defines the amount of money to apply as an adjustment, the type of adjustment to apply, and whether the item is included or excluded from the adjustment.") { +type PriceAdjustment @doc(description: "PriceAdjustment is deprecated. Taxes will be included or excluded in the price. The PricedAdjustment object defines the amount of money to apply as an adjustment, the type of adjustment to apply, and whether the item is included or excluded from the adjustment.") { amount: Money @doc(description: "The amount of the price adjustment and its currency code.") - code: PriceAdjustmentCodesEnum @doc(description: "Indicates whether the adjustment involves tax, weee, or weee_tax.") - description: PriceAdjustmentDescriptionEnum @doc(description: "Indicates whether the entity described by the code attribute is included or excluded from the adjustment.") + code: PriceAdjustmentCodesEnum @deprecated(reason: "PriceAdjustment is deprecated.") @doc(description: "Indicates whether the adjustment involves tax, weee, or weee_tax.") + description: PriceAdjustmentDescriptionEnum @deprecated(reason: "PriceAdjustment is deprecated.") @doc(description: "Indicates whether the entity described by the code attribute is included or excluded from the adjustment.") } -enum PriceAdjustmentCodesEnum @doc(description: "Note: This enumeration contains values defined in modules other than the Catalog module.") { +enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated. This enumeration contains values defined in modules other than the Catalog module.") { } -enum PriceAdjustmentDescriptionEnum @doc(description: "This enumeration states whether a price adjustment is included or excluded.") { +enum PriceAdjustmentDescriptionEnum @doc(description: "PriceAdjustmentDescriptionEnum is deprecated. This enumeration states whether a price adjustment is included or excluded.") { INCLUDED EXCLUDED } diff --git a/app/code/Magento/Weee/Model/ResourceModel/Tax.php b/app/code/Magento/Weee/Model/ResourceModel/Tax.php index d10cd244d853..9e8551d60288 100644 --- a/app/code/Magento/Weee/Model/ResourceModel/Tax.php +++ b/app/code/Magento/Weee/Model/ResourceModel/Tax.php @@ -5,9 +5,6 @@ */ namespace Magento\Weee\Model\ResourceModel; -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Condition\ConditionInterface; - /** * Wee tax resource model * @@ -51,7 +48,7 @@ protected function _construct() } /** - * Fetch one + * Fetch one calculated weee attribute from a select criteria * * @param \Magento\Framework\DB\Select|string $select * @return string @@ -62,6 +59,8 @@ public function fetchOne($select) } /** + * Is there a weee attribute available for the location provided + * * @param int $countryId * @param int $regionId * @param int $websiteId @@ -96,6 +95,8 @@ public function isWeeeInLocation($countryId, $regionId, $websiteId) } /** + * Fetch calculated weee attributes by location, store and entity + * * @param int $countryId * @param int $regionId * @param int $websiteId diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index 3bc95d6f6f9f..9803bd58d477 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -13,6 +13,8 @@ use Magento\Catalog\Model\Product\Type; /** + * Weee tax model + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 @@ -144,6 +146,8 @@ protected function _construct() } /** + * Get the weee amount + * * @param Product $product * @param null|false|\Magento\Framework\DataObject $shipping * @param null|false|\Magento\Framework\DataObject $billing @@ -173,6 +177,8 @@ public function getWeeeAmount( } /** + * Get the weee amount excluding tax + * * @param Product $product * @param null|false|\Magento\Framework\DataObject $shipping * @param null|false|\Magento\Framework\DataObject $billing @@ -203,6 +209,8 @@ public function getWeeeAmountExclTax( } /** + * Get the weee attribute codes + * * @param bool $forceEnabled * @return array */ @@ -214,8 +222,8 @@ public function getWeeeAttributeCodes($forceEnabled = false) /** * Retrieve Wee tax attribute codes * - * @param null|string|bool|int|Store $store - * @param bool $forceEnabled + * @param null|string|bool|int|Store $store + * @param bool $forceEnabled * @return array */ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) @@ -231,6 +239,8 @@ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) } /** + * Retrieve the relevant wee tax attributes assigned to a product by location + * * @param Product $product * @param null|false|\Magento\Quote\Model\Quote\Address $shipping * @param null|false|\Magento\Quote\Model\Quote\Address $billing @@ -241,6 +251,7 @@ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * phpcs:disable Generic.Metrics.NestingLevel */ public function getProductWeeeAttributes( $product, @@ -283,7 +294,7 @@ public function getProductWeeeAttributes( return $result; } - /** @var \Magento\Tax\Model\Calculation $calculator */ + /** @var Calculation $calculator */ $calculator = $this->_calculationFactory->create(); $customerId = $this->_customerSession->getCustomerId(); @@ -332,7 +343,7 @@ public function getProductWeeeAttributes( $amount = $value; $amountExclTax = $value; if ($calculateTax && $this->weeeConfig->isTaxable($store)) { - /** @var \Magento\Tax\Model\Calculation $calculator */ + /** @var Calculation $calculator */ $defaultPercent = $calculator->getRate( $defaultRateRequest->setProductClassId($product->getTaxClassId()) ); @@ -392,6 +403,8 @@ public function getProductWeeeAttributes( } /** + * Is there a weee attribute available for the location provided + * * @param int $countryId * @param int $regionId * @param int $websiteId diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php similarity index 98% rename from app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php rename to app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php index 44c16a499a40..98164c18e858 100644 --- a/app/code/Magento/WeeeGraphQl/Model/Resolver/FptResolver.php +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php @@ -19,9 +19,8 @@ /** * Resolver for FixedProductTax object that retrieves an array of FPT attributes with prices */ -class FptResolver implements ResolverInterface +class FixedProductTax implements ResolverInterface { - /** * @var Data */ diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index 03c3d0d91819..39b77bb569ac 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -4,12 +4,12 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/framework": "*" - }, - "suggest": { + "magento/framework": "*", "magento/module-store": "*", "magento/module-tax": "*", - "magento/module-weee": "*", + "magento/module-weee": "*" + }, + "suggest": { "magento/module-catalog-graph-ql": "*" }, "license": [ diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 9e7e3e19e42b..95ca88ee7a99 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -1,13 +1,13 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. -enum PriceAdjustmentCodesEnum { - WEEE - WEEE_TAX +enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated, use ProductPrice.") { + WEEE @deprecated(reason: "WEEE is deprecated, use fixed_product_taxes.label") + WEEE_TAX @deprecated(reason: "WEEE_TAX is deprecated, use fixed_product_taxes. Tax is included or excluded in the amount") } type ProductPrice { - fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FptResolver") + fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FixedProductTax") } type FixedProductTax @doc(description: "A single FPT that can be applied to a product price.") { From 5ec8aa58ea27b7d893cc246d5c622e0ccd6fa08f Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 2 Oct 2019 14:52:25 -0500 Subject: [PATCH 0801/1172] MC-20244: Pricing :: FPT calculation - fix empty line --- app/code/Magento/Weee/Model/ResourceModel/Tax.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/code/Magento/Weee/Model/ResourceModel/Tax.php b/app/code/Magento/Weee/Model/ResourceModel/Tax.php index 9e8551d60288..2cbb6054a31e 100644 --- a/app/code/Magento/Weee/Model/ResourceModel/Tax.php +++ b/app/code/Magento/Weee/Model/ResourceModel/Tax.php @@ -144,7 +144,6 @@ public function fetchWeeeTaxCalculationsByEntity($countryId, $regionId, $website (int)$entityId ); - $order = ['weeeTax.state ' . \Magento\Framework\DB\Select::SQL_DESC, 'weeeTax.website_id ' . \Magento\Framework\DB\Select::SQL_DESC]; $attributeSelect->order($order); From 745ac409ea121d9d602ebf2d471531c97cf4746a Mon Sep 17 00:00:00 2001 From: Bruno Roeder <brunoadrielr@gmail.com> Date: Wed, 2 Oct 2019 17:13:20 -0300 Subject: [PATCH 0802/1172] Added cdata to all comments with curly brackets --- app/code/Magento/Backend/etc/adminhtml/system.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 261229d2db63..d80acc885016 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -486,17 +486,17 @@ <field id="base_link_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Base Link URL</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May start with {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May start with {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="base_static_url" translate="label comment" type="text" sortOrder="25" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Base URL for Static View Files</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May be empty or start with {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May be empty or start with {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="base_media_url" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Base URL for User Media Files</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May be empty or start with {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May be empty or start with {{unsecure_base_url}} placeholder.]]></comment> </field> </group> <group id="secure" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1"> @@ -510,17 +510,17 @@ <field id="base_link_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Secure Base Link URL</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May start with {{secure_base_url}} or {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May start with {{secure_base_url}} or {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="base_static_url" translate="label comment" type="text" sortOrder="25" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Secure Base URL for Static View Files</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="base_media_url" translate="label comment" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Secure Base URL for User Media Files</label> <backend_model>Magento\Config\Model\Config\Backend\Baseurl</backend_model> - <comment>May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.</comment> + <comment><![CDATA[May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.]]></comment> </field> <field id="use_in_frontend" translate="label comment" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> <label>Use Secure URLs on Storefront</label> From db7a1136dbf10deeb0754c10eb07c568cfd896d9 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Wed, 2 Oct 2019 15:33:55 -0500 Subject: [PATCH 0803/1172] MC-20244: Pricing :: FPT calculation - revert caching --- app/code/Magento/Weee/Model/Tax.php | 227 +++++++++++++--------------- 1 file changed, 105 insertions(+), 122 deletions(-) diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index 9803bd58d477..3c62dbc65e0d 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -90,9 +90,6 @@ class Tax extends \Magento\Framework\Model\AbstractModel */ protected $accountManagement; - /** @var array */ - private $weeAtrributesCache = []; - /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -261,144 +258,130 @@ public function getProductWeeeAttributes( $calculateTax = null, $round = true ) { - $cacheKey = sprintf( - '%s-%s-%s-%s-%s', - $product->getId(), - $shipping && $shipping->getId() ? $shipping->getId() : '', - $billing && $billing->getId() ? $billing->getId() : '', - $website && $website->getId() ? $website->getId() : $website ? $website : '', - $calculateTax, - $round - ); $result = []; - if (isset($this->weeAtrributesCache[$cacheKey])) { - $result = $this->weeAtrributesCache[$cacheKey]; - } else { - $websiteId = null; - /** @var \Magento\Store\Model\Store $store */ - $store = null; - if (!$website) { - $store = $product->getStore(); - if ($store) { - $websiteId = $store->getWebsiteId(); - } - } - if (!$websiteId) { - $websiteObject = $this->_storeManager->getWebsite($website); - $websiteId = $websiteObject->getId(); - $store = $websiteObject->getDefaultGroup()->getDefaultStore(); + $websiteId = null; + /** @var \Magento\Store\Model\Store $store */ + $store = null; + if (!$website) { + $store = $product->getStore(); + if ($store) { + $websiteId = $store->getWebsiteId(); } + } + if (!$websiteId) { + $websiteObject = $this->_storeManager->getWebsite($website); + $websiteId = $websiteObject->getId(); + $store = $websiteObject->getDefaultGroup()->getDefaultStore(); + } - $allWeee = $this->getWeeeTaxAttributeCodes($store); - if (!$allWeee) { - return $result; - } + $allWeee = $this->getWeeeTaxAttributeCodes($store); + if (!$allWeee) { + return $result; + } - /** @var Calculation $calculator */ - $calculator = $this->_calculationFactory->create(); + /** @var Calculation $calculator */ + $calculator = $this->_calculationFactory->create(); - $customerId = $this->_customerSession->getCustomerId(); - if ($shipping && $shipping->getCountryId()) { - $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId(); + $customerId = $this->_customerSession->getCustomerId(); + if ($shipping && $shipping->getCountryId()) { + $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId(); + } else { + // if customer logged use it default shipping and billing address + if ($customerId) { + $shipping = $this->accountManagement->getDefaultShippingAddress($customerId); + $billing = $this->accountManagement->getDefaultBillingAddress($customerId); + $customerTaxClass = null; } else { - // if customer logged use it default shipping and billing address - if ($customerId) { - $shipping = $this->accountManagement->getDefaultShippingAddress($customerId); - $billing = $this->accountManagement->getDefaultBillingAddress($customerId); - $customerTaxClass = null; - } else { - $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress(); - $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress(); - if (!empty($billingAddressArray)) { - $billing = new \Magento\Framework\DataObject($billingAddressArray); - } - if (!empty($shippingAddressArray)) { - $shipping = new \Magento\Framework\DataObject($shippingAddressArray); - } - $customerTaxClass = $this->_customerSession->getCustomerTaxClassId(); + $shippingAddressArray = $this->_customerSession->getDefaultTaxShippingAddress(); + $billingAddressArray = $this->_customerSession->getDefaultTaxBillingAddress(); + if (!empty($billingAddressArray)) { + $billing = new \Magento\Framework\DataObject($billingAddressArray); } + if (!empty($shippingAddressArray)) { + $shipping = new \Magento\Framework\DataObject($shippingAddressArray); + } + $customerTaxClass = $this->_customerSession->getCustomerTaxClassId(); } + } - $rateRequest = $calculator->getRateRequest( - $shipping, - $billing, - $customerTaxClass, - $store, - $customerId - ); - $defaultRateRequest = $calculator->getDefaultRateRequest($store); - - $productAttributes = $this->getResource()->fetchWeeeTaxCalculationsByEntity( - $rateRequest->getCountryId(), - $rateRequest->getRegionId(), - $websiteId, - $store->getId(), - $product->getId() - ); - - foreach ($productAttributes as $attribute) { - $value = $attribute['weee_value']; - if ($value) { - $taxAmount = $amount = 0; - $amount = $value; - $amountExclTax = $value; - if ($calculateTax && $this->weeeConfig->isTaxable($store)) { - /** @var Calculation $calculator */ - $defaultPercent = $calculator->getRate( - $defaultRateRequest->setProductClassId($product->getTaxClassId()) - ); - $currentPercent = $calculator->getRate( - $rateRequest->setProductClassId($product->getTaxClassId()) - ); - if ($this->_taxData->priceIncludesTax($store)) { - $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent); - if ($round) { - $amountInclTax = $this->priceCurrency->round($amountInclTax); - } - $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100; - if ($round) { - $taxAmount = $this->priceCurrency->round($taxAmount); - } - $amountExclTax = $amountInclTax - $taxAmount; - } else { - $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest); - if (is_array($appliedRates) && count($appliedRates) > 1) { - $taxAmount = 0; - foreach ($appliedRates as $appliedRate) { - $taxRate = $appliedRate['percent']; - if ($round) { - $taxAmount += $this->priceCurrency->round($value * $taxRate / 100); - } else { - $taxAmount += $value * $taxRate / 100; - } - } - } else { + $rateRequest = $calculator->getRateRequest( + $shipping, + $billing, + $customerTaxClass, + $store, + $customerId + ); + $defaultRateRequest = $calculator->getDefaultRateRequest($store); + + $productAttributes = $this->getResource()->fetchWeeeTaxCalculationsByEntity( + $rateRequest->getCountryId(), + $rateRequest->getRegionId(), + $websiteId, + $store->getId(), + $product->getId() + ); + + foreach ($productAttributes as $attribute) { + $value = $attribute['weee_value']; + if ($value) { + $taxAmount = $amount = 0; + $amount = $value; + $amountExclTax = $value; + if ($calculateTax && $this->weeeConfig->isTaxable($store)) { + /** @var Calculation $calculator */ + $defaultPercent = $calculator->getRate( + $defaultRateRequest->setProductClassId($product->getTaxClassId()) + ); + $currentPercent = $calculator->getRate( + $rateRequest->setProductClassId($product->getTaxClassId()) + ); + if ($this->_taxData->priceIncludesTax($store)) { + $amountInclTax = $value / (100 + $defaultPercent) * (100 + $currentPercent); + if ($round) { + $amountInclTax = $this->priceCurrency->round($amountInclTax); + } + $taxAmount = $amountInclTax - $amountInclTax / (100 + $currentPercent) * 100; + if ($round) { + $taxAmount = $this->priceCurrency->round($taxAmount); + } + $amountExclTax = $amountInclTax - $taxAmount; + } else { + $appliedRates = $this->_calculationFactory->create()->getAppliedRates($rateRequest); + if (is_array($appliedRates) && count($appliedRates) > 1) { + $taxAmount = 0; + foreach ($appliedRates as $appliedRate) { + $taxRate = $appliedRate['percent']; if ($round) { - $taxAmount = $this->priceCurrency->round( - $value * $currentPercent / 100 - ); + $taxAmount += $this->priceCurrency->round($value * $taxRate / 100); } else { - $taxAmount = $value * $currentPercent / 100; + $taxAmount += $value * $taxRate / 100; } } + } else { + if ($round) { + $taxAmount = $this->priceCurrency->round( + $value * $currentPercent / 100 + ); + } else { + $taxAmount = $value * $currentPercent / 100; + } } } + } - $one = new \Magento\Framework\DataObject(); - $one->setName( - $attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label']) - ) - ->setAmount($amount) - ->setTaxAmount($taxAmount) - ->setAmountExclTax($amountExclTax) - ->setCode($attribute['attribute_code']); + $one = new \Magento\Framework\DataObject(); + $one->setName( + $attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label']) + ) + ->setAmount($amount) + ->setTaxAmount($taxAmount) + ->setAmountExclTax($amountExclTax) + ->setCode($attribute['attribute_code']); - $result[] = $one; - } + $result[] = $one; } - - $this->weeAtrributesCache[$cacheKey] = $result; } + return $result; } From 1e0193d5d0cb1953e91e0be0dc98ee8eba8fae98 Mon Sep 17 00:00:00 2001 From: Deepty Thampy <dthampy@adobe.com> Date: Wed, 2 Oct 2019 18:10:30 -0500 Subject: [PATCH 0804/1172] MC-20508: Api-functional tests for Product prices including FPT - added test coverage for all the FPT and catalog display configurations --- .../Catalog/ProductPriceWithFPTTest.php | 505 ++++++++++++++++++ .../Weee/_files/fixed_product_attribute.php | 1 + .../Magento/Weee/_files/product_with_fpt.php | 2 + .../Weee/_files/product_with_fpt_rollback.php | 3 +- 4 files changed, 510 insertions(+), 1 deletion(-) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php new file mode 100644 index 000000000000..ca9fdbe2f245 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php @@ -0,0 +1,505 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Storage\WriterInterface; +use Magento\Framework\ObjectManager\ObjectManager; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Tax\Model\ClassModel as TaxClassModel; +use Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory as TaxClassCollectionFactory; + +class ProductPriceWithFPTTest extends GraphQlAbstract +{ + /** @var ObjectManager $objectManager */ + private $objectManager; + + protected function setUp() :void + { + $this->objectManager = Bootstrap::getObjectManager(); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxAndIncludeFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/calculation/price_includes_tax', '0'); + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $prod2 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + + // final price and regular price are the sum of product price, FPT and product tax + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/calculation/price_includes_tax', '0'); + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + // final price and regular price are the sum of product price and FPT + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT Only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT Description + * Apply Tax to FPT = Yes + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + $configWriter->save('tax/weee/apply_vat', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + //12.7 + 7.5% of 12.7 = 13.65 + $fptWithTax = round(13.65, 2) ; + // final price and regular price are the sum of product price and FPT + $this->assertEquals(113.65, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(113.65, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(113.65, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(113.65, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals($fptWithTax, round($fixedProductTax['amount']['value'], 2)); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + + /** + * Use multiple FPTs per product with the below tax/fpt configurations + * + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT description + * Apply tax on FPT : Yes + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/Weee/_files/fixed_product_attribute.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + $configWriter->save('tax/weee/apply_vat', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $product1->setFixedProductAttribute( + [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10, 'delete' => '']] + ); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertEquals(124.4, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertCount(2, $product['price_range']['fixed_product_taxes'], 'Fixed product tax count is incorrect'); + $this->assertResponseFields( + $product['price_range']['fixed_product_taxes'], + [ + [ + 'amount' => [ + 'value' => 10.75 + ], + 'label' => 'fixed_product_attribute' + ], + [ + 'amount' => [ + 'value' => 13.6525 + ], + 'label' => 'fpt_for_all_front_label' + ] + ] + ); + } + + /** + * Get GraphQl query to fetch products by sku + * + * @param array $skus + * @return string + */ + private function getProductQuery(array $skus): string + { + $stringSkus = '"' . implode('","', $skus) . '"'; + return <<<QUERY +{ + products(filter: {sku: {in: [$stringSkus]}}, sort: {name: ASC}) { + items { + name + sku + price_range { + minimum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + fixed_product_taxes{ + amount{value} + label + } + } + maximum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + fixed_product_taxes + { + amount{value} + label + } + } + } + } + } +} +QUERY; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php index a20d1cac9422..5a635b3c7ac4 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php @@ -25,6 +25,7 @@ 'is_static' => 1, 'attribute_set_id' => $defaultSetId, 'attribute_group_id' => $attributeGroupId, + 'frontend_label' =>'fixed_product_attribute_label' ]; /** @var \Magento\Catalog\Model\Entity\Attribute $attribute */ diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php index 0e67a8947a79..30835f690158 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php @@ -27,6 +27,8 @@ $groupId )->setAttributeSetId( $attributeSetId +)->setFrontendLabel( + 'fpt_for_all_front_label' )->setFrontendInput( 'weee' )->setIsUserDefined( diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php index d0305f461eb0..d0a6bbb0d1cc 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php @@ -13,7 +13,8 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); -$product->load(101); + +$product = $product->loadByAttribute('sku', 'simple-with-ftp'); if ($product->getId()) { $product->delete(); } From 39111d677bc98c52c8c0362c79ac1145f1bf738b Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Thu, 3 Oct 2019 10:03:37 +0530 Subject: [PATCH 0805/1172] Fixed inconsistent grammar --- app/code/Magento/Newsletter/etc/adminhtml/menu.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Newsletter/etc/adminhtml/menu.xml b/app/code/Magento/Newsletter/etc/adminhtml/menu.xml index a9cedf1c7a1e..8fc21494b5de 100644 --- a/app/code/Magento/Newsletter/etc/adminhtml/menu.xml +++ b/app/code/Magento/Newsletter/etc/adminhtml/menu.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd"> <menu> - <add id="Magento_Newsletter::newsletter_template" title="Newsletter Template" translate="title" module="Magento_Newsletter" parent="Magento_Backend::marketing_communications" sortOrder="30" action="newsletter/template/" resource="Magento_Newsletter::template"/> + <add id="Magento_Newsletter::newsletter_template" title="Newsletter Templates" translate="title" module="Magento_Newsletter" parent="Magento_Backend::marketing_communications" sortOrder="30" action="newsletter/template/" resource="Magento_Newsletter::template"/> <add id="Magento_Newsletter::newsletter_queue" title="Newsletter Queue" translate="title" module="Magento_Newsletter" sortOrder="40" parent="Magento_Backend::marketing_communications" action="newsletter/queue/" resource="Magento_Newsletter::queue"/> <add id="Magento_Newsletter::newsletter_subscriber" title="Newsletter Subscribers" translate="title" module="Magento_Newsletter" sortOrder="50" parent="Magento_Backend::marketing_communications" action="newsletter/subscriber/" resource="Magento_Newsletter::subscriber"/> <add id="Magento_Newsletter::newsletter_problem" title="Newsletter Problem Reports" translate="title" module="Magento_Newsletter" sortOrder="50" parent="Magento_Reports::report_marketing" action="newsletter/problem/" resource="Magento_Newsletter::problem"/> From 42e4103ce6765a16f30980dcc19d48b3fbdcc433 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <engcom-vendorworker-foxtrot@adobe.com> Date: Thu, 3 Oct 2019 12:33:30 +0300 Subject: [PATCH 0806/1172] magento/magento2#24835: MFTF tests update. --- app/code/Magento/Newsletter/Test/Mftf/Data/AdminMenuData.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Newsletter/Test/Mftf/Data/AdminMenuData.xml b/app/code/Magento/Newsletter/Test/Mftf/Data/AdminMenuData.xml index 1df1cd5f8dae..02657340bf34 100644 --- a/app/code/Magento/Newsletter/Test/Mftf/Data/AdminMenuData.xml +++ b/app/code/Magento/Newsletter/Test/Mftf/Data/AdminMenuData.xml @@ -19,8 +19,8 @@ <data key="dataUiId">magento-newsletter-newsletter-subscriber</data> </entity> <entity name="AdminMenuMarketingCommunicationsNewsletterTemplate"> - <data key="pageTitle">Newsletter Template</data> - <data key="title">Newsletter Template</data> + <data key="pageTitle">Newsletter Templates</data> + <data key="title">Newsletter Templates</data> <data key="dataUiId">magento-newsletter-newsletter-template</data> </entity> <entity name="AdminMenuReportsMarketingNewsletterProblemReports"> From 6509f403abb24f45daad958c978141343b215a71 Mon Sep 17 00:00:00 2001 From: Veronika Kurochkina <veronika_kurochkina@epam.com> Date: Thu, 3 Oct 2019 13:10:39 +0300 Subject: [PATCH 0807/1172] MC-17653: Cannot schedule update for catalog price rule for date attribute - Fix merge conflict --- .../Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml index c364dca59223..614d464130ba 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml @@ -75,6 +75,10 @@ <grabTextFrom selector="{{PriceRuleConditionsSection.firstProductAttributeSelected}}" stepKey="grabTextFromSelectedAttribute" after="today"/> <assertEquals expected="$today" actual="$grabTextFromSelectedAttribute" stepKey="assertTodayDate" after="grabTextFromSelectedAttribute"/> </actionGroup> + <actionGroup name="AdminCreateMultipleWebsiteCatalogPriceRule" extends="createCatalogPriceRule"> + <remove keyForRemoval="selectSite"/> + <selectOption selector="{{AdminNewCatalogPriceRule.websites}}" parameterArray="['FirstWebsite', 'SecondWebsite']" stepKey="selectWebsite"/> + </actionGroup> <actionGroup name="CreateCatalogPriceRuleViaTheUi"> <arguments> <argument name="catalogRule" defaultValue="_defaultCatalogRule"/> From 271e0b9ba64007095384c35c9416f187c6619bb8 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Thu, 3 Oct 2019 13:28:31 +0300 Subject: [PATCH 0808/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Model/Cart/GetShippingAddress.php | 23 ++++++++++++++++--- .../Model/Cart/SetShippingAddressesOnCart.php | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php index 6e35091aecd7..badfe8ca4810 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php @@ -12,6 +12,7 @@ use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Quote\Model\Quote\Address; +use Magento\QuoteGraphQl\Model\Cart\Address\SaveQuoteAddressToCustomerAddressBook; /** * Get shipping address @@ -23,12 +24,21 @@ class GetShippingAddress */ private $quoteAddressFactory; + /** + * @var SaveQuoteAddressToCustomerAddressBook + */ + private $saveQuoteAddressToCustomerAddressBook; + /** * @param QuoteAddressFactory $quoteAddressFactory + * @param SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook */ - public function __construct(QuoteAddressFactory $quoteAddressFactory) - { + public function __construct( + QuoteAddressFactory $quoteAddressFactory, + SaveQuoteAddressToCustomerAddressBook $saveQuoteAddressToCustomerAddressBook + ) { $this->quoteAddressFactory = $quoteAddressFactory; + $this->saveQuoteAddressToCustomerAddressBook = $saveQuoteAddressToCustomerAddressBook; } /** @@ -62,8 +72,15 @@ public function execute(ContextInterface $context, array $shippingAddressInput): ); } + $customerId = $context->getUserId(); + if (null === $customerAddressId) { $shippingAddress = $this->quoteAddressFactory->createBasedOnInputData($addressInput); + + // need to save address only for registered user and if save_in_address_book = true + if (0 !== $customerId && !empty($addressInput['save_in_address_book'])) { + $this->saveQuoteAddressToCustomerAddressBook->execute($shippingAddress, $customerId); + } } else { if (false === $context->getExtensionAttributes()->getIsCustomer()) { throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.')); @@ -71,7 +88,7 @@ public function execute(ContextInterface $context, array $shippingAddressInput): $shippingAddress = $this->quoteAddressFactory->createBasedOnCustomerAddress( (int)$customerAddressId, - $context->getUserId() + $customerId ); } diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php index d4f2853467b3..6b1296eaf375 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/SetShippingAddressesOnCart.php @@ -7,7 +7,6 @@ namespace Magento\QuoteGraphQl\Model\Cart; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Model\Query\ContextInterface; use Magento\Quote\Api\Data\CartInterface; @@ -21,6 +20,7 @@ class SetShippingAddressesOnCart implements SetShippingAddressesOnCartInterface * @var AssignShippingAddressToCart */ private $assignShippingAddressToCart; + /** * @var GetShippingAddress */ From 179c5a2f3a3748beeec43807738674438f793b85 Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Thu, 3 Oct 2019 06:26:10 -0500 Subject: [PATCH 0809/1172] MC-15986: Category Filtering - added description changes from review --- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5e8f5590bbd3..5712db9f8bc7 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -16,7 +16,7 @@ type Query { @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") @doc(description: "The category query searches for categories that match the criteria specified in the search and filter attributes.") @deprecated(reason: "Use 'categoryList' query instead of 'category' query") @cache(cacheIdentity: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\CategoryTreeIdentity") categoryList( filters: CategoryFilterInput @doc(description: "Identifies which Category filter inputs to search for and return.") - ): [CategoryTree] @doc(description: "Categories filter.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryList") + ): [CategoryTree] @doc(description: "Returns an array of categories based on the specified filters.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryList") } type Price @doc(description: "The Price object defines the price of a product as well as any tax-related adjustments.") { @@ -113,7 +113,7 @@ type CustomizableAreaValue @doc(description: "CustomizableAreaValue defines the max_characters: Int @doc(description: "The maximum number of characters that can be entered for this customizable option.") } -type CategoryTree implements CategoryInterface @doc(description: "Category Tree implementation.") { +type CategoryTree implements CategoryInterface @doc(description: "An array containing the filtered categories and their subcategories") { children: [CategoryTree] @doc(description: "Child categories tree.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } @@ -282,7 +282,7 @@ input ProductAttributeFilterInput @doc(description: "ProductAttributeFilterInput input CategoryFilterInput @doc(description: "CategoryFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") { - ids: FilterEqualTypeInput @doc(description: "Filter by category ID that uniquely identifies and filters the category.") + ids: FilterEqualTypeInput @doc(description: "Filter by category ID that uniquely identifies the category.") url_key: FilterEqualTypeInput @doc(description: "Filter by the part of the URL that identifies the category") name: FilterMatchTypeInput @doc(description: "Filter by the display name of the category.") } From fa4567a98747918f0e8554443897b55584c16e1f Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Thu, 3 Oct 2019 06:35:24 -0500 Subject: [PATCH 0810/1172] MC-15986: Category Filtering - added resolver for category tree --- .../Model/Category/CategoryFilter.php | 66 +++++++++++ .../Model/Resolver/CategoryList.php | 105 ++++++++++++++++++ .../Products/Query/FieldSelection.php | 6 +- 3 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php new file mode 100644 index 000000000000..574f5dd2715c --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php @@ -0,0 +1,66 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Category;; + +use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; +use Magento\Catalog\Api\CategoryRepositoryInterface; + +/** + * Category filter allows to filter collection using 'id, url_key, name' from search criteria. + */ +class CategoryFilter +{ + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * @var CategoryRepositoryInterface + */ + private $categoryRepository; + + /** + * @param CategoryRepositoryInterface $categoryRepository; + * @param CollectionFactory $collectionFactory + */ + public function __construct( + CategoryRepositoryInterface $categoryRepository, + CollectionFactory $collectionFactory + ) { + $this->categoryRepository = $categoryRepository; + $this->collectionFactory = $collectionFactory; + } + + /** + * Filter for filtering the requested categories id's based on url_key, ids, name in the result. + * + * @param array $args + * + * @return array|int + */ + public function applyFilters(array $args) + { + $categoryCollection = $this->collectionFactory->create(); + foreach($args['filters'] as $field => $cond){ + foreach($cond as $condType => $value){ + if($field === 'ids'){ + $categoryCollection->addIdFilter($value); + } else { + $categoryCollection->addAttributeToFilter($field, [$condType => $value]); + } + } + } + $categoryIds = []; + $categoriesData = $categoryCollection->getData(); + foreach ($categoriesData as $categoryData){ + $categoryIds[] = (int)$categoryData['entity_id']; + } + return $categoryIds; + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php new file mode 100644 index 000000000000..932b88c68f1f --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php @@ -0,0 +1,105 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\CatalogGraphQl\Model\Resolver; + +use Magento\Catalog\Model\Category; +use Magento\CatalogGraphQl\Model\Resolver\Category\CheckCategoryIsActive; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree; +use Magento\CatalogGraphQl\Model\Category\CategoryFilter; + +/** + * Category tree resolver, used for GraphQL category data request processing. + */ +class CategoryList implements ResolverInterface +{ + /** + * Name of type in GraphQL + */ + const CATEGORY_INTERFACE = 'CategoryInterface'; + + /** + * @var CategoryTree + */ + private $categoryTree; + + /** + * @var CategoryFilter + */ + private $categoryFilter; + + /** + * @var ExtractDataFromCategoryTree + */ + private $extractDataFromCategoryTree; + + /** + * @var CheckCategoryIsActive + */ + private $checkCategoryIsActive; + + /** + * @param CategoryTree $categoryTree + * @param ExtractDataFromCategoryTree $extractDataFromCategoryTree + * @param CheckCategoryIsActive $checkCategoryIsActive + * @param CategoryFilter $categoryFilter + */ + public function __construct( + CategoryTree $categoryTree, + ExtractDataFromCategoryTree $extractDataFromCategoryTree, + CheckCategoryIsActive $checkCategoryIsActive, + CategoryFilter $categoryFilter + ) { + $this->categoryTree = $categoryTree; + $this->extractDataFromCategoryTree = $extractDataFromCategoryTree; + $this->checkCategoryIsActive = $checkCategoryIsActive; + $this->categoryFilter = $categoryFilter; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (isset($value[$field->getName()])) { + return $value[$field->getName()]; + } + + if (!isset($args['filters'])) { + throw new GraphQlInputException( + __( "'filters' input argument is required.") + ); + } + + $rootCategoryIds = $this->categoryFilter->applyFilters($args); + $result = []; + $categoriesTreeData = []; + + foreach ($rootCategoryIds as $rootCategoryId) { + if ($rootCategoryId !== Category::TREE_ROOT_ID) { + $this->checkCategoryIsActive->execute($rootCategoryId); + } + $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); + + if (empty($categoriesTree) || ($categoriesTree->count() == 0)) { + throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist')); + } + $categoriesTreeData[] = $categoriesTree; + } + + foreach ($categoriesTreeData as $treeData ) { + $result[] = $this->extractDataFromCategoryTree->execute($treeData); + } + return current($result); + } +} diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/FieldSelection.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/FieldSelection.php index 3912bab05ebb..ae4f2e911a5b 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/FieldSelection.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/Query/FieldSelection.php @@ -60,9 +60,9 @@ private function getProductFields(ResolveInfo $info): array $fieldNames[] = $this->collectProductFieldNames($selection, $fieldNames); } } - - $fieldNames = array_merge(...$fieldNames); - + if (!empty($fieldNames)) { + $fieldNames = array_merge(...$fieldNames); + } return $fieldNames; } From fd7522ff7c584a123be556c3b8fbb89d05a95c15 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Thu, 3 Oct 2019 14:40:50 +0300 Subject: [PATCH 0811/1172] graphQl-914: [Customer] Improve consistency of country field in customer address --- .../Address/CreateCustomerAddress.php | 1 + .../Address/ExtractCustomerAddressData.php | 4 +++ .../CustomerGraphQl/etc/schema.graphqls | 5 ++-- .../Customer/CreateCustomerAddressTest.php | 21 ++++++++------- .../Customer/UpdateCustomerAddressTest.php | 27 ++++++++++--------- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php index 474bd99a8f13..9637b3e555b8 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/CreateCustomerAddress.php @@ -67,6 +67,7 @@ public function __construct( */ public function execute(int $customerId, array $data): AddressInterface { + // It is needed because AddressInterface has country_id field. if (isset($data['country_code'])) { $data['country_id'] = $data['country_code']; } diff --git a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/ExtractCustomerAddressData.php b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/ExtractCustomerAddressData.php index 8741bff7aa88..7992ca834292 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Customer/Address/ExtractCustomerAddressData.php +++ b/app/code/Magento/CustomerGraphQl/Model/Customer/Address/ExtractCustomerAddressData.php @@ -127,6 +127,10 @@ public function execute(AddressInterface $address): array $addressData['customer_id'] = null; + if (isset($addressData['country_id'])) { + $addressData['country_code'] = $addressData['country_id']; + } + return $addressData; } } diff --git a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls index fea55ec38567..9ce2d61aa458 100644 --- a/app/code/Magento/CustomerGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CustomerGraphQl/etc/schema.graphqls @@ -28,7 +28,7 @@ input CustomerAddressInput { city: String @doc(description: "The city or town") region: CustomerAddressRegionInput @doc(description: "An object containing the region name, region code, and region ID") postcode: String @doc(description: "The customer's ZIP or postal code") - country_id: CountryCodeEnum @doc(description: "The customer's country") @deprecated(reason: "Use country_code instead.") + country_id: CountryCodeEnum @doc(description: "Deprecated, use country_code instead.") country_code: CountryCodeEnum @doc(description: "The customer's country") default_shipping: Boolean @doc(description: "Indicates whether the address is the default shipping address") default_billing: Boolean @doc(description: "Indicates whether the address is the default billing address") @@ -103,7 +103,8 @@ type CustomerAddress @doc(description: "CustomerAddress contains detailed inform customer_id: Int @doc(description: "The customer ID") @deprecated(reason: "customer_id is not needed as part of CustomerAddress, address ID (id) is unique identifier for the addresses.") region: CustomerAddressRegion @doc(description: "An object containing the region name, region code, and region ID") region_id: Int @deprecated(reason: "Region ID is excessive on storefront and region code should suffice for all scenarios") - country_id: String @doc(description: "The customer's country") + country_id: String @doc(description: "The customer's country") @deprecated(reason: "Use country_code instead.") + country_code: CountryCodeEnum @doc(description: "The customer's country") street: [String] @doc(description: "An array of strings that define the street number and name") company: String @doc(description: "The customer's company") telephone: String @doc(description: "The telephone number") diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php index 8860965d07f0..9ccd3b0d46c7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/CreateCustomerAddressTest.php @@ -139,7 +139,6 @@ public function testCreateCustomerAddress() */ public function testCreateCustomerAddressWithCountryCode() { - $customerId = 1; $newAddress = [ 'region' => [ 'region' => 'Arizona', @@ -195,7 +194,7 @@ public function testCreateCustomerAddressWithCountryCode() region_id region_code } - country_id + country_code street company telephone @@ -220,16 +219,14 @@ public function testCreateCustomerAddressWithCountryCode() $response = $this->graphQlMutation($mutation, [], '', $this->getCustomerAuthHeaders($userName, $password)); $this->assertArrayHasKey('createCustomerAddress', $response); $this->assertArrayHasKey('customer_id', $response['createCustomerAddress']); - $this->assertEquals($customerId, $response['createCustomerAddress']['customer_id']); + $this->assertEquals(null, $response['createCustomerAddress']['customer_id']); $this->assertArrayHasKey('id', $response['createCustomerAddress']); $address = $this->addressRepository->getById($response['createCustomerAddress']['id']); $this->assertEquals($address->getId(), $response['createCustomerAddress']['id']); - $newAddress['country_id'] = $newAddress['country_code']; - unset($newAddress['country_code']); - $this->assertCustomerAddressesFields($address, $response['createCustomerAddress']); - $this->assertCustomerAddressesFields($address, $newAddress); + $this->assertCustomerAddressesFields($address, $response['createCustomerAddress'], 'country_code'); + $this->assertCustomerAddressesFields($address, $newAddress, 'country_code'); } /** @@ -412,12 +409,16 @@ public function invalidInputDataProvider() * * @param AddressInterface $address * @param array $actualResponse + * @param string $countryFieldName */ - private function assertCustomerAddressesFields(AddressInterface $address, array $actualResponse): void - { + private function assertCustomerAddressesFields( + AddressInterface $address, + array $actualResponse, + string $countryFieldName = 'country_id' + ): void { /** @var $addresses */ $assertionMap = [ - ['response_field' => 'country_id', 'expected_value' => $address->getCountryId()], + ['response_field' => $countryFieldName, 'expected_value' => $address->getCountryId()], ['response_field' => 'street', 'expected_value' => $address->getStreet()], ['response_field' => 'company', 'expected_value' => $address->getCompany()], ['response_field' => 'telephone', 'expected_value' => $address->getTelephone()], diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php index 84525a55f8a9..d92c003c080e 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Customer/UpdateCustomerAddressTest.php @@ -85,7 +85,6 @@ public function testUpdateCustomerAddressWithCountryCode() { $userName = 'customer@example.com'; $password = 'password'; - $customerId = 1; $addressId = 1; $mutation = $this->getMutationWithCountryCode($addressId); @@ -93,15 +92,15 @@ public function testUpdateCustomerAddressWithCountryCode() $response = $this->graphQlMutation($mutation, [], '', $this->getCustomerAuthHeaders($userName, $password)); $this->assertArrayHasKey('updateCustomerAddress', $response); $this->assertArrayHasKey('customer_id', $response['updateCustomerAddress']); - $this->assertEquals($customerId, $response['updateCustomerAddress']['customer_id']); + $this->assertEquals(null, $response['updateCustomerAddress']['customer_id']); $this->assertArrayHasKey('id', $response['updateCustomerAddress']); $address = $this->addressRepository->getById($addressId); $this->assertEquals($address->getId(), $response['updateCustomerAddress']['id']); - $this->assertCustomerAddressesFields($address, $response['updateCustomerAddress']); + $this->assertCustomerAddressesFields($address, $response['updateCustomerAddress'], 'country_code'); $updateAddress = $this->getAddressDataCanadaCountry(); - $this->assertCustomerAddressesFields($address, $updateAddress); + $this->assertCustomerAddressesFields($address, $updateAddress, 'country_code'); } /** @@ -159,12 +158,16 @@ public function testUpdateCustomerAddressWithMissingAttribute() * * @param AddressInterface $address * @param array $actualResponse + * @param string $countryFieldName */ - private function assertCustomerAddressesFields(AddressInterface $address, $actualResponse): void - { + private function assertCustomerAddressesFields( + AddressInterface $address, + $actualResponse, + string $countryFieldName = 'country_id' + ): void { /** @var $addresses */ $assertionMap = [ - ['response_field' => 'country_id', 'expected_value' => $address->getCountryId()], + ['response_field' => $countryFieldName, 'expected_value' => $address->getCountryId()], ['response_field' => 'street', 'expected_value' => $address->getStreet()], ['response_field' => 'company', 'expected_value' => $address->getCompany()], ['response_field' => 'telephone', 'expected_value' => $address->getTelephone()], @@ -443,7 +446,7 @@ private function getAddressDataCanadaCountry(): array 'region_id' => 66, 'region_code' => 'AB' ], - 'country_id' => 'CA', + 'country_code' => 'CA', 'street' => ['Line 1 Street', 'Line 2'], 'company' => 'Company Name', 'telephone' => '123456789', @@ -531,8 +534,8 @@ private function getMutation(int $addressId): string private function getMutationWithCountryCode(int $addressId): string { $updateAddress = $this->getAddressDataCanadaCountry(); - $defaultShippingText = $updateAddress['default_shipping'] ? "true" : "false"; - $defaultBillingText = $updateAddress['default_billing'] ? "true" : "false"; + $defaultShippingText = $updateAddress['default_shipping'] ? 'true' : 'false'; + $defaultBillingText = $updateAddress['default_billing'] ? 'true' : 'false'; $mutation = <<<MUTATION @@ -543,7 +546,7 @@ private function getMutationWithCountryCode(int $addressId): string region_id: {$updateAddress['region']['region_id']} region_code: "{$updateAddress['region']['region_code']}" } - country_code: {$updateAddress['country_id']} + country_code: {$updateAddress['country_code']} street: ["{$updateAddress['street'][0]}","{$updateAddress['street'][1]}"] company: "{$updateAddress['company']}" telephone: "{$updateAddress['telephone']}" @@ -566,7 +569,7 @@ private function getMutationWithCountryCode(int $addressId): string region_id region_code } - country_id + country_code street company telephone From 5ad96052adf4a83e1d84533e37e0c801edb9a872 Mon Sep 17 00:00:00 2001 From: RomanKis <roman.kis.y@gmail.com> Date: Thu, 3 Oct 2019 14:45:58 +0300 Subject: [PATCH 0812/1172] graphQl-509: `save_in_address_book` has no impact on Address Book --- .../Model/Cart/GetShippingAddress.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php index badfe8ca4810..b25a8aed6ca8 100644 --- a/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php +++ b/app/code/Magento/QuoteGraphQl/Model/Cart/GetShippingAddress.php @@ -72,6 +72,26 @@ public function execute(ContextInterface $context, array $shippingAddressInput): ); } + $shippingAddress = $this->createShippingAddress($context, $customerAddressId, $addressInput); + + return $shippingAddress; + } + + /** + * Create shipping address. + * + * @param ContextInterface $context + * @param int|null $customerAddressId + * @param array|null $addressInput + * + * @return \Magento\Quote\Model\Quote\Address + * @throws GraphQlAuthorizationException + */ + private function createShippingAddress( + ContextInterface $context, + ?int $customerAddressId, + ?array $addressInput + ) { $customerId = $context->getUserId(); if (null === $customerAddressId) { From 5bc1526f6bc4e5384c5c0c27d08b1d58b553fce0 Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Thu, 3 Oct 2019 16:32:17 +0300 Subject: [PATCH 0813/1172] MC-17469: Fatal error is displayed during multishipping checkout when open Cart page in another window --- app/code/Magento/Multishipping/Block/Checkout/Shipping.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php index 9cfcb4b64794..99450fc53807 100644 --- a/app/code/Magento/Multishipping/Block/Checkout/Shipping.php +++ b/app/code/Magento/Multishipping/Block/Checkout/Shipping.php @@ -70,7 +70,9 @@ public function getCheckout() } /** - * @inheritDoc + * Add page title and prepare layout + * + * @return $this */ protected function _prepareLayout() { From 46e21b2a4a6b3ed7aea2d4d1f4e4e471a7471ed2 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Wed, 2 Oct 2019 19:35:58 -0500 Subject: [PATCH 0814/1172] MC-17518: Cart Rest API not showing all shipping assignments for multi-shipping --- .../DisableMultishippingMode.php} | 4 +- ...n.php => MultishippingQuoteRepository.php} | 4 +- ...tPlugin.php => ResetShippingAssigment.php} | 2 +- .../DisableMultishippingModeTest.php} | 10 +- app/code/Magento/Multishipping/etc/di.xml | 2 +- .../Magento/Multishipping/etc/frontend/di.xml | 8 +- .../Multishipping/Api/CartRepositoryTest.php | 139 ++++++++++++++++++ .../Magento/Quote/Api/CartRepositoryTest.php | 46 ------ 8 files changed, 154 insertions(+), 61 deletions(-) rename app/code/Magento/Multishipping/{Controller/Checkout/Plugin.php => Plugin/DisableMultishippingMode.php} (93%) rename app/code/Magento/Multishipping/Plugin/{MultishippingQuoteRepositoryPlugin.php => MultishippingQuoteRepository.php} (98%) rename app/code/Magento/Multishipping/Plugin/{ResetShippingAssigmentPlugin.php => ResetShippingAssigment.php} (97%) rename app/code/Magento/Multishipping/Test/Unit/{Controller/Checkout/PluginTest.php => Plugin/DisableMultishippingModeTest.php} (91%) create mode 100644 dev/tests/api-functional/testsuite/Magento/Multishipping/Api/CartRepositoryTest.php diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php b/app/code/Magento/Multishipping/Plugin/DisableMultishippingMode.php similarity index 93% rename from app/code/Magento/Multishipping/Controller/Checkout/Plugin.php rename to app/code/Magento/Multishipping/Plugin/DisableMultishippingMode.php index f60feb2b834b..fff2346d7624 100644 --- a/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php +++ b/app/code/Magento/Multishipping/Plugin/DisableMultishippingMode.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -namespace Magento\Multishipping\Controller\Checkout; +namespace Magento\Multishipping\Plugin; use Magento\Checkout\Model\Cart; use Magento\Framework\App\Action\Action; @@ -13,7 +13,7 @@ /** * Turns Off Multishipping mode for Quote. */ -class Plugin +class DisableMultishippingMode { /** * @var Cart diff --git a/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php b/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepository.php similarity index 98% rename from app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php rename to app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepository.php index db972cf9bd7c..af19e4bc91f5 100644 --- a/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepositoryPlugin.php +++ b/app/code/Magento/Multishipping/Plugin/MultishippingQuoteRepository.php @@ -15,9 +15,9 @@ use Magento\Quote\Model\ShippingAssignmentFactory; /** - * Plugin for multishipping quote processing in WebAPI. + * Plugin for multishipping quote processing. */ -class MultishippingQuoteRepositoryPlugin +class MultishippingQuoteRepository { /** * @var ShippingAssignmentFactory diff --git a/app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php b/app/code/Magento/Multishipping/Plugin/ResetShippingAssigment.php similarity index 97% rename from app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php rename to app/code/Magento/Multishipping/Plugin/ResetShippingAssigment.php index 376dbf723b88..deac19e23a23 100644 --- a/app/code/Magento/Multishipping/Plugin/ResetShippingAssigmentPlugin.php +++ b/app/code/Magento/Multishipping/Plugin/ResetShippingAssigment.php @@ -13,7 +13,7 @@ /** * Resets quote shipping assignments when item is removed from multishipping quote. */ -class ResetShippingAssigmentPlugin +class ResetShippingAssigment { /** * @var ShippingAssignmentProcessor diff --git a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php b/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php similarity index 91% rename from app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php rename to app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php index 5397317ca299..96aa364c3873 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Controller/Checkout/PluginTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php @@ -10,15 +10,15 @@ use Magento\Checkout\Controller\Index\Index; use Magento\Checkout\Model\Cart; -use Magento\Multishipping\Controller\Checkout\Plugin; +use Magento\Multishipping\Plugin\DisableMultishippingMode; use Magento\Quote\Api\Data\CartExtensionInterface; use Magento\Quote\Api\Data\ShippingAssignmentInterface; use Magento\Quote\Model\Quote; /** - * Class PluginTest + * Class DisableMultishippingModeTest */ -class PluginTest extends \PHPUnit\Framework\TestCase +class DisableMultishippingModeTest extends \PHPUnit\Framework\TestCase { /** * @var \PHPUnit_Framework_MockObject_MockObject @@ -31,7 +31,7 @@ class PluginTest extends \PHPUnit\Framework\TestCase private $quoteMock; /** - * @var Plugin + * @var DisableMultishippingMode */ private $object; @@ -48,7 +48,7 @@ protected function setUp() $this->cartMock->expects($this->once()) ->method('getQuote') ->will($this->returnValue($this->quoteMock)); - $this->object = new \Magento\Multishipping\Controller\Checkout\Plugin($this->cartMock); + $this->object = new DisableMultishippingMode($this->cartMock); } /** diff --git a/app/code/Magento/Multishipping/etc/di.xml b/app/code/Magento/Multishipping/etc/di.xml index 993376da8378..ad0d341d6b2e 100644 --- a/app/code/Magento/Multishipping/etc/di.xml +++ b/app/code/Magento/Multishipping/etc/di.xml @@ -10,6 +10,6 @@ <plugin name="multishipping_shipping_addresses" type="Magento\Multishipping\Model\Cart\CartTotalRepositoryPlugin" /> </type> <type name="Magento\Quote\Model\QuoteRepository"> - <plugin name="multishipping_quote_repository" type="Magento\Multishipping\Plugin\MultishippingQuoteRepositoryPlugin" /> + <plugin name="multishipping_quote_repository" type="Magento\Multishipping\Plugin\MultishippingQuoteRepository" /> </type> </config> diff --git a/app/code/Magento/Multishipping/etc/frontend/di.xml b/app/code/Magento/Multishipping/etc/frontend/di.xml index 3d85f4c8a447..481b95280a4a 100644 --- a/app/code/Magento/Multishipping/etc/frontend/di.xml +++ b/app/code/Magento/Multishipping/etc/frontend/di.xml @@ -31,13 +31,13 @@ </arguments> </type> <type name="Magento\Checkout\Controller\Cart\Add"> - <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" /> + <plugin name="multishipping_disabler" type="Magento\Multishipping\Plugin\DisableMultishippingMode" sortOrder="50" /> </type> <type name="Magento\Checkout\Controller\Cart\UpdatePost"> - <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" /> + <plugin name="multishipping_disabler" type="Magento\Multishipping\Plugin\DisableMultishippingMode" sortOrder="50" /> </type> <type name="Magento\Checkout\Controller\Index\Index"> - <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" /> + <plugin name="multishipping_disabler" type="Magento\Multishipping\Plugin\DisableMultishippingMode" sortOrder="50" /> </type> <type name="Magento\Checkout\Model\Cart"> <plugin name="multishipping_session_mapper" type="Magento\Multishipping\Model\Checkout\Type\Multishipping\Plugin" sortOrder="50" /> @@ -46,6 +46,6 @@ <plugin name="multishipping_clear_addresses" type="Magento\Multishipping\Model\Cart\Controller\CartPlugin" sortOrder="50" /> </type> <type name="Magento\Quote\Model\Quote"> - <plugin name="multishipping_reset_shipping_assigment" type="Magento\Multishipping\Plugin\ResetShippingAssigmentPlugin"/> + <plugin name="multishipping_reset_shipping_assigment" type="Magento\Multishipping\Plugin\ResetShippingAssigment"/> </type> </config> diff --git a/dev/tests/api-functional/testsuite/Magento/Multishipping/Api/CartRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Multishipping/Api/CartRepositoryTest.php new file mode 100644 index 000000000000..46844438fdd9 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/Multishipping/Api/CartRepositoryTest.php @@ -0,0 +1,139 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Multishipping\Api; + +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Quote\Api\CartRepositoryInterface; +use Magento\Quote\Model\Quote; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; +use Magento\TestFramework\TestCase\WebapiAbstract; + +/** + * Tests web-api for multishipping quote. + */ +class CartRepositoryTest extends WebapiAbstract +{ + /** + * @var ObjectManager + */ + private $objectManager; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @var SortOrderBuilder + */ + private $sortOrderBuilder; + + /** + * @var FilterBuilder + */ + private $filterBuilder; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->filterBuilder = $this->objectManager->create(FilterBuilder::class); + $this->sortOrderBuilder = $this->objectManager->create(SortOrderBuilder::class); + $this->searchCriteriaBuilder = $this->objectManager->create(SearchCriteriaBuilder::class); + } + + /** + * @inheritdoc + */ + protected function tearDown() + { + try { + /** @var CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class); + $cart = $this->getCart('multishipping_quote_id'); + $quoteRepository->delete($cart); + } catch (\InvalidArgumentException $e) { + // Do nothing if cart fixture was not used + } + parent::tearDown(); + } + + /** + * Tests that multishipping quote contains all addresses in shipping assignments. + * + * @magentoApiDataFixture Magento/Multishipping/Fixtures/quote_with_split_items.php + */ + public function testGetMultishippingCart() + { + $cart = $this->getCart('multishipping_quote_id'); + $cartId = $cart->getId(); + + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => '/V1/carts/' . $cartId, + 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => 'quoteCartRepositoryV1', + 'serviceVersion' => 'V1', + 'operation' => 'quoteCartRepositoryV1Get', + ], + ]; + + $requestData = ['cartId' => $cartId]; + $cartData = $this->_webApiCall($serviceInfo, $requestData); + + $shippingAssignments = $cart->getExtensionAttributes()->getShippingAssignments(); + foreach ($shippingAssignments as $key => $shippingAssignment) { + $address = $shippingAssignment->getShipping()->getAddress(); + $cartItem = $shippingAssignment->getItems()[0]; + $this->assertEquals( + $address->getId(), + $cartData['extension_attributes']['shipping_assignments'][$key]['shipping']['address']['id'] + ); + $this->assertEquals( + $cartItem->getSku(), + $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['sku'] + ); + $this->assertEquals( + $cartItem->getQty(), + $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['qty'] + ); + } + } + + /** + * Retrieve quote by given reserved order ID + * + * @param string $reservedOrderId + * @return Quote + * @throws \InvalidArgumentException + */ + private function getCart(string $reservedOrderId): Quote + { + /** @var SearchCriteriaBuilder $searchCriteriaBuilder */ + $searchCriteriaBuilder = $this->objectManager->get(SearchCriteriaBuilder::class); + $searchCriteria = $searchCriteriaBuilder->addFilter('reserved_order_id', $reservedOrderId) + ->create(); + + /** @var CartRepositoryInterface $quoteRepository */ + $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class); + $items = $quoteRepository->getList($searchCriteria)->getItems(); + + if (empty($items)) { + throw new \InvalidArgumentException('There is no quote with provided reserved order ID.'); + } + + return array_pop($items); + } +} diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php index 7ffc4311e40e..5a894758dc9e 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php @@ -66,8 +66,6 @@ protected function tearDown() $quoteRepository = $this->objectManager->get(CartRepositoryInterface::class); $cart = $this->getCart('test01'); $quoteRepository->delete($cart); - $cart = $this->getCart('multishipping_quote_id'); - $quoteRepository->delete($cart); } catch (\InvalidArgumentException $e) { // Do nothing if cart fixture was not used } @@ -145,50 +143,6 @@ public function testGetCart() $this->assertEquals($cart->getStoreToQuoteRate(), $cartData['currency']['store_to_quote_rate']); } - /** - * Tests that multishipping quote contains all addresses in shipping assignments. - * - * @magentoApiDataFixture Magento/Multishipping/Fixtures/quote_with_split_items.php - */ - public function testGetMultishippingCart() - { - $cart = $this->getCart('multishipping_quote_id'); - $cartId = $cart->getId(); - - $serviceInfo = [ - 'rest' => [ - 'resourcePath' => '/V1/carts/' . $cartId, - 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET, - ], - 'soap' => [ - 'service' => 'quoteCartRepositoryV1', - 'serviceVersion' => 'V1', - 'operation' => 'quoteCartRepositoryV1Get', - ], - ]; - - $requestData = ['cartId' => $cartId]; - $cartData = $this->_webApiCall($serviceInfo, $requestData); - - $shippingAssignments = $cart->getExtensionAttributes()->getShippingAssignments(); - foreach ($shippingAssignments as $key => $shippingAssignment) { - $address = $shippingAssignment->getShipping()->getAddress(); - $cartItem = $shippingAssignment->getItems()[0]; - $this->assertEquals( - $address->getId(), - $cartData['extension_attributes']['shipping_assignments'][$key]['shipping']['address']['id'] - ); - $this->assertEquals( - $cartItem->getSku(), - $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['sku'] - ); - $this->assertEquals( - $cartItem->getQty(), - $cartData['extension_attributes']['shipping_assignments'][$key]['items'][0]['qty'] - ); - } - } - /** * Tests exception when cartId is not provided. * From db1771d1cff37f66bb295f0add9419e99d84f009 Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Thu, 3 Oct 2019 10:29:35 -0500 Subject: [PATCH 0815/1172] MC-20534: Migrate remaining failed MFTF tests to SearchEngineMysqlSuite --- .../Catalog/Test/Mftf/Data/ProductData.xml | 14 +++++ ...CustomOptionsSuiteAndImportOptionsTest.xml | 2 + .../Test/AdminSimpleProductImagesTest.xml | 2 + ...eForSimpleProductWithCustomOptionsTest.xml | 52 +++---------------- 4 files changed, 26 insertions(+), 44 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index 1335a2c5046c..aad43bb7011c 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -559,6 +559,20 @@ <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> </entity> + <entity name="ApiVirtualProductWithDescriptionAndUnderscoredSku" type="product"> + <data key="sku" unique="suffix">api_virtual_product</data> + <data key="type_id">virtual</data> + <data key="attribute_set_id">4</data> + <data key="visibility">4</data> + <data key="name" unique="suffix">Api Virtual Product</data> + <data key="price">123.00</data> + <data key="urlKey" unique="suffix">api-virtual-product</data> + <data key="status">1</data> + <data key="quantity">100</data> + <requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductDescription</requiredEntity> + <requiredEntity type="custom_attribute_array">ApiProductShortDescription</requiredEntity> + </entity> <entity name="SimpleProductWithNewFromDate" type="product"> <data key="sku" unique="suffix">SimpleProduct</data> <data key="type_id">simple</data> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml index 58737dd50974..23f772a395a7 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml @@ -117,6 +117,8 @@ <!-- Verify we see success message --> <see selector="{{AdminProductFormSection.successMessage}}" userInput="You saved the product." stepKey="seeAssertVirtualProductSuccessMessage"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> <!-- Verify customer see created virtual product with custom options suite and import options(from above step) on storefront page and is searchable by sku --> <amOnPage url="{{StorefrontProductPage.url(virtualProductCustomImportOptions.urlKey)}}" stepKey="goToProductPage"/> diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml index 1cd0e15780c1..4875197380f3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleProductImagesTest.xml @@ -144,6 +144,8 @@ <!-- Save the second product --> <click selector="{{AdminProductFormActionSection.saveButton}}" stepKey="saveProduct2"/> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> <!-- Go to the admin grid and see the uploaded image --> <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="goToProductIndex3"/> diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml index 5b7e722c92a0..a251ee1e235d 100644 --- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml +++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductWithCustomOptionsTest.xml @@ -77,63 +77,27 @@ <actionGroup ref="SaveAndApplyCatalogPriceRuleActionGroup" stepKey="saveAndApplyCatalogPriceRule"/> <magentoCLI command="indexer:reindex" stepKey="reindex"/> <magentoCLI command="cache:flush" stepKey="flushCache"/> - + <!-- Navigate to category on store front --> <amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/> - - <!-- Check product 1 name on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Name"> - <argument name="productInfo" value="$createProduct1.name$"/> - <argument name="productNumber" value="3"/> - </actionGroup> <!-- Check product 1 price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1Price"> - <argument name="productInfo" value="$51.10"/> - <argument name="productNumber" value="3"/> - </actionGroup> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$51.10" stepKey="storefrontProduct1Price"/> <!-- Check product 1 regular price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct1RegularPrice"> - <argument name="productInfo" value="$56.78"/> - <argument name="productNumber" value="3"/> - </actionGroup> - - <!-- Check product 2 name on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct2Name"> - <argument name="productInfo" value="$createProduct2.name$"/> - <argument name="productNumber" value="2"/> - </actionGroup> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct1.name$)}}" userInput="$56.78" stepKey="storefrontProduct1RegularPrice"/> <!-- Check product 2 price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct2Price"> - <argument name="productInfo" value="$51.10"/> - <argument name="productNumber" value="2"/> - </actionGroup> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$51.10" stepKey="storefrontProduct2Price"/> - <!-- Check product 2 price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct2RegularPrice"> - <argument name="productInfo" value="$56.78"/> - <argument name="productNumber" value="2"/> - </actionGroup> - - <!-- Check product 3 name on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct3Name"> - <argument name="productInfo" value="$createProduct3.name$"/> - <argument name="productNumber" value="1"/> - </actionGroup> + <!-- Check product 2 regular price on store front category page --> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct2.name$)}}" userInput="$56.78" stepKey="storefrontProduct2RegularPrice"/> <!-- Check product 3 price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct3Price"> - <argument name="productInfo" value="$51.10"/> - <argument name="productNumber" value="1"/> - </actionGroup> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$51.10" stepKey="storefrontProduct3Price"/> <!-- Check product 3 regular price on store front category page --> - <actionGroup ref="AssertProductDetailsOnStorefrontActionGroup" stepKey="storefrontProduct3RegularPrice"> - <argument name="productInfo" value="$56.78"/> - <argument name="productNumber" value="1"/> - </actionGroup> + <see selector="{{StorefrontCategoryProductSection.ProductInfoByName($createProduct3.name$)}}" userInput="$56.78" stepKey="storefrontProduct3RegularPrice"/> <!-- Navigate to product 1 on store front --> <amOnPage url="{{StorefrontProductPage.url($createProduct1.name$)}}" stepKey="goToProductPage1"/> From 287e906eaf3dd0b93f3f39e43a0cd79ef98e17ea Mon Sep 17 00:00:00 2001 From: Tomash Khamlai <tomash.khamlai@gmail.com> Date: Thu, 3 Oct 2019 19:40:51 +0300 Subject: [PATCH 0816/1172] Extend test coverage for BraintreeGraphQ Cover exception: - `Required parameter "is_active_payment_token_enabler" for "braintree" is missing.` Cover: - Case when Magento\Braintree\Gateway\Request\PaymentDataBuilder receives MERCHANT_ACCOUNT_ID (deprecated) Signed-off-by: Tomash Khamlai <tomash.khamlai@gmail.com> --- .../CreateBraintreeClientTokenTest.php | 1 + .../Customer/SetPaymentMethodTest.php | 58 ++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/CreateBraintreeClientTokenTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/CreateBraintreeClientTokenTest.php index 1564d00fa599..7d69c49ae6aa 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/CreateBraintreeClientTokenTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/CreateBraintreeClientTokenTest.php @@ -20,6 +20,7 @@ class CreateBraintreeClientTokenTest extends GraphQlAbstract * @magentoConfigFixture default_store payment/braintree/active 1 * @magentoConfigFixture default_store payment/braintree/environment sandbox * @magentoConfigFixture default_store payment/braintree/merchant_id def_merchant_id + * @magentoConfigFixture default_store payment/braintree/merchant_account_id def_merchant_id * @magentoConfigFixture default_store payment/braintree/public_key def_public_key * @magentoConfigFixture default_store payment/braintree/private_key def_private_key */ diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php index 84a639af30b0..b48e9064dae7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Braintree/Customer/SetPaymentMethodTest.php @@ -8,6 +8,7 @@ namespace Magento\GraphQl\Braintree\Customer; use Magento\Braintree\Gateway\Command\GetPaymentNonceCommand; +use Magento\Framework\Exception\AuthenticationException; use Magento\Framework\Registry; use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\Integration\Api\CustomerTokenServiceInterface; @@ -261,6 +262,34 @@ public function testSetPaymentMethodInvalidMethodInput(string $methodCode) $this->graphQlMutation($setPaymentQuery, [], '', $this->getHeaderMap()); } + /** + * @magentoConfigFixture default_store carriers/flatrate/active 1 + * @magentoConfigFixture default_store payment/braintree/active 1 + * @magentoConfigFixture default_store payment/braintree_cc_vault/active 1 + * @magentoConfigFixture default_store payment/braintree/environment sandbox + * @magentoConfigFixture default_store payment/braintree/merchant_id def_merchant_id + * @magentoConfigFixture default_store payment/braintree/public_key def_public_key + * @magentoConfigFixture default_store payment/braintree/private_key def_private_key + * @magentoApiDataFixture Magento/Customer/_files/customer.php + * @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/customer/create_empty_cart.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/add_simple_product.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_shipping_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_new_billing_address.php + * @magentoApiDataFixture Magento/GraphQl/Quote/_files/set_flatrate_shipping_method.php + * @dataProvider dataProviderTestSetPaymentMethodInvalidInput + * @expectedException \Exception + */ + public function testSetPaymentMethodWithoutRequiredPaymentMethodInput() + { + $reservedOrderId = 'test_quote'; + $maskedQuoteId = $this->getMaskedQuoteIdByReservedOrderId->execute($reservedOrderId); + + $setPaymentQuery = $this->getSetPaymentBraintreeQueryInvalidPaymentMethodInput($maskedQuoteId); + $this->expectExceptionMessage("for \"braintree\" is missing."); + $this->graphQlMutation($setPaymentQuery, [], '', $this->getHeaderMap()); + } + public function dataProviderTestSetPaymentMethodInvalidInput(): array { return [ @@ -371,6 +400,33 @@ private function getSetPaymentBraintreeQueryInvalidInput(string $maskedQuoteId, QUERY; } + /** + * @param string $maskedQuoteId + * @return string + */ + private function getSetPaymentBraintreeQueryInvalidPaymentMethodInput(string $maskedQuoteId): string + { + return <<<QUERY +mutation { + setPaymentMethodOnCart(input:{ + cart_id:"{$maskedQuoteId}" + payment_method:{ + code:"braintree" + braintree:{ + payment_method_nonce:"fake-valid-nonce" + } + } + }) { + cart { + selected_payment_method { + code + } + } + } +} +QUERY; + } + /** * @param string $maskedQuoteId * @param string $methodCode @@ -437,7 +493,7 @@ private function getPaymentTokenQuery(): string * @param string $username * @param string $password * @return array - * @throws \Magento\Framework\Exception\AuthenticationException + * @throws AuthenticationException */ private function getHeaderMap(string $username = 'customer@example.com', string $password = 'password'): array { From ecd52b945c28bad14267c31f14e1284d55b5ce6b Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Thu, 3 Oct 2019 12:09:09 -0500 Subject: [PATCH 0817/1172] MC-15986: Category Filtering - added resolver changes for category list query --- .../Model/Category/CategoryFilter.php | 29 ++++++------------ .../Model/Resolver/CategoryList.php | 30 +++++-------------- .../CatalogGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 18 insertions(+), 43 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php index 574f5dd2715c..5058bb2e07c6 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php @@ -5,10 +5,9 @@ */ declare(strict_types=1); -namespace Magento\CatalogGraphQl\Model\Category;; +namespace Magento\CatalogGraphQl\Model\Category; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; -use Magento\Catalog\Api\CategoryRepositoryInterface; /** * Category filter allows to filter collection using 'id, url_key, name' from search criteria. @@ -21,19 +20,11 @@ class CategoryFilter private $collectionFactory; /** - * @var CategoryRepositoryInterface - */ - private $categoryRepository; - - /** - * @param CategoryRepositoryInterface $categoryRepository; * @param CollectionFactory $collectionFactory */ public function __construct( - CategoryRepositoryInterface $categoryRepository, CollectionFactory $collectionFactory ) { - $this->categoryRepository = $categoryRepository; $this->collectionFactory = $collectionFactory; } @@ -41,15 +32,14 @@ public function __construct( * Filter for filtering the requested categories id's based on url_key, ids, name in the result. * * @param array $args - * - * @return array|int + * @return array */ - public function applyFilters(array $args) + public function applyFilters(array $args): array { $categoryCollection = $this->collectionFactory->create(); - foreach($args['filters'] as $field => $cond){ - foreach($cond as $condType => $value){ - if($field === 'ids'){ + foreach ($args['filters'] as $field => $cond) { + foreach ($cond as $condType => $value) { + if ($field === 'ids') { $categoryCollection->addIdFilter($value); } else { $categoryCollection->addAttributeToFilter($field, [$condType => $value]); @@ -57,10 +47,9 @@ public function applyFilters(array $args) } } $categoryIds = []; - $categoriesData = $categoryCollection->getData(); - foreach ($categoriesData as $categoryData){ - $categoryIds[] = (int)$categoryData['entity_id']; + foreach ($categoryCollection as $category) { + $categoryIds[] = (int)$category->getId(); } - return $categoryIds; + return $categoryIds; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php index 932b88c68f1f..2511e07dc4f8 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php @@ -14,20 +14,14 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree; use Magento\CatalogGraphQl\Model\Category\CategoryFilter; /** - * Category tree resolver, used for GraphQL category data request processing. + * Category List resolver, used for GraphQL category data request processing. */ class CategoryList implements ResolverInterface { - /** - * Name of type in GraphQL - */ - const CATEGORY_INTERFACE = 'CategoryInterface'; - /** * @var CategoryTree */ @@ -76,30 +70,22 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value } if (!isset($args['filters'])) { - throw new GraphQlInputException( - __( "'filters' input argument is required.") - ); + $rootCategoryIds = [(int)$context->getExtensionAttributes()->getStore()->getRootCategoryId()]; + } else { + $rootCategoryIds = $this->categoryFilter->applyFilters($args); } - $rootCategoryIds = $this->categoryFilter->applyFilters($args); $result = []; - $categoriesTreeData = []; - foreach ($rootCategoryIds as $rootCategoryId) { if ($rootCategoryId !== Category::TREE_ROOT_ID) { $this->checkCategoryIsActive->execute($rootCategoryId); } - $categoriesTree = $this->categoryTree->getTree($info, $rootCategoryId); - - if (empty($categoriesTree) || ($categoriesTree->count() == 0)) { + $categoryTree = $this->categoryTree->getTree($info, $rootCategoryId); + if (empty($categoryTree)) { throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist')); } - $categoriesTreeData[] = $categoriesTree; - } - - foreach ($categoriesTreeData as $treeData ) { - $result[] = $this->extractDataFromCategoryTree->execute($treeData); + $result[] = current($this->extractDataFromCategoryTree->execute($categoryTree)); } - return current($result); + return $result; } } diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 0cc3901a1f07..9c729a175ad0 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -129,7 +129,7 @@ type CustomizableAreaValue @doc(description: "CustomizableAreaValue defines the max_characters: Int @doc(description: "The maximum number of characters that can be entered for this customizable option.") } -type CategoryTree implements CategoryInterface @doc(description: "An array containing the filtered categories and their subcategories") { +type CategoryTree implements CategoryInterface @doc(description: "Category Tree implementation.") { children: [CategoryTree] @doc(description: "Child categories tree.") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\CategoryTree") } From 64fb8a1f22df1487623d4aa7d17de20d5817d052 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 3 Oct 2019 12:44:58 -0500 Subject: [PATCH 0818/1172] MC-20508: Api-functional tests for Product prices including FPT - added FPT schema implementation - deprecated price adjustments in schema - added test coverage for product with FPT attributes --- .../Model/Resolver/Product/PriceRange.php | 24 +- .../CatalogGraphQl/etc/schema.graphqls | 10 +- .../Magento/Weee/Model/ResourceModel/Tax.php | 93 ++-- .../Model/Resolver/FixedProductTax.php | 87 +++ app/code/Magento/WeeeGraphQl/composer.json | 6 +- .../Magento/WeeeGraphQl/etc/schema.graphqls | 15 +- .../Catalog/ProductPriceWithFPTTest.php | 509 ++++++++++++++++++ .../Weee/_files/fixed_product_attribute.php | 59 +- .../fixed_product_attribute_rollback.php | 24 +- .../Magento/Weee/_files/product_with_fpt.php | 4 + .../Weee/_files/product_with_fpt_rollback.php | 5 +- 11 files changed, 751 insertions(+), 85 deletions(-) create mode 100644 app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php index 2607af0ed0ab..9396b1f02b97 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Product/PriceRange.php @@ -62,10 +62,16 @@ public function resolve( $product = $value['model']; $product->unsetData('minimal_price'); - return [ - 'minimum_price' => $this->getMinimumProductPrice($product, $store), - 'maximum_price' => $this->getMaximumProductPrice($product, $store) - ]; + $requestedFields = $info->getFieldSelection(10); + $returnArray = []; + + if (isset($requestedFields['minimum_price'])) { + $returnArray['minimum_price'] = $this->getMinimumProductPrice($product, $store); + } + if (isset($requestedFields['maximum_price'])) { + $returnArray['maximum_price'] = $this->getMaximumProductPrice($product, $store); + } + return $returnArray; } /** @@ -80,8 +86,9 @@ private function getMinimumProductPrice(SaleableInterface $product, StoreInterfa $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); $regularPrice = $priceProvider->getMinimalRegularPrice($product)->getValue(); $finalPrice = $priceProvider->getMinimalFinalPrice($product)->getValue(); - - return $this->formatPrice($regularPrice, $finalPrice, $store); + $minPriceArray = $this->formatPrice($regularPrice, $finalPrice, $store); + $minPriceArray['model'] = $product; + return $minPriceArray; } /** @@ -96,8 +103,9 @@ private function getMaximumProductPrice(SaleableInterface $product, StoreInterfa $priceProvider = $this->priceProviderPool->getProviderByProductType($product->getTypeId()); $regularPrice = $priceProvider->getMaximalRegularPrice($product)->getValue(); $finalPrice = $priceProvider->getMaximalFinalPrice($product)->getValue(); - - return $this->formatPrice($regularPrice, $finalPrice, $store); + $maxPriceArray = $this->formatPrice($regularPrice, $finalPrice, $store); + $maxPriceArray['model'] = $product; + return $maxPriceArray; } /** diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index e70b64e7f97d..0ec29369a85a 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -21,16 +21,16 @@ type Price @doc(description: "Price is deprecated, replaced by ProductPrice. The adjustments: [PriceAdjustment] @deprecated(reason: "Price is deprecated, use ProductPrice.") @doc(description: "An array that provides information about tax, weee, or weee_tax adjustments.") } -type PriceAdjustment @doc(description: "The PricedAdjustment object defines the amount of money to apply as an adjustment, the type of adjustment to apply, and whether the item is included or excluded from the adjustment.") { +type PriceAdjustment @doc(description: "PriceAdjustment is deprecated. Taxes will be included or excluded in the price. The PricedAdjustment object defines the amount of money to apply as an adjustment, the type of adjustment to apply, and whether the item is included or excluded from the adjustment.") { amount: Money @doc(description: "The amount of the price adjustment and its currency code.") - code: PriceAdjustmentCodesEnum @doc(description: "Indicates whether the adjustment involves tax, weee, or weee_tax.") - description: PriceAdjustmentDescriptionEnum @doc(description: "Indicates whether the entity described by the code attribute is included or excluded from the adjustment.") + code: PriceAdjustmentCodesEnum @deprecated(reason: "PriceAdjustment is deprecated.") @doc(description: "Indicates whether the adjustment involves tax, weee, or weee_tax.") + description: PriceAdjustmentDescriptionEnum @deprecated(reason: "PriceAdjustment is deprecated.") @doc(description: "Indicates whether the entity described by the code attribute is included or excluded from the adjustment.") } -enum PriceAdjustmentCodesEnum @doc(description: "Note: This enumeration contains values defined in modules other than the Catalog module.") { +enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated. This enumeration contains values defined in modules other than the Catalog module.") { } -enum PriceAdjustmentDescriptionEnum @doc(description: "This enumeration states whether a price adjustment is included or excluded.") { +enum PriceAdjustmentDescriptionEnum @doc(description: "PriceAdjustmentDescriptionEnum is deprecated. This enumeration states whether a price adjustment is included or excluded.") { INCLUDED EXCLUDED } diff --git a/app/code/Magento/Weee/Model/ResourceModel/Tax.php b/app/code/Magento/Weee/Model/ResourceModel/Tax.php index b097e4a018f2..2cbb6054a31e 100644 --- a/app/code/Magento/Weee/Model/ResourceModel/Tax.php +++ b/app/code/Magento/Weee/Model/ResourceModel/Tax.php @@ -5,9 +5,6 @@ */ namespace Magento\Weee\Model\ResourceModel; -use Magento\Catalog\Model\Product; -use Magento\Catalog\Model\Product\Condition\ConditionInterface; - /** * Wee tax resource model * @@ -21,6 +18,11 @@ class Tax extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $dateTime; + /** + * @var array + */ + private $weeeTaxCalculationsByEntityCache = []; + /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Framework\Stdlib\DateTime $dateTime @@ -46,7 +48,7 @@ protected function _construct() } /** - * Fetch one + * Fetch one calculated weee attribute from a select criteria * * @param \Magento\Framework\DB\Select|string $select * @return string @@ -57,6 +59,8 @@ public function fetchOne($select) } /** + * Is there a weee attribute available for the location provided + * * @param int $countryId * @param int $regionId * @param int $websiteId @@ -91,6 +95,8 @@ public function isWeeeInLocation($countryId, $regionId, $websiteId) } /** + * Fetch calculated weee attributes by location, store and entity + * * @param int $countryId * @param int $regionId * @param int $websiteId @@ -100,43 +106,56 @@ public function isWeeeInLocation($countryId, $regionId, $websiteId) */ public function fetchWeeeTaxCalculationsByEntity($countryId, $regionId, $websiteId, $storeId, $entityId) { - $attributeSelect = $this->getConnection()->select(); - $attributeSelect->from( - ['eavTable' => $this->getTable('eav_attribute')], - ['eavTable.attribute_code', 'eavTable.attribute_id', 'eavTable.frontend_label'] - )->joinLeft( - ['eavLabel' => $this->getTable('eav_attribute_label')], - 'eavLabel.attribute_id = eavTable.attribute_id and eavLabel.store_id = ' .((int) $storeId), - 'eavLabel.value as label_value' - )->joinInner( - ['weeeTax' => $this->getTable('weee_tax')], - 'weeeTax.attribute_id = eavTable.attribute_id', - 'weeeTax.value as weee_value' - )->where( - 'eavTable.frontend_input = ?', - 'weee' - )->where( - 'weeeTax.website_id IN(?)', - [$websiteId, 0] - )->where( - 'weeeTax.country = ?', - $countryId - )->where( - 'weeeTax.state IN(?)', - [$regionId, 0] - )->where( - 'weeeTax.entity_id = ?', - (int)$entityId + $cacheKey = sprintf( + '%s-%s-%s-%s-%s', + $countryId, + $regionId, + $websiteId, + $storeId, + $entityId ); + if (!isset($this->weeeTaxCalculationsByEntityCache[$cacheKey])) { + $attributeSelect = $this->getConnection()->select(); + $attributeSelect->from( + ['eavTable' => $this->getTable('eav_attribute')], + ['eavTable.attribute_code', 'eavTable.attribute_id', 'eavTable.frontend_label'] + )->joinLeft( + ['eavLabel' => $this->getTable('eav_attribute_label')], + 'eavLabel.attribute_id = eavTable.attribute_id and eavLabel.store_id = ' . ((int)$storeId), + 'eavLabel.value as label_value' + )->joinInner( + ['weeeTax' => $this->getTable('weee_tax')], + 'weeeTax.attribute_id = eavTable.attribute_id', + 'weeeTax.value as weee_value' + )->where( + 'eavTable.frontend_input = ?', + 'weee' + )->where( + 'weeeTax.website_id IN(?)', + [$websiteId, 0] + )->where( + 'weeeTax.country = ?', + $countryId + )->where( + 'weeeTax.state IN(?)', + [$regionId, 0] + )->where( + 'weeeTax.entity_id = ?', + (int)$entityId + ); - $order = ['weeeTax.state ' . \Magento\Framework\DB\Select::SQL_DESC, - 'weeeTax.website_id ' . \Magento\Framework\DB\Select::SQL_DESC]; - $attributeSelect->order($order); + $order = ['weeeTax.state ' . \Magento\Framework\DB\Select::SQL_DESC, + 'weeeTax.website_id ' . \Magento\Framework\DB\Select::SQL_DESC]; + $attributeSelect->order($order); - $values = $this->getConnection()->fetchAll($attributeSelect); + $values = $this->getConnection()->fetchAll($attributeSelect); - if ($values) { - return $values; + if ($values) { + $this->weeeTaxCalculationsByEntityCache[$cacheKey] = $values; + return $values; + } + } else { + return $this->weeeTaxCalculationsByEntityCache[$cacheKey]; } return []; diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php new file mode 100644 index 000000000000..98164c18e858 --- /dev/null +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/FixedProductTax.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\WeeeGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Weee\Helper\Data; +use Magento\Framework\Exception\LocalizedException; +use Magento\Tax\Helper\Data as TaxHelper; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Tax\Model\Config; + +/** + * Resolver for FixedProductTax object that retrieves an array of FPT attributes with prices + */ +class FixedProductTax implements ResolverInterface +{ + /** + * @var Data + */ + private $weeeHelper; + + /** + * @var TaxHelper + */ + private $taxHelper; + + /** + * @param Data $weeeHelper + * @param TaxHelper $taxHelper + */ + public function __construct(Data $weeeHelper, TaxHelper $taxHelper) + { + $this->weeeHelper = $weeeHelper; + $this->taxHelper = $taxHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('"model" value should be specified')); + } + + $fptArray = []; + $product = $value['model']; + + /** @var StoreInterface $store */ + $store = $context->getExtensionAttributes()->getStore(); + + if ($this->weeeHelper->isEnabled($store)) { + $attributes = $this->weeeHelper->getProductWeeeAttributesForDisplay($product); + foreach ($attributes as $attribute) { + $displayInclTaxes = $this->taxHelper->getPriceDisplayType($store); + $amount = $attribute->getData('amount'); + //add display mode for WEE to not return WEE if excluded + if ($displayInclTaxes === Config::DISPLAY_TYPE_EXCLUDING_TAX) { + $amount = $attribute->getData('amount_excl_tax'); + } elseif ($displayInclTaxes === Config::DISPLAY_TYPE_INCLUDING_TAX) { + $amount = $attribute->getData('amount_excl_tax') + $attribute->getData('tax_amount'); + } + $fptArray[] = [ + 'amount' => [ + 'value' => $amount, + 'currency' => $value['final_price']['currency'], + ], + 'label' => $attribute->getData('name') + ]; + } + } + + return $fptArray; + } +} diff --git a/app/code/Magento/WeeeGraphQl/composer.json b/app/code/Magento/WeeeGraphQl/composer.json index 0bf303f789a7..39b77bb569ac 100644 --- a/app/code/Magento/WeeeGraphQl/composer.json +++ b/app/code/Magento/WeeeGraphQl/composer.json @@ -4,10 +4,12 @@ "type": "magento2-module", "require": { "php": "~7.1.3||~7.2.0||~7.3.0", - "magento/framework": "*" + "magento/framework": "*", + "magento/module-store": "*", + "magento/module-tax": "*", + "magento/module-weee": "*" }, "suggest": { - "magento/module-weee": "*", "magento/module-catalog-graph-ql": "*" }, "license": [ diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 731260ce9e1e..95ca88ee7a99 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -1,7 +1,16 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. -enum PriceAdjustmentCodesEnum { - WEE - WEETAX +enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated, use ProductPrice.") { + WEEE @deprecated(reason: "WEEE is deprecated, use fixed_product_taxes.label") + WEEE_TAX @deprecated(reason: "WEEE_TAX is deprecated, use fixed_product_taxes. Tax is included or excluded in the amount") +} + +type ProductPrice { + fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FixedProductTax") +} + +type FixedProductTax @doc(description: "A single FPT that can be applied to a product price.") { + amount: Money @doc(description: "Amount of the FPT as a money object.") + label: String @doc(description: "The label assigned to the FPT to be displayed on the frontend.") } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php new file mode 100644 index 000000000000..336559e5e445 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php @@ -0,0 +1,509 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\App\Config\Storage\WriterInterface; +use Magento\Framework\ObjectManager\ObjectManager; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\TestCase\GraphQlAbstract; +use Magento\Tax\Model\ClassModel as TaxClassModel; +use Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory as TaxClassCollectionFactory; + +class ProductPriceWithFPTTest extends GraphQlAbstract +{ + /** @var ObjectManager $objectManager */ + private $objectManager; + + protected function setUp() :void + { + $this->objectManager = Bootstrap::getObjectManager(); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxAndIncludeFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/calculation/price_includes_tax', '0'); + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $prod2 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + + // final price and regular price are the sum of product price, FPT and product tax + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + } + + /** + * Catalog Prices : Excluding Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/calculation/price_includes_tax', '0'); + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/weee/apply_vat', '0'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + // final price and regular price are the sum of product price and FPT + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Excluding Tax + * FPT Display setting: Including FPT and FPT description + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '1'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT Only + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + // final price and regular price are the sum of product price and FPT + $this->assertEquals(112.7, $product['price_range']['minimum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['minimum_price']['final_price']['value']); + + $this->assertEquals(112.7, $product['price_range']['maximum_price']['regular_price']['value']); + $this->assertEquals(112.7, $product['price_range']['maximum_price']['final_price']['value']); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals(12.7, $fixedProductTax['amount']['value']); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + /** + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT Description + * Apply Tax to FPT = Yes + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '0'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + $configWriter->save('tax/weee/apply_vat', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + + //12.7 + 7.5% of 12.7 = 13.65 + $fptWithTax = round(13.65, 2) ; + // final price and regular price are the sum of product price and FPT + $this->assertEquals(113.65, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertEquals(113.65, round($product['price_range']['minimum_price']['final_price']['value'], 2)); + + $this->assertEquals(113.65, round($product['price_range']['maximum_price']['regular_price']['value'], 2)); + $this->assertEquals(113.65, round($product['price_range']['maximum_price']['final_price']['value'], 2)); + + $this->assertNotEmpty($product['price_range']['minimum_price']['fixed_product_taxes']); + $fixedProductTax = $product['price_range']['minimum_price']['fixed_product_taxes'][0]; + $this->assertEquals($fptWithTax, round($fixedProductTax['amount']['value'], 2)); + $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); + } + + + /** + * Use multiple FPTs per product with the below tax/fpt configurations + * + * Catalog Prices : Including Tax + * Catalog Display setting: Including Tax + * FPT Display setting: Including FPT and FPT description + * Apply tax on FPT : Yes + * + * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php + * @magentoApiDataFixture Magento/Weee/_files/fixed_product_attribute.php + * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php + */ + public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs() + { + /** @var WriterInterface $configWriter */ + $configWriter = $this->objectManager->get(WriterInterface::class); + + $configWriter->save('tax/display/type', '2'); + $configWriter->save('tax/weee/enable', '1'); + $configWriter->save('tax/weee/display', '1'); + $configWriter->save('tax/defaults/region', '1'); + $configWriter->save('tax/calculation/price_includes_tax', '1'); + $configWriter->save('tax/weee/apply_vat', '1'); + + /** @var ScopeConfigInterface $scopeConfig */ + $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); + $scopeConfig->clean(); + + /** @var TaxClassCollectionFactory $taxClassCollectionFactory */ + $taxClassCollectionFactory = $this->objectManager->get(TaxClassCollectionFactory::class); + $taxClassCollection = $taxClassCollectionFactory->create(); + /** @var TaxClassModel $taxClass */ + $taxClassCollection->addFieldToFilter('class_type', TaxClassModel::TAX_CLASS_TYPE_PRODUCT); + $taxClass = $taxClassCollection->getFirstItem(); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); + /** @var Product $product1 */ + $product1 = $productRepository->get('simple-with-ftp'); + $product1->setCustomAttribute('tax_class_id', $taxClass->getClassId()); + $product1->setFixedProductAttribute( + [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10, 'delete' => '']] + ); + $productRepository->save($product1); + + $skus = ['simple-with-ftp']; + $query = $this->getProductQuery($skus); + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertNotEmpty($result['products']['items']); + $product = $result['products']['items'][0]; + $this->assertEquals(124.40, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); + $this->assertCount( + 2, + $product['price_range']['minimum_price']['fixed_product_taxes'], + 'Fixed product tax count is incorrect' + ); + $this->assertResponseFields( + $product['price_range']['minimum_price']['fixed_product_taxes'], + [ + [ + 'amount' => [ + 'value' => 13.6525 + ], + 'label' => 'fpt_for_all_front_label' + ], + [ + 'amount' => [ + 'value' => 10.75 + ], + 'label' => 'fixed_product_attribute_front_label' + ], + ] + ); + } + + /** + * Get GraphQl query to fetch products by sku + * + * @param array $skus + * @return string + */ + private function getProductQuery(array $skus): string + { + $stringSkus = '"' . implode('","', $skus) . '"'; + return <<<QUERY +{ + products(filter: {sku: {in: [$stringSkus]}}, sort: {name: ASC}) { + items { + name + sku + price_range { + minimum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + fixed_product_taxes{ + amount{value} + label + } + } + maximum_price { + regular_price { + value + currency + } + final_price { + value + currency + } + discount { + amount_off + percent_off + } + fixed_product_taxes + { + amount{value} + label + } + } + } + } + } +} +QUERY; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php index a20d1cac9422..426cbdfd50a3 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php @@ -3,31 +3,46 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); -$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - -/** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */ -$attributeSet = $objectManager->create(\Magento\Eav\Model\Entity\Attribute\Set::class); +use Magento\Catalog\Model\Product; +use Magento\TestFramework\Helper\Bootstrap; -$entityType = $objectManager->create(\Magento\Eav\Model\Entity\Type::class)->loadByCode('catalog_product'); -$defaultSetId = $objectManager->create(\Magento\Catalog\Model\Product::class)->getDefaultAttributeSetid(); +/** @var \Magento\Catalog\Setup\CategorySetup $installer */ +$installer = Bootstrap::getObjectManager()->create( + \Magento\Catalog\Setup\CategorySetup::class +); +$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default'); +$entityModel = Bootstrap::getObjectManager()->create(\Magento\Eav\Model\Entity::class); +$entityTypeId = $entityModel->setType(Product::ENTITY)->getTypeId(); +$groupId = $installer->getDefaultAttributeGroupId($entityTypeId, $attributeSetId); -$attributeGroupId = $attributeSet->getDefaultGroupId($entityType->getDefaultAttributeSetId()); +/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ +$attribute = Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class +); +$attribute->setAttributeCode( + 'fixed_product_attribute' +)->setEntityTypeId( + $entityTypeId +)->setAttributeGroupId( + $groupId +)->setAttributeSetId( + $attributeSetId +)->setFrontendLabel( + 'fixed_product_attribute_front_label' +)->setFrontendInput( + 'weee' +)->setIsUserDefined( + 1 +)->save(); -$attributeData = [ - 'entity_type_id' => $entityType->getId(), - 'attribute_code' => 'fixed_product_attribute', - 'backend_model' => 'Magento\Weee\Model\Attribute\Backend\Weee\Tax', - 'is_required' => 0, - 'is_user_defined' => 1, - 'is_static' => 1, - 'attribute_set_id' => $defaultSetId, - 'attribute_group_id' => $attributeGroupId, -]; +/** @var $product \Magento\Catalog\Model\Product */ +$product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); -/** @var \Magento\Catalog\Model\Entity\Attribute $attribute */ -$attribute = $objectManager->create(\Magento\Eav\Model\Entity\Attribute::class); -$attribute->setData($attributeData); -$attribute->save(); +$product = $product->loadByAttribute('sku', 'simple-with-ftp'); +if ($product->getId()) { + $product->setFixedProductAttribute( + [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10.00, 'delete' => '']] + )->save(); +} diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php index 1d6e15b2e9a9..5ceabcd75cbd 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php @@ -3,12 +3,24 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - declare(strict_types=1); -$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); +use Magento\TestFramework\Helper\Bootstrap; + +$objectManager = Bootstrap::getObjectManager(); +/** @var \Magento\Framework\Registry $registry */ +$registry = $objectManager->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ +$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); +$attribute->load('fixed_product_attribute', 'attribute_code'); +if ($attribute->getId()) { + $attribute->delete(); +} -/* @var EavAttribute $attribute */ -$attribute = $objectManager->get(\Magento\Eav\Model\Entity\Attribute::class); -$attribute->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'fixed_product_attribute'); -$attribute->delete(); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php index 0e67a8947a79..59a5516bd67d 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt.php @@ -16,6 +16,7 @@ $entityTypeId = $entityModel->setType(Product::ENTITY)->getTypeId(); $groupId = $installer->getDefaultAttributeGroupId($entityTypeId, $attributeSetId); +/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ $attribute = Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\ResourceModel\Eav\Attribute::class ); @@ -27,12 +28,15 @@ $groupId )->setAttributeSetId( $attributeSetId +)->setFrontendLabel( + 'fpt_for_all_front_label' )->setFrontendInput( 'weee' )->setIsUserDefined( 1 )->save(); +/** @var Product $product */ $product = Bootstrap::getObjectManager()->create(Product::class); $product->setTypeId( 'simple' diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php index d0305f461eb0..ba024011274a 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php @@ -13,12 +13,13 @@ /** @var $product \Magento\Catalog\Model\Product */ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); -$product->load(101); + +$product = $product->loadByAttribute('sku', 'simple-with-ftp'); if ($product->getId()) { $product->delete(); } -/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */ +/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */ $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class); $attribute->load('fpt_for_all', 'attribute_code'); From 88446dd0820c7adc682bafb3f254f57454c2480b Mon Sep 17 00:00:00 2001 From: Soumya Unnikrishnan <sunnikri@adobe.com> Date: Thu, 3 Oct 2019 13:15:07 -0500 Subject: [PATCH 0819/1172] MQE-1686: Paypal integration test leveraging Adobe Vault - PayPalSmartButtonInCheckoutPage Added action group for SamplePaypalConfig. --- ...xpressCheckoutConfigurationActionGroup.xml | 24 +++++++++++++++++++ ...figPaymentsConflictResolutionForPayPal.xml | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml index 1ed519a8a3db..4d752d837764 100644 --- a/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml +++ b/app/code/Magento/Paypal/Test/Mftf/ActionGroup/PayPalExpressCheckoutConfigurationActionGroup.xml @@ -33,6 +33,30 @@ <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> </actionGroup> + <actionGroup name="SampleConfigPayPalExpressCheckout"> + <annotations> + <description>Goes to the 'Configuration' page for 'Payment Methods'. Fills in the provided Sample PayPal credentials and other details. Clicks on Save.</description> + </annotations> + <arguments> + <argument name="credentials" defaultValue="SamplePaypalExpressConfig"/> + <argument name="countryCode" type="string" defaultValue="us"/> + </arguments> + <amOnPage url="{{AdminConfigPaymentMethodsPage.url}}" stepKey="navigateToPaymentConfigurationPage"/> + <waitForPageLoad stepKey="waitForPageLoad1"/> + <click selector="{{PayPalExpressCheckoutConfigSection.configureBtn(countryCode)}}" stepKey="clickPayPalConfigureBtn"/> + <waitForElementVisible selector="{{PayPalAdvancedSettingConfigSection.advancedSettingTab(countryCode)}}" stepKey="waitForAdvancedSettingTab"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.email(countryCode)}}" userInput="{{credentials.paypal_express_email}}" stepKey="inputEmailAssociatedWithPayPalMerchantAccount"/> + <selectOption selector ="{{PayPalExpressCheckoutConfigSection.apiMethod(countryCode)}}" userInput="API Signature" stepKey="inputAPIAuthenticationMethods"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.username(countryCode)}}" userInput="{{credentials.paypal_express_api_username}}" stepKey="inputAPIUsername"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.password(countryCode)}}" userInput="{{credentials.paypal_express_api_password}}" stepKey="inputAPIPassword"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.signature(countryCode)}}" userInput="{{credentials.paypal_express_api_signature}}" stepKey="inputAPISignature"/> + <selectOption selector ="{{PayPalExpressCheckoutConfigSection.sandboxMode(countryCode)}}" userInput="Yes" stepKey="enableSandboxMode"/> + <selectOption selector="{{PayPalExpressCheckoutConfigSection.enableSolution(countryCode)}}" userInput="Yes" stepKey="enableSolution"/> + <fillField selector ="{{PayPalExpressCheckoutConfigSection.merchantID(countryCode)}}" userInput="{{credentials.paypal_express_merchantID}}" stepKey="inputMerchantID"/> + <!--Save configuration--> + <click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/> + </actionGroup> + <actionGroup name="CreatePayPalOrderWithSelectedPaymentMethodActionGroup" extends="CreateOrderToPrintPageActionGroup"> <annotations> <description>EXTENDS: CreateOrderToPrintPageActionGroup. Clicks on PayPal. Fills the PayPay details in the modal. PLEASE NOTE: The PayPal Payment credentials are Hardcoded using 'Payer'.</description> diff --git a/app/code/Magento/Paypal/Test/Mftf/Test/AdminConfigPaymentsConflictResolutionForPayPal.xml b/app/code/Magento/Paypal/Test/Mftf/Test/AdminConfigPaymentsConflictResolutionForPayPal.xml index a6e741f0151e..cfc7d66ba23c 100644 --- a/app/code/Magento/Paypal/Test/Mftf/Test/AdminConfigPaymentsConflictResolutionForPayPal.xml +++ b/app/code/Magento/Paypal/Test/Mftf/Test/AdminConfigPaymentsConflictResolutionForPayPal.xml @@ -20,7 +20,7 @@ </annotations> <before> <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> - <actionGroup ref="ConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpress"> + <actionGroup ref="SampleConfigPayPalExpressCheckout" stepKey="ConfigPayPalExpress"> <argument name="credentials" value="SamplePaypalExpressConfig"/> </actionGroup> </before> From d015409302077afc9943449b743a398714e62958 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Thu, 3 Oct 2019 13:39:02 -0500 Subject: [PATCH 0820/1172] MC-17518: Cart Rest API not showing all shipping assignments for multi-shipping -Fix namespace --- .../Test/Unit/Plugin/DisableMultishippingModeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php b/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php index 96aa364c3873..02ae1a70ce80 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Plugin/DisableMultishippingModeTest.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace Magento\Multishipping\Test\Unit\Controller\Checkout; +namespace Magento\Multishipping\Test\Unit\Plugin; use Magento\Checkout\Controller\Index\Index; use Magento\Checkout\Model\Cart; From be5455a58240b57e4dc0c44a5cea2bb5a2e01c57 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Thu, 3 Oct 2019 13:51:17 -0500 Subject: [PATCH 0821/1172] MC-21481: TransportBuilder doesn't add "to" email-addresses, if given in array --- .../Magento/Framework/Mail/Template/TransportBuilder.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php index 4a8d6572faaf..f2f61cfd7ef1 100644 --- a/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php +++ b/lib/internal/Magento/Framework/Mail/Template/TransportBuilder.php @@ -427,6 +427,8 @@ private function addAddressByType(string $addressType, $email, ?string $name = n $this->messageData[$addressType], $convertedAddressArray ); + } else { + $this->messageData[$addressType] = $convertedAddressArray; } } } From 87385d6ea05c1ec1fe0c7d9bdb25d1a250fc2d75 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 3 Oct 2019 15:15:36 -0500 Subject: [PATCH 0822/1172] MC-20508: Api-functional tests for Product prices including FPT - refactor data providers --- .../Catalog/ProductPriceWithFPTTest.php | 297 ++++++++++++++---- 1 file changed, 241 insertions(+), 56 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php index 336559e5e445..69308b38cbf7 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php @@ -7,7 +7,6 @@ namespace Magento\GraphQl\Catalog; - use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product; use Magento\Framework\App\Config\ScopeConfigInterface; @@ -18,11 +17,19 @@ use Magento\Tax\Model\ClassModel as TaxClassModel; use Magento\Tax\Model\ResourceModel\TaxClass\CollectionFactory as TaxClassCollectionFactory; +/** + * Test for Product Price With FPT + * + * @SuppressWarnings(PHPMD.TooManyPublicMethods) + */ class ProductPriceWithFPTTest extends GraphQlAbstract { - /** @var ObjectManager $objectManager */ + /** @var ObjectManager $objectManager */ private $objectManager; + /** + * @inheritdoc + */ protected function setUp() :void { $this->objectManager = Bootstrap::getObjectManager(); @@ -33,19 +40,21 @@ protected function setUp() :void * Catalog Display setting: Excluding Tax * FPT Display setting: Including FPT only * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceExcludeTaxAndIncludeFPTOnlySettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceExcludeTaxAndIncludeFPTOnly() + public function testCatalogPriceExcludeTaxAndIncludeFPTOnly(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '1'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '0'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/weee/apply_vat', '0'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -72,24 +81,46 @@ public function testCatalogPriceExcludeTaxAndIncludeFPTOnly() $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); } + /** + * CatalogPriceExcludeTaxAndIncludeFPTOnlyProvider settings data provider + * + * @return array + */ + public function catalogPriceExcludeTaxAndIncludeFPTOnlySettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/display/type' => '1', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '0', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '0', + ] + ] + ]; + } + /** * Catalog Prices : Excluding Tax * Catalog Display setting: Excluding Tax * FPT Display setting: Including FPT and FPT description * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceExcludeTaxAndIncludeFPTWithDescriptionSettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription() + public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '1'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '1'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/weee/apply_vat', '0'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -116,25 +147,46 @@ public function testCatalogPriceExcludeTaxAndIncludeFPTWithDescription() $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); } + /** + * CatalogPriceExcludeTaxAndIncludeFPTWithDescription settings data provider + * + * @return array + */ + public function catalogPriceExcludeTaxAndIncludeFPTWithDescriptionSettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/display/type' => '1', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '1', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '0', + ] + ] + ]; + } + /** * Catalog Prices : Excluding Tax * Catalog Display setting: Including Tax * FPT Display setting: Including FPT only * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnlySettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly() + public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/calculation/price_includes_tax', '0'); - $configWriter->save('tax/display/type', '2'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '0'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/weee/apply_vat', '0'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -170,25 +222,47 @@ public function testCatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTO $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); } + /** + * CatalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnly settings data provider + * + * @return array + */ + public function catalogPriceExcludeTaxCatalogDisplayIncludeTaxAndIncludeFPTOnlySettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' => '0', + 'tax/display/type' => '2', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '0', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '0', + ] + ] + ]; + } + /** * Catalog Prices : Excluding Tax * Catalog Display setting: Including Tax * FPT Display setting: Including FPT and FPT description * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescriptionSettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription() + public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/calculation/price_includes_tax', '0'); - $configWriter->save('tax/display/type', '2'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '1'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/weee/apply_vat', '0'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -224,24 +298,47 @@ public function testCatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescri $this->assertEquals(120.2, round($product['price_range']['maximum_price']['final_price']['value'], 2)); } + /** + * CatalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescription settings data provider + * + * @return array + */ + public function catalogPriceExclTaxCatalogDisplayInclTaxAndInclFPTWithDescriptionSettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' => '0', + 'tax/display/type' => '2', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '1', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '0', + ] + ] + ]; + } + /** * Catalog Prices : Including Tax * Catalog Display setting: Excluding Tax * FPT Display setting: Including FPT and FPT description * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescriptionSettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription() + public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '1'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '1'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/calculation/price_includes_tax', '1'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -268,24 +365,47 @@ public function testCatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescri $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); } + /** + * CatalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescription settings data provider + * + * @return array + */ + public function catalogPriceInclTaxCatalogDisplayExclTaxAndInclFPTWithDescriptionSettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' => '1', + 'tax/display/type' => '1', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '1', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '1', + ] + ] + ]; + } + /** * Catalog Prices : Including Tax * Catalog Display setting: Including Tax * FPT Display setting: Including FPT Only * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnlySettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly() + public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '2'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '0'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/calculation/price_includes_tax', '1'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -312,26 +432,49 @@ public function testCatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly() $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); } + /** + * CatalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnly settings data provider + * + * @return array + */ + public function catalogPriceInclTaxCatalogDisplayInclTaxAndInclFPTOnlySettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' => '1', + 'tax/display/type' => '2', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '0', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '0', + ] + ] + ]; + } + /** * Catalog Prices : Including Tax * Catalog Display setting: Including Tax * FPT Display setting: Including FPT and FPT Description * Apply Tax to FPT = Yes * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPTSettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT() - { + public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT( + array $weeTaxSettings + ) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '2'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '0'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/calculation/price_includes_tax', '1'); - $configWriter->save('tax/weee/apply_vat', '1'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -357,7 +500,7 @@ public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithT $product = $result['products']['items'][0]; //12.7 + 7.5% of 12.7 = 13.65 - $fptWithTax = round(13.65, 2) ; + $fptWithTax = round(13.65, 2); // final price and regular price are the sum of product price and FPT $this->assertEquals(113.65, round($product['price_range']['minimum_price']['regular_price']['value'], 2)); $this->assertEquals(113.65, round($product['price_range']['minimum_price']['final_price']['value'], 2)); @@ -371,6 +514,26 @@ public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithT $this->assertEquals('fpt_for_all_front_label', $fixedProductTax['label']); } + /** + * CatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPT settings data provider + * + * @return array + */ + public function catalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAppliedOnFPTSettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' > '1', + 'tax/display/type' => '2', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '0', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '1', + ] + ] + ]; + } /** * Use multiple FPTs per product with the below tax/fpt configurations @@ -380,21 +543,22 @@ public function testCatalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithT * FPT Display setting: Including FPT and FPT description * Apply tax on FPT : Yes * + * @param array $weeTaxSettings + * @return void + * + * @dataProvider catalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTsSettingsProvider * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php * @magentoApiDataFixture Magento/Weee/_files/fixed_product_attribute.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ - public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs() + public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs(array $weeTaxSettings) { /** @var WriterInterface $configWriter */ $configWriter = $this->objectManager->get(WriterInterface::class); - $configWriter->save('tax/display/type', '2'); - $configWriter->save('tax/weee/enable', '1'); - $configWriter->save('tax/weee/display', '1'); - $configWriter->save('tax/defaults/region', '1'); - $configWriter->save('tax/calculation/price_includes_tax', '1'); - $configWriter->save('tax/weee/apply_vat', '1'); + foreach ($weeTaxSettings as $path => $value) { + $configWriter->save($path, $value); + } /** @var ScopeConfigInterface $scopeConfig */ $scopeConfig = $this->objectManager->get(ScopeConfigInterface::class); @@ -447,6 +611,27 @@ public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs( ); } + /** + * CatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTsSettingsProvider settings data provider + * + * @return array + */ + public function catalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTsSettingsProvider() + { + return [ + [ + 'weeTaxSettings' => [ + 'tax/calculation/price_includes_tax' => '1', + 'tax/display/type' => '2', + 'tax/weee/enable' => '1', + 'tax/weee/display' => '1', + 'tax/defaults/region' => '1', + 'tax/weee/apply_vat' => '1', + ] + ] + ]; + } + /** * Get GraphQl query to fetch products by sku * From db9d9f4c846f9ede712ac00f891bcaa913bad5a6 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 3 Oct 2019 15:27:16 -0500 Subject: [PATCH 0823/1172] MC-20508: Api-functional tests for Product prices including FPT - refactor data providers --- .../testsuite/Magento/GraphQl/Tax/ProductViewTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php index dfbe943ecdcd..f235595de86d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php @@ -263,7 +263,7 @@ private function assertBaseFields($product, $actualResponse) [ 'minimalPrice' => [ 'amount' => [ - 'value' => 4.106501, + 'value' => 4.1065, 'currency' => 'USD' ], 'adjustments' => [ @@ -281,7 +281,7 @@ private function assertBaseFields($product, $actualResponse) ], 'regularPrice' => [ 'amount' => [ - 'value' => 10.750001, + 'value' => 10.7500, 'currency' => 'USD' ], 'adjustments' => [ @@ -299,7 +299,7 @@ private function assertBaseFields($product, $actualResponse) ], 'maximalPrice' => [ 'amount' => [ - 'value' => 4.106501, + 'value' => 4.1065, 'currency' => 'USD' ], 'adjustments' => [ From 40d27a35e5adf5ef47bea3e6a0c37c5cccb24ecd Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Thu, 3 Oct 2019 16:13:20 -0500 Subject: [PATCH 0824/1172] MC-20508: Api-functional tests for Product prices including FPT - fix static --- .../testsuite/Magento/GraphQl/Tax/ProductViewTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php index f235595de86d..048ccb70af0d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Tax/ProductViewTest.php @@ -253,7 +253,7 @@ private function getFixtureTaxRules() */ private function assertBaseFields($product, $actualResponse) { - // ['product_object_field_name', 'expected_value'] + // product_object_field_name, expected_value $assertionMap = [ ['response_field' => 'attribute_set_id', 'expected_value' => $product->getAttributeSetId()], ['response_field' => 'created_at', 'expected_value' => $product->getCreatedAt()], From f6446259cea26f20c9f2471b86127af136c3352c Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Thu, 3 Oct 2019 17:24:52 -0500 Subject: [PATCH 0825/1172] MC-15986: Category Filtering - added resolver changes on filter --- .../Model/Category/CategoryFilter.php | 18 +++++++-------- .../Model/Resolver/CategoryList.php | 23 ++++++++++++++++--- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php index 5058bb2e07c6..42f35a871185 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php @@ -32,24 +32,24 @@ public function __construct( * Filter for filtering the requested categories id's based on url_key, ids, name in the result. * * @param array $args - * @return array + * @param \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection + * @return bool */ - public function applyFilters(array $args): array - { - $categoryCollection = $this->collectionFactory->create(); + public function applyFilters( + array $args, + \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection + ): bool { foreach ($args['filters'] as $field => $cond) { foreach ($cond as $condType => $value) { if ($field === 'ids') { $categoryCollection->addIdFilter($value); + } elseif ($condType === 'match') { + $categoryCollection->addAttributeToFilter($field, ['like' => "%{$value}%"]); } else { $categoryCollection->addAttributeToFilter($field, [$condType => $value]); } } } - $categoryIds = []; - foreach ($categoryCollection as $category) { - $categoryIds[] = (int)$category->getId(); - } - return $categoryIds; + return true; } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php index 2511e07dc4f8..140cb68be679 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php @@ -16,6 +16,7 @@ use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\CategoryTree; use Magento\CatalogGraphQl\Model\Category\CategoryFilter; +use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; /** * Category List resolver, used for GraphQL category data request processing. @@ -27,6 +28,11 @@ class CategoryList implements ResolverInterface */ private $categoryTree; + /** + * @var CollectionFactory + */ + private $collectionFactory; + /** * @var CategoryFilter */ @@ -47,17 +53,20 @@ class CategoryList implements ResolverInterface * @param ExtractDataFromCategoryTree $extractDataFromCategoryTree * @param CheckCategoryIsActive $checkCategoryIsActive * @param CategoryFilter $categoryFilter + * @param CollectionFactory $collectionFactory */ public function __construct( CategoryTree $categoryTree, ExtractDataFromCategoryTree $extractDataFromCategoryTree, CheckCategoryIsActive $checkCategoryIsActive, - CategoryFilter $categoryFilter + CategoryFilter $categoryFilter, + CollectionFactory $collectionFactory ) { $this->categoryTree = $categoryTree; $this->extractDataFromCategoryTree = $extractDataFromCategoryTree; $this->checkCategoryIsActive = $checkCategoryIsActive; $this->categoryFilter = $categoryFilter; + $this->collectionFactory = $collectionFactory; } /** @@ -69,10 +78,18 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value return $value[$field->getName()]; } + $categoryCollection = $this->collectionFactory->create(); + $categoryCollection->addAttributeToFilter('is_active', 1); + $categoryCollection->addAttributeToSelect(['name','url_key', 'ids']); + if (!isset($args['filters'])) { $rootCategoryIds = [(int)$context->getExtensionAttributes()->getStore()->getRootCategoryId()]; } else { - $rootCategoryIds = $this->categoryFilter->applyFilters($args); + $this->categoryFilter->applyFilters($args, $categoryCollection); + $rootCategoryIds = []; + foreach ($categoryCollection as $category) { + $rootCategoryIds[] = (int)$category->getId(); + } } $result = []; @@ -81,7 +98,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $this->checkCategoryIsActive->execute($rootCategoryId); } $categoryTree = $this->categoryTree->getTree($info, $rootCategoryId); - if (empty($categoryTree)) { + if (empty($categoryTree) || ($categoryTree->count() == 0)) { throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist')); } $result[] = current($this->extractDataFromCategoryTree->execute($categoryTree)); From b66bafe743204efe0c6b56b48d9c602e18e58ad6 Mon Sep 17 00:00:00 2001 From: Buba Suma <soumah@adobe.com> Date: Thu, 3 Oct 2019 16:18:36 -0500 Subject: [PATCH 0826/1172] MC-21467: Reorder from admin throws an error when adding products - Fix return key press in products grid filter submits the "create order" form in admin --- .../view/adminhtml/templates/widget/grid.phtml | 3 +++ .../adminhtml/templates/widget/grid/extended.phtml | 3 +++ .../Gateway/Validator/ErrorCodeProvider.php | 13 ++++++++----- .../Block/Adminhtml/Order/Create/Search/Grid.php | 12 ++++++------ .../view/adminhtml/web/order/create/scripts.js | 14 ++++++++++++++ lib/web/mage/adminhtml/grid.js | 5 +++++ 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml index b712bc6c9531..7f6f2bbd13fa 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid.phtml @@ -170,6 +170,9 @@ $numColumns = $block->getColumns() !== null ? count($block->getColumns()) : 0; <?php if ($block->getSortableUpdateCallback()) : ?> <?= $block->escapeJs($block->getJsObjectName()) ?>.sortableUpdateCallback = <?= /* @noEscape */ $block->getSortableUpdateCallback() ?>; <?php endif; ?> + <?php if ($block->getFilterKeyPressCallback()) : ?> + <?= $block->escapeJs($block->getJsObjectName()) ?>.filterKeyPressCallback = <?= /* @noEscape */ $block->getFilterKeyPressCallback() ?>; + <?php endif; ?> <?= $block->escapeJs($block->getJsObjectName()) ?>.bindSortable(); <?php if ($block->getRowInitCallback()) : ?> <?= $block->escapeJs($block->getJsObjectName()) ?>.initRowCallback = <?= /* @noEscape */ $block->getRowInitCallback() ?>; diff --git a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml index 0bb453f25d7c..527ddc436207 100644 --- a/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml +++ b/app/code/Magento/Backend/view/adminhtml/templates/widget/grid/extended.phtml @@ -272,6 +272,9 @@ $numColumns = count($block->getColumns()); <?php if ($block->getCheckboxCheckCallback()) : ?> <?= $block->escapeJs($block->getJsObjectName()) ?>.checkboxCheckCallback = <?= /* @noEscape */ $block->getCheckboxCheckCallback() ?>; <?php endif; ?> + <?php if ($block->getFilterKeyPressCallback()) : ?> + <?= $block->escapeJs($block->getJsObjectName()) ?>.filterKeyPressCallback = <?= /* @noEscape */ $block->getFilterKeyPressCallback() ?>; + <?php endif; ?> <?php if ($block->getRowInitCallback()) : ?> <?= $block->escapeJs($block->getJsObjectName()) ?>.initRowCallback = <?= /* @noEscape */ $block->getRowInitCallback() ?>; <?= $block->escapeJs($block->getJsObjectName()) ?>.initGridRows(); diff --git a/app/code/Magento/Braintree/Gateway/Validator/ErrorCodeProvider.php b/app/code/Magento/Braintree/Gateway/Validator/ErrorCodeProvider.php index 58ce33305da8..2f73dd8f380d 100644 --- a/app/code/Magento/Braintree/Gateway/Validator/ErrorCodeProvider.php +++ b/app/code/Magento/Braintree/Gateway/Validator/ErrorCodeProvider.php @@ -11,6 +11,7 @@ use Braintree\Error\Validation; use Braintree\Result\Error; use Braintree\Result\Successful; +use Braintree\Transaction; /** * Processes errors codes from Braintree response. @@ -38,12 +39,14 @@ public function getErrorCodes($response): array $result[] = $error->code; } - if (isset($response->transaction) && $response->transaction->status === 'gateway_rejected') { - $result[] = $response->transaction->gatewayRejectionReason; - } + if (isset($response->transaction) && $response->transaction) { + if ($response->transaction->status === Transaction::GATEWAY_REJECTED) { + $result[] = $response->transaction->gatewayRejectionReason; + } - if (isset($response->transaction) && $response->transaction->status === 'processor_declined') { - $result[] = $response->transaction->processorResponseCode; + if ($response->transaction->status === Transaction::PROCESSOR_DECLINED) { + $result[] = $response->transaction->processorResponseCode; + } } return $result; diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php index 9a271f741edd..001c581dc0da 100644 --- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php +++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Search/Grid.php @@ -5,8 +5,7 @@ */ namespace Magento\Sales\Block\Adminhtml\Order\Create\Search; -use Magento\Sales\Block\Adminhtml\Order\Create\Search\Grid\DataProvider\ProductCollection - as ProductCollectionDataProvider; +use Magento\Sales\Block\Adminhtml\Order\Create\Search\Grid\DataProvider\ProductCollection; use Magento\Framework\App\ObjectManager; /** @@ -48,7 +47,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended protected $_productFactory; /** - * @var ProductCollectionDataProvider $productCollectionProvider + * @var ProductCollection $productCollectionProvider */ private $productCollectionProvider; @@ -60,7 +59,7 @@ class Grid extends \Magento\Backend\Block\Widget\Grid\Extended * @param \Magento\Backend\Model\Session\Quote $sessionQuote * @param \Magento\Sales\Model\Config $salesConfig * @param array $data - * @param ProductCollectionDataProvider|null $productCollectionProvider + * @param ProductCollection|null $productCollectionProvider */ public function __construct( \Magento\Backend\Block\Template\Context $context, @@ -70,14 +69,14 @@ public function __construct( \Magento\Backend\Model\Session\Quote $sessionQuote, \Magento\Sales\Model\Config $salesConfig, array $data = [], - ProductCollectionDataProvider $productCollectionProvider = null + ProductCollection $productCollectionProvider = null ) { $this->_productFactory = $productFactory; $this->_catalogConfig = $catalogConfig; $this->_sessionQuote = $sessionQuote; $this->_salesConfig = $salesConfig; $this->productCollectionProvider = $productCollectionProvider - ?: ObjectManager::getInstance()->get(ProductCollectionDataProvider::class); + ?: ObjectManager::getInstance()->get(ProductCollection::class); parent::__construct($context, $backendHelper, $data); } @@ -94,6 +93,7 @@ protected function _construct() $this->setCheckboxCheckCallback('order.productGridCheckboxCheck.bind(order)'); $this->setRowInitCallback('order.productGridRowInit.bind(order)'); $this->setDefaultSort('entity_id'); + $this->setFilterKeyPressCallback('order.productGridFilterKeyPress'); $this->setUseAjax(true); if ($this->getRequest()->getParam('collapse')) { $this->setIsCollapsed(true); diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js index 3fe9d0878288..4e0741451074 100644 --- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js +++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js @@ -795,6 +795,20 @@ define([ grid.reloadParams = {'products[]':this.gridProducts.keys()}; }, + productGridFilterKeyPress: function (grid, event) { + var returnKey = parseInt(Event.KEY_RETURN || 13, 10); + + if (event.keyCode === returnKey) { + if (typeof event.stopPropagation === 'function') { + event.stopPropagation(); + } + + if (typeof event.preventDefault === 'function') { + event.preventDefault(); + } + } + }, + /** * Submit configured products to quote */ diff --git a/lib/web/mage/adminhtml/grid.js b/lib/web/mage/adminhtml/grid.js index 1c9319f95a64..28bdb96e5cdb 100644 --- a/lib/web/mage/adminhtml/grid.js +++ b/lib/web/mage/adminhtml/grid.js @@ -63,6 +63,7 @@ define([ this.initRowCallback = false; this.doFilterCallback = false; this.sortableUpdateCallback = false; + this.filterKeyPressCallback = false; this.reloadParams = false; @@ -511,6 +512,10 @@ define([ if (event.keyCode == Event.KEY_RETURN) { //eslint-disable-line eqeqeq this.doFilter(); } + + if (this.filterKeyPressCallback) { + this.filterKeyPressCallback(this, event); + } }, /** From fc7e0240ea3ae2288db1374b7a5d5f36bf891827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Szubert?= <bartlomiejszubert@gmail.com> Date: Fri, 4 Oct 2019 09:52:08 +0200 Subject: [PATCH 0827/1172] Fix #13278 - revert docblock changes in interface --- .../Magento/SalesRule/Api/Data/RuleInterface.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/SalesRule/Api/Data/RuleInterface.php b/app/code/Magento/SalesRule/Api/Data/RuleInterface.php index b811289798e3..d7d72bef293b 100644 --- a/app/code/Magento/SalesRule/Api/Data/RuleInterface.php +++ b/app/code/Magento/SalesRule/Api/Data/RuleInterface.php @@ -61,14 +61,14 @@ public function setName($name); /** * Get display label * - * @return RuleLabelInterface[]|null + * @return \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null */ public function getStoreLabels(); /** * Set display label * - * @param RuleLabelInterface[]|null $storeLabels + * @param \Magento\SalesRule\Api\Data\RuleLabelInterface[]|null $storeLabels * @return $this */ public function setStoreLabels(array $storeLabels = null); @@ -182,14 +182,14 @@ public function setIsActive($isActive); /** * Get condition for the rule * - * @return ConditionInterface|null + * @return \Magento\SalesRule\Api\Data\ConditionInterface|null */ public function getCondition(); /** * Set condition for the rule * - * @param ConditionInterface|null $condition + * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $condition * @return $this */ public function setCondition(ConditionInterface $condition = null); @@ -197,14 +197,14 @@ public function setCondition(ConditionInterface $condition = null); /** * Get action condition * - * @return ConditionInterface|null + * @return \Magento\SalesRule\Api\Data\ConditionInterface|null */ public function getActionCondition(); /** * Set action condition * - * @param ConditionInterface|null $actionCondition + * @param \Magento\SalesRule\Api\Data\ConditionInterface|null $actionCondition * @return $this */ public function setActionCondition(ConditionInterface $actionCondition = null); @@ -438,14 +438,14 @@ public function setSimpleFreeShipping($simpleFreeShipping); /** * Retrieve existing extension attributes object or create a new one. * - * @return RuleExtensionInterface|null + * @return \Magento\SalesRule\Api\Data\RuleExtensionInterface|null */ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param RuleExtensionInterface $extensionAttributes + * @param \Magento\SalesRule\Api\Data\RuleExtensionInterface $extensionAttributes * @return $this */ public function setExtensionAttributes(RuleExtensionInterface $extensionAttributes); From e5a2b2620786bf58e4fe9c4c2df888f8be0dc64e Mon Sep 17 00:00:00 2001 From: Daniel Ruf <d.ruf@bitexpert.de> Date: Fri, 4 Oct 2019 10:16:56 +0200 Subject: [PATCH 0828/1172] Change array to object --- .../view/frontend/web/js/model/cart/estimate-service.js | 4 ++-- .../view/frontend/web/js/model/shipping-rate-service.js | 2 +- .../view/frontend/web/js/model/shipping-save-processor.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js index 54e496131972..fd12eed76ed5 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/estimate-service.js @@ -13,8 +13,8 @@ define([ ], function (quote, defaultProcessor, totalsDefaultProvider, shippingService, cartCache, customerData) { 'use strict'; - var rateProcessors = [], - totalsProcessors = [], + var rateProcessors = {}, + totalsProcessors = {}, /** * Estimate totals for shipping address and update shipping rates. diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js index 7eddc0d1a58d..be2199961e07 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js @@ -10,7 +10,7 @@ define([ ], function (quote, defaultProcessor, customerAddressProcessor) { 'use strict'; - var processors = []; + var processors = {}; processors.default = defaultProcessor; processors['customer-address'] = customerAddressProcessor; diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js index d506f0a4359c..cf26f682ad3a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js @@ -11,7 +11,7 @@ define([ ], function (defaultProcessor) { 'use strict'; - var processors = []; + var processors = {}; processors['default'] = defaultProcessor; From d7acc36cb36d7e72fe37a2549545ffb88c9f669c Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 4 Oct 2019 12:17:27 +0400 Subject: [PATCH 0829/1172] MC-18215: Error message while creating shipping label - Updated automated test script --- .../AdminGeneralStoreInfomationConfigData.xml | 33 +++++++++++++++++++ .../AdminGeneralStoreInfomationConfigData.xml | 22 ------------- 2 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml diff --git a/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml b/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml new file mode 100644 index 000000000000..a8db2f94d69a --- /dev/null +++ b/app/code/Magento/Backend/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> + <entity name="AdminGeneralSetStoreNameConfigData"> + <data key="path">general/store_information/name</data> + <data key="value">New Store Information</data> + </entity> + <entity name="AdminGeneralSetStorePhoneConfigData"> + <data key="path">general/store_information/phone</data> + </entity> + <entity name="AdminGeneralSetCountryConfigData"> + <data key="path">general/store_information/country_id</data> + </entity> + <entity name="AdminGeneralSetCityConfigData"> + <data key="path">general/store_information/city</data> + </entity> + <entity name="AdminGeneralSetPostcodeConfigData"> + <data key="path">general/store_information/postcode</data> + </entity> + <entity name="AdminGeneralSetStreetAddressConfigData"> + <data key="path">general/store_information/street_line1</data> + </entity> + <entity name="AdminGeneralSetStreetAddress2ConfigData"> + <data key="path">general/store_information/street_line2</data> + </entity> +</entities> diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml index ae0801736d3a..e4c020cc449f 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AdminGeneralStoreInfomationConfigData.xml @@ -8,28 +8,6 @@ <entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd"> - <entity name="AdminGeneralSetStoreNameConfigData"> - <data key="path">general/store_information/name</data> - <data key="value">New Store Information</data> - </entity> - <entity name="AdminGeneralSetStorePhoneConfigData"> - <data key="path">general/store_information/phone</data> - </entity> - <entity name="AdminGeneralSetCountryConfigData"> - <data key="path">general/store_information/country_id</data> - </entity> - <entity name="AdminGeneralSetCityConfigData"> - <data key="path">general/store_information/city</data> - </entity> - <entity name="AdminGeneralSetPostcodeConfigData"> - <data key="path">general/store_information/postcode</data> - </entity> - <entity name="AdminGeneralSetStreetAddressConfigData"> - <data key="path">general/store_information/street_line1</data> - </entity> - <entity name="AdminGeneralSetStreetAddress2ConfigData"> - <data key="path">general/store_information/street_line2</data> - </entity> <entity name="AdminGeneralSetVatNumberConfigData"> <data key="path">general/store_information/merchant_vat_number</data> <data key="value">111607872</data> From 04f4b88d6eb23d4e51990a51757bf16cc6f69f95 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <d.ruf@bitexpert.de> Date: Fri, 4 Oct 2019 10:18:46 +0200 Subject: [PATCH 0830/1172] Correctly check if the type is undefined --- lib/web/mage/decorate.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web/mage/decorate.js b/lib/web/mage/decorate.js index 238735ac455b..9308c2b60e84 100644 --- a/lib/web/mage/decorate.js +++ b/lib/web/mage/decorate.js @@ -25,7 +25,7 @@ items; if (list.length > 0) { - items = typeof isRecursive === undefined || isRecursive ? + items = typeof isRecursive === 'undefined' || isRecursive ? list.find('li') : list.children(); items.decorate('generic', ['odd', 'even', 'last']); From 70379ee8fc78c36460685a284c24d04f5e0f39a9 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <d.ruf@bitexpert.de> Date: Fri, 4 Oct 2019 10:19:44 +0200 Subject: [PATCH 0831/1172] Correctly check the behaviourType --- .../Ui/view/base/web/js/form/components/insert-listing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js index b33f0b5c7239..53580fc069c4 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js @@ -155,7 +155,7 @@ define([ updateExternalValueByEditableData: function () { var updatedExtValue; - if (!this.behaviourType === 'edit' || _.isEmpty(this.editableData) || _.isEmpty(this.externalValue())) { + if (!(this.behaviourType === 'edit') || _.isEmpty(this.editableData) || _.isEmpty(this.externalValue())) { return; } From 1ea74daaea02b4b2406406aca18c8511a5b37bea Mon Sep 17 00:00:00 2001 From: Daniel Ruf <d.ruf@bitexpert.de> Date: Fri, 4 Oct 2019 10:20:58 +0200 Subject: [PATCH 0832/1172] Remove unnecessary parentheses --- lib/web/mage/popup-window.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/web/mage/popup-window.js b/lib/web/mage/popup-window.js index 37c3b27a4510..194a18ce150b 100644 --- a/lib/web/mage/popup-window.js +++ b/lib/web/mage/popup-window.js @@ -57,8 +57,8 @@ define([ settings.windowURL = settings.windowURL || element.attr('href'); if (settings.centerBrowser) { - centeredY = window.screenY + ((window.outerHeight / 2 - settings.height / 2)); - centeredX = window.screenX + ((window.outerWidth / 2 - settings.width / 2)); + centeredY = window.screenY + (window.outerHeight / 2 - settings.height / 2); + centeredX = window.screenX + (window.outerWidth / 2 - settings.width / 2); windowFeatures += ',left=' + centeredX + ',top=' + centeredY; } else if (settings.centerScreen) { centeredY = (screen.height - settings.height) / 2; From 33b6015edfe77e72102dd266e03a10de863cb561 Mon Sep 17 00:00:00 2001 From: Alex <vildulv@gmail.com> Date: Fri, 4 Oct 2019 12:02:39 +0300 Subject: [PATCH 0833/1172] Update AbstractForm.php --- lib/internal/Magento/Framework/Data/Form/AbstractForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php index f3b26dc7a9bf..c7ac994501ca 100644 --- a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php +++ b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php @@ -138,7 +138,7 @@ public function addElement(AbstractElement $element, $after = null) * Add child element * * if $after parameter is false - then element adds to end of collection - * if $after parameter is null - then element adds to befin of collection + * if $after parameter is null - then element adds to begin of collection * if $after parameter is string - then element adds after of the element with some id * * @param string $elementId From dbf2c29bef8ec4a768156bd7ace0c99647bec631 Mon Sep 17 00:00:00 2001 From: "Kristof Ringleff, Fooman" <kristof@fooman.co.nz> Date: Fri, 4 Oct 2019 22:28:41 +1300 Subject: [PATCH 0834/1172] Fix multiple copy to recipients --- app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php index c4523981ac72..ae188309ea64 100644 --- a/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php +++ b/app/code/Magento/Sales/Model/Order/Email/SenderBuilder.php @@ -85,8 +85,8 @@ public function sendCopyTo() $copyTo = $this->identityContainer->getEmailCopyTo(); if (!empty($copyTo)) { - $this->configureEmailTemplate(); foreach ($copyTo as $email) { + $this->configureEmailTemplate(); $this->transportBuilder->addTo($email); $transport = $this->transportBuilder->getTransport(); $transport->sendMessage(); From 8baeec344c5063d65eff5a79a0ddf7125ecc6951 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Thu, 3 Oct 2019 22:37:40 +0530 Subject: [PATCH 0835/1172] Fixed issue #24779 --- .../Checkout/view/frontend/templates/button.phtml | 5 ++++- .../frontend/templates/order/creditmemo/items.phtml | 10 ++++++---- .../view/frontend/templates/order/info/buttons.phtml | 7 ++++--- .../view/frontend/templates/order/invoice/items.phtml | 8 +++++--- .../Shipping/view/frontend/templates/items.phtml | 10 ++++++---- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/code/Magento/Checkout/view/frontend/templates/button.phtml b/app/code/Magento/Checkout/view/frontend/templates/button.phtml index b0087794ea85..6d1f076e6b26 100644 --- a/app/code/Magento/Checkout/view/frontend/templates/button.phtml +++ b/app/code/Magento/Checkout/view/frontend/templates/button.phtml @@ -7,7 +7,10 @@ <?php /** @var $block \Magento\Checkout\Block\Onepage\Success */ ?> <?php if ($block->getCanViewOrder() && $block->getCanPrintOrder()) :?> - <a href="<?= $block->escapeUrl($block->getPrintUrl()) ?>" target="_blank" class="print"> + <a href="<?= $block->escapeUrl($block->getPrintUrl()) ?>" + class="action print" + target="_blank" + rel="noopener"> <?= $block->escapeHtml(__('Print receipt')) ?> </a> <?= $block->getChildHtml() ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml index 019baeea54e2..cb84dcc3fae8 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/creditmemo/items.phtml @@ -7,8 +7,9 @@ <?php $_order = $block->getOrder() ?> <div class="actions-toolbar"> <a href="<?= $block->escapeUrl($block->getPrintAllCreditmemosUrl($_order)) ?>" - onclick="this.target='_blank'" - class="action print"> + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print All Refunds')) ?></span> </a> </div> @@ -16,8 +17,9 @@ <div class="order-title"> <strong><?= $block->escapeHtml(__('Refund #')) ?><?= $block->escapeHtml($_creditmemo->getIncrementId()) ?> </strong> <a href="<?= $block->escapeUrl($block->getPrintCreditmemoUrl($_creditmemo)) ?>" - onclick="this.target='_blank'" - class="action print"> + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print Refund')) ?></span> </a> </div> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml index 6b87d3c22331..2872291a0eaa 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/info/buttons.phtml @@ -16,9 +16,10 @@ <span><?= $block->escapeHtml(__('Reorder')) ?></span> </a> <?php endif ?> - <a class="action print" - href="<?= $block->escapeUrl($block->getPrintUrl($_order)) ?>" - onclick="this.target='_blank';"> + <a href="<?= $block->escapeUrl($block->getPrintUrl($_order)) ?>" + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print Order')) ?></span> </a> <?= $block->getChildHtml() ?> diff --git a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml index 419060bfba71..ba3440f03c00 100644 --- a/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml +++ b/app/code/Magento/Sales/view/frontend/templates/order/invoice/items.phtml @@ -7,8 +7,9 @@ <?php $_order = $block->getOrder() ?> <div class="actions-toolbar"> <a href="<?= $block->escapeUrl($block->getPrintAllInvoicesUrl($_order)) ?>" + class="action print" target="_blank" - class="action print"> + rel="noopener"> <span><?= $block->escapeHtml(__('Print All Invoices')) ?></span> </a> </div> @@ -16,8 +17,9 @@ <div class="order-title"> <strong><?= $block->escapeHtml(__('Invoice #')) ?><?= $block->escapeHtml($_invoice->getIncrementId()) ?></strong> <a href="<?= $block->escapeUrl($block->getPrintInvoiceUrl($_invoice)) ?>" - onclick="this.target='_blank'" - class="action print"> + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print Invoice')) ?></span> </a> </div> diff --git a/app/code/Magento/Shipping/view/frontend/templates/items.phtml b/app/code/Magento/Shipping/view/frontend/templates/items.phtml index f0f1423ed47a..177628c6b201 100644 --- a/app/code/Magento/Shipping/view/frontend/templates/items.phtml +++ b/app/code/Magento/Shipping/view/frontend/templates/items.phtml @@ -15,8 +15,9 @@ <?= $block->getChildHtml('track-all-link') ?> <?php endif; ?> <a href="<?= $block->escapeUrl($block->getPrintAllShipmentsUrl($_order)) ?>" - onclick="this.target='_blank'" - class="action print"> + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print All Shipments')) ?></span> </a> </div> @@ -24,8 +25,9 @@ <div class="order-title"> <strong><?= $block->escapeHtml(__('Shipment #')) ?><?= $block->escapeHtml($_shipment->getIncrementId()) ?></strong> <a href="<?= $block->escapeUrl($block->getPrintShipmentUrl($_shipment)) ?>" - onclick="this.target='_blank'" - class="action print"> + class="action print" + target="_blank" + rel="noopener"> <span><?= $block->escapeHtml(__('Print Shipment')) ?></span> </a> <a href="#" From 574b2423913ec00ee710c3ae117ab4102b8bb0ec Mon Sep 17 00:00:00 2001 From: Alex <vildulv@gmail.com> Date: Fri, 4 Oct 2019 13:21:13 +0300 Subject: [PATCH 0836/1172] Update AbstractForm.php --- .../Magento/Framework/Data/Form/AbstractForm.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php index c7ac994501ca..47ba04bb6898 100644 --- a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php +++ b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php @@ -137,14 +137,14 @@ public function addElement(AbstractElement $element, $after = null) /** * Add child element * - * if $after parameter is false - then element adds to end of collection - * if $after parameter is null - then element adds to begin of collection - * if $after parameter is string - then element adds after of the element with some id + * If $after parameter is false - then element adds to end of collection + * If $after parameter is null - then element adds to befin of collection + * If $after parameter is string - then element adds after of the element with some id * - * @param string $elementId - * @param string $type - * @param array $config - * @param bool|string|null $after + * @param string $elementId + * @param string $type + * @param array $config + * @param bool|string|null $after * @return AbstractElement */ public function addField($elementId, $type, $config, $after = false) From 10f89e73f3515cb9e3a03a04f62bda7fb1a2c0f1 Mon Sep 17 00:00:00 2001 From: Yuliya Labudova <Yuliya_Labudova@epam.com> Date: Fri, 4 Oct 2019 13:50:13 +0300 Subject: [PATCH 0837/1172] MC-21426: Fix all broken Product related tests in Page Builder Component - Fix query for staging. --- .../Catalog/Model/ResourceModel/Category.php | 17 ++++++++++++++--- .../Model/ResourceModel/Product/Collection.php | 7 ++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php index 797ce72ae9b7..9e0d174a4ccc 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php @@ -18,6 +18,8 @@ use Magento\Framework\DataObject; use Magento\Framework\EntityManager\EntityManager; use Magento\Catalog\Setup\CategorySetup; +use Magento\Framework\EntityManager\MetadataPool; +use Magento\Catalog\Api\Data\ProductInterface; /** * Resource model for category entity @@ -95,6 +97,11 @@ class Category extends AbstractResource */ private $indexerProcessor; + /** + * @var MetadataPool + */ + private $metadataPool; + /** * Category constructor. * @param \Magento\Eav\Model\Entity\Context $context @@ -106,6 +113,7 @@ class Category extends AbstractResource * @param Processor $indexerProcessor * @param array $data * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer + * @param MetadataPool|null $metadataPool * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -117,7 +125,8 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory, Processor $indexerProcessor, $data = [], - \Magento\Framework\Serialize\Serializer\Json $serializer = null + \Magento\Framework\Serialize\Serializer\Json $serializer = null, + MetadataPool $metadataPool = null ) { parent::__construct( $context, @@ -132,6 +141,7 @@ public function __construct( $this->indexerProcessor = $indexerProcessor; $this->serializer = $serializer ?: ObjectManager::getInstance() ->get(\Magento\Framework\Serialize\Serializer\Json::class); + $this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class); } /** @@ -1160,13 +1170,14 @@ public function getCategoryWithChildren(int $categoryId): array return []; } + $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $select = $connection->select() ->from( ['cce' => $this->getTable('catalog_category_entity')], - ['entity_id', 'parent_id', 'path'] + [$linkField, 'parent_id', 'path'] )->join( ['cce_int' => $this->getTable('catalog_category_entity_int')], - 'cce.entity_id = cce_int.entity_id', + 'cce.' . $linkField . ' = cce_int.' . $linkField, ['is_anchor' => 'cce_int.value'] )->where( 'cce_int.attribute_id = ?', diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 42d55892b6ec..3239d3e1cba2 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -2113,13 +2113,14 @@ private function getChildrenCategories(int $categoryId): array $firstCategory = array_shift($categories); if ($firstCategory['is_anchor'] == 1) { - $anchorCategory[] = (int)$firstCategory['entity_id']; + $linkField = $this->getProductEntityMetadata()->getLinkField(); + $anchorCategory[] = (int)$firstCategory[$linkField]; foreach ($categories as $category) { if (in_array($category['parent_id'], $categoryIds) && in_array($category['parent_id'], $anchorCategory)) { - $categoryIds[] = (int)$category['entity_id']; + $categoryIds[] = (int)$category[$linkField]; if ($category['is_anchor'] == 1) { - $anchorCategory[] = (int)$category['entity_id']; + $anchorCategory[] = (int)$category[$linkField]; } } } From 2fee2347b6ffae73b2ae40f9c73237a090379c3c Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 4 Oct 2019 14:51:20 +0400 Subject: [PATCH 0838/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6411 --- .../ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml | 3 +++ .../AdminChangeTableRatesShippingMethodStatusActionGroup.xml | 3 +++ ...AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml | 2 +- .../Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml index cfed144184e4..b8493bf28837 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderSelectShippingMethodActionGroup.xml @@ -9,6 +9,9 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminOrderSelectShippingMethodActionGroup"> + <annotations> + <description>Select Shipping method from admin order page.</description> + </annotations> <arguments> <argument name="methodTitle" type="string" defaultValue="flatrate"/> <argument name="methodName" type="string" defaultValue="fixed"/> diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml index 2df78f3a0d1a..e0fec2a6dc4d 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/AdminChangeTableRatesShippingMethodStatusActionGroup.xml @@ -18,6 +18,9 @@ <selectOption selector="{{AdminShippingMethodTableRatesSection.carriersTableRateActive}}" userInput="{{status}}" stepKey="changeTableRatesMethodStatus"/> </actionGroup> <actionGroup name="AdminImportFileTableRatesShippingMethodActionGroup"> + <annotations> + <description>Import a file in Table Rates tab in Shipping Method config page.</description> + </annotations> <arguments> <argument name="file" type="string" defaultValue="test_tablerates.csv"/> </arguments> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml index 3decca9a971d..cf43f8cf7b73 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/AdminCreateOrderCustomStoreShippingMethodTableRatesTest.xml @@ -11,7 +11,7 @@ <test name="AdminCreateOrderCustomStoreShippingMethodTableRatesTest"> <annotations> <features value="Shipping"/> - <stories value="Shipping method Table Rates settings gets from wrong store"/> + <stories value="Shipping method Table Rates"/> <title value="Create order on second store with shipping method Table Rates"/> <description value="Create order on second store with shipping method Table Rates"/> <severity value="MAJOR"/> diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml index fc54101c3a5f..1a43ae1d2bbd 100644 --- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml +++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminWebsitePageActionGroup.xml @@ -9,6 +9,9 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> <actionGroup name="AdminGoCreatedWebsitePageActionGroup"> + <annotations> + <description>Filter website name in grid and go first found website page</description> + </annotations> <arguments> <argument name="websiteName" type="string" defaultValue="SecondWebsite"/> </arguments> From 2a3353ed32e957b1f2385f453eca8c221c0f230d Mon Sep 17 00:00:00 2001 From: Mikalai Shostka <Mikalai_Shostka@epam.com> Date: Fri, 4 Oct 2019 14:01:29 +0300 Subject: [PATCH 0839/1172] MC-18825: Increase test coverage for Promotion and Loyalty functional area - Stabilization for test AdminRemoveDefaultImageBundleProductTest --- .../Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml index 1438958b92b6..730df90b31be 100644 --- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml +++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml @@ -24,6 +24,10 @@ <createData entity="SimpleProduct2" stepKey="simpleProduct2"/> </before> <after> + <!-- Delete the bundled product we created in the test body --> + <actionGroup ref="deleteProductBySku" stepKey="deleteBundleProduct"> + <argument name="sku" value="{{BundleProduct.sku}}"/> + </actionGroup> <amOnPage url="{{AdminLogoutPage.url}}" stepKey="amOnLogoutPage"/> <deleteData createDataKey="simpleProduct1" stepKey="deleteSimpleProduct1"/> <deleteData createDataKey="simpleProduct2" stepKey="deleteSimpleProduct2"/> From 4ee20488273f435ceb9ae572250466ccddb58c6e Mon Sep 17 00:00:00 2001 From: Lusine Papyan <Lusine_Papyan@epam.com> Date: Fri, 4 Oct 2019 15:09:44 +0400 Subject: [PATCH 0840/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Automation test for MC-6405 --- ...isplayTableRatesShippingMethodForAETest.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml index 5b6bcd1ebcd9..a93377c694df 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml @@ -30,7 +30,7 @@ <deleteData createDataKey="createProduct" stepKey="deleteProduct"/> <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> - <comment userInput="Rollback config" stepKey="rollbackConfigComment"/> + <!--Rollback config--> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodSystemConfigPage"/> <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="AdminSwitchStoreViewToMainWebsite"> <argument name="website" value="_defaultWebsite"/> @@ -41,7 +41,7 @@ <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveSystemConfig"/> <actionGroup ref="logout" stepKey="logout"/> </after> - <comment userInput="Admin Configuration: enable Table Rates and import CSV file with the rates" stepKey="prepareAdminConfigurationComment"/> + <!--Admin Configuration: enable Table Rates and import CSV file with the rates--> <actionGroup ref="AdminOpenShippingMethodsConfigPageActionGroup" stepKey="openShippingMethodConfigPage"/> <actionGroup ref="AdminSwitchWebsiteActionGroup" stepKey="AdminSwitchStoreView"> <argument name="website" value="_defaultWebsite"/> @@ -49,28 +49,28 @@ <actionGroup ref="AdminChangeTableRatesShippingMethodStatusActionGroup" stepKey="enableTableRatesShippingMethod"/> <attachFile selector="{{AdminShippingMethodTableRatesSection.importFile}}" userInput="tablerates.csv" stepKey="attachFileForImport"/> <actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/> - <comment userInput="Login as created customer" stepKey="loginAsCustomerComment"/> + <!--Login as created customer--> <actionGroup ref="LoginToStorefrontActionGroup" stepKey="loginAsCustomer"> <argument name="Customer" value="$$createCustomer$$"/> </actionGroup> - <comment userInput="Add the created product to the shopping cart" stepKey="addProductToCartComment"/> + <!--Add the created product to the shopping cart--> <actionGroup ref="AddSimpleProductToCart" stepKey="addProductToCart"> <argument name="product" value="$$createProduct$$"/> </actionGroup> - <comment userInput="Proceed to Checkout from the mini cart" stepKey="proceedToCheckoutComment"/> + <!--Proceed to Checkout from the mini cart--> <actionGroup ref="GoToCheckoutFromMinicartActionGroup" stepKey="goToCheckoutFromMinicart" /> - <comment userInput="Shipping Method: select table rate" stepKey="assertShippingMethodComment"/> + <!--Shipping Method: select table rate--> <actionGroup ref="AssertStoreFrontShippingMethodAvailableActionGroup" stepKey="assertShippingMethodAvailable"> <argument name="shippingMethodName" value="Best Way"/> </actionGroup> <actionGroup ref="SetShippingMethodActionGroup" stepKey="setShippingMethodTableRate"> <argument name="shippingMethodName" value="Best Way"/> </actionGroup> - <comment userInput="Proceed to Review and Payments section" stepKey="proceedToReviewAndPaymentsComment"/> + <!--Proceed to Review and Payments section--> <click selector="{{CheckoutShippingSection.next}}" stepKey="clickToSaveShippingInfo"/> <waitForLoadingMaskToDisappear stepKey="waitForLoadingMaskAfterClickNext"/> <waitForPageLoad stepKey="waitForReviewAndPaymentsPageIsLoaded"/> - <comment userInput="Place order and assert the message of success" stepKey="placeOrderComment"/> - <actionGroup ref="ClickPlaceOrderActionGroup" stepKey="clickOnPlaceOrder"/> + <!--Place order and assert the message of success--> + <actionGroup ref="ClickPlaceOrderActionGroup" stepKey="placeOrderProductSuccessful"/> </test> </tests> From 2b9a7ca6f3e9fee0bd81daddeeb609f40b861df4 Mon Sep 17 00:00:00 2001 From: Alex <vildulv@gmail.com> Date: Fri, 4 Oct 2019 14:21:01 +0300 Subject: [PATCH 0841/1172] Update AbstractForm.php --- lib/internal/Magento/Framework/Data/Form/AbstractForm.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php index 47ba04bb6898..4a082d71ddd4 100644 --- a/lib/internal/Magento/Framework/Data/Form/AbstractForm.php +++ b/lib/internal/Magento/Framework/Data/Form/AbstractForm.php @@ -67,9 +67,11 @@ public function __construct(Factory $factoryElement, CollectionFactory $factoryC * Please override this one instead of overriding real __construct constructor * * @return void + * @codingStandardsIgnoreStart */ protected function _construct() { + //@codingStandardsIgnoreEnd } /** From f4bd79ad6b8f7072edd36c2df1451044553b6795 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky <p.bystritsky@yandex.ru> Date: Fri, 4 Oct 2019 15:30:43 +0300 Subject: [PATCH 0842/1172] Added integration test for Magento\Sales\Cron\CleanExpiredQuotes class. --- .../Sales/Cron/CleanExpiredQuotesTest.php | 65 +++++++++++++++++++ .../testsuite/Magento/Sales/_files/quotes.php | 35 ++++++++++ .../Magento/Sales/_files/quotes_rollback.php | 36 ++++++++++ 3 files changed, 136 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/Sales/Cron/CleanExpiredQuotesTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php create mode 100644 dev/tests/integration/testsuite/Magento/Sales/_files/quotes_rollback.php diff --git a/dev/tests/integration/testsuite/Magento/Sales/Cron/CleanExpiredQuotesTest.php b/dev/tests/integration/testsuite/Magento/Sales/Cron/CleanExpiredQuotesTest.php new file mode 100644 index 000000000000..1b68bc0520ce --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/Cron/CleanExpiredQuotesTest.php @@ -0,0 +1,65 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Sales\Cron; + +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Quote\Model\QuoteRepository; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Test for Magento\Sales\Cron\CleanExpiredQuotes class. + * + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + */ +class CleanExpiredQuotesTest extends \PHPUnit\Framework\TestCase +{ + /** + * @var CleanExpiredQuotes + */ + private $cleanExpiredQuotes; + + /** + * @var QuoteRepository + */ + private $quoteRepository; + + /** + * @var SearchCriteriaBuilder + */ + private $searchCriteriaBuilder; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = Bootstrap::getObjectManager(); + $this->cleanExpiredQuotes = $objectManager->get(CleanExpiredQuotes::class); + $this->quoteRepository = $objectManager->get(QuoteRepository::class); + $this->searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); + } + + /** + * Check if outdated quotes are deleted. + * + * @magentoConfigFixture default_store checkout/cart/delete_quote_after -365 + * @magentoDataFixture Magento/Sales/_files/quotes.php + */ + public function testExecute() + { + $this->cleanExpiredQuotes->execute(); + $searchCriteria = $this->searchCriteriaBuilder->create(); + $totalCount = $this->quoteRepository->getList($searchCriteria)->getTotalCount(); + + $this->assertEquals( + 1, + $totalCount + ); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php new file mode 100644 index 000000000000..b916fc024041 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Quote\Model\QuoteFactory; +use Magento\Quote\Model\QuoteRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; + +require dirname(dirname(__DIR__)) . '/Store/_files/second_store.php'; + +/** @var $objectManager ObjectManager */ +$objectManager = Bootstrap::getObjectManager(); +/** @var QuoteFactory $quoteFactory */ +$quoteFactory = $objectManager->get(QuoteFactory::class); +/** @var QuoteRepository $quoteRepository */ +$quoteRepository = $objectManager->get(QuoteRepository::class); + +$quotes = [ + 'quote for first store' => [ + 'store' => 1, + ], + 'quote for second store' => [ + 'store' => 2, + ], +]; + +foreach ($quotes as $quoteData) { + $quote = $quoteFactory->create(); + $quote->setStoreId($quoteData['store']); + $quoteRepository->save($quote); +} diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quotes_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes_rollback.php new file mode 100644 index 000000000000..7b7fd615e534 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quotes_rollback.php @@ -0,0 +1,36 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Registry; +use Magento\Quote\Model\QuoteRepository; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\ObjectManager; + +/** @var ObjectManager $objectManager */ +$objectManager = Bootstrap::getObjectManager(); + +/** @var Registry $registry */ +$registry = $objectManager->get(Registry::class); +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var QuoteRepository $quoteRepository */ +$quoteRepository = $objectManager->get(QuoteRepository::class); +/** @var SearchCriteriaBuilder $searchCriteriaBuilder */ +$searchCriteriaBuilder = $objectManager->get(SearchCriteriaBuilder::class); +$searchCriteria = $searchCriteriaBuilder->create(); +$items = $quoteRepository->getList($searchCriteria) + ->getItems(); +foreach ($items as $item) { + $quoteRepository->delete($item); +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); + +require dirname(dirname(__DIR__)) . '/Store/_files/second_store_rollback.php'; From 7e78f8f8109e7618a2739592b7ebe6d4abd9ba74 Mon Sep 17 00:00:00 2001 From: "ivan.pletnyov" <ivan.pletnyov@transoftgroup.com> Date: Fri, 4 Oct 2019 16:13:26 +0300 Subject: [PATCH 0843/1172] MC-20666: Add custom options to simple product --- .../Product/Save/CreateCustomOptionsTest.php | 279 +++++ .../Model/Product/CreateCustomOptionsTest.php | 984 ++++++++++++++++++ .../Catalog/Model/Product/OptionTest.php | 149 --- 3 files changed, 1263 insertions(+), 149 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Save/CreateCustomOptionsTest.php create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Product/CreateCustomOptionsTest.php delete mode 100644 dev/tests/integration/testsuite/Magento/Catalog/Model/Product/OptionTest.php diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Save/CreateCustomOptionsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Save/CreateCustomOptionsTest.php new file mode 100644 index 000000000000..c17e8d36846e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Save/CreateCustomOptionsTest.php @@ -0,0 +1,279 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Controller\Adminhtml\Product\Save; + +use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\App\Request\Http as HttpRequest; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Message\MessageInterface; +use Magento\TestFramework\TestCase\AbstractBackendController; + +/** + * Base test cases for product custom options with type "field". + * Option add via dispatch product controller action save with options data in POST data. + * + * @magentoAppArea adminhtml + */ +class CreateCustomOptionsTest extends AbstractBackendController +{ + /** + * Test add to product custom option with type "field". + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider productWithNewOptionsDataProvider + * + * @param array $productPostData + * @throws NoSuchEntityException + */ + public function testSaveCustomOptionWithTypeField(array $productPostData): void + { + $this->getRequest()->setPostValue($productPostData); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->_objectManager->create(ProductRepositoryInterface::class); + /** @var ProductCustomOptionRepositoryInterface $optionRepository */ + $optionRepository = $this->_objectManager->create(ProductCustomOptionRepositoryInterface::class); + $product = $productRepository->get('simple'); + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); + $this->dispatch('backend/catalog/product/save/id/' . $product->getEntityId()); + $this->assertSessionMessages( + $this->contains('You saved the product.'), + MessageInterface::TYPE_SUCCESS + ); + $productOptions = $optionRepository->getProductOptions($product); + $this->assertCount(2, $productOptions); + foreach ($productOptions as $customOption) { + $postOptionData = $productPostData['product']['options'][$customOption->getTitle()] ?? null; + $this->assertNotNull($postOptionData); + $this->assertEquals($postOptionData['title'], $customOption->getTitle()); + $this->assertEquals($postOptionData['type'], $customOption->getType()); + $this->assertEquals($postOptionData['is_require'], $customOption->getIsRequire()); + $this->assertEquals($postOptionData['sku'], $customOption->getSku()); + $this->assertEquals($postOptionData['price'], $customOption->getPrice()); + $this->assertEquals($postOptionData['price_type'], $customOption->getPriceType()); + if (isset($postOptionData['max_characters'])) { + $this->assertEquals($postOptionData['max_characters'], $customOption->getMaxCharacters()); + } else { + $this->assertEquals(0, $customOption->getMaxCharacters()); + } + } + } + + /** + * Return all data for add option to product for all cases. + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * + * @return array + */ + public function productWithNewOptionsDataProvider(): array + { + return [ + 'required_options' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 1, + 'sku' => 'test-option-title-2', + 'max_characters' => 50, + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + ], + ], + ], + 'not_required_options' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 0, + 'sku' => 'test-option-title-2', + 'max_characters' => 50, + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + ], + ], + ], + 'options_with_fixed_price' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 1, + 'sku' => 'test-option-title-2', + 'max_characters' => 50, + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'percent', + ], + ], + ], + ], + ], + 'options_with_percent_price' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 1, + 'sku' => 'test-option-title-2', + 'max_characters' => 50, + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 20, + 'price_type' => 'percent', + ], + ], + ], + ], + ], + 'options_with_max_charters_configuration' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 30, + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 1, + 'sku' => 'test-option-title-2', + 'max_characters' => 50, + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + ], + ], + ], + 'options_without_max_charters_configuration' => [ + [ + 'product' => [ + 'options' => [ + 'Test option title 1' => [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'Test option title 2' => [ + 'record_id' => 1, + 'sort_order' => 2, + 'is_require' => 1, + 'sku' => 'test-option-title-2', + 'title' => 'Test option title 2', + 'type' => 'field', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + ], + ], + ], + ]; + } + + /** + * Delete all custom options from product. + */ + protected function tearDown(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->_objectManager->create(ProductRepositoryInterface::class); + /** @var ProductCustomOptionRepositoryInterface $optionRepository */ + $optionRepository = $this->_objectManager->create(ProductCustomOptionRepositoryInterface::class); + try { + $product = $productRepository->get('simple'); + foreach ($optionRepository->getProductOptions($product) as $customOption) { + $optionRepository->delete($customOption); + } + } catch (\Exception $e) { + $product = null; + } + + parent::tearDown(); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/CreateCustomOptionsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/CreateCustomOptionsTest.php new file mode 100644 index 000000000000..2715f7a7a0dc --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/CreateCustomOptionsTest.php @@ -0,0 +1,984 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Catalog\Model\Product; + +use Magento\Catalog\Api\Data\ProductCustomOptionInterface; +use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory; +use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterfaceFactory; +use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Exception\CouldNotSaveException; +use Magento\Framework\Exception\InputException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Exception\StateException; +use Magento\Framework\ObjectManagerInterface; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Test product custom options create. + * Testing option types: "Area", "File", "Drop-down", "Radio-Buttons", + * "Checkbox", "Multiple Select", "Date", "Date & Time" and "Time". + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @magentoAppArea adminhtml + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + */ +class CreateCustomOptionsTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $objectManager; + + /** + * Product repository. + * + * @var ProductRepositoryInterface + */ + private $productRepository; + + /** + * Custom option factory. + * + * @var ProductCustomOptionInterfaceFactory + */ + private $customOptionFactory; + + /** + * @var ProductCustomOptionValuesInterfaceFactory + */ + private $customOptionValueFactory; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @inheritdoc + */ + protected function setUp() + { + $this->objectManager = Bootstrap::getObjectManager(); + $this->productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $this->customOptionFactory = $this->objectManager->create(ProductCustomOptionInterfaceFactory::class); + $this->customOptionValueFactory = $this->objectManager + ->create(ProductCustomOptionValuesInterfaceFactory::class); + $this->storeManager = $this->objectManager->get(StoreManagerInterface::class); + } + + /** + * Test to save option price by store. + * + * @magentoDataFixture Magento/Catalog/_files/product_with_options.php + * @magentoDataFixture Magento/Store/_files/core_second_third_fixturestore.php + * + * @magentoConfigFixture default_store catalog/price/scope 1 + * @magentoConfigFixture secondstore_store catalog/price/scope 1 + * + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + public function testSaveOptionPriceByStore(): void + { + $secondWebsitePrice = 22.0; + $defaultStoreId = $this->storeManager->getStore()->getId(); + $secondStoreId = $this->storeManager->getStore('secondstore')->getId(); + $product = $this->productRepository->get('simple'); + $option = $product->getOptions()[0]; + $defaultPrice = $option->getPrice(); + $option->setPrice($secondWebsitePrice); + $product->setStoreId($secondStoreId); + // set Current store='secondstore' to correctly save product options for 'secondstore' + $this->storeManager->setCurrentStore($secondStoreId); + $this->productRepository->save($product); + $this->storeManager->setCurrentStore($defaultStoreId); + $product = $this->productRepository->get('simple', false, Store::DEFAULT_STORE_ID, true); + $option = $product->getOptions()[0]; + $this->assertEquals($defaultPrice, $option->getPrice(), 'Price value by default store is wrong'); + $product = $this->productRepository->get('simple', false, $secondStoreId, true); + $option = $product->getOptions()[0]; + $this->assertEquals($secondWebsitePrice, $option->getPrice(), 'Price value by store_id=1 is wrong'); + } + + /** + * Test add to product custom options with text type. + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider productCustomOptionsTypeTextDataProvider + * + * @param array $optionData + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + public function testCreateOptionsWithTypeText(array $optionData): void + { + $option = $this->baseCreateCustomOptionAndAssert($optionData); + $this->assertEquals($optionData['price'], $option->getPrice()); + $this->assertEquals($optionData['price_type'], $option->getPriceType()); + $this->assertEquals($optionData['sku'], $option->getSku()); + + if (isset($optionData['max_characters'])) { + $this->assertEquals($optionData['max_characters'], $option->getMaxCharacters()); + } else { + $this->assertEquals(0, $option->getMaxCharacters()); + } + } + + /** + * Tests removing ineligible characters from file_extension. + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider fileExtensionsDataProvider + * + * @param string $rawExtensions + * @param string $expectedExtensions + * @throws NoSuchEntityException + * @throws CouldNotSaveException + * @throws InputException + * @throws StateException + */ + public function testFileExtensions(string $rawExtensions, string $expectedExtensions): void + { + $product = $this->productRepository->get('simple'); + $optionData = [ + 'title' => 'file option', + 'type' => 'file', + 'is_require' => true, + 'sort_order' => 3, + 'price' => 30.0, + 'price_type' => 'percent', + 'sku' => 'sku3', + 'file_extension' => $rawExtensions, + 'image_size_x' => 10, + 'image_size_y' => 20, + ]; + $fileOption = $this->customOptionFactory->create(['data' => $optionData]); + $product->addOption($fileOption); + $this->productRepository->save($product); + $product = $this->productRepository->get('simple'); + $fileOption = $product->getOptions()[0]; + $actualExtensions = $fileOption->getFileExtension(); + $this->assertEquals($expectedExtensions, $actualExtensions); + } + + /** + * Test add to product custom options with select type. + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider productCustomOptionsTypeSelectDataProvider + * + * @param array $optionData + * @param array $optionValueData + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + public function testCreateOptionsWithTypeSelect(array $optionData, array $optionValueData): void + { + $optionValue = $this->customOptionValueFactory->create(['data' => $optionValueData]); + $optionData['values'] = [$optionValue]; + $option = $this->baseCreateCustomOptionAndAssert($optionData); + $optionValues = $option->getValues(); + $this->assertCount(1, $optionValues); + $this->assertNotNull($optionValues); + $optionValue = reset($optionValues); + $this->assertEquals($optionValueData['title'], $optionValue->getTitle()); + $this->assertEquals($optionValueData['price'], $optionValue->getPrice()); + $this->assertEquals($optionValueData['price_type'], $optionValue->getPriceType()); + $this->assertEquals($optionValueData['sku'], $optionValue->getSku()); + $this->assertEquals($optionValueData['sort_order'], $optionValue->getSortOrder()); + } + + /** + * Test add to product custom options with date type. + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider productCustomOptionsTypeDateDataProvider + * + * @param array $optionData + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + public function testCreateOptionsWithTypeDate(array $optionData): void + { + $option = $this->baseCreateCustomOptionAndAssert($optionData); + $this->assertEquals($optionData['price'], $option->getPrice()); + $this->assertEquals($optionData['price_type'], $option->getPriceType()); + $this->assertEquals($optionData['sku'], $option->getSku()); + } + + /** + * Check that error throws if we save porduct with custom option without some field. + * + * @magentoDataFixture Magento/Catalog/_files/product_without_options.php + * + * @dataProvider productCustomOptionsWithErrorDataProvider + * + * @param array $optionData + * @param string $expectedErrorText + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + public function testCreateOptionWithError(array $optionData, string $expectedErrorText): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + $product = $productRepository->get('simple'); + $createdOption = $this->customOptionFactory->create(['data' => $optionData]); + $product->setOptions([$createdOption]); + $this->expectExceptionMessage($expectedErrorText); + $productRepository->save($product); + } + + /** + * Add option to product with type text data provider. + * + * @return array + */ + public function productCustomOptionsTypeTextDataProvider(): array + { + return [ + 'area_field_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'area_field_not_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'area_field_options_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'area_field_options_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'percent', + ], + ], + 'area_field_options_with_max_charters_configuration' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 30, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'area_field_options_without_max_charters_configuration' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + ]; + } + + /** + * Data provider for testFileExtensions. + * + * @return array + */ + public function fileExtensionsDataProvider(): array + { + return [ + ['JPG, PNG, GIF', 'jpg, png, gif'], + ['jpg, jpg, jpg', 'jpg'], + ['jpg, png, gif', 'jpg, png, gif'], + ['jpg png gif', 'jpg, png, gif'], + ['!jpg@png#gif%', 'jpg, png, gif'], + ['jpg, png, 123', 'jpg, png, 123'], + ['', ''], + ]; + } + + /** + * Add option to product with type text data provider. + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * + * @return array + */ + public function productCustomOptionsTypeSelectDataProvider(): array + { + return [ + 'drop_down_field_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'drop_down', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'drop_down_field_not_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'title' => 'Test option 1', + 'type' => 'drop_down', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'drop_down_field_option_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'drop_down', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'drop_down_field_option_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'drop_down', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'percent', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'radio_field_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'radio', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'radio_field_not_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'title' => 'Test option 1', + 'type' => 'radio', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'radio_field_option_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'radio', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'radio_field_option_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'radio', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'percent', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'checkbox_field_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'checkbox', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'checkbox_field_not_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'title' => 'Test option 1', + 'type' => 'checkbox', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'checkbox_field_option_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'checkbox', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'checkbox_field_option_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'checkbox', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'percent', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'multiple_field_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'multiple', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'multiple_field_not_required_option' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'title' => 'Test option 1', + 'type' => 'multiple', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'multiple_field_option_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'multiple', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'fixed', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + 'multiple_field_option_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'title' => 'Test option 1', + 'type' => 'multiple', + 'price_type' => 'fixed', + ], + [ + 'record_id' => 0, + 'title' => 'Test option 1 value 1', + 'price' => 10, + 'price_type' => 'percent', + 'sku' => 'test-option-1-value-1', + 'sort_order' => 1, + ], + ], + ]; + } + + /** + * Add option to product with type text data provider. + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * + * @return array + */ + public function productCustomOptionsTypeDateDataProvider(): array + { + return [ + 'date_field_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_field_not_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_field_options_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_field_options_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date', + 'price' => 10, + 'price_type' => 'percent', + ], + ], + 'date_time_field_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date_time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_time_field_not_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date_time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_time_field_options_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date_time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'date_time_field_options_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'date_time', + 'price' => 10, + 'price_type' => 'percent', + ], + ], + 'time_field_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'time_field_not_required_options' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 0, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'time_field_options_with_fixed_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'time', + 'price' => 10, + 'price_type' => 'fixed', + ], + ], + 'time_field_options_with_percent_price' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'title' => 'Test option title 1', + 'type' => 'time', + 'price' => 10, + 'price_type' => 'percent', + ], + ], + ]; + } + + /** + * Add option to product for get option save error data provider. + * + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * + * @return array + */ + public function productCustomOptionsWithErrorDataProvider(): array + { + return [ + 'error_option_without_product_sku' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + ], + 'The ProductSku is empty. Set the ProductSku and try again.', + ], + 'error_option_without_type' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'price' => 10, + 'price_type' => 'fixed', + 'product_sku' => 'simple', + ], + "Missed values for option required fields\nInvalid option type", + ], + 'error_option_wrong_price_type' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'test_wrong_price_type', + 'product_sku' => 'simple', + ], + 'Invalid option value', + ], + 'error_option_without_price_type' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price' => 10, + 'product_sku' => 'simple', + ], + 'Invalid option value', + ], + 'error_option_without_price_value' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => 'Test option title 1', + 'type' => 'area', + 'price_type' => 'fixed', + 'product_sku' => 'simple', + ], + 'Invalid option value', + ], + 'error_option_without_title' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + 'product_sku' => 'simple', + ], + "Missed values for option required fields", + ], + 'error_option_with_empty_title' => [ + [ + 'record_id' => 0, + 'sort_order' => 1, + 'is_require' => 1, + 'sku' => 'test-option-title-1', + 'max_characters' => 50, + 'title' => '', + 'type' => 'area', + 'price' => 10, + 'price_type' => 'fixed', + 'product_sku' => 'simple', + ], + "Missed values for option required fields", + ], + ]; + } + + /** + * Delete all custom options from product. + */ + protected function tearDown(): void + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + /** @var ProductCustomOptionRepositoryInterface $optionRepository */ + $optionRepository = $this->objectManager->create(ProductCustomOptionRepositoryInterface::class); + try { + $product = $productRepository->get('simple'); + foreach ($optionRepository->getProductOptions($product) as $customOption) { + $optionRepository->delete($customOption); + } + } catch (\Exception $e) { + } + + parent::tearDown(); + } + + /** + * Create custom option and save product with created option, check base assertions. + * + * @param array $optionData + * @return ProductCustomOptionInterface + * @throws CouldNotSaveException + * @throws InputException + * @throws NoSuchEntityException + * @throws StateException + */ + private function baseCreateCustomOptionAndAssert(array $optionData): ProductCustomOptionInterface + { + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + /** @var ProductCustomOptionRepositoryInterface $optionRepository */ + $optionRepository = $this->objectManager->create(ProductCustomOptionRepositoryInterface::class); + $product = $productRepository->get('simple'); + $createdOption = $this->customOptionFactory->create(['data' => $optionData]); + $createdOption->setProductSku($product->getSku()); + $product->setOptions([$createdOption]); + $productRepository->save($product); + $productCustomOptions = $optionRepository->getProductOptions($product); + $this->assertCount(1, $productCustomOptions); + $option = reset($productCustomOptions); + $this->assertEquals($optionData['title'], $option->getTitle()); + $this->assertEquals($optionData['type'], $option->getType()); + $this->assertEquals($optionData['is_require'], $option->getIsRequire()); + + return $option; + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/OptionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/OptionTest.php deleted file mode 100644 index bfb49686447c..000000000000 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/OptionTest.php +++ /dev/null @@ -1,149 +0,0 @@ -<?php -/** - * Copyright © Magento, Inc. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Catalog\Model\Product; - -use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory; -use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Store\Model\Store; -use Magento\Store\Model\StoreManagerInterface; -use Magento\TestFramework\Helper\Bootstrap; - -/** - * @magentoAppArea adminhtml - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - */ -class OptionTest extends \PHPUnit\Framework\TestCase -{ - /** - * Product repository. - * - * @var ProductRepositoryInterface - */ - private $productRepository; - - /** - * Custom option factory. - * - * @var ProductCustomOptionInterfaceFactory - */ - private $customOptionFactory; - - /** - * @var StoreManagerInterface - */ - private $storeManager; - - /** - * @inheritdoc - */ - protected function setUp() - { - $this->productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class); - $this->customOptionFactory = Bootstrap::getObjectManager()->create(ProductCustomOptionInterfaceFactory::class); - $this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class); - } - - /** - * Tests removing ineligible characters from file_extension. - * - * @param string $rawExtensions - * @param string $expectedExtensions - * @dataProvider fileExtensionsDataProvider - * @magentoDataFixture Magento/Catalog/_files/product_without_options.php - */ - public function testFileExtensions(string $rawExtensions, string $expectedExtensions) - { - /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->productRepository->get('simple'); - /** @var \Magento\Catalog\Model\Product\Option $fileOption */ - $fileOption = $this->createFileOption($rawExtensions); - $product->addOption($fileOption); - $product->save(); - $product = $this->productRepository->get('simple'); - $fileOption = $product->getOptions()[0]; - $actualExtensions = $fileOption->getFileExtension(); - $this->assertEquals($expectedExtensions, $actualExtensions); - } - - /** - * Data provider for testFileExtensions. - * - * @return array - */ - public function fileExtensionsDataProvider() - { - return [ - ['JPG, PNG, GIF', 'jpg, png, gif'], - ['jpg, jpg, jpg', 'jpg'], - ['jpg, png, gif', 'jpg, png, gif'], - ['jpg png gif', 'jpg, png, gif'], - ['!jpg@png#gif%', 'jpg, png, gif'], - ['jpg, png, 123', 'jpg, png, 123'], - ['', ''], - ]; - } - - /** - * Create file type option for product. - * - * @param string $rawExtensions - * @return \Magento\Catalog\Api\Data\ProductCustomOptionInterface|void - */ - private function createFileOption(string $rawExtensions) - { - $data = [ - 'title' => 'file option', - 'type' => 'file', - 'is_require' => true, - 'sort_order' => 3, - 'price' => 30.0, - 'price_type' => 'percent', - 'sku' => 'sku3', - 'file_extension' => $rawExtensions, - 'image_size_x' => 10, - 'image_size_y' => 20, - ]; - - return $this->customOptionFactory->create(['data' => $data]); - } - - /** - * Test to save option price by store - * - * @magentoDataFixture Magento/Catalog/_files/product_with_options.php - * @magentoDataFixture Magento/Store/_files/core_second_third_fixturestore.php - * @magentoConfigFixture default_store catalog/price/scope 1 - * @magentoConfigFixture secondstore_store catalog/price/scope 1 - */ - public function testSaveOptionPriceByStore() - { - $secondWebsitePrice = 22.0; - $defaultStoreId = $this->storeManager->getStore()->getId(); - $secondStoreId = $this->storeManager->getStore('secondstore')->getId(); - - /** @var \Magento\Catalog\Model\Product $product */ - $product = $this->productRepository->get('simple'); - $option = $product->getOptions()[0]; - $defaultPrice = $option->getPrice(); - - $option->setPrice($secondWebsitePrice); - $product->setStoreId($secondStoreId); - // set Current store='secondstore' to correctly save product options for 'secondstore' - $this->storeManager->setCurrentStore($secondStoreId); - $this->productRepository->save($product); - $this->storeManager->setCurrentStore($defaultStoreId); - - $product = $this->productRepository->get('simple', false, Store::DEFAULT_STORE_ID, true); - $option = $product->getOptions()[0]; - $this->assertEquals($defaultPrice, $option->getPrice(), 'Price value by default store is wrong'); - - $product = $this->productRepository->get('simple', false, $secondStoreId, true); - $option = $product->getOptions()[0]; - $this->assertEquals($secondWebsitePrice, $option->getPrice(), 'Price value by store_id=1 is wrong'); - } -} From 1f6883cbe1bbb764fa7c21a2dbd098d04eaa1b0f Mon Sep 17 00:00:00 2001 From: Cari Spruiell <spruiell@adobe.com> Date: Fri, 4 Oct 2019 10:13:16 -0500 Subject: [PATCH 0844/1172] PB-27: Resolve & improve GraphQL error with Products widget - update performance benchmark with new test --- setup/performance-toolkit/benchmark.jmx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/setup/performance-toolkit/benchmark.jmx b/setup/performance-toolkit/benchmark.jmx index 00ae0bdbb8a4..fe4a424f2de8 100644 --- a/setup/performance-toolkit/benchmark.jmx +++ b/setup/performance-toolkit/benchmark.jmx @@ -504,6 +504,11 @@ <stringProp name="Argument.value">${__P(graphqlGetCmsPageByIdPercentage,0)}</stringProp> <stringProp name="Argument.metadata">=</stringProp> </elementProp> + <elementProp name="graphqlGetCmsPageWithPageBuilderProductListPercentage" elementType="Argument"> + <stringProp name="Argument.name">graphqlGetCmsPageWithPageBuilderProductListPercentage</stringProp> + <stringProp name="Argument.value">${__P(graphqlGetCmsPageWithPageBuilderProductListPercentage,0)}</stringProp> + <stringProp name="Argument.metadata">=</stringProp> + </elementProp> <elementProp name="graphqlGetConfigurableProductDetailsByNamePercentage" elementType="Argument"> <stringProp name="Argument.name">graphqlGetConfigurableProductDetailsByNamePercentage</stringProp> <stringProp name="Argument.value">${__P(graphqlGetConfigurableProductDetailsByNamePercentage,0)}</stringProp> From 506a67390342ba00003492c70ab730e60e495d3f Mon Sep 17 00:00:00 2001 From: Archit <42545374+gargarchit@users.noreply.github.com> Date: Fri, 4 Oct 2019 22:08:19 +0530 Subject: [PATCH 0845/1172] Update ReadMe --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7662290cc09c..abe9b14ec7ac 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a ## Install Magento -* [Installation Guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). +* [Installation Guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html). ## Learn More About GraphQL in Magento 2 @@ -18,7 +18,7 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a <h2>Contributing to the Magento 2 Code Base</h2> Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions. -To learn about how to make a contribution, click [here][1]. +To learn about how to contribute, click [here][1]. To learn about issues, click [here][2]. To open an issue, click [here][3]. @@ -30,14 +30,14 @@ To suggest documentation improvements, click [here][4]. [4]: https://devdocs.magento.com <h3>Community Maintainers</h3> -The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks these Community Maintainers for their valuable contributions. +The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks to these Community Maintainers for their valuable contributions. <a href="https://magento.com/magento-contributors#maintainers"> <img src="https://raw.githubusercontent.com/wiki/magento/magento2/images/maintainers.png"/> </a> <h3>Top Contributors</h3> -Magento is thankful for any contribution that can improve our code base, documentation or increase test coverage. We always recognize our most active members, as their contributions are the foundation of the Magento Open Source platform. +Magento is thankful for any contribution that can improve our codebase, documentation or increase test coverage. We always recognize our most active members, as their contributions are the foundation of the Magento Open Source platform. <a href="https://magento.com/magento-contributors"> <img src="https://raw.githubusercontent.com/wiki/magento/magento2/images/contributors.png"/> </a> @@ -48,7 +48,7 @@ Please review the [Code Contributions guide](https://devdocs.magento.com/guides/ ## Reporting Security Issues -To report security vulnerabilities or learn more about reporting security issues in Magento software or web sites visit the [Magento Bug Bounty Program](https://hackerone.com/magento) on hackerone. Please create a hackerone account [there](https://hackerone.com/magento) to submit and follow-up your issue. +To report security vulnerabilities or learn more about reporting security issues in Magento software or web sites visit the [Magento Bug Bounty Program](https://hackerone.com/magento) on hackerone. Please create a hackerone account [there](https://hackerone.com/magento) to submit and follow-up on your issue. Stay up-to-date on the latest security news and patches for Magento by signing up for [Security Alert Notifications](https://magento.com/security/sign-up). @@ -64,7 +64,7 @@ Please see LICENSE_EE.txt for the full text of the MEE License or visit https:// ## Community Engineering Slack -To connect with Magento and the Community, join us on the [Magento Community Engineering Slack](https://magentocommeng.slack.com). If you are interested in joining Slack, or a specific channel, send us request at [engcom@adobe.com](mailto:engcom@adobe.com) or [self signup](https://tinyurl.com/engcom-slack). +To connect with Magento and the Community, join us on the [Magento Community Engineering Slack](https://magentocommeng.slack.com). If you are interested in joining Slack, or a specific channel, send us a request at [engcom@adobe.com](mailto:engcom@adobe.com) or [self signup](https://tinyurl.com/engcom-slack). We have channels for each project. These channels are recommended for new members: From ac375e1a012faffe79a767c8b92fddb11f5d1186 Mon Sep 17 00:00:00 2001 From: Archit <42545374+gargarchit@users.noreply.github.com> Date: Fri, 4 Oct 2019 22:27:24 +0530 Subject: [PATCH 0846/1172] Update Readme according to Review --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abe9b14ec7ac..91d0d902cb61 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ To suggest documentation improvements, click [here][4]. [4]: https://devdocs.magento.com <h3>Community Maintainers</h3> -The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks to these Community Maintainers for their valuable contributions. +The members of this team have been recognized for their outstanding commitment to maintaining and improving Magento. Magento has granted them permission to accept, merge, and reject pull requests, as well as review issues, and thanks these Community Maintainers for their valuable contributions. <a href="https://magento.com/magento-contributors#maintainers"> <img src="https://raw.githubusercontent.com/wiki/magento/magento2/images/maintainers.png"/> From 43b3924ec974015f520c3cc7ef0581cbee4cba97 Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Fri, 4 Oct 2019 12:10:20 -0500 Subject: [PATCH 0847/1172] MC-21459: Check/Money Order Language in Admin order view is always from Default Store View --- .../view/adminhtml/templates/info/checkmo.phtml | 3 ++- .../view/adminhtml/templates/info/pdf/checkmo.phtml | 3 ++- .../view/adminhtml/templates/info/purchaseorder.phtml | 3 ++- .../Payment/view/adminhtml/templates/info/default.phtml | 3 ++- .../Payment/view/adminhtml/templates/info/pdf/default.phtml | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml index 36f9d35327fc..28395f8eeb84 100644 --- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/checkmo.phtml @@ -7,8 +7,9 @@ /** * @var $block \Magento\OfflinePayments\Block\Info\Checkmo */ +$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId()); ?> -<?= $block->escapeHtml($block->getMethod()->getTitle()) ?> +<?= $block->escapeHtml($paymentTitle) ?> <?php if ($block->getInfo()->getAdditionalInformation()) : ?> <?php if ($block->getPayableTo()) : ?> <br /><?= $block->escapeHtml(__('Make Check payable to: %1', $block->getPayableTo())) ?> diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml index d8d952526e67..f85a8f8357dd 100644 --- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml +++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/pdf/checkmo.phtml @@ -7,8 +7,9 @@ /** * @var $block \Magento\OfflinePayments\Block\Info\Checkmo */ +$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId()); ?> -<?= $block->escapeHtml($block->getMethod()->getTitle()) ?> +<?= $block->escapeHtml($paymentTitle) ?> {{pdf_row_separator}} <?php if ($block->getInfo()->getAdditionalInformation()) : ?> {{pdf_row_separator}} diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml index 2a6de7f0cc35..ae7f654a1350 100644 --- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml +++ b/app/code/Magento/OfflinePayments/view/adminhtml/templates/info/purchaseorder.phtml @@ -6,8 +6,9 @@ /** * @var $block \Magento\OfflinePayments\Block\Info\Purchaseorder */ +$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId()); ?> -<div class="order-payment-method-name"><?= $block->escapeHtml($block->getMethod()->getTitle()) ?></div> +<div class="order-payment-method-name"><?= $block->escapeHtml($paymentTitle) ?></div> <table class="data-table admin__table-secondary"> <tr> <th><?= $block->escapeHtml(__('Purchase Order Number')) ?>:</th> diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml index 8b9c37f11256..3cd88bddbfb1 100644 --- a/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml +++ b/app/code/Magento/Payment/view/adminhtml/templates/info/default.phtml @@ -9,8 +9,9 @@ * @see \Magento\Payment\Block\Info */ $specificInfo = $block->getSpecificInformation(); +$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId()); ?> -<?= $block->escapeHtml($block->getMethod()->getTitle()) ?> +<?= $block->escapeHtml($paymentTitle) ?> <?php if ($specificInfo) : ?> <table class="data-table admin__table-secondary"> diff --git a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml index a8583ea5549f..54b9e48d07a9 100644 --- a/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml +++ b/app/code/Magento/Payment/view/adminhtml/templates/info/pdf/default.phtml @@ -8,8 +8,9 @@ * @see \Magento\Payment\Block\Info * @var \Magento\Payment\Block\Info $block */ +$paymentTitle = $block->getMethod()->getConfigData('title', $block->getInfo()->getOrder()->getStoreId()); ?> -<?= $block->escapeHtml($block->getMethod()->getTitle()) ?>{{pdf_row_separator}} +<?= $block->escapeHtml($paymentTitle) ?>{{pdf_row_separator}} <?php if ($specificInfo = $block->getSpecificInformation()) : ?> <?php foreach ($specificInfo as $label => $value) : ?> From fce0447f8ca43d96f9de08386223c2c1e1ac9728 Mon Sep 17 00:00:00 2001 From: Stanislav Idolov <sidolov@adobe.com> Date: Fri, 4 Oct 2019 13:14:58 -0500 Subject: [PATCH 0848/1172] magento-engcom/magento2ce#3317: Reverted method return type --- .../Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php index 79597e07be76..284cb01148f6 100644 --- a/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php +++ b/app/code/Magento/Backend/Block/Widget/Grid/Massaction/AbstractMassaction.php @@ -127,7 +127,7 @@ private function isVisible(DataObject $item) * Retrieve massaction item with id $itemId * * @param string $itemId - * @return Item|null + * @return \Magento\Backend\Block\Widget\Grid\Massaction\Item|null */ public function getItem($itemId) { From 6496f4e2bff89ee709f45cc16f3f64d31c971cdf Mon Sep 17 00:00:00 2001 From: Roman Kabanov <roman@convert.no> Date: Fri, 4 Oct 2019 09:45:56 +0300 Subject: [PATCH 0849/1172] Correct image params - allow to disable image frame, fix image params hash --- app/code/Magento/Catalog/Helper/Image.php | 12 ++- .../Catalog/Model/View/Asset/Image.php | 10 +-- .../Catalog/Test/Unit/Helper/ImageTest.php | 85 +++++++++++++++++-- .../Test/Unit/Model/View/Asset/ImageTest.php | 53 +++++++++--- 4 files changed, 129 insertions(+), 31 deletions(-) diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index 9b8d0ad75a8c..110b798df9df 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -213,31 +213,29 @@ protected function setImageProperties() // Set 'keep frame' flag $frame = $this->getFrame(); - if (!empty($frame)) { - $this->_getModel()->setKeepFrame($frame); - } + $this->_getModel()->setKeepFrame($frame); // Set 'constrain only' flag $constrain = $this->getAttribute('constrain'); - if (!empty($constrain)) { + if (null !== $constrain) { $this->_getModel()->setConstrainOnly($constrain); } // Set 'keep aspect ratio' flag $aspectRatio = $this->getAttribute('aspect_ratio'); - if (!empty($aspectRatio)) { + if (null !== $aspectRatio) { $this->_getModel()->setKeepAspectRatio($aspectRatio); } // Set 'transparency' flag $transparency = $this->getAttribute('transparency'); - if (!empty($transparency)) { + if (null !== $transparency) { $this->_getModel()->setKeepTransparency($transparency); } // Set background color $background = $this->getAttribute('background'); - if (!empty($background)) { + if (null !== $background) { $this->_getModel()->setBackgroundColor($background); } diff --git a/app/code/Magento/Catalog/Model/View/Asset/Image.php b/app/code/Magento/Catalog/Model/View/Asset/Image.php index dfae9f4b0da9..4128b7730820 100644 --- a/app/code/Magento/Catalog/Model/View/Asset/Image.php +++ b/app/code/Magento/Catalog/Model/View/Asset/Image.php @@ -200,11 +200,11 @@ private function convertToReadableFormat($miscParams) $miscParams['image_width'] = 'w:' . ($miscParams['image_width'] ?? 'empty'); $miscParams['quality'] = 'q:' . ($miscParams['quality'] ?? 'empty'); $miscParams['angle'] = 'r:' . ($miscParams['angle'] ?? 'empty'); - $miscParams['keep_aspect_ratio'] = (isset($miscParams['keep_aspect_ratio']) ? '' : 'non') . 'proportional'; - $miscParams['keep_frame'] = (isset($miscParams['keep_frame']) ? '' : 'no') . 'frame'; - $miscParams['keep_transparency'] = (isset($miscParams['keep_transparency']) ? '' : 'no') . 'transparency'; - $miscParams['constrain_only'] = (isset($miscParams['constrain_only']) ? 'do' : 'not') . 'constrainonly'; - $miscParams['background'] = isset($miscParams['background']) + $miscParams['keep_aspect_ratio'] = (!empty($miscParams['keep_aspect_ratio']) ? '' : 'non') . 'proportional'; + $miscParams['keep_frame'] = (!empty($miscParams['keep_frame']) ? '' : 'no') . 'frame'; + $miscParams['keep_transparency'] = (!empty($miscParams['keep_transparency']) ? '' : 'no') . 'transparency'; + $miscParams['constrain_only'] = (!empty($miscParams['constrain_only']) ? 'do' : 'not') . 'constrainonly'; + $miscParams['background'] = !empty($miscParams['background']) ? 'rgb' . implode(',', $miscParams['background']) : 'nobackground'; return $miscParams; diff --git a/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php index 2759371dc96e..bddf969b8322 100644 --- a/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php @@ -29,6 +29,11 @@ class ImageTest extends \PHPUnit\Framework\TestCase */ protected $assetRepository; + /** + * @var \Magento\Framework\Config\View|\PHPUnit\Framework\MockObject\MockObject + */ + protected $configView; + /** * @var \Magento\Framework\View\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -58,6 +63,10 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); + $this->configView = $this->getMockBuilder(\Magento\Framework\Config\View::class) + ->disableOriginalConstructor() + ->getMock(); + $this->viewConfig = $this->getMockBuilder(\Magento\Framework\View\ConfigInterface::class) ->getMockForAbstractClass(); @@ -151,23 +160,89 @@ public function initDataProvider() ]; } + /** + * @param array $data - optional 'frame' key + * @param bool $whiteBorders view config + * @param bool $expectedKeepFrame + * @dataProvider initKeepFrameDataProvider + */ + public function testInitKeepFrame($data, $whiteBorders, $expectedKeepFrame) + { + $imageId = 'test_image_id'; + $attributes = []; + + $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->prepareAttributes($data, $imageId); + + $this->configView->expects(isset($data['frame']) ? $this->never() : $this->once()) + ->method('getVarValue') + ->with('Magento_Catalog', 'product_image_white_borders') + ->willReturn($whiteBorders); + + $this->viewConfig->expects($this->once()) + ->method('getViewConfig') + ->willReturn($this->configView); + + $this->image->expects($this->once()) + ->method('setKeepFrame') + ->with($expectedKeepFrame) + ->willReturnSelf(); + + $this->helper->init($productMock, $imageId, $attributes); + } + + /** + * @return array + */ + public function initKeepFrameDataProvider() + { + return [ + // when frame defined explicitly, it wins + [ + 'mediaImage' => [ + 'frame' => 1, + ], + 'whiteBorders' => true, + 'expected' => true, + ], + [ + 'mediaImage' => [ + 'frame' => 0, + ], + 'whiteBorders' => true, + 'expected' => false, + ], + // when frame is not defined, var is used + [ + 'mediaImage' => [], + 'whiteBorders' => true, + 'expected' => true, + ], + [ + 'mediaImage' => [], + 'whiteBorders' => false, + 'expected' => false, + ], + ]; + } + /** * @param $data * @param $imageId */ protected function prepareAttributes($data, $imageId) { - $configViewMock = $this->getMockBuilder(\Magento\Framework\Config\View::class) - ->disableOriginalConstructor() - ->getMock(); - $configViewMock->expects($this->once()) + $this->configView->expects($this->once()) ->method('getMediaAttributes') ->with('Magento_Catalog', Image::MEDIA_TYPE_CONFIG_NODE, $imageId) ->willReturn($data); $this->viewConfig->expects($this->once()) ->method('getViewConfig') - ->willReturn($configViewMock); + ->willReturn($this->configView); } /** diff --git a/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php index eb7b70c8a171..6832d5b3399d 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php @@ -7,6 +7,7 @@ use Magento\Catalog\Model\Product\Media\ConfigInterface; use Magento\Catalog\Model\View\Asset\Image; +use Magento\Framework\Encryption\Encryptor; use Magento\Framework\Encryption\EncryptorInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\View\Asset\ContextInterface; @@ -103,9 +104,10 @@ public function testGetContext() /** * @param string $filePath * @param array $miscParams + * @param string $readableParams * @dataProvider getPathDataProvider */ - public function testGetPath($filePath, $miscParams) + public function testGetPath($filePath, $miscParams, $readableParams) { $imageModel = $this->objectManager->getObject( Image::class, @@ -118,11 +120,13 @@ public function testGetPath($filePath, $miscParams) 'miscParams' => $miscParams ] ); - $miscParams['background'] = isset($miscParams['background']) ? implode(',', $miscParams['background']) : ''; $absolutePath = '/var/www/html/magento2ce/pub/media/catalog/product'; - $hashPath = md5(implode('_', $miscParams)); + $hashPath = 'somehash'; $this->context->method('getPath')->willReturn($absolutePath); - $this->encryptor->method('hash')->willReturn($hashPath); + $this->encryptor->expects(static::once()) + ->method('hash') + ->with($readableParams, $this->anything()) + ->willReturn($hashPath); static::assertEquals( $absolutePath . '/cache/'. $hashPath . $filePath, $imageModel->getPath() @@ -132,9 +136,10 @@ public function testGetPath($filePath, $miscParams) /** * @param string $filePath * @param array $miscParams + * @param string $readableParams * @dataProvider getPathDataProvider */ - public function testGetUrl($filePath, $miscParams) + public function testGetUrl($filePath, $miscParams, $readableParams) { $imageModel = $this->objectManager->getObject( Image::class, @@ -147,11 +152,13 @@ public function testGetUrl($filePath, $miscParams) 'miscParams' => $miscParams ] ); - $miscParams['background'] = isset($miscParams['background']) ? implode(',', $miscParams['background']) : ''; $absolutePath = 'http://localhost/pub/media/catalog/product'; - $hashPath = md5(implode('_', $miscParams)); + $hashPath = 'somehash'; $this->context->expects(static::once())->method('getBaseUrl')->willReturn($absolutePath); - $this->encryptor->expects(static::once())->method('hash')->willReturn($hashPath); + $this->encryptor->expects(static::once()) + ->method('hash') + ->with($readableParams, $this->anything()) + ->willReturn($hashPath); static::assertEquals( $absolutePath . '/cache/' . $hashPath . $filePath, $imageModel->getUrl() @@ -166,7 +173,8 @@ public function getPathDataProvider() return [ [ '/some_file.png', - [], //default value for miscParams + [], //default value for miscParams, + 'h:empty_w:empty_q:empty_r:empty_nonproportional_noframe_notransparency_notconstrainonly_nobackground', ], [ '/some_file_2.png', @@ -174,15 +182,32 @@ public function getPathDataProvider() 'image_type' => 'thumbnail', 'image_height' => 75, 'image_width' => 75, - 'keep_aspect_ratio' => 'proportional', - 'keep_frame' => 'frame', - 'keep_transparency' => 'transparency', - 'constrain_only' => 'doconstrainonly', + 'keep_aspect_ratio' => true, + 'keep_frame' => true, + 'keep_transparency' => true, + 'constrain_only' => true, 'background' => [233,1,0], 'angle' => null, 'quality' => 80, ], - ] + 'h:75_w:75_proportional_frame_transparency_doconstrainonly_rgb233,1,0_r:empty_q:80', + ], + [ + '/some_file_3.png', + [ + 'image_type' => 'thumbnail', + 'image_height' => 75, + 'image_width' => 75, + 'keep_aspect_ratio' => false, + 'keep_frame' => false, + 'keep_transparency' => false, + 'constrain_only' => false, + 'background' => [233,1,0], + 'angle' => 90, + 'quality' => 80, + ], + 'h:75_w:75_nonproportional_noframe_notransparency_notconstrainonly_rgb233,1,0_r:90_q:80', + ], ]; } } From cfbe6eeb08d0dead5443bb249c00aac43fffc1e2 Mon Sep 17 00:00:00 2001 From: Dan Mooney <dmooney@adobe.com> Date: Fri, 4 Oct 2019 13:33:37 -0500 Subject: [PATCH 0850/1172] PB-41: Multiple AJAX requests while searching in ui-select in PageBuilder - Debounce requests using Knockout's notifyWhenChangesStop for Product - Product is the only UrlInput type with searchUrl --- app/code/Magento/Catalog/Ui/Component/UrlInput/Product.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Catalog/Ui/Component/UrlInput/Product.php b/app/code/Magento/Catalog/Ui/Component/UrlInput/Product.php index be73940237db..453da64dc5b2 100644 --- a/app/code/Magento/Catalog/Ui/Component/UrlInput/Product.php +++ b/app/code/Magento/Catalog/Ui/Component/UrlInput/Product.php @@ -46,6 +46,7 @@ public function getConfig(): array 'template' => 'ui/grid/filters/elements/ui-select', 'searchUrl' => $this->urlBuilder->getUrl('catalog/product/search'), 'filterPlaceholder' => __('Product Name or SKU'), + 'filterRateLimitMethod' => 'notifyWhenChangesStop', 'isDisplayEmptyPlaceholder' => true, 'emptyOptionsHtml' => __('Start typing to find products'), 'missingValuePlaceholder' => __('Product with ID: %s doesn\'t exist'), From 65a6eb46a3385e360e47495570158134e3565944 Mon Sep 17 00:00:00 2001 From: Stsiapan Korf <Stsiapan_Korf@epam.com> Date: Fri, 4 Oct 2019 21:25:18 +0300 Subject: [PATCH 0851/1172] MC-18826: Increase test coverage for Cart & Checkout and Order Processing functional areas - Fix comments for MC-6405 --- ...nGroup.xml => StorefrontSetShippingMethodActionGroup.xml} | 5 ++++- .../StorefrontDisplayTableRatesShippingMethodForAETest.xml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) rename app/code/Magento/Shipping/Test/Mftf/ActionGroup/{StorefrontShipmentActionGroup.xml => StorefrontSetShippingMethodActionGroup.xml} (75%) diff --git a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontSetShippingMethodActionGroup.xml similarity index 75% rename from app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml rename to app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontSetShippingMethodActionGroup.xml index 6e75ed921717..7fdfe6d88b8e 100644 --- a/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontShipmentActionGroup.xml +++ b/app/code/Magento/Shipping/Test/Mftf/ActionGroup/StorefrontSetShippingMethodActionGroup.xml @@ -8,7 +8,10 @@ <actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> - <actionGroup name="SetShippingMethodActionGroup"> + <actionGroup name="StorefrontSetShippingMethodActionGroup"> + <annotations> + <description>Selects the provided Shipping Method on checkout shipping and wait loading mask.</description> + </annotations> <arguments> <argument name="shippingMethodName" type="string" defaultValue="Flat Rate"/> </arguments> diff --git a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml index a93377c694df..bb29a4a28bcf 100644 --- a/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml +++ b/app/code/Magento/Shipping/Test/Mftf/Test/StorefrontDisplayTableRatesShippingMethodForAETest.xml @@ -63,7 +63,7 @@ <actionGroup ref="AssertStoreFrontShippingMethodAvailableActionGroup" stepKey="assertShippingMethodAvailable"> <argument name="shippingMethodName" value="Best Way"/> </actionGroup> - <actionGroup ref="SetShippingMethodActionGroup" stepKey="setShippingMethodTableRate"> + <actionGroup ref="StorefrontSetShippingMethodActionGroup" stepKey="setShippingMethodTableRate"> <argument name="shippingMethodName" value="Best Way"/> </actionGroup> <!--Proceed to Review and Payments section--> From f582c7598251002b5f3ee62c6762cda7f8cfa6d8 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Fri, 4 Oct 2019 14:35:19 -0500 Subject: [PATCH 0852/1172] MC-21481: TransportBuilder doesn't add "to" email-addresses, if given in array --- .../Mail/Template/TransportBuilderMock.php | 3 +- .../Mail/TransportInterfaceMock.php | 11 +- .../Email/Model/_files/email_template.php | 6 +- .../Framework/Mail/TransportBuilderTest.php | 100 ++++++++++++++++++ 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php index 9f697a1be633..3f236821b24a 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php @@ -38,11 +38,12 @@ public function getSentMessage() * Return transport mock. * * @return \Magento\TestFramework\Mail\TransportInterfaceMock + * @throws \Magento\Framework\Exception\LocalizedException */ public function getTransport() { $this->prepareMessage(); $this->reset(); - return new \Magento\TestFramework\Mail\TransportInterfaceMock(); + return new \Magento\TestFramework\Mail\TransportInterfaceMock($this->message); } } diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php index 8f967b501a59..58f031813b48 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php @@ -8,6 +8,13 @@ class TransportInterfaceMock implements \Magento\Framework\Mail\TransportInterface { + private $message; + + public function __construct($message = '') + { + $this->message = $message; + } + /** * Mock of send a mail using transport * @@ -21,10 +28,10 @@ public function sendMessage() /** * Get message * - * @return string + * @return mixed */ public function getMessage() { - return ''; + return $this->message; } } diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php b/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php index bbbcc3133d4b..6d5f760d7894 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/_files/email_template.php @@ -10,9 +10,9 @@ $template->setOptions(['area' => 'test area', 'store' => 1]); $template->setData( [ - 'template_text' => - file_get_contents(__DIR__ . '/template_fixture.html'), - 'template_code' => \Magento\Theme\Model\Config\ValidatorTest::TEMPLATE_CODE + 'template_text' => file_get_contents(__DIR__ . '/template_fixture.html'), + 'template_code' => \Magento\Theme\Model\Config\ValidatorTest::TEMPLATE_CODE, + 'template_type' => \Magento\Email\Model\Template::TYPE_TEXT ] ); $template->save(); diff --git a/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php b/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php new file mode 100644 index 000000000000..03bdc9a36552 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Framework/Mail/TransportBuilderTest.php @@ -0,0 +1,100 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\Framework\Mail; + +use Magento\Email\Model\BackendTemplate; +use Magento\Email\Model\Template; +use Magento\Framework\Mail\Template\TransportBuilder; +use Magento\Framework\ObjectManagerInterface; +use Magento\TestFramework\Helper\Bootstrap; +use PHPUnit\Framework\TestCase; + +/** + * Class EmailMessageTest + */ +class TransportBuilderTest extends TestCase +{ + /** + * @var ObjectManagerInterface + */ + private $di; + + /** + * @var TransportBuilder + */ + protected $builder; + + /** + * @var Template + */ + protected $template; + + protected function setUp() + { + $this->di = Bootstrap::getObjectManager(); + $this->builder = $this->di->get(TransportBuilder::class); + $this->template = $this->di->get(Template::class); + } + + /** + * @magentoDataFixture Magento/Email/Model/_files/email_template.php + * @magentoDbIsolation enabled + * + * @param string|array $email + * @dataProvider emailDataProvider + * @throws \Magento\Framework\Exception\LocalizedException + */ + public function testAddToEmail($email) + { + $templateId = $this->template->load('email_exception_fixture', 'template_code')->getId(); + + $this->builder->setTemplateModel(BackendTemplate::class); + + $vars = ['reason' => 'Reason', 'customer' => 'Customer']; + $options = ['area' => 'frontend', 'store' => 1]; + $this->builder->setTemplateIdentifier($templateId)->setTemplateVars($vars)->setTemplateOptions($options); + + $this->builder->addTo($email); + + /** @var EmailMessage $emailMessage */ + $emailMessage = $this->builder->getTransport(); + + $addresses = $emailMessage->getMessage()->getTo(); + + $emails = []; + /** @var Address $toAddress */ + foreach ($addresses as $address) { + $emails[] = $address->getEmail(); + } + + if (is_string($email)) { + $this->assertCount(1, $emails); + $this->assertEquals($email, $emails[0]); + } else { + $this->assertEquals($email, $emails); + } + } + + /** + * @return array + */ + public function emailDataProvider(): array + { + return [ + [ + 'billy.everything@someserver.com', + ], + [ + [ + 'billy.everything@someserver.com', + 'john.doe@someserver.com', + ] + ] + ]; + } +} From de79f954f25d1189993274529763e528f5ac93f0 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 4 Oct 2019 14:58:02 -0500 Subject: [PATCH 0853/1172] MC-21491: Pricing :: FPT display settings - implement schema & resolver --- .../Model/Resolver/StoreConfig.php | 115 ++++++++++++++++++ .../Magento/WeeeGraphQl/etc/schema.graphqls | 14 +++ 2 files changed, 129 insertions(+) create mode 100644 app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php diff --git a/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php b/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php new file mode 100644 index 000000000000..49c034185d80 --- /dev/null +++ b/app/code/Magento/WeeeGraphQl/Model/Resolver/StoreConfig.php @@ -0,0 +1,115 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\WeeeGraphQl\Model\Resolver; + +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Weee\Helper\Data; +use Magento\Tax\Helper\Data as TaxHelper; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Weee\Model\Tax as WeeeDisplayConfig; +use Magento\Framework\Pricing\Render; + +class StoreConfig implements ResolverInterface +{ + /** + * @var string + */ + private static $weeeDisplaySettingsNone = 'NONE'; + + /** + * @var array + */ + private static $weeeDisplaySettings = [ + WeeeDisplayConfig::DISPLAY_INCL => 'INCLUDING_FPT', + WeeeDisplayConfig::DISPLAY_INCL_DESCR => 'INCLUDING_FPT_AND_FPT_DESCRIPTION', + WeeeDisplayConfig::DISPLAY_EXCL_DESCR_INCL => 'EXCLUDING_FPT_INCLUDING_FPT_AND_FPT_DESCRIPTION', + WeeeDisplayConfig::DISPLAY_EXCL => 'EXCLUDING_FPT' + ]; + + /** + * @var Data + */ + private $weeeHelper; + + /** + * @var TaxHelper + */ + private $taxHelper; + + /** + * @var array + */ + private $computedFptSettings = []; + + /** + * @param Data $weeeHelper + * @param TaxHelper $taxHelper + */ + public function __construct(Data $weeeHelper, TaxHelper $taxHelper) + { + $this->weeeHelper = $weeeHelper; + $this->taxHelper = $taxHelper; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (empty($this->computedFptSettings)) { + /** @var StoreInterface $store */ + $store = $context->getExtensionAttributes()->getStore(); + $storeId = (int)$store->getId(); + + $this->computedFptSettings = [ + 'product_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone, + 'category_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone, + 'sales_fixed_product_tax_display_setting' => self::$weeeDisplaySettingsNone, + ]; + if ($this->weeeHelper->isEnabled($store)) { + $productFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_ITEM_VIEW, $storeId); + $categoryFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_ITEM_LIST, $storeId); + $salesModulesFptDisplay = $this->getWeeDisplaySettingsByZone(Render::ZONE_SALES, $storeId); + + $this->computedFptSettings = [ + 'product_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$productFptDisplay] ?? + self::$weeeDisplaySettingsNone, + 'category_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$categoryFptDisplay] ?? + self::$weeeDisplaySettingsNone, + 'sales_fixed_product_tax_display_setting' => self::$weeeDisplaySettings[$salesModulesFptDisplay] ?? + self::$weeeDisplaySettingsNone, + ]; + } + } + + return $this->computedFptSettings[$info->fieldName] ?? null; + } + + /** + * Get the weee system display setting + * + * @param string $zone + * @param string $storeId + * @return string + */ + private function getWeeDisplaySettingsByZone(string $zone, int $storeId): int + { + return (int) $this->weeeHelper->typeOfDisplay( + null, + $zone, + $storeId + ); + } +} diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 95ca88ee7a99..0d29703289c5 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -14,3 +14,17 @@ type FixedProductTax @doc(description: "A single FPT that can be applied to a pr amount: Money @doc(description: "Amount of the FPT as a money object.") label: String @doc(description: "The label assigned to the FPT to be displayed on the frontend.") } + +type StoreConfig { + product_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") + category_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") + sales_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") +} + +enum FixedProductTaxDisplaySettings @doc(description: "This enumeration display settings for the fixed product tax") { + INCLUDING_FPT + INCLUDING_FPT_AND_FPT_DESCRIPTION + EXCLUDING_FPT_INCLUDING_FPT_AND_FPT_DESCRIPTION + EXCLUDING_FPT + NONE +} From 44fc4c0a3e0b829b8b6d6c7f940249f0bcce3c39 Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Fri, 4 Oct 2019 15:39:48 -0500 Subject: [PATCH 0854/1172] MC-21481: TransportBuilder doesn't add "to" email-addresses, if given in array --- .../TestFramework/Mail/Template/TransportBuilderMock.php | 3 +++ .../Magento/TestFramework/Mail/TransportInterfaceMock.php | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php index 3f236821b24a..cd9512c22789 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/Template/TransportBuilderMock.php @@ -6,6 +6,9 @@ namespace Magento\TestFramework\Mail\Template; +/** + * Class TransportBuilderMock + */ class TransportBuilderMock extends \Magento\Framework\Mail\Template\TransportBuilder { /** diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php index 58f031813b48..4cc9533a0e2d 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php @@ -6,10 +6,18 @@ namespace Magento\TestFramework\Mail; +/** + * Class TransportInterfaceMock + */ class TransportInterfaceMock implements \Magento\Framework\Mail\TransportInterface { private $message; + /** + * TransportInterfaceMock constructor. + * + * @param string $message + */ public function __construct($message = '') { $this->message = $message; From 0a308f0a7663d490d8256def18a41e69a63d57fd Mon Sep 17 00:00:00 2001 From: Viktor Tymchynskyi <vtymchynskyi@magento.com> Date: Fri, 4 Oct 2019 15:52:15 -0500 Subject: [PATCH 0855/1172] MC-21459: Check/Money Order Language in Admin order view is always from Default Store View --- .../Magento/Payment/Block/InfoTest.php | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php b/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php index 3bd966018b94..ff4f3f8a58bc 100644 --- a/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php +++ b/dev/tests/integration/testsuite/Magento/Payment/Block/InfoTest.php @@ -5,9 +5,24 @@ */ namespace Magento\Payment\Block; +use Magento\Framework\View\Element\Text; +use Magento\Framework\View\LayoutInterface; +use Magento\OfflinePayments\Model\Banktransfer; +use Magento\OfflinePayments\Model\Checkmo; +use Magento\Payment\Block\Info as BlockInfo; +use Magento\Payment\Block\Info\Instructions; +use Magento\Payment\Model\Info; +use Magento\Sales\Model\Order; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Class InfoTest + */ class InfoTest extends \PHPUnit\Framework\TestCase { /** + * Tests payment info block. + * * @magentoConfigFixture current_store payment/banktransfer/title Bank Method Title * @magentoConfigFixture current_store payment/checkmo/title Checkmo Title Of The Method * @magentoAppArea adminhtml @@ -15,37 +30,32 @@ class InfoTest extends \PHPUnit\Framework\TestCase public function testGetChildPdfAsArray() { /** @var $layout \Magento\Framework\View\Layout */ - $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( - \Magento\Framework\View\LayoutInterface::class - ); - $block = $layout->createBlock(\Magento\Payment\Block\Info::class, 'block'); + $layout = Bootstrap::getObjectManager()->get(LayoutInterface::class); + $block = $layout->createBlock(BlockInfo::class, 'block'); - /** @var $paymentInfoBank \Magento\Payment\Model\Info */ - $paymentInfoBank = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Payment\Model\Info::class - ); - $paymentInfoBank->setMethodInstance( - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\OfflinePayments\Model\Banktransfer::class - ) + /** @var $paymentInfoBank Info */ + $paymentInfoBank = Bootstrap::getObjectManager()->create( + Info::class ); - /** @var $childBank \Magento\Payment\Block\Info\Instructions */ - $childBank = $layout->addBlock(\Magento\Payment\Block\Info\Instructions::class, 'child.one', 'block'); + $order = Bootstrap::getObjectManager()->create(Order::class); + $banktransferPayment = Bootstrap::getObjectManager()->create(Banktransfer::class); + $paymentInfoBank->setMethodInstance($banktransferPayment); + $paymentInfoBank->setOrder($order); + /** @var $childBank Instructions */ + $childBank = $layout->addBlock(Instructions::class, 'child.one', 'block'); $childBank->setInfo($paymentInfoBank); $nonExpectedHtml = 'non-expected html'; - $childHtml = $layout->addBlock(\Magento\Framework\View\Element\Text::class, 'child.html', 'block'); + $childHtml = $layout->addBlock(Text::class, 'child.html', 'block'); $childHtml->setText($nonExpectedHtml); - /** @var $paymentInfoCheckmo \Magento\Payment\Model\Info */ - $paymentInfoCheckmo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Payment\Model\Info::class - ); - $paymentInfoCheckmo->setMethodInstance( - \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\OfflinePayments\Model\Checkmo::class - ) + /** @var $paymentInfoCheckmo Info */ + $paymentInfoCheckmo = Bootstrap::getObjectManager()->create( + Info::class ); + $checkmoPayment = Bootstrap::getObjectManager()->create(Checkmo::class); + $paymentInfoCheckmo->setMethodInstance($checkmoPayment); + $paymentInfoCheckmo->setOrder($order); /** @var $childCheckmo \Magento\OfflinePayments\Block\Info\Checkmo */ $childCheckmo = $layout->addBlock( \Magento\OfflinePayments\Block\Info\Checkmo::class, From 379ca7e401387ca487d7a26c733705fde6f386a8 Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 4 Oct 2019 16:02:48 -0500 Subject: [PATCH 0856/1172] MC-20456: Category filtering - add api-functional tests --- .../GraphQl/Catalog/CategoryListTest.php | 425 ++++++++++++++++++ .../Magento/Catalog/_files/categories.php | 2 + 2 files changed, 427 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php new file mode 100644 index 000000000000..cbf09ca5d2e6 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryListTest.php @@ -0,0 +1,425 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQl\Catalog; + +use Magento\TestFramework\TestCase\GraphQlAbstract; + +/** + * Test CategoryList GraphQl query + */ +class CategoryListTest extends GraphQlAbstract +{ + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @dataProvider filterSingleCategoryDataProvider + * @param $field + * @param $condition + * @param $value + */ + public function testFilterSingleCategoryByField($field, $condition, $value, $expectedResult) + { + $query = <<<QUERY +{ + categoryList(filters: { $field : { $condition : "$value" } }){ + id + name + url_key + url_path + children_count + path + position + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(1, $result['categoryList']); + $this->assertResponseFields($result['categoryList'][0], $expectedResult); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + * @dataProvider filterMultipleCategoriesDataProvider + * @param $field + * @param $condition + * @param $value + * @param $expectedResult + */ + public function testFilterMultipleCategoriesByField($field, $condition, $value, $expectedResult) + { + $query = <<<QUERY +{ + categoryList(filters: { $field : { $condition : $value } }){ + id + name + url_key + url_path + children_count + path + position + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(count($expectedResult), $result['categoryList']); + foreach ($expectedResult as $i => $expected) { + $this->assertResponseFields($result['categoryList'][$i], $expected); + } + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testFilterCategoryByMultipleFields() + { + $query = <<<QUERY +{ + categoryList(filters: {ids: {in: ["6","7","8","9","10"]}, name: {match: "Movable"}}){ + id + name + url_key + url_path + children_count + path + position + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(3, $result['categoryList']); + + $expectedCategories = [7 => 'Movable', 9 => 'Movable Position 1', 10 => 'Movable Position 2']; + $actualCategories = array_column($result['categoryList'], 'name', 'id'); + $this->assertEquals($expectedCategories, $actualCategories); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testFilterWithInactiveCategory() + { + $query = <<<QUERY +{ + categoryList(filters: {url_key: {in: ["inactive", "category-2"]}}){ + id + name + url_key + url_path + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(1, $result['categoryList']); + $actualCategories = array_column($result['categoryList'], 'url_key', 'id'); + $this->assertContains('category-2', $actualCategories); + $this->assertNotContains('inactive', $actualCategories); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testQueryChildCategoriesWithProducts() + { + $query = <<<QUERY +{ + categoryList(filters: {ids: {in: ["3"]}}){ + id + name + url_key + url_path + description + products{ + total_count + items{ + name + sku + } + } + children{ + name + url_key + description + products{ + total_count + items{ + name + sku + } + } + children{ + name + } + } + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $a = 3; + + $this->assertArrayNotHasKey('errors', $result); + $this->assertCount(1, $result['categoryList']); + $baseCategory = $result['categoryList'][0]; + + $this->assertEquals('Category 1', $baseCategory['name']); + $this->assertArrayHasKey('products', $baseCategory); + //Check base category products + $expectedBaseCategoryProducts = [ + ['sku' => 'simple', 'name' => 'Simple Product'], + ['sku' => '12345', 'name' => 'Simple Product Two'], + ['sku' => 'simple-4', 'name' => 'Simple Product Three'] + ]; + $this->assertCategoryProducts($baseCategory, $expectedBaseCategoryProducts); + //Check base category children + $expectedBaseCategoryChildren = [ + ['name' => 'Category 1.1', 'description' => 'Category 1.1 description.'], + ['name' => 'Category 1.2', 'description' => 'Its a description of Test Category 1.2'] + ]; + $this->assertCategoryChildren($baseCategory, $expectedBaseCategoryChildren); + + //Check first child category + $firstChildCategory = $baseCategory['children'][0]; + $this->assertEquals('Category 1.1', $firstChildCategory['name']); + $this->assertEquals('Category 1.1 description.', $firstChildCategory['description']); + $firstChildCategoryExpectedProducts = [ + ['sku' => 'simple', 'name' => 'Simple Product'], + ['sku' => '12345', 'name' => 'Simple Product Two'], + ]; + $this->assertCategoryProducts($firstChildCategory, $firstChildCategoryExpectedProducts); + $firstChildCategoryChildren = [['name' =>'Category 1.1.1']]; + $this->assertCategoryChildren($firstChildCategory, $firstChildCategoryChildren); + //Check second child category + $secondChildCategory = $baseCategory['children'][1]; + $this->assertEquals('Category 1.2', $secondChildCategory['name']); + $this->assertEquals('Its a description of Test Category 1.2', $secondChildCategory['description']); + $firstChildCategoryExpectedProducts = [ + ['sku' => 'simple', 'name' => 'Simple Product'], + ['sku' => 'simple-4', 'name' => 'Simple Product Three'] + ]; + $this->assertCategoryProducts($secondChildCategory, $firstChildCategoryExpectedProducts); + $firstChildCategoryChildren = []; + $this->assertCategoryChildren($secondChildCategory, $firstChildCategoryChildren); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/categories.php + */ + public function testNoResultsFound() + { + $query = <<<QUERY +{ + categoryList(filters: {url_key: {in: ["inactive", "does-not-exist"]}}){ + id + name + url_key + url_path + children_count + path + position + } +} +QUERY; + + $result = $this->graphQlQuery($query); + $this->assertArrayNotHasKey('errors', $result); + $this->assertArrayHasKey('categoryList', $result); + $this->assertEquals([], $result['categoryList']); + } + + /** + * @return array + */ + public function filterSingleCategoryDataProvider(): array + { + return [ + [ + 'ids', + 'eq', + '4', + [ + 'id' => '4', + 'name' => 'Category 1.1', + 'url_key' => 'category-1-1', + 'url_path' => 'category-1/category-1-1', + 'children_count' => '0', + 'path' => '1/2/3/4', + 'position' => '1' + ] + ], + [ + 'name', + 'match', + 'Movable Position 2', + [ + 'id' => '10', + 'name' => 'Movable Position 2', + 'url_key' => 'movable-position-2', + 'url_path' => 'movable-position-2', + 'children_count' => '0', + 'path' => '1/2/10', + 'position' => '6' + ] + ], + [ + 'url_key', + 'eq', + 'category-1-1-1', + [ + 'id' => '5', + 'name' => 'Category 1.1.1', + 'url_key' => 'category-1-1-1', + 'url_path' => 'category-1/category-1-1/category-1-1-1', + 'children_count' => '0', + 'path' => '1/2/3/4/5', + 'position' => '1' + ] + ], + ]; + } + + /** + * @return array + */ + public function filterMultipleCategoriesDataProvider(): array + { + return[ + //Filter by multiple IDs + [ + 'ids', + 'in', + '["4", "9", "10"]', + [ + [ + 'id' => '4', + 'name' => 'Category 1.1', + 'url_key' => 'category-1-1', + 'url_path' => 'category-1/category-1-1', + 'children_count' => '0', + 'path' => '1/2/3/4', + 'position' => '1' + ], + [ + 'id' => '9', + 'name' => 'Movable Position 1', + 'url_key' => 'movable-position-1', + 'url_path' => 'movable-position-1', + 'children_count' => '0', + 'path' => '1/2/9', + 'position' => '5' + ], + [ + 'id' => '10', + 'name' => 'Movable Position 2', + 'url_key' => 'movable-position-2', + 'url_path' => 'movable-position-2', + 'children_count' => '0', + 'path' => '1/2/10', + 'position' => '6' + ] + ] + ], + //Filter by multiple url keys + [ + 'url_key', + 'in', + '["category-1-2", "movable"]', + [ + [ + 'id' => '7', + 'name' => 'Movable', + 'url_key' => 'movable', + 'url_path' => 'movable', + 'children_count' => '0', + 'path' => '1/2/7', + 'position' => '3' + ], + [ + 'id' => '13', + 'name' => 'Category 1.2', + 'url_key' => 'category-1-2', + 'url_path' => 'category-1/category-1-2', + 'children_count' => '0', + 'path' => '1/2/3/13', + 'position' => '2' + ] + ] + ], + //Filter by matching multiple names + [ + 'name', + 'match', + '"Position"', + [ + [ + 'id' => '9', + 'name' => 'Movable Position 1', + 'url_key' => 'movable-position-1', + 'url_path' => 'movable-position-1', + 'children_count' => '0', + 'path' => '1/2/9', + 'position' => '5' + ], + [ + 'id' => '10', + 'name' => 'Movable Position 2', + 'url_key' => 'movable-position-2', + 'url_path' => 'movable-position-2', + 'children_count' => '0', + 'path' => '1/2/10', + 'position' => '6' + ], + [ + 'id' => '11', + 'name' => 'Movable Position 3', + 'url_key' => 'movable-position-3', + 'url_path' => 'movable-position-3', + 'children_count' => '0', + 'path' => '1/2/11', + 'position' => '7' + ] + ] + ] + ]; + } + + /** + * Check category products + * + * @param array $category + * @param array $expectedProducts + */ + private function assertCategoryProducts(array $category, array $expectedProducts) + { + $this->assertEquals(count($expectedProducts), $category['products']['total_count']); + $this->assertCount(count($expectedProducts), $category['products']['items']); + $this->assertResponseFields($category['products']['items'], $expectedProducts); + } + + /** + * Check category child categories + * + * @param array $category + * @param array $expectedChildren + */ + private function assertCategoryChildren(array $category, array $expectedChildren) + { + $this->assertArrayHasKey('children', $category); + $this->assertCount(count($expectedChildren), $category['children']); + foreach ($expectedChildren as $i => $expectedChild) { + $this->assertResponseFields($category['children'][$i], $expectedChild); + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php index a5ab96193246..25bb55ffbc32 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories.php @@ -64,6 +64,7 @@ ->setIsActive(true) ->setIsAnchor(true) ->setPosition(1) + ->setDescription('Category 1.1 description.') ->save(); $category = $objectManager->create(\Magento\Catalog\Model\Category::class); @@ -79,6 +80,7 @@ ->setPosition(1) ->setCustomUseParentSettings(0) ->setCustomDesign('Magento/blank') + ->setDescription('This is the description for Category 1.1.1') ->save(); $category = $objectManager->create(\Magento\Catalog\Model\Category::class); From 3a298f658503b9629d903c81ddc1c616990a634f Mon Sep 17 00:00:00 2001 From: Roman Lytvynenko <lytvynen@adobe.com> Date: Fri, 4 Oct 2019 16:14:00 -0500 Subject: [PATCH 0857/1172] MC-21481: TransportBuilder doesn't add "to" email-addresses, if given in array --- .../Magento/TestFramework/Mail/TransportInterfaceMock.php | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php index 4cc9533a0e2d..3340608d4a75 100644 --- a/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php +++ b/dev/tests/integration/framework/Magento/TestFramework/Mail/TransportInterfaceMock.php @@ -30,6 +30,7 @@ public function __construct($message = '') */ public function sendMessage() { + //phpcs:ignore Squiz.PHP.NonExecutableCode.ReturnNotRequired return; } From a505d6dd9a651beffd79bab876e9adedd9a7882d Mon Sep 17 00:00:00 2001 From: Anusha Vattam <avattam@adobe.com> Date: Fri, 4 Oct 2019 16:15:02 -0500 Subject: [PATCH 0858/1172] MC-15986: Category Filtering - add changes in category filter --- .../Model/Category/CategoryFilter.php | 41 +++++++++++++++---- .../Model/Resolver/CategoryList.php | 10 +---- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php index 42f35a871185..8de0d13e51e9 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/CategoryFilter.php @@ -7,7 +7,9 @@ namespace Magento\CatalogGraphQl\Model\Category; +use Magento\Catalog\Api\Data\CategoryInterface; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; +use Magento\Catalog\Model\ResourceModel\Category\Collection; /** * Category filter allows to filter collection using 'id, url_key, name' from search criteria. @@ -32,24 +34,47 @@ public function __construct( * Filter for filtering the requested categories id's based on url_key, ids, name in the result. * * @param array $args - * @param \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection - * @return bool + * @param Collection $categoryCollection */ public function applyFilters( array $args, - \Magento\Catalog\Model\ResourceModel\Category\Collection $categoryCollection - ): bool { + Collection $categoryCollection + ): void { + $categoryCollection->addAttributeToFilter(CategoryInterface::KEY_IS_ACTIVE, ['eq' => 1]); foreach ($args['filters'] as $field => $cond) { foreach ($cond as $condType => $value) { if ($field === 'ids') { $categoryCollection->addIdFilter($value); - } elseif ($condType === 'match') { - $categoryCollection->addAttributeToFilter($field, ['like' => "%{$value}%"]); } else { - $categoryCollection->addAttributeToFilter($field, [$condType => $value]); + $this->addAttributeFilter($categoryCollection, $field, $condType, $value); } } } - return true; + } + + /** + * @param Collection $categoryCollection + * @param string $field + * @param string $condType + * @param string|array $value + */ + private function addAttributeFilter($categoryCollection, $field, $condType, $value) + { + if ($condType === 'match') { + $this->addMatchFilter($categoryCollection, $field, $value); + return; + } + $categoryCollection->addAttributeToFilter($field, [$condType => $value]); + } + + /** + * + * @param Collection $categoryCollection + * @param string $field + * @param string $value + */ + private function addMatchFilter($categoryCollection, $field, $value) + { + $categoryCollection->addAttributeToFilter($field, ['like' => "%{$value}%"]); } } diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php index 140cb68be679..5e51791593cb 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/CategoryList.php @@ -7,7 +7,6 @@ namespace Magento\CatalogGraphQl\Model\Resolver; -use Magento\Catalog\Model\Category; use Magento\CatalogGraphQl\Model\Resolver\Category\CheckCategoryIsActive; use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\ExtractDataFromCategoryTree; use Magento\Framework\GraphQl\Config\Element\Field; @@ -77,10 +76,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if (isset($value[$field->getName()])) { return $value[$field->getName()]; } - $categoryCollection = $this->collectionFactory->create(); - $categoryCollection->addAttributeToFilter('is_active', 1); - $categoryCollection->addAttributeToSelect(['name','url_key', 'ids']); if (!isset($args['filters'])) { $rootCategoryIds = [(int)$context->getExtensionAttributes()->getStore()->getRootCategoryId()]; @@ -91,14 +87,10 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $rootCategoryIds[] = (int)$category->getId(); } } - $result = []; foreach ($rootCategoryIds as $rootCategoryId) { - if ($rootCategoryId !== Category::TREE_ROOT_ID) { - $this->checkCategoryIsActive->execute($rootCategoryId); - } $categoryTree = $this->categoryTree->getTree($info, $rootCategoryId); - if (empty($categoryTree) || ($categoryTree->count() == 0)) { + if (empty($categoryTree)) { throw new GraphQlNoSuchEntityException(__('Category doesn\'t exist')); } $result[] = current($this->extractDataFromCategoryTree->execute($categoryTree)); From 1c3e72a6895d6acf4edd846e22540ba7da34798e Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 4 Oct 2019 16:28:36 -0500 Subject: [PATCH 0859/1172] MC-20508: Api-functional tests for Product prices including FPT - add some docs to schema - fix static and revert Model tax --- .../CatalogGraphQl/etc/schema.graphqls | 2 +- .../Magento/TaxGraphQl/etc/schema.graphqls | 2 +- app/code/Magento/Weee/Model/Tax.php | 22 ++++--------------- .../Magento/WeeeGraphQl/etc/schema.graphqls | 8 +++---- 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 0ec29369a85a..6f2532635ca2 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -27,7 +27,7 @@ type PriceAdjustment @doc(description: "PriceAdjustment is deprecated. Taxes wil description: PriceAdjustmentDescriptionEnum @deprecated(reason: "PriceAdjustment is deprecated.") @doc(description: "Indicates whether the entity described by the code attribute is included or excluded from the adjustment.") } -enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated. This enumeration contains values defined in modules other than the Catalog module.") { +enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustment.code is deprecated. This enumeration contains values defined in modules other than the Catalog module.") { } enum PriceAdjustmentDescriptionEnum @doc(description: "PriceAdjustmentDescriptionEnum is deprecated. This enumeration states whether a price adjustment is included or excluded.") { diff --git a/app/code/Magento/TaxGraphQl/etc/schema.graphqls b/app/code/Magento/TaxGraphQl/etc/schema.graphqls index 2b8198347844..d0be08fe9a1b 100644 --- a/app/code/Magento/TaxGraphQl/etc/schema.graphqls +++ b/app/code/Magento/TaxGraphQl/etc/schema.graphqls @@ -2,5 +2,5 @@ # See COPYING.txt for license details. enum PriceAdjustmentCodesEnum { - TAX + TAX @deprecated(reason: "PriceAdjustmentCodesEnum is deprecated. Tax is included or excluded in price. Tax is not shown separtely in Catalog") } diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index 3c62dbc65e0d..941faed0498f 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -13,8 +13,6 @@ use Magento\Catalog\Model\Product\Type; /** - * Weee tax model - * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @api * @since 100.0.2 @@ -143,8 +141,6 @@ protected function _construct() } /** - * Get the weee amount - * * @param Product $product * @param null|false|\Magento\Framework\DataObject $shipping * @param null|false|\Magento\Framework\DataObject $billing @@ -174,8 +170,6 @@ public function getWeeeAmount( } /** - * Get the weee amount excluding tax - * * @param Product $product * @param null|false|\Magento\Framework\DataObject $shipping * @param null|false|\Magento\Framework\DataObject $billing @@ -206,8 +200,6 @@ public function getWeeeAmountExclTax( } /** - * Get the weee attribute codes - * * @param bool $forceEnabled * @return array */ @@ -219,8 +211,8 @@ public function getWeeeAttributeCodes($forceEnabled = false) /** * Retrieve Wee tax attribute codes * - * @param null|string|bool|int|Store $store - * @param bool $forceEnabled + * @param null|string|bool|int|Store $store + * @param bool $forceEnabled * @return array */ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) @@ -236,8 +228,6 @@ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) } /** - * Retrieve the relevant wee tax attributes assigned to a product by location - * * @param Product $product * @param null|false|\Magento\Quote\Model\Quote\Address $shipping * @param null|false|\Magento\Quote\Model\Quote\Address $billing @@ -248,7 +238,6 @@ public function getWeeeTaxAttributeCodes($store = null, $forceEnabled = false) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - * phpcs:disable Generic.Metrics.NestingLevel */ public function getProductWeeeAttributes( $product, @@ -279,7 +268,7 @@ public function getProductWeeeAttributes( return $result; } - /** @var Calculation $calculator */ + /** @var \Magento\Tax\Model\Calculation $calculator */ $calculator = $this->_calculationFactory->create(); $customerId = $this->_customerSession->getCustomerId(); @@ -328,7 +317,7 @@ public function getProductWeeeAttributes( $amount = $value; $amountExclTax = $value; if ($calculateTax && $this->weeeConfig->isTaxable($store)) { - /** @var Calculation $calculator */ + /** @var \Magento\Tax\Model\Calculation $calculator */ $defaultPercent = $calculator->getRate( $defaultRateRequest->setProductClassId($product->getTaxClassId()) ); @@ -381,13 +370,10 @@ public function getProductWeeeAttributes( $result[] = $one; } } - return $result; } /** - * Is there a weee attribute available for the location provided - * * @param int $countryId * @param int $regionId * @param int $websiteId diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 95ca88ee7a99..5c6d2f98b43f 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -1,13 +1,13 @@ # Copyright © Magento, Inc. All rights reserved. # See COPYING.txt for license details. -enum PriceAdjustmentCodesEnum @doc(description: "PriceAdjustmentCodesEnum is deprecated, use ProductPrice.") { - WEEE @deprecated(reason: "WEEE is deprecated, use fixed_product_taxes.label") - WEEE_TAX @deprecated(reason: "WEEE_TAX is deprecated, use fixed_product_taxes. Tax is included or excluded in the amount") +enum PriceAdjustmentCodesEnum { + WEEE @deprecated(reason: "WEEE code is deprecated, use fixed_product_taxes.label") + WEEE_TAX @deprecated(reason: "Use fixed_product_taxes. PriceAdjustmentCodesEnum is deprecated. Tax is included or excluded in price. Tax is not shown separtely in Catalog") } type ProductPrice { - fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FixedProductTax") + fixed_product_taxes: [FixedProductTax] @doc(description: "The multiple FPTs that can be applied to a product price.") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\FixedProductTax") } type FixedProductTax @doc(description: "A single FPT that can be applied to a product price.") { From b659839bb3db98050622ccb129728faef7e3e8e4 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Fri, 4 Oct 2019 17:02:17 -0500 Subject: [PATCH 0860/1172] MC-21491: Pricing :: FPT display settings - modify docs --- app/code/Magento/WeeeGraphQl/etc/schema.graphqls | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls index 0d29703289c5..467b5f701c2f 100644 --- a/app/code/Magento/WeeeGraphQl/etc/schema.graphqls +++ b/app/code/Magento/WeeeGraphQl/etc/schema.graphqls @@ -16,15 +16,15 @@ type FixedProductTax @doc(description: "A single FPT that can be applied to a pr } type StoreConfig { - product_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") - category_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") - sales_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") + product_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The product page display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") + category_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The category page display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") + sales_fixed_product_tax_display_setting : FixedProductTaxDisplaySettings @doc(description: "The sales modules pages display setting for the fixed product tax") @resolver(class: "Magento\\WeeeGraphQl\\Model\\Resolver\\StoreConfig") } enum FixedProductTaxDisplaySettings @doc(description: "This enumeration display settings for the fixed product tax") { - INCLUDING_FPT - INCLUDING_FPT_AND_FPT_DESCRIPTION - EXCLUDING_FPT_INCLUDING_FPT_AND_FPT_DESCRIPTION - EXCLUDING_FPT - NONE + INCLUDING_FPT @doc(description: "Fixed product tax amount(s) is included into the price and details from fixed_product_taxes should not be displayed") + INCLUDING_FPT_AND_FPT_DESCRIPTION @doc(description: "Fixed product tax amount(s) is included into the price and the details from fixed_product_taxes should be displayed") + EXCLUDING_FPT_INCLUDING_FPT_AND_FPT_DESCRIPTION @doc(description: "Fixed product tax amount(s) is included into the price and the details from fixed_product_taxes should be shown, also price without the amount(s) of fixed_product_taxes should be displayed") + EXCLUDING_FPT @doc(description: "Fixed product tax amount(s) is excluded from the price and details from fixed_product_taxes should not be displayed") + NONE @doc(description: "Fixed product tax feature is disabled and we should not show or query fixed_product_taxes field") } From b35c2693366b0841063548ecdeeb43eff9a550fd Mon Sep 17 00:00:00 2001 From: Daniel Renaud <drenaud@magento.com> Date: Fri, 4 Oct 2019 17:08:58 -0500 Subject: [PATCH 0861/1172] MC-21480: Add caching for CategoryList resolver - integration test --- .../Catalog/CategoryListCacheTest.php | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php diff --git a/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php new file mode 100644 index 000000000000..b91e55267896 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GraphQlCache/Controller/Catalog/CategoryListCacheTest.php @@ -0,0 +1,80 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +declare(strict_types=1); + +namespace Magento\GraphQlCache\Controller\Catalog; + +use Magento\GraphQlCache\Controller\AbstractGraphqlCacheTest; + +/** + * Test caching works for categoryList query + * + * @magentoAppArea graphql + * @magentoCache full_page enabled + * @magentoDbIsolation disabled + */ +class CategoryListCacheTest extends AbstractGraphqlCacheTest +{ + /** + * Test cache tags are generated + * + * @magentoDataFixture Magento/Catalog/_files/category_product.php + */ + public function testRequestCacheTagsForCategoryList(): void + { + $categoryId ='333'; + $query + = <<<QUERY + { + categoryList(filters: {ids: {in: ["$categoryId"]}}) { + id + name + url_key + description + product_count + } + } +QUERY; + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } + + /** + * Test request is served from cache + * + * @magentoDataFixture Magento/Catalog/_files/category_product.php + */ + public function testSecondRequestIsServedFromCache() + { + $categoryId ='333'; + $query + = <<<QUERY + { + categoryList(filters: {ids: {in: ["$categoryId"]}}) { + id + name + url_key + description + product_count + } + } +QUERY; + $expectedCacheTags = ['cat_c','cat_c_' . $categoryId, 'FPC']; + + $response = $this->dispatchGraphQlGETRequest(['query' => $query]); + $this->assertEquals('MISS', $response->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $response->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEquals($expectedCacheTags, $actualCacheTags); + + $cacheResponse = $this->dispatchGraphQlGETRequest(['query' => $query]); + $this->assertEquals('HIT', $cacheResponse->getHeader('X-Magento-Cache-Debug')->getFieldValue()); + $actualCacheTags = explode(',', $cacheResponse->getHeader('X-Magento-Tags')->getFieldValue()); + $this->assertEquals($expectedCacheTags, $actualCacheTags); + } +} From aa7665b2278ebfc3c34991b499c8f3492b42613d Mon Sep 17 00:00:00 2001 From: Oleksandr Miroshnichenko <omiroshnichenko@magento.com> Date: Fri, 4 Oct 2019 17:11:06 -0500 Subject: [PATCH 0862/1172] MC-20534: Migrate remaining failed MFTF tests to SearchEngineMysqlSuite --- .../Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml | 3 +-- .../NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml index be5d9dca425a..21f8e2e070e3 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Test/StorefrontProductNameWithDoubleQuote.xml @@ -117,8 +117,7 @@ <waitForPageLoad stepKey="waitforCategoryPageToLoad2"/> <!--Open product display page--> - <click selector="{{StorefrontCategoryProductSection.ProductTitleByNumber('1')}}" stepKey="goToProduct2DisplayPage"/> - <!--<click selector="{{StorefrontCategoryProductSection.ProductTitleByName(productWithHTMLEntityOne.name)}}" stepKey="clickProductToGoProductPage"/>--> + <click selector="{{StorefrontCategoryProductSection.ProductTitleByName(productWithHTMLEntityTwo.name)}}" stepKey="clickProductToGoSecondProductPage"/> <waitForPageLoad stepKey="waitForProductDisplayPageLoad3"/> <!--Verify the breadcrumbs on Product Display page--> diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml index 3c98f9177f4a..fd6656b1d1b2 100644 --- a/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml +++ b/app/code/Magento/Checkout/Test/Mftf/Test/NoErrorCartCheckoutForProductsDeletedFromMiniCartTest.xml @@ -26,6 +26,8 @@ <field key="price">100.00</field> <requiredEntity createDataKey="createCategory"/> </createData> + <magentoCLI command="indexer:reindex" stepKey="reindex"/> + <magentoCLI command="cache:flush" stepKey="flushCache"/> </before> <after> <deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/> From 98c7dc3e3ccddcb3317014ee1588c488c6baee1f Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Sat, 5 Oct 2019 09:32:09 -0500 Subject: [PATCH 0863/1172] MC-20508: Api-functional tests for Product prices including FPT - fix test to support multitests --- .../{fixed_product_attribute.php => product_with_two_fpt.php} | 2 +- ...attribute_rollback.php => product_with_two_fpt_rollback.php} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename dev/tests/integration/testsuite/Magento/Weee/_files/{fixed_product_attribute.php => product_with_two_fpt.php} (97%) rename dev/tests/integration/testsuite/Magento/Weee/_files/{fixed_product_attribute_rollback.php => product_with_two_fpt_rollback.php} (100%) diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php similarity index 97% rename from dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php rename to dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php index 426cbdfd50a3..c302b7f75de9 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php @@ -41,7 +41,7 @@ $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); $product = $product->loadByAttribute('sku', 'simple-with-ftp'); -if ($product->getId()) { +if ($product && $product->getId()) { $product->setFixedProductAttribute( [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10.00, 'delete' => '']] )->save(); diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php similarity index 100% rename from dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute_rollback.php rename to dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php From d7f8c4a7e0bb779372162efa7770c18d1f256167 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Sat, 5 Oct 2019 09:33:08 -0500 Subject: [PATCH 0864/1172] MC-20508: Api-functional tests for Product prices including FPT - fix test to support multitests --- .../Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php | 3 +-- .../testsuite/Magento/Weee/_files/product_with_two_fpt.php | 2 ++ .../Magento/Weee/_files/product_with_two_fpt_rollback.php | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php index 69308b38cbf7..3f568c2635d0 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceWithFPTTest.php @@ -547,8 +547,7 @@ public function catalogPriceIncTaxCatalogDisplayInclTaxInclFPTWithDescrWithTaxAp * @return void * * @dataProvider catalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTsSettingsProvider - * @magentoApiDataFixture Magento/Weee/_files/product_with_fpt.php - * @magentoApiDataFixture Magento/Weee/_files/fixed_product_attribute.php + * @magentoApiDataFixture Magento/Weee/_files/product_with_two_fpt.php * @magentoApiDataFixture Magento/GraphQl/Tax/_files/tax_rule_for_region_1.php */ public function testCatalogPriceInclTaxCatalogDisplayIncludeTaxAndMuyltipleFPTs(array $weeTaxSettings) diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php index c302b7f75de9..92137a59b1db 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt.php @@ -8,6 +8,8 @@ use Magento\Catalog\Model\Product; use Magento\TestFramework\Helper\Bootstrap; +require __DIR__ . '/product_with_fpt.php'; + /** @var \Magento\Catalog\Setup\CategorySetup $installer */ $installer = Bootstrap::getObjectManager()->create( \Magento\Catalog\Setup\CategorySetup::class diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php index 5ceabcd75cbd..5e87438492dc 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_two_fpt_rollback.php @@ -22,5 +22,7 @@ $attribute->delete(); } +require __DIR__ . '/product_with_fpt_rollback.php'; + $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); From e8cfc5525ffc08915197d7713030f8b7127c819f Mon Sep 17 00:00:00 2001 From: Gabriel Caruso <carusogabriel34@gmail.com> Date: Sat, 5 Oct 2019 16:58:49 +0200 Subject: [PATCH 0865/1172] Remove useless aliasses for imports --- .../ConfigurableProduct/UpdateConfigurableCartItemsTest.php | 2 +- .../GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php | 2 +- .../_files/product_downloadable_with_custom_options.php | 2 +- .../product_downloadable_with_purchased_separately_links.php | 2 +- ...roduct_downloadable_without_purchased_separately_links.php | 2 +- .../Test/Unit/Rule/Design/AllPurposeActionTest.php | 4 ++-- lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php | 2 +- .../Framework/Api/ExtensionAttribute/JoinProcessor.php | 2 +- .../Framework/Api/ExtensionAttribute/JoinProcessorHelper.php | 2 +- .../Controller/Test/Unit/Router/Route/FactoryTest.php | 2 +- lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php | 2 +- .../Framework/ObjectManager/Test/Unit/Config/CompiledTest.php | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/UpdateConfigurableCartItemsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/UpdateConfigurableCartItemsTest.php index 4f4e7ecab6fe..8f32caa9dcf0 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/UpdateConfigurableCartItemsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/ConfigurableProduct/UpdateConfigurableCartItemsTest.php @@ -9,7 +9,7 @@ namespace Magento\GraphQl\ConfigurableProduct; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; -use Magento\Framework\Exception\NoSuchEntityException as NoSuchEntityException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\GraphQl\Quote\GetMaskedQuoteIdByReservedOrderId; use Magento\Quote\Model\Quote\Item; use Magento\Quote\Model\QuoteFactory; diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php index 62c1ae0dab3c..d1edf742931c 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/EditQuoteItemWithCustomOptionsTest.php @@ -9,7 +9,7 @@ use Magento\Catalog\Api\ProductCustomOptionRepositoryInterface; use Magento\Catalog\Api\ProductRepositoryInterface; -use Magento\Framework\Exception\NoSuchEntityException as NoSuchEntityException; +use Magento\Framework\Exception\NoSuchEntityException; use Magento\Quote\Model\Quote\Item; use Magento\Quote\Model\QuoteFactory; use Magento\Quote\Model\ResourceModel\Quote as QuoteResource; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_custom_options.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_custom_options.php index b5528dd27ee7..f0a26f8a36d9 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_custom_options.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_custom_options.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -use Magento\TestFramework\Helper\Bootstrap as Bootstrap; +use Magento\TestFramework\Helper\Bootstrap; require __DIR__ . '/product_downloadable_with_purchased_separately_links.php'; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php index 6ceb4d90787e..f8028b2587fa 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_with_purchased_separately_links.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -use Magento\TestFramework\Helper\Bootstrap as Bootstrap; +use Magento\TestFramework\Helper\Bootstrap; use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Downloadable\Model\Product\Type as ProductType; use Magento\Catalog\Model\Product\Visibility as ProductVisibility; diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php index f55261be04ce..e6540f15b010 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable_without_purchased_separately_links.php @@ -5,7 +5,7 @@ */ declare(strict_types=1); -use Magento\TestFramework\Helper\Bootstrap as Bootstrap; +use Magento\TestFramework\Helper\Bootstrap; use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus; use Magento\Downloadable\Model\Product\Type as ProductType; use Magento\Catalog\Model\Product\Visibility as ProductVisibility; diff --git a/dev/tests/static/framework/Magento/CodeMessDetector/Test/Unit/Rule/Design/AllPurposeActionTest.php b/dev/tests/static/framework/Magento/CodeMessDetector/Test/Unit/Rule/Design/AllPurposeActionTest.php index 408853141e53..ac7e8b507a82 100644 --- a/dev/tests/static/framework/Magento/CodeMessDetector/Test/Unit/Rule/Design/AllPurposeActionTest.php +++ b/dev/tests/static/framework/Magento/CodeMessDetector/Test/Unit/Rule/Design/AllPurposeActionTest.php @@ -11,9 +11,9 @@ use Magento\CodeMessDetector\Rule\Design\AllPurposeAction; use Magento\Framework\App\Action\HttpGetActionInterface; use Magento\Framework\App\ActionInterface; -use PHPUnit\Framework\TestCase as TestCase; +use PHPUnit\Framework\TestCase; use PHPUnit_Framework_MockObject_MockObject as MockObject; -use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMocker; +use PHPUnit\Framework\MockObject\Builder\InvocationMocker; use PHPMD\Report; use PHPMD\Node\ClassNode; diff --git a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php index af781e19d045..567216c29dca 100644 --- a/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php +++ b/lib/internal/Magento/Framework/Acl/Loader/ResourceLoader.php @@ -8,7 +8,7 @@ namespace Magento\Framework\Acl\Loader; use Magento\Framework\Acl; -use Magento\Framework\Acl\AclResource as AclResource; +use Magento\Framework\Acl\AclResource; use Magento\Framework\Acl\AclResource\ProviderInterface; use Magento\Framework\Acl\AclResourceFactory; diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php index 28f053e1afa8..253ed558fa36 100644 --- a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php +++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessor.php @@ -7,7 +7,7 @@ namespace Magento\Framework\Api\ExtensionAttribute; use Magento\Framework\Api\ExtensionAttribute\Config; -use Magento\Framework\Api\ExtensionAttribute\Config\Converter as Converter; +use Magento\Framework\Api\ExtensionAttribute\Config\Converter; use Magento\Framework\Data\Collection\AbstractDb as DbCollection; use Magento\Framework\Reflection\TypeProcessor; use Magento\Framework\Api\ExtensibleDataInterface; diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorHelper.php b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorHelper.php index f49c1fd0b515..24d04dfa01db 100644 --- a/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorHelper.php +++ b/lib/internal/Magento/Framework/Api/ExtensionAttribute/JoinProcessorHelper.php @@ -7,7 +7,7 @@ namespace Magento\Framework\Api\ExtensionAttribute; use Magento\Framework\Api\ExtensionAttribute\Config; -use Magento\Framework\Api\ExtensionAttribute\Config\Converter as Converter; +use Magento\Framework\Api\ExtensionAttribute\Config\Converter; use Magento\Framework\Api\SimpleDataObjectConverter; /** diff --git a/lib/internal/Magento/Framework/Controller/Test/Unit/Router/Route/FactoryTest.php b/lib/internal/Magento/Framework/Controller/Test/Unit/Router/Route/FactoryTest.php index 87adadbd34e3..df08e7776262 100644 --- a/lib/internal/Magento/Framework/Controller/Test/Unit/Router/Route/FactoryTest.php +++ b/lib/internal/Magento/Framework/Controller/Test/Unit/Router/Route/FactoryTest.php @@ -9,7 +9,7 @@ use \Magento\Framework\Controller\Router\Route\Factory; use Magento\Framework\Controller\Router\Route\Factory as RouteFactory; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class FactoryTest extends \PHPUnit\Framework\TestCase { diff --git a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php index c1c1e7c17709..5803b900bd80 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php +++ b/lib/internal/Magento/Framework/ObjectManager/Profiler/Log.php @@ -5,7 +5,7 @@ */ namespace Magento\Framework\ObjectManager\Profiler; -use Magento\Framework\ObjectManager\Profiler\Tree\Item as Item; +use Magento\Framework\ObjectManager\Profiler\Tree\Item; /** * Class Log diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/CompiledTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/CompiledTest.php index 000e9fb529a6..e61d8f089065 100644 --- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/CompiledTest.php +++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/CompiledTest.php @@ -6,7 +6,7 @@ namespace Magento\Framework\ObjectManager\Test\Unit\Config; use Magento\Framework\ObjectManager\Config\Compiled; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManager; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; class CompiledTest extends \PHPUnit\Framework\TestCase { From e737e7df68821f36727437c673e3b8eac35537cd Mon Sep 17 00:00:00 2001 From: Gabriel Caruso <carusogabriel34@gmail.com> Date: Sat, 5 Oct 2019 16:33:09 +0200 Subject: [PATCH 0866/1172] Remove requirement of always available SPL extension Since PHP 5.3.0, the SPL extension is always available and it can not be disabled. Ref: https://php.net/manual/en/spl.installation.php --- composer.json | 1 - composer.lock | 3 +-- .../Framework/Composer/_files/testFromClone/composer.json | 1 - lib/internal/Magento/Framework/composer.json | 1 - 4 files changed, 1 insertion(+), 5 deletions(-) diff --git a/composer.json b/composer.json index fdbfb664c9b1..f1497b17ecf9 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,6 @@ "ext-pdo_mysql": "*", "ext-simplexml": "*", "ext-soap": "*", - "ext-spl": "*", "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*", diff --git a/composer.lock b/composer.lock index 9d6805ac8be4..0ccc8d7482d2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "856f519091be654f930aa51de44332a7", + "content-hash": "b9aa969dbc121878e5a9ed27aee0c252", "packages": [ { "name": "braintree/braintree_php", @@ -10260,7 +10260,6 @@ "ext-pdo_mysql": "*", "ext-simplexml": "*", "ext-soap": "*", - "ext-spl": "*", "ext-xsl": "*", "ext-zip": "*", "lib-libxml": "*" diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/composer.json b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/composer.json index fe1d382b361f..404db202c6e7 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/composer.json +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromClone/composer.json @@ -17,7 +17,6 @@ "ext-intl": "*", "ext-mcrypt": "*", "ext-simplexml": "*", - "ext-spl": "*", "lib-libxml": "*", "composer/composer": "1.0.0-alpha9", "magento/magento-composer-installer": "*", diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json index af2eb913fe3f..dfbfb5a25deb 100644 --- a/lib/internal/Magento/Framework/composer.json +++ b/lib/internal/Magento/Framework/composer.json @@ -19,7 +19,6 @@ "ext-intl": "*", "ext-openssl": "*", "ext-simplexml": "*", - "ext-spl": "*", "ext-xsl": "*", "ext-bcmath": "*", "lib-libxml": "*", From 1ac83c02293088ad3f5e52b5f0d6062a4e197cc3 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso <carusogabriel34@gmail.com> Date: Sat, 5 Oct 2019 17:25:41 +0200 Subject: [PATCH 0867/1172] Remove useless semicolons These ones were not found via the `no_empty_statement` from `php-cs-fixer`. --- .../_files/product_simple_with_non_latin_url_key.php | 4 ++-- .../Fixtures/quote_with_configurable_product.php | 2 +- lib/internal/Magento/Framework/Lock/Backend/Database.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php index 23fd8d7fe324..928c036e8fb4 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_non_latin_url_key.php @@ -41,7 +41,7 @@ $productRepository->save($product); } catch (\Exception $e) { // problems during save -}; +} /** @var ProductInterface $product */ $product = $objectManager->create(ProductInterface::class); @@ -60,4 +60,4 @@ $productRepository->save($product); } catch (\Exception $e) { // problems during save -}; +} diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php b/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php index 2a472371fd19..023421e4cd2b 100644 --- a/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php +++ b/dev/tests/integration/testsuite/Magento/Multishipping/Fixtures/quote_with_configurable_product.php @@ -118,7 +118,7 @@ $item->setQty(1); $address->setTotalQty(1); $address->addItem($item); - }; + } } $billingAddressData = [ diff --git a/lib/internal/Magento/Framework/Lock/Backend/Database.php b/lib/internal/Magento/Framework/Lock/Backend/Database.php index 096e77a11768..a5a76ba60f4e 100644 --- a/lib/internal/Magento/Framework/Lock/Backend/Database.php +++ b/lib/internal/Magento/Framework/Lock/Backend/Database.php @@ -76,7 +76,7 @@ public function lock(string $name, int $timeout = -1): bool { if (!$this->deploymentConfig->isDbAvailable()) { return true; - }; + } $name = $this->addPrefix($name); /** @@ -117,7 +117,7 @@ public function unlock(string $name): bool { if (!$this->deploymentConfig->isDbAvailable()) { return true; - }; + } $name = $this->addPrefix($name); @@ -145,7 +145,7 @@ public function isLocked(string $name): bool { if (!$this->deploymentConfig->isDbAvailable()) { return false; - }; + } $name = $this->addPrefix($name); From 37d9f6c971d903e4c5ce9d52e35d98a180a481c0 Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Sat, 5 Oct 2019 11:13:55 -0500 Subject: [PATCH 0868/1172] MC-20508: Api-functional tests for Product prices including FPT - fix test to support multitests --- .../testsuite/Magento/Weee/_files/fixed_product_attribute.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php index 426cbdfd50a3..c302b7f75de9 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/fixed_product_attribute.php @@ -41,7 +41,7 @@ $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); $product = $product->loadByAttribute('sku', 'simple-with-ftp'); -if ($product->getId()) { +if ($product && $product->getId()) { $product->setFixedProductAttribute( [['website_id' => 0, 'country' => 'US', 'state' => 0, 'price' => 10.00, 'delete' => '']] )->save(); From 28f5700a4b76bdc5d180f2bb509bac80ee95e62d Mon Sep 17 00:00:00 2001 From: Cristian Partica <cpartica@magento.com> Date: Sat, 5 Oct 2019 15:40:47 -0500 Subject: [PATCH 0869/1172] MC-20508: Api-functional tests for Product prices including FPT - fix test to support multitests --- .../testsuite/Magento/Weee/_files/product_with_fpt_rollback.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php index ba024011274a..a32c7c03a9f0 100644 --- a/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Weee/_files/product_with_fpt_rollback.php @@ -15,7 +15,7 @@ $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); $product = $product->loadByAttribute('sku', 'simple-with-ftp'); -if ($product->getId()) { +if ($product && $product->getId()) { $product->delete(); } From 8d1a45f9c301b713b4a1bca2cc0c557c5c9772f3 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <mac1@daniel-ruf.de> Date: Fri, 4 Oct 2019 23:57:06 +0200 Subject: [PATCH 0870/1172] Remove useless parentheses --- .../Magento/Catalog/Controller/Adminhtml/Product/Edit.php | 2 +- .../Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php | 2 +- .../Magento/NewRelicReporting/Model/Apm/Deployments.php | 2 +- .../Observer/MakePersistentQuoteGuestObserver.php | 4 ++-- app/code/Magento/Ui/Component/Control/SplitButton.php | 6 +++--- .../app/Magento/Catalog/Test/Fixture/Product/TaxClass.php | 2 +- setup/src/Magento/Setup/Model/Installer.php | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php index c31ceabcda65..02c474f096d0 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php @@ -51,7 +51,7 @@ public function execute() $productId = (int) $this->getRequest()->getParam('id'); $product = $this->productBuilder->build($this->getRequest()); - if (($productId && !$product->getEntityId())) { + if ($productId && !$product->getEntityId()) { /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ $resultRedirect = $this->resultRedirectFactory->create(); $this->messageManager->addErrorMessage(__('This product doesn\'t exist.')); diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php index 4039ff862f6f..287b5b514ee8 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php @@ -726,7 +726,7 @@ public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupC // TODO: getAttributeModel() should not be used when MAGETWO-48284 is complete $childData = $this->arrayManager->get($configPath, $meta, []); - if (($rules = $this->catalogEavValidationRules->build($this->getAttributeModel($attribute), $childData))) { + if ($rules = $this->catalogEavValidationRules->build($this->getAttributeModel($attribute), $childData)) { $meta = $this->arrayManager->merge($configPath, $meta, ['validation' => $rules]); } diff --git a/app/code/Magento/NewRelicReporting/Model/Apm/Deployments.php b/app/code/Magento/NewRelicReporting/Model/Apm/Deployments.php index bacdd3e4a81f..f12b784cfb5b 100644 --- a/app/code/Magento/NewRelicReporting/Model/Apm/Deployments.php +++ b/app/code/Magento/NewRelicReporting/Model/Apm/Deployments.php @@ -88,7 +88,7 @@ public function setDeployment($description, $change = false, $user = false) return false; } - if (($response->getStatus() < 200 || $response->getStatus() > 210)) { + if ($response->getStatus() < 200 || $response->getStatus() > 210) { $this->logger->warning('Deployment marker request did not send a 200 status code.'); return false; } diff --git a/app/code/Magento/Persistent/Observer/MakePersistentQuoteGuestObserver.php b/app/code/Magento/Persistent/Observer/MakePersistentQuoteGuestObserver.php index 94726bc9b1d0..31356059ee8b 100644 --- a/app/code/Magento/Persistent/Observer/MakePersistentQuoteGuestObserver.php +++ b/app/code/Magento/Persistent/Observer/MakePersistentQuoteGuestObserver.php @@ -65,8 +65,8 @@ public function execute(\Magento\Framework\Event\Observer $observer) /** @var $action \Magento\Persistent\Controller\Index */ $action = $observer->getEvent()->getControllerAction(); if ($action instanceof \Magento\Persistent\Controller\Index) { - if ((($this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn()) - || $this->_persistentData->isShoppingCartPersist()) + if (($this->_persistentSession->isPersistent() && !$this->_customerSession->isLoggedIn()) + || $this->_persistentData->isShoppingCartPersist() ) { $this->quoteManager->setGuest(true); } diff --git a/app/code/Magento/Ui/Component/Control/SplitButton.php b/app/code/Magento/Ui/Component/Control/SplitButton.php index ef57268566ba..e1f475344d26 100644 --- a/app/code/Magento/Ui/Component/Control/SplitButton.php +++ b/app/code/Magento/Ui/Component/Control/SplitButton.php @@ -83,12 +83,12 @@ public function getButtonAttributesHtml() 'style' => $this->getStyle(), ]; - if (($idHard = $this->getIdHard())) { + if ($idHard = $this->getIdHard()) { $attributes['id'] = $idHard; } //TODO perhaps we need to skip data-mage-init when disabled="disabled" - if (($dataAttribute = $this->getDataAttribute())) { + if ($dataAttribute = $this->getDataAttribute()) { $this->getDataAttributes($dataAttribute, $attributes); } @@ -112,7 +112,7 @@ public function getToggleAttributesHtml() $title = $this->getLabel(); } - if (($currentClass = $this->getClass())) { + if ($currentClass = $this->getClass()) { $classes[] = $currentClass; } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/TaxClass.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/TaxClass.php index 23e0236fe7ba..70d2730868db 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/TaxClass.php +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/Product/TaxClass.php @@ -52,7 +52,7 @@ class TaxClass extends DataSource public function __construct(FixtureFactory $fixtureFactory, array $params, $data = []) { $this->params = $params; - if ((!isset($data['dataset']) && !isset($data['tax_product_class']))) { + if (!isset($data['dataset']) && !isset($data['tax_product_class'])) { $this->data = $data; return; } diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index 7a097e49c628..23f8a13c8bfe 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -429,7 +429,7 @@ private function createModulesConfig($request, $dryRun = false) $disable = $this->readListOfModules($all, $request, InstallCommand::INPUT_KEY_DISABLE_MODULES); $result = []; foreach ($all as $module) { - if ((isset($currentModules[$module]) && !$currentModules[$module])) { + if (isset($currentModules[$module]) && !$currentModules[$module]) { $result[$module] = 0; } else { $result[$module] = 1; @@ -925,7 +925,7 @@ private function throwExceptionForNotWritablePaths(array $paths) */ private function handleDBSchemaData($setup, $type, array $request) { - if (!(($type === 'schema') || ($type === 'data'))) { + if (!($type === 'schema' || $type === 'data')) { throw new \Magento\Setup\Exception("Unsupported operation type $type is requested"); } $resource = new \Magento\Framework\Module\ModuleResource($this->context); From a289dc4bf5e1b789289d775dcc817fde6669cc40 Mon Sep 17 00:00:00 2001 From: Adarsh Manickam <adarsh.apple@icloud.com> Date: Tue, 1 Oct 2019 10:43:26 +0530 Subject: [PATCH 0871/1172] Issue#24785: Added JS method to handle input checks with MFTF --- .../StorefrontDownloadableProductSection.xml | 1 + ...wnloadableLinksDownloadableProductTest.xml | 122 ++++++++++++++++++ .../view/frontend/web/js/downloadable.js | 25 ++++ 3 files changed, 148 insertions(+) create mode 100644 app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml diff --git a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml index 20b62ef06030..dc2a58be138e 100644 --- a/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml +++ b/app/code/Magento/Downloadable/Test/Mftf/Section/StorefrontDownloadableProductSection.xml @@ -15,5 +15,6 @@ <element name="downloadableLinkSampleByTitle" type="text" selector="//label[contains(., '{{title}}')]/a[contains(@class, 'sample link')]" parameterized="true"/> <element name="downloadableSampleLabel" type="text" selector="//a[contains(.,normalize-space('{{title}}'))]" parameterized="true" timeout="30"/> <element name="downloadableLinkSelectAllCheckbox" type="checkbox" selector="#links_all" /> + <element name="downloadableLinkSelectAllLabel" type="text" selector="label[for='links_all']" /> </section> </sections> diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml new file mode 100644 index 000000000000..b0424b1976c1 --- /dev/null +++ b/app/code/Magento/Downloadable/Test/Mftf/Test/ManualSelectAllDownloadableLinksDownloadableProductTest.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="ManualSelectAllDownloadableLinksDownloadableProductTest"> + <annotations> + <features value="Catalog"/> + <stories value="Create Downloadable Product"/> + <title value="Manual select all downloadable links downloadable product test"/> + <description value="Manually selecting all downloadable links must change 'Select/Unselect all' button label to 'Unselect all', and 'Select all' otherwise"/> + <severity value="MAJOR"/> + <group value="Downloadable"/> + </annotations> + <before> + <!-- Create category --> + <createData entity="SimpleSubCategory" stepKey="createCategory"/> + + <!-- Login as admin --> + <actionGroup ref="LoginAsAdmin" stepKey="LoginAsAdmin"/> + + <!-- Create downloadable product --> + <amOnPage url="{{AdminProductIndexPage.url}}" stepKey="amOnProductGridPage"/> + <waitForPageLoad stepKey="waitForProductGridPageLoad"/> + <actionGroup ref="GoToSpecifiedCreateProductPage" stepKey="createProduct"> + <argument name="productType" value="downloadable"/> + </actionGroup> + + <!-- Fill downloadable product values --> + <actionGroup ref="fillMainProductFormNoWeight" stepKey="fillDownloadableProductForm"> + <argument name="product" value="DownloadableProduct"/> + </actionGroup> + + <!-- Add downloadable product to category --> + <searchAndMultiSelectOption selector="{{AdminProductFormSection.categoriesDropdown}}" + parameterArray="[$$createCategory.name$$]" stepKey="fillCategory"/> + + <!-- Fill downloadable link information before the creation link --> + <actionGroup ref="AdminAddDownloadableLinkInformationActionGroup" stepKey="addDownloadableLinkInformation"/> + + <!-- Links can be purchased separately --> + <checkOption selector="{{AdminProductDownloadableSection.isLinksPurchasedSeparately}}" + stepKey="checkOptionPurchaseSeparately"/> + + <!-- Add first downloadable link --> + <actionGroup ref="addDownloadableProductLinkWithMaxDownloads" stepKey="addFirstDownloadableProductLink"> + <argument name="link" value="downloadableLinkWithMaxDownloads"/> + </actionGroup> + + <!-- Add second downloadable link --> + <actionGroup ref="addDownloadableProductLink" stepKey="addSecondDownloadableProductLink"> + <argument name="link" value="downloadableLink"/> + </actionGroup> + + <!-- Save product --> + <actionGroup ref="saveProductForm" stepKey="saveProduct"/> + </before> + <after> + <!-- Delete category --> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + + <!-- Delete created downloadable product --> + <actionGroup ref="deleteProductUsingProductGrid" stepKey="deleteProduct"> + <argument name="product" value="DownloadableProduct"/> + </actionGroup> + + <!-- Log out --> + <actionGroup ref="logout" stepKey="logout"/> + </after> + + <!-- Step 1: Navigate to store front Product page as guest --> + <amOnPage url="/{{DownloadableProduct.sku}}.html" + stepKey="amOnStorefrontProductPage"/> + + <!-- Step 2: Check first downloadable link checkbox --> + <click + selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLinkWithMaxDownloads.title)}}" + stepKey="selectFirstCheckbox"/> + + <!-- Step 3: Check second downloadable link checkbox --> + <click + selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" + stepKey="selectSecondCheckbox"/> + + <!-- Step 4: Grab "Select/Unselect All" button label text --> + <grabTextFrom + selector="{{StorefrontDownloadableProductSection.downloadableLinkSelectAllLabel}}" + stepKey="grabUnselectAllButtonText"/> + + <!-- Step 5: Assert that 'Select/Unselect all' button text is 'Unselect all' after manually checking all checkboxes --> + <assertEquals + message="Assert that 'Select/Unselect all' button text is 'Unselect all' after manually checking all checkboxes" + stepKey="assertButtonTextOne"> + <expectedResult type="string">Unselect all</expectedResult> + <actualResult type="string">{$grabUnselectAllButtonText}</actualResult> + </assertEquals> + + <!-- Step 6: Uncheck second downloadable link checkbox --> + <click + selector="{{StorefrontDownloadableProductSection.downloadableLinkByTitle(downloadableLink.title)}}" + stepKey="unselectSecondCheckbox"/> + + <!-- Step 7: Grab "Select/Unselect All" button label text --> + <grabTextFrom + selector="{{StorefrontDownloadableProductSection.downloadableLinkSelectAllLabel}}" + stepKey="grabSelectAllButtonText"/> + + <!-- Step 8: Assert that 'Select/Unselect all' button text is 'Select all' after manually unchecking one checkbox --> + <assertEquals + message="Assert that 'Select/Unselect all' button text is 'Select all' after manually unchecking one checkbox" + stepKey="assertButtonTextTwo"> + <expectedResult type="string">Select all</expectedResult> + <actualResult type="string">{$grabSelectAllButtonText}</actualResult> + </assertEquals> + + </test> +</tests> diff --git a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js index a1e8c785c696..5fc14f45d280 100644 --- a/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js +++ b/app/code/Magento/Downloadable/view/frontend/web/js/downloadable.js @@ -65,6 +65,31 @@ define([ } } }); + + this.reloadAllCheckText(); + }, + + /** + * Reload all-elements-checkbox's label + * @private + */ + reloadAllCheckText: function () { + let allChecked = true, + allElementsCheck = $(this.options.allElements), + allElementsLabel = $('label[for="' + allElementsCheck.attr('id') + '"] > span'); + $(this.options.linkElement).each(function () { + if (!this.checked) { + allChecked = false; + } + }); + + if (allChecked) { + allElementsLabel.text(allElementsCheck.attr('data-checked')); + allElementsCheck.prop('checked', true) + } else { + allElementsLabel.text(allElementsCheck.attr('data-notchecked')); + allElementsCheck.prop('checked', false) + } } }); From 3374a5a9d11ee3a5577fd5f25a600852a9875039 Mon Sep 17 00:00:00 2001 From: Brent Robert <brent.robert@phpro.be> Date: Sun, 6 Oct 2019 14:34:26 +0200 Subject: [PATCH 0872/1172] Make email preview responsive Make email preview responsive --- .../Magento/backend/web/css/styles-old.less | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/design/adminhtml/Magento/backend/web/css/styles-old.less b/app/design/adminhtml/Magento/backend/web/css/styles-old.less index 44fca79c31be..b2afde435a62 100644 --- a/app/design/adminhtml/Magento/backend/web/css/styles-old.less +++ b/app/design/adminhtml/Magento/backend/web/css/styles-old.less @@ -4070,6 +4070,21 @@ } } +.adminhtml-email_template-preview { + .cms-revision-preview { + padding-top: 56.25%; + position: relative; + + #preview_iframe { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + } +} + .admin__scope-old { .buttons-set { margin: 0 0 15px; From f0cfb96351cda42bd76afc203111988266940c67 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <mac1@daniel-ruf.de> Date: Sun, 6 Oct 2019 16:14:44 +0200 Subject: [PATCH 0873/1172] Replace deprecated "big" element --- .../Sales/view/adminhtml/templates/order/details.phtml | 4 ++-- .../Sales/view/adminhtml/templates/order/totals/due.phtml | 4 ++-- .../Sales/view/adminhtml/templates/order/totals/grand.phtml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml index b700f1b3a65a..70373f177d8b 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/details.phtml @@ -81,8 +81,8 @@ $_order = $block->getOrder() ?> </tr> <?php endif; ?> <tr bgcolor="#DEE5E8"> - <td colspan="2" align="right" style="padding:3px 9px"><strong><big><?= $block->escapeHtml(__('Grand Total')) ?></big></strong></td> - <td align="right" style="padding:6px 9px"><strong><big><?= /* @noEscape */ $_order->formatPrice($_order->getGrandTotal()) ?></big></strong></td> + <td colspan="2" align="right" style="padding:3px 9px"><strong style="font-size: larger"><?= $block->escapeHtml(__('Grand Total')) ?></strong></td> + <td align="right" style="padding:6px 9px"><strong style="font-size: larger"><?= /* @noEscape */ $_order->formatPrice($_order->getGrandTotal()) ?></strong></td> </tr> </tfoot> </table> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/totals/due.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/totals/due.phtml index 87d7c85c2d9e..f8e914a2c9b2 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/totals/due.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/totals/due.phtml @@ -6,7 +6,7 @@ ?> <?php if ($block->getCanDisplayTotalDue()) : ?> <tr> - <td class="label"><big><strong><?= $block->escapeHtml(__('Total Due')) ?></strong></big></td> - <td class="emph"><big><?= /* @noEscape */ $block->displayPriceAttribute('total_due', true) ?></big></td> + <td class="label"><strong style="font-size: larger"><?= $block->escapeHtml(__('Total Due')) ?></strong></td> + <td class="emph" style="font-size: larger"><?= /* @noEscape */ $block->displayPriceAttribute('total_due', true) ?></td> </tr> <?php endif; ?> diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/totals/grand.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/totals/grand.phtml index dc76799251c7..af5d58d47fce 100644 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/totals/grand.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/totals/grand.phtml @@ -9,13 +9,13 @@ <tr> <td class="label"> - <strong><big> + <strong style="font-size: larger"> <?php if ($block->getGrandTotalTitle()) : ?> <?= $block->escapeHtml($block->getGrandTotalTitle()) ?> <?php else : ?> <?= $block->escapeHtml(__('Grand Total')) ?> <?php endif; ?> - </big></strong> + </strong> </td> - <td class="emph"><big><?= /* @noEscape */ $block->displayPriceAttribute('grand_total', true) ?></big></td> + <td class="emph" style="font-size: larger"><?= /* @noEscape */ $block->displayPriceAttribute('grand_total', true) ?></td> </tr> From 5d6b72df4ad46b4391b314581dee831399821517 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <mac1@daniel-ruf.de> Date: Sun, 6 Oct 2019 16:42:07 +0200 Subject: [PATCH 0874/1172] Remove duplicate CSS properties --- .../module/components/_currency-addon.less | 2 +- .../_files/static/theme/web/css/styles.css | 33 ------------------- lib/web/mage/calendar.css | 1 - lib/web/mage/translate-inline-vde.css | 1 - 4 files changed, 1 insertion(+), 36 deletions(-) diff --git a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less index 659b1fa811db..fa158589feb9 100644 --- a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less +++ b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_currency-addon.less @@ -22,10 +22,10 @@ position: relative; display: -webkit-inline-flex; display: -ms-inline-flexbox; + display: inline-flex; -webkit-flex-direction: row; -ms-flex-direction: row; flex-direction: row; - display: inline-flex; flex-flow: row nowrap; width: 100%; diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css index 90ca42321c92..35305fb2392d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css +++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/theme/web/css/styles.css @@ -484,7 +484,6 @@ table .col-draggable .draggable-handle { border: 0; display: inline; line-height: 1.42857143; - margin: 0; padding: 0; color: #1979c3; text-decoration: none; @@ -621,7 +620,6 @@ fieldset[disabled] .grid-actions .action-reset { background: none; border: 0; display: inline; - line-height: 1.42857143; margin: 0; padding: 0; color: #1979c3; @@ -683,7 +681,6 @@ fieldset[disabled] .pager .action-next { text-decoration: none; } .pager .action-previous > span { - clip: rect(0, 0, 0, 0); border: 0; clip: rect(0 0 0 0); height: 1px; @@ -733,7 +730,6 @@ fieldset[disabled] .pager .action-next { text-decoration: none; } .pager .action-next > span { - clip: rect(0, 0, 0, 0); border: 0; clip: rect(0 0 0 0); height: 1px; @@ -1510,7 +1506,6 @@ fieldset[disabled] .pager .action-next { text-decoration: none; } .search-global-field .label > span { - clip: rect(0, 0, 0, 0); border: 0; clip: rect(0 0 0 0); height: 1px; @@ -1622,7 +1617,6 @@ fieldset[disabled] .pager .action-next { color: #676056; } .notifications-action .text { - clip: rect(0, 0, 0, 0); border: 0; clip: rect(0 0 0 0); height: 1px; @@ -1707,7 +1701,6 @@ fieldset[disabled] .pager .action-next { z-index: 1; top: 12px; right: 12px; - display: inline-block; background-image: none; background: none; border: 0; @@ -2358,7 +2351,6 @@ fieldset[disabled] .notifications-close.action { text-decoration: none; } #product-variations-matrix .actions-image-uploader { - display: inline-block; position: relative; display: block; width: 50px; @@ -3109,7 +3101,6 @@ body > * { background-image: none; background: none; border: 0; - margin: 0; padding: 0; -moz-box-sizing: content-box; box-shadow: none; @@ -3396,7 +3387,6 @@ fieldset[disabled] .page-main-actions .page-actions .action-add.mselect-button-a box-shadow: none; text-shadow: none; text-decoration: none; - line-height: inherit; font-weight: 400; color: #026294; line-height: normal; @@ -3464,7 +3454,6 @@ fieldset[disabled] .store-switcher .actions.dropdown .action.toggle { margin-top: 10px; } .store-switcher .actions.dropdown ul.dropdown-menu .dropdown-toolbar a { - display: inline-block; text-decoration: none; display: block; } @@ -4833,17 +4822,11 @@ fieldset[disabled] .control-text + .ui-datepicker-trigger { width: 100%; } .filters-toggle { - background: #f2ebde; - padding: 6px 13px; color: #645d53; - border: 1px solid #ada89e; cursor: pointer; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1.3rem; - font-weight: 500; - line-height: 1.4rem; box-sizing: border-box; - margin: 3px; vertical-align: middle; display: inline-block; background-image: none; @@ -4946,7 +4929,6 @@ fieldset[disabled] .filters-toggle { .filters-item .action-remove { background-image: none; background: #f2ebde; - padding: 6px 13px; color: #645d53; border: 1px solid #ada89e; cursor: pointer; @@ -5038,17 +5020,11 @@ fieldset[disabled] .filters-item .action-remove { position: absolute; top: 3px; right: 7px; - background: #f2ebde; - padding: 6px 13px; color: #645d53; - border: 1px solid #ada89e; cursor: pointer; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1.3rem; - font-weight: 500; - line-height: 1.4rem; box-sizing: border-box; - margin: 3px; vertical-align: middle; display: inline-block; background-image: none; @@ -5283,13 +5259,11 @@ fieldset[disabled] .filters-form .action-close { border: 1px solid #c2c2c2; border-radius: 1px; height: 32px; - width: 100%; padding: 0 9px; font-size: 14px; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 1.428571429; background-clip: padding-box; - vertical-align: baseline; width: auto; white-space: nowrap; vertical-align: middle; @@ -5487,17 +5461,11 @@ fieldset[disabled] .filters .field-date .group .hasDatepicker + .ui-datepicker-t background: rgba(0, 0, 0, 0.2); } .mass-select-toggle { - background: #f2ebde; - padding: 6px 13px; color: #645d53; - border: 1px solid #ada89e; cursor: pointer; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 1.3rem; - font-weight: 500; - line-height: 1.4rem; box-sizing: border-box; - margin: 3px; vertical-align: middle; display: inline-block; background-image: none; @@ -5754,7 +5722,6 @@ fieldset[disabled] .mass-select-toggle { .page-actions.fixed .page-actions-inner, .page-content, .page-footer { - width: auto; min-width: 960px; max-width: 1300px; margin: 0 auto; diff --git a/lib/web/mage/calendar.css b/lib/web/mage/calendar.css index 071270feeeb3..da19f389d308 100644 --- a/lib/web/mage/calendar.css +++ b/lib/web/mage/calendar.css @@ -141,7 +141,6 @@ padding: 0; } .ui-datepicker { - background: #ffffff; padding: 15px; border: #ffffff 4px solid; -webkit-box-sizing: border-box; diff --git a/lib/web/mage/translate-inline-vde.css b/lib/web/mage/translate-inline-vde.css index 369c1fb9a2f0..f898bb01c43d 100644 --- a/lib/web/mage/translate-inline-vde.css +++ b/lib/web/mage/translate-inline-vde.css @@ -52,7 +52,6 @@ } .translate-dialog .ui-dialog-buttonset { - padding-right: 0; margin-right: 0; float: right; background: rgba(223, 243, 250, 1.0); From 38c9db4c210db436d5e0711b627e48c3e31babe1 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso <carusogabriel34@gmail.com> Date: Sun, 6 Oct 2019 16:52:31 +0200 Subject: [PATCH 0875/1172] Remove unecessaries ternary conditions --- .../testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php | 2 +- .../testsuite/Magento/GraphQl/Catalog/ProductImageTest.php | 2 +- .../lib/Magento/Mtf/Client/Element/LiselectstoreElement.php | 2 +- .../Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php | 2 +- .../Review/Test/TestCase/MassActionsProductReviewEntityTest.php | 2 +- .../Magento/Framework/Acl/AclResource/Config/Converter/Dom.php | 2 +- lib/internal/Magento/Framework/App/MaintenanceMode.php | 2 +- .../Magento/Framework/Code/Reader/NamespaceResolver.php | 2 +- .../Magento/Framework/GraphQl/Schema/Type/ScalarTypes.php | 2 +- lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php | 2 +- lib/internal/Magento/Framework/Url.php | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php index e805bc940704..b6687b4e171d 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/MediaGalleryTest.php @@ -198,6 +198,6 @@ private function checkImageExists(string $url): bool curl_exec($connection); $responseStatus = curl_getinfo($connection, CURLINFO_HTTP_CODE); // phpcs:enable Magento2.Functions.DiscouragedFunction - return $responseStatus === 200 ? true : false; + return $responseStatus === 200; } } diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php index b957292a3ac2..52463485a34f 100644 --- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductImageTest.php @@ -144,6 +144,6 @@ private function checkImageExists(string $url): bool curl_exec($connection); $responseStatus = curl_getinfo($connection, CURLINFO_HTTP_CODE); - return $responseStatus === 200 ? true : false; + return $responseStatus === 200; } } diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php index 49f2577b2621..703744b17e87 100644 --- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php +++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/LiselectstoreElement.php @@ -133,7 +133,7 @@ public function getValues() */ protected function isSubstring($haystack, $pattern) { - return preg_match("/$pattern/", $haystack) != 0 ? true : false; + return preg_match("/$pattern/", $haystack) != 0; } /** diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php index f1ab25501328..a06ee2332704 100644 --- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php +++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php @@ -311,7 +311,7 @@ public function fillBundleOptions($bundleOptions) { foreach ($bundleOptions as $option) { $selector = sprintf($this->bundleOptionBlock, $option['title']); - $useDefault = isset($option['use_default']) && strtolower($option['use_default']) == 'true' ? true : false; + $useDefault = isset($option['use_default']) && strtolower($option['use_default']) == 'true'; if (!$useDefault) { /** @var Option $optionBlock */ $optionBlock = $this->blockFactory->create( diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php index e7dd72d1d426..da5e7101e4b3 100644 --- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php +++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/MassActionsProductReviewEntityTest.php @@ -102,7 +102,7 @@ public function test($gridActions, $gridStatus) $this->reviewIndex->getReviewGrid()->massaction( [['title' => $this->review->getTitle()]], [$gridActions => $gridStatus], - ($gridActions == 'Delete' ? true : false) + ($gridActions == 'Delete') ); } diff --git a/lib/internal/Magento/Framework/Acl/AclResource/Config/Converter/Dom.php b/lib/internal/Magento/Framework/Acl/AclResource/Config/Converter/Dom.php index 68762a8a6c04..72e2dbd5bf7b 100644 --- a/lib/internal/Magento/Framework/Acl/AclResource/Config/Converter/Dom.php +++ b/lib/internal/Magento/Framework/Acl/AclResource/Config/Converter/Dom.php @@ -53,7 +53,7 @@ protected function _convertResourceNode(\DOMNode $resourceNode) $sortOrderNode = $resourceAttributes->getNamedItem('sortOrder'); $resourceData['sortOrder'] = $sortOrderNode !== null ? (int)$sortOrderNode->nodeValue : 0; $disabledNode = $resourceAttributes->getNamedItem('disabled'); - $resourceData['disabled'] = $disabledNode !== null && $disabledNode->nodeValue == 'true' ? true : false; + $resourceData['disabled'] = $disabledNode !== null && $disabledNode->nodeValue == 'true'; // convert child resource nodes if needed $resourceData['children'] = []; /** @var $childNode \DOMNode */ diff --git a/lib/internal/Magento/Framework/App/MaintenanceMode.php b/lib/internal/Magento/Framework/App/MaintenanceMode.php index e813522a0151..11347e4220c2 100644 --- a/lib/internal/Magento/Framework/App/MaintenanceMode.php +++ b/lib/internal/Magento/Framework/App/MaintenanceMode.php @@ -110,7 +110,7 @@ public function setAddresses($addresses) throw new \InvalidArgumentException("One or more IP-addresses is expected (comma-separated)\n"); } $result = $this->flagDir->writeFile(self::IP_FILENAME, $addresses); - return false !== $result ? true : false; + return false !== $result; } /** diff --git a/lib/internal/Magento/Framework/Code/Reader/NamespaceResolver.php b/lib/internal/Magento/Framework/Code/Reader/NamespaceResolver.php index 8c22170a126f..b1126e96bec8 100644 --- a/lib/internal/Magento/Framework/Code/Reader/NamespaceResolver.php +++ b/lib/internal/Magento/Framework/Code/Reader/NamespaceResolver.php @@ -50,7 +50,7 @@ public function resolveNamespace($type, array $availableNamespaces) ) { $name = explode(self::NS_SEPARATOR, $type); $unqualifiedName = $name[0]; - $isQualifiedName = count($name) > 1 ? true : false; + $isQualifiedName = count($name) > 1; if (isset($availableNamespaces[$unqualifiedName])) { $namespace = $availableNamespaces[$unqualifiedName]; if ($isQualifiedName) { diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/ScalarTypes.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/ScalarTypes.php index dfb8b748469b..ebcbbeaa04ca 100644 --- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/ScalarTypes.php +++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/ScalarTypes.php @@ -21,7 +21,7 @@ class ScalarTypes public function isScalarType(string $typeName) : bool { $standardTypes = \GraphQL\Type\Definition\Type::getStandardTypes(); - return isset($standardTypes[$typeName]) ? true : false; + return isset($standardTypes[$typeName]); } /** diff --git a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php index 2cc2da62e71c..376dfb5d7258 100644 --- a/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php +++ b/lib/internal/Magento/Framework/HTTP/PhpEnvironment/Response.php @@ -130,7 +130,7 @@ public function setHttpResponseCode($code) throw new \InvalidArgumentException('Invalid HTTP response code'); } - $this->isRedirect = (300 <= $code && 307 >= $code) ? true : false; + $this->isRedirect = (300 <= $code && 307 >= $code); $this->setStatusCode($code); return $this; diff --git a/lib/internal/Magento/Framework/Url.php b/lib/internal/Magento/Framework/Url.php index 11aeb1c0c79b..2cd6db17a96e 100644 --- a/lib/internal/Magento/Framework/Url.php +++ b/lib/internal/Magento/Framework/Url.php @@ -1067,7 +1067,7 @@ public function sessionUrlVar($html) */ // @codingStandardsIgnoreEnd function ($match) { - if ($this->useSessionIdForUrl($match[2] == 'S' ? true : false)) { + if ($this->useSessionIdForUrl($match[2] == 'S')) { return $match[1] . $this->_sidResolver->getSessionIdQueryParam($this->_session) . '=' . $this->_session->getSessionId() . (isset($match[3]) ? $match[3] : ''); } else { From 9dfedbc9c373d8d7a75d76033bd77d280a27e468 Mon Sep 17 00:00:00 2001 From: Daniel Ruf <mac1@daniel-ruf.de> Date: Sun, 6 Oct 2019 17:24:50 +0200 Subject: [PATCH 0876/1172] Replace deprecated "nobr" element --- lib/web/css/docs/layout.html | 8 ++++---- lib/web/css/docs/responsive.html | 6 +++--- lib/web/css/docs/source/_layout.less | 8 ++++---- lib/web/css/docs/source/_responsive.less | 6 +++--- lib/web/css/docs/source/_variables.less | 8 ++++---- lib/web/css/docs/variables.html | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/web/css/docs/layout.html b/lib/web/css/docs/layout.html index 77ed0597f074..b338c66ffae7 100644 --- a/lib/web/css/docs/layout.html +++ b/lib/web/css/docs/layout.html @@ -55,25 +55,25 @@ <tr> <th>@layout-class-1column</th> <td class="vars_value">page-layout-1column</td> - <td class="vars_value">'' | false | <nobr>page-layout-1column</nobr> | <nobr>page-layout-2columns-left</nobr> | <nobr>page-layout-2columns-right</nobr> | <nobr>page-layout-3columns</nobr></td> + <td class="vars_value">'' | false | <span style="white-space: nowrap">page-layout-1column</span> | <span style="white-space: nowrap">page-layout-2columns-left</span> | <span style="white-space: nowrap">page-layout-2columns-right</span> | <span style="white-space: nowrap">page-layout-3columns</span></td> <td>Class name for one column layout</td> </tr> <tr> <th>@layout-class-2columns__left</th> <td class="vars_value">page-layout-2columns-left</td> - <td class="vars_value">'' | false | <nobr>page-layout-1column</nobr> | <nobr>page-layout-2columns-left</nobr> | <nobr>page-layout-2columns-right</nobr> | <nobr>page-layout-3columns</nobr></td> + <td class="vars_value">'' | false | <span style="white-space: nowrap">page-layout-1column</span> | <span style="white-space: nowrap">page-layout-2columns-left</span> | <span style="white-space: nowrap">page-layout-2columns-right</span> | <span style="white-space: nowrap">page-layout-3columns</span></td> <td>Class name for two columns layout with left sidebar</td> </tr> <tr> <th nowrap="nowrap">@layout-class-2columns__right</th> <td class="vars_value">page-layout-2columns-right</td> - <td class="vars_value">'' | false | <nobr>page-layout-1column</nobr> | <nobr>page-layout-2columns-left</nobr> | <nobr>page-layout-2columns-right</nobr> | <nobr>page-layout-3columns</nobr></td> + <td class="vars_value">'' | false | <span style="white-space: nowrap">page-layout-1column</span> | <span style="white-space: nowrap">page-layout-2columns-left</span> | <span style="white-space: nowrap">page-layout-2columns-right</span> | <span style="white-space: nowrap">page-layout-3columns</span></td> <td>Class name for two columns layout with right sidebar</td> </tr> <tr> <th>@layout-class-3columns</th> <td class="vars_value">page-layout-3columns</td> - <td class="vars_value">'' | false | <nobr>page-layout-1column</nobr> | <nobr>page-layout-2columns-left</nobr> | <nobr>page-layout-2columns-right</nobr> | <nobr>page-layout-3columns</nobr></td> + <td class="vars_value">'' | false | <span style="white-space: nowrap">page-layout-1column</span> | <span style="white-space: nowrap">page-layout-2columns-left</span> | <span style="white-space: nowrap">page-layout-2columns-right</span> | <span style="white-space: nowrap">page-layout-3columns</span></td> <td>Class name for three columns layout with left sidebar</td> </tr> <tr> diff --git a/lib/web/css/docs/responsive.html b/lib/web/css/docs/responsive.html index 48d0bd551bd9..ebc42e698f60 100644 --- a/lib/web/css/docs/responsive.html +++ b/lib/web/css/docs/responsive.html @@ -7,7 +7,7 @@ <!DOCTYPE html><html><head><title>responsive | Magento UI Library

Responsive

-

Magento UI library provides a strong approach for working with media queries. It`s based on recursive call of .media-width() mixin defined anywhere in project but invoked in one place in lib/web/css/source/lib/_responsive.less. That's why in the resulting styles.css we have every media query only once with all the rules there, not a multiple calls for the same query.

+

Magento UI library provides a strong approach for working with media queries. It`s based on recursive call of .media-width() mixin defined anywhere in project but invoked in one place in lib/web/css/source/lib/_responsive.less. That's why in the resulting styles.css we have every media query only once with all the rules there, not a multiple calls for the same query.

To see the media queries work resize window to understand which breakpoint is applied.