diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php index b2722ec019785..847499901ccdb 100644 --- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php +++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php @@ -99,9 +99,10 @@ public function execute() return $this->ajaxRequestResponse($category, $resultPage); } + $resultPageTitle = $categoryId ? $category->getName() . ' (ID: ' . $categoryId . ')' : __('Categories'); $resultPage->setActiveMenu('Magento_Catalog::catalog_categories'); $resultPage->getConfig()->getTitle()->prepend(__('Categories')); - $resultPage->getConfig()->getTitle()->prepend($categoryId ? $category->getName() : __('Categories')); + $resultPage->getConfig()->getTitle()->prepend($resultPageTitle); $resultPage->addBreadcrumb(__('Manage Catalog Categories'), __('Manage Categories')); $block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js'); diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php index e72d5b48a3691..7e7234d1ebbf8 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php @@ -125,7 +125,10 @@ public function save(\Magento\Catalog\Api\Data\ProductAttributeInterface $attrib $attribute->setFrontendInput($existingModel->getFrontendInput()); if (is_array($attribute->getFrontendLabels())) { - $frontendLabel[0] = $existingModel->getDefaultFrontendLabel(); + $defaultFrontendLabel = $attribute->getDefaultFrontendLabel(); + $frontendLabel[0] = !empty($defaultFrontendLabel) + ? $defaultFrontendLabel + : $existingModel->getDefaultFrontendLabel(); foreach ($attribute->getFrontendLabels() as $item) { $frontendLabel[$item->getStoreId()] = $item->getLabel(); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php index 00f82e5319d70..87159b4e2d6d3 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php @@ -12,6 +12,7 @@ use Magento\Catalog\Model\Product\Attribute\Repository; use Magento\Catalog\Model\ResourceModel\Eav\Attribute; use Magento\Catalog\Api\Data\ProductAttributeInterface; +use Magento\Eav\Api\Data\AttributeFrontendLabelInterface; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -288,4 +289,42 @@ public function testSaveDoesNotSaveAttributeOptionsIfOptionsAreAbsentInPayload() $this->model->save($attributeMock); } + + public function testSaveSavesDefaultFrontendLabelIfItIsPresentInPayload() + { + $labelMock = $this->getMock(AttributeFrontendLabelInterface::class); + $labelMock->expects($this->any())->method('getStoreId')->willReturn(1); + $labelMock->expects($this->any())->method('getLabel')->willReturn('Store Scope Label'); + + $attributeId = 1; + $attributeCode = 'existing_attribute_code'; + $attributeMock = $this->getMock(Attribute::class, [], [], '', false); + $attributeMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode); + $attributeMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId); + $attributeMock->expects($this->any())->method('getDefaultFrontendLabel')->willReturn('Default Label'); + $attributeMock->expects($this->any())->method('getFrontendLabels')->willReturn([$labelMock]); + $attributeMock->expects($this->any())->method('getOptions')->willReturn([]); + + + $existingModelMock = $this->getMock(Attribute::class, [], [], '', false); + $existingModelMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId); + $existingModelMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode); + + $this->eavAttributeRepositoryMock->expects($this->any()) + ->method('get') + ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode) + ->willReturn($existingModelMock); + + $attributeMock->expects($this->once()) + ->method('setDefaultFrontendLabel') + ->with( + [ + 0 => 'Default Label', + 1 => 'Store Scope Label' + ] + ); + $this->attributeResourceMock->expects($this->once())->method('save')->with($attributeMock); + + $this->model->save($attributeMock); + } } diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml index 1c58e3424b1c1..5b8034e87fef7 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml @@ -208,6 +208,8 @@ }, submit : function() { + var i, child, newNode; + if( TreePanels.root.firstChild == TreePanels.root.lastChild ) { return; } @@ -221,6 +223,7 @@ if( editSet.currentNode && editSet.currentNode.attributes.cls == 'folder' ) { TreePanels.root.removeChild(editSet.currentNode); + for( i in editSet.currentNode.childNodes ) { if( editSet.currentNode.childNodes[i].id ) { child = editSet.currentNode.childNodes[i]; @@ -231,12 +234,20 @@ } } } + editSet.req.removeGroups[editSet.currentNode.id] = editSet.currentNode.id; editSet.currentNode = false; } }, SystemNodesExists : function(currentNode) { + if (!currentNode) { + alert({ + content: 'escapeJs(__('Please select a node.')) ?>' + }); + return; + } + for (i in currentNode.childNodes) { if (currentNode.childNodes[i].id) { child = editSet.currentNode.childNodes[i]; @@ -253,31 +264,40 @@ addGroup : function() { prompt({ + title: "", content: "", value: "", + validation: true, + validationRules: ['required-entry'], + attributesForm: { + novalidate: 'novalidate', + action: '' + }, + attributesField: { + name: 'name', + 'data-validate': '{required:true}', + maxlength: '255' + }, actions: { confirm: function (group_name) { group_name = group_name.strip(); - if( group_name == '' ) { - self.addGroup(); - } else if( group_name != false && group_name != null && group_name != '' ) { - - if (!editSet.validateGroupName(group_name, 0)) { - return; - } - - var newNode = new Ext.tree.TreeNode({ - text : group_name.escapeHTML(), - cls : 'folder', - allowDrop : true, - allowDrag : true - }); - TreePanels.root.appendChild(newNode); - newNode.addListener('beforemove', editSet.groupBeforeMove); - newNode.addListener('beforeinsert', editSet.groupBeforeInsert); - newNode.addListener('beforeappend', editSet.groupBeforeInsert); - newNode.addListener('click', editSet.register); + + if (!editSet.validateGroupName(group_name, 0)) { + return; } + + var newNode = new Ext.tree.TreeNode({ + text : group_name.escapeHTML(), + cls : 'folder', + allowDrop : true, + allowDrag : true + }); + + TreePanels.root.appendChild(newNode); + newNode.addListener('beforemove', editSet.groupBeforeMove); + newNode.addListener('beforeinsert', editSet.groupBeforeInsert); + newNode.addListener('beforeappend', editSet.groupBeforeInsert); + newNode.addListener('click', editSet.register); } } }); @@ -302,7 +322,7 @@ } for (var i=0; i < TreePanels.root.childNodes.length; i++) { if (TreePanels.root.childNodes[i].text.toLowerCase() == name.toLowerCase() && TreePanels.root.childNodes[i].id != exceptNodeId) { - errorText = ''; + errorText = ''; alert({ content: errorText.replace("/name/",name) }); diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js index 937c83c14faa4..c2f16d82959d0 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js @@ -6,7 +6,8 @@ define([ 'jquery', 'underscore', 'uiRegistry', - 'jquery/ui' + 'jquery/ui', + 'mage/translate' ], function ($, _, registry) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js index b330ccfd8c125..a2e05dcc1c69c 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js @@ -7,7 +7,8 @@ define([ 'jquery', 'Magento_Ui/js/lib/validation/utils', 'Magento_Ui/js/form/element/abstract', - 'Magento_Ui/js/lib/validation/validator' + 'Magento_Ui/js/lib/validation/validator', + 'mage/translate' ], function ($, utils, Abstract, validator) { 'use strict'; diff --git a/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js b/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js index d6e47f6df33a0..5dba397d9bc43 100644 --- a/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js +++ b/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js @@ -4,7 +4,8 @@ */ define([ 'uiComponent', - 'Magento_Customer/js/customer-data' + 'Magento_Customer/js/customer-data', + 'mage/translate' ], function (Component, customerData) { 'use strict'; @@ -12,23 +13,22 @@ define([ function initSidebar() { if (sidebarInitialized) { - return ; + return; } sidebarInitialized = true; require([ 'jquery', 'mage/mage' ], function ($) { + /*eslint-disable max-len*/ $('[data-role=compare-products-sidebar]').mage('compareItems', { - "removeConfirmMessage": $.mage.__( - "Are you sure you want to remove this item from your Compare Products list?" - ), - "removeSelector": "#compare-items a.action.delete", - "clearAllConfirmMessage": $.mage.__( - "Are you sure you want to remove all items from your Compare Products list?" - ), - "clearAllSelector": "#compare-clear-all" + 'removeConfirmMessage': $.mage.__('Are you sure you want to remove this item from your Compare Products list?'), + 'removeSelector': '#compare-items a.action.delete', + 'clearAllConfirmMessage': $.mage.__('Are you sure you want to remove all items from your Compare Products list?'), + 'clearAllSelector': '#compare-clear-all' }); + + /*eslint-enable max-len*/ }); } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js index 4e2fbdc5dfa50..bee4480b0dfb1 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js @@ -21,7 +21,7 @@ define([], function () { return { email: addressData.email, - countryId: (addressData.country_id) ? addressData.country_id : window.checkoutConfig.defaultCountryId, + countryId: addressData['country_id'] || addressData.countryId || window.checkoutConfig.defaultCountryId, regionId: regionId, regionCode: (addressData.region) ? addressData.region.region_code : null, region: (addressData.region) ? addressData.region.region : null, diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js index 55678fc701d5b..420d50b83478a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js @@ -12,7 +12,8 @@ define( '../action/select-shipping-address', './postcode-validator', 'mage/translate', - 'uiRegistry' + 'uiRegistry', + 'Magento_Checkout/js/model/quote' ], function ( $, @@ -22,7 +23,8 @@ define( selectShippingAddress, postcodeValidator, $t, - uiRegistry + uiRegistry, + quote ) { 'use strict'; @@ -41,7 +43,7 @@ define( * @param {Object} validator */ registerValidator: function (carrier, validator) { - if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) { + if (checkoutConfig.activeCarriers.indexOf(carrier) !== -1) { validators.push(validator); } }, @@ -174,6 +176,7 @@ define( address; if (this.validateAddressData(addressFlat)) { + addressFlat = $.extend(true, {}, quote.shippingAddress(), addressFlat); address = addressConverter.formAddressDataToQuoteAddress(addressFlat); selectShippingAddress(address); } 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 433adfb7f824d..ea88d2c1e7b10 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js @@ -224,7 +224,7 @@ define([ if (msg) { alert({ - content: $.mage.__(msg) + content: msg }); } } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js index 0e5e1dc35bf63..7e0f5b8771747 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js @@ -8,7 +8,8 @@ define([ 'jquery', 'ko', 'underscore', - 'sidebar' + 'sidebar', + 'mage/translate' ], function (Component, customerData, $, ko, _) { 'use strict'; @@ -68,9 +69,7 @@ define([ 'qty': ':input.cart-item-qty', 'button': ':button.update-cart-item' }, - 'confirmMessage': $.mage.__( - 'Are you sure you would like to remove this item from the shopping cart?' - ) + 'confirmMessage': $.mage.__('Are you sure you would like to remove this item from the shopping cart?') }); } diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml index 8d9aea7bb20c5..6a29cb1497175 100644 --- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml @@ -29,7 +29,8 @@ require([ 'jquery', 'mage/template', 'jquery/file-uploader', - 'domReady!' + 'domReady!', + 'mage/translate' ], function ($, mageTemplate) { $('#getHtmlId() ?> .fileupload').fileupload({ dataType: 'json', diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js index 4d1867669ade0..7d574a32498d0 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js @@ -8,7 +8,8 @@ define([ 'jquery', 'Magento_Ui/js/core/app', 'underscore', - 'notification' + 'notification', + 'mage/translate' ], function (Component, $, bootstrap, _) { 'use strict'; @@ -221,9 +222,7 @@ define([ if (data.items.length) { this.productsModal.notification('add', { - message: $.mage.__( - 'Choose a new product to delete and replace the current product configuration.' - ), + message: $.mage.__('Choose a new product to delete and replace the current product configuration.'), messageContainer: this.gridSelector }); } else { diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js index 3653e91894c29..994fbf25e3b0f 100644 --- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js +++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js @@ -51,9 +51,13 @@ define([ this.setNotificationMessage(); }, setNotificationMessage: function () { + /*eslint-disable max-len*/ + var msg = $.mage.__('When you remove or add an attribute, we automatically update all configurations and you will need to recreate current configurations manually.'); + + /*eslint-enable max-len*/ + if (this.mode === 'edit') { - this.wizard.setNotificationMessage($.mage.__('When you remove or add an attribute, we automatically ' + - 'update all configurations and you will need to recreate current configurations manually.')); + this.wizard.setNotificationMessage(msg); } }, doSelectSavedAttributes: function () { diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml index 2fe4a23944694..d4fe3ec72a073 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml @@ -104,7 +104,8 @@ require([ 'mage/template', 'jquery/file-uploader', 'mage/mage', - 'prototype' + 'prototype', + 'mage/translate' ], function(jQuery, registry, mageTemplate){ registry.get('downloadable', function (Downloadable) { var linkTemplate = ''+ diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml index 699bfce3acd1a..510a3d3fcc8d7 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml +++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml @@ -63,7 +63,8 @@ require([ 'uiRegistry', 'mage/template', 'jquery/file-uploader', - 'prototype' + 'prototype', + 'mage/translate' ], function (jQuery, registry, mageTemplate) { registry.get('downloadable', function (Downloadable) { var sampleTemplate = ''+ diff --git a/app/code/Magento/Eav/Model/CustomAttributesMapper.php b/app/code/Magento/Eav/Model/CustomAttributesMapper.php new file mode 100644 index 0000000000000..51b9277714278 --- /dev/null +++ b/app/code/Magento/Eav/Model/CustomAttributesMapper.php @@ -0,0 +1,124 @@ +attributeRepository = $attributeRepository; + $this->metadataPool = $metadataPool; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + } + + /** + * {@inheritdoc} + */ + public function entityToDatabase($entityType, $data) + { + if (!$this->metadataPool->hasConfiguration($entityType) + || !$this->metadataPool->getMetadata($entityType)->getEavEntityType() + ) { + return $data; + } + if (isset($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES])) { + foreach ($this->getNonStaticAttributes($entityType) as $attribute) { + foreach ($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES] as $key => $customAttribute) { + if ($customAttribute[AttributeInterface::ATTRIBUTE_CODE] == $attribute->getAttributeCode()) { + unset($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][$key]); + $data[$attribute->getAttributeCode()] = $customAttribute[AttributeInterface::VALUE]; + } + } + } + } + return $data; + } + + /** + * {@inheritdoc} + */ + public function databaseToEntity($entityType, $data) + { + $metadata = $this->metadataPool->getMetadata($entityType); + if (!$metadata->getEavEntityType()) { + return $data; + } + foreach ($this->getNonStaticAttributes($entityType) as $attribute) { + if (isset($data[$attribute->getAttributeCode()])) { + $data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][] = [ + AttributeInterface::ATTRIBUTE_CODE => $attribute->getAttributeCode(), + AttributeInterface::VALUE => $data[$attribute->getAttributeCode()] + ]; + } + } + return $data; + } + + /** + * Get custom attributes + * + * @param string $entityType + * @return \Magento\Eav\Api\Data\AttributeInterface[] + * @throws \Exception + */ + private function getNonStaticAttributes($entityType) + { + if (!isset($this->attributes[$entityType])) { + $metadata = $this->metadataPool->getMetadata($entityType); + $searchResult = $this->attributeRepository->getList( + $metadata->getEavEntityType(), + $this->searchCriteriaBuilder->addFilter('attribute_set_id', null, 'neq')->create() + ); + $attributes = []; + foreach ($searchResult->getItems() as $attribute) { + if (!$attribute->isStatic()) { + $attributes[] = $attribute; + } + } + $this->attributes[$entityType] = $attributes; + } + return $this->attributes[$entityType]; + } +} diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php b/app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php similarity index 88% rename from lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php rename to app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php index 56977af1dd6eb..f7e98f751497a 100644 --- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php +++ b/app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php @@ -3,10 +3,11 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Framework\EntityManager\Test\Unit; - -use Magento\Framework\App\ResourceConnection; +namespace Magento\Eav\Test\Unit\Model; +/** + * Class CustomAttributesMapperTest + */ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase { /** @@ -55,7 +56,7 @@ public function testEntityToDatabase() ->willReturn(true); $metadataPool->expects($this->any()) ->method('getMetadata') - ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class)) + ->with($this->equalTo(\Magento\Framework\Api\CustomAttributesDataInterface::class)) ->will($this->returnValue($metadata)); $metadataPool->expects($this->once()) ->method('hasConfiguration') @@ -75,16 +76,16 @@ public function testEntityToDatabase() ->method('create') ->will($this->returnValue($searchCriteria)); - /** @var \Magento\Framework\EntityManager\CustomAttributesMapper $customAttributesMapper */ + /** @var \Magento\Eav\Model\CustomAttributesMapper $customAttributesMapper */ $customAttributesMapper = $this->objectManager - ->getObject(\Magento\Framework\EntityManager\CustomAttributesMapper::class, [ + ->getObject(\Magento\Eav\Model\CustomAttributesMapper::class, [ 'attributeRepository' => $attributeRepository, 'metadataPool' => $metadataPool, 'searchCriteriaBuilder' => $searchCriteriaBuilder ]); $actual = $customAttributesMapper->entityToDatabase( - \Magento\Customer\Api\Data\AddressInterface::class, + \Magento\Framework\Api\CustomAttributesDataInterface::class, [ \Magento\Framework\Api\CustomAttributesDataInterface::CUSTOM_ATTRIBUTES => [ 'test' => [ @@ -151,7 +152,7 @@ public function testDatabaseToEntity() ->getMock(); $metadataPool->expects($this->any()) ->method('getMetadata') - ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class)) + ->with($this->equalTo(\Magento\Framework\Api\CustomAttributesDataInterface::class)) ->will($this->returnValue($metadata)); $searchCriteriaBuilder = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaBuilder::class) @@ -168,15 +169,15 @@ public function testDatabaseToEntity() ->method('create') ->will($this->returnValue($searchCriteria)); - /** @var \Magento\Framework\EntityManager\CustomAttributesMapper $customAttributesMapper */ + /** @var \Magento\Eav\Model\CustomAttributesMapper $customAttributesMapper */ $customAttributesMapper = $this->objectManager - ->getObject(\Magento\Framework\EntityManager\CustomAttributesMapper::class, [ + ->getObject(\Magento\Eav\Model\CustomAttributesMapper::class, [ 'attributeRepository' => $attributeRepository, 'metadataPool' => $metadataPool, 'searchCriteriaBuilder' => $searchCriteriaBuilder ]); $actual = $customAttributesMapper->databaseToEntity( - \Magento\Customer\Api\Data\AddressInterface::class, + \Magento\Framework\Api\CustomAttributesDataInterface::class, [ 'test' => 'test', 'test4' => 'test4', @@ -200,10 +201,10 @@ public function testDatabaseToEntity() private function getAttributes() { /* Attribute with the code we want to copy */ - $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) + $attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) ->disableOriginalConstructor() ->setMethods(['isStatic', 'getAttributeCode']) - ->getMock(); + ->getMockForAbstractClass(); $attribute->expects($this->any()) ->method('isStatic') ->will($this->returnValue(false)); @@ -212,10 +213,10 @@ private function getAttributes() ->will($this->returnValue('test')); /* Attribute with the code we don't want to copy */ - $attribute1 = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) + $attribute1 = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) ->disableOriginalConstructor() ->setMethods(['isStatic', 'getAttributeCode']) - ->getMock(); + ->getMockForAbstractClass(); $attribute1->expects($this->any()) ->method('isStatic') ->will($this->returnValue(false)); @@ -224,10 +225,10 @@ private function getAttributes() ->will($this->returnValue('test1')); /* Static attribute but with the code which exists in custom attributes */ - $attribute2 = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class) + $attribute2 = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class) ->disableOriginalConstructor() ->setMethods(['isStatic', 'getAttributeCode']) - ->getMock(); + ->getMockForAbstractClass(); $attribute2->expects($this->any()) ->method('isStatic') ->will($this->returnValue(true)); diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml index 49d6753bc48da..e273eab770c17 100644 --- a/app/code/Magento/Eav/etc/di.xml +++ b/app/code/Magento/Eav/etc/di.xml @@ -152,5 +152,10 @@ Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessor + + + Magento\Eav\Model\CustomAttributesMapper + + diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php index 6e614545b23d0..431d8ed4a5587 100644 --- a/app/code/Magento/Newsletter/Model/Subscriber.php +++ b/app/code/Magento/Newsletter/Model/Subscriber.php @@ -542,11 +542,17 @@ protected function _updateCustomerSubscription($customerId, $subscribe) $sendInformationEmail = false; $status = self::STATUS_SUBSCRIBED; + $isConfirmNeed = $this->_scopeConfig->getValue( + self::XML_PATH_CONFIRMATION_FLAG, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ) == 1 ? true : false; if ($subscribe) { if (AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED == $this->customerAccountManagement->getConfirmationStatus($customerId) ) { $status = self::STATUS_UNCONFIRMED; + } else if ($isConfirmNeed) { + $status = self::STATUS_NOT_ACTIVE; } } else { $status = self::STATUS_UNSUBSCRIBED; @@ -581,7 +587,9 @@ protected function _updateCustomerSubscription($customerId, $subscribe) $sendSubscription = $sendInformationEmail; if ($sendSubscription === null xor $sendSubscription) { try { - if ($this->isStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) { + if ($isConfirmNeed) { + $this->sendConfirmationRequestEmail(); + } else if ($this->isStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) { $this->sendUnsubscriptionEmail(); } elseif ($this->isStatusChanged() && $status == self::STATUS_SUBSCRIBED) { $this->sendConfirmationSuccessEmail(); diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php index 789a8bdcd4397..ea884a9e720c3 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php @@ -260,6 +260,37 @@ public function testSubscribeCustomerById() $this->subscriber->subscribeCustomerById($customerId); } + public function testSubscribeCustomerById1() + { + $customerId = 1; + $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + ->getMock(); + $this->customerRepository->expects($this->atLeastOnce()) + ->method('getById') + ->with($customerId)->willReturn($customerDataMock); + $this->resource->expects($this->atLeastOnce()) + ->method('loadByCustomerData') + ->with($customerDataMock) + ->willReturn( + [ + 'subscriber_id' => 1, + 'subscriber_status' => 3 + ] + ); + $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id'); + $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf(); + $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id'); + $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email'); + $this->sendEmailCheck(); + $this->customerAccountManagement->expects($this->once()) + ->method('getConfirmationStatus') + ->willReturn(\Magento\Customer\Api\AccountManagementInterface::ACCOUNT_CONFIRMATION_NOT_REQUIRED); + $this->scopeConfig->expects($this->atLeastOnce())->method('getValue')->with()->willReturn(true); + + $this->subscriber->subscribeCustomerById($customerId); + $this->assertEquals(\Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE, $this->subscriber->getStatus()); + } + public function testUnsubscribe() { $this->resource->expects($this->once())->method('save')->willReturnSelf(); diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js index e859a03491cba..4a733dd155a22 100644 --- a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js +++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js @@ -12,7 +12,8 @@ 'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator', 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator', 'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator', - 'Magento_Payment/js/model/credit-card-validation/credit-card-data' + 'Magento_Payment/js/model/credit-card-validation/credit-card-data', + 'mage/translate' ], factory); } else { factory(jQuery); @@ -40,7 +41,7 @@ return false; } }, - 'Please enter a valid credit card type number.' + $.mage.__('Please enter a valid credit card type number.') ], 'validate-card-number': [ /** @@ -51,7 +52,7 @@ function (number) { return creditCardNumberValidator(number).isValid; }, - 'Please enter a valid credit card number.' + $.mage.__('Please enter a valid credit card number.') ], 'validate-card-date': [ /** @@ -62,7 +63,7 @@ function (date) { return monthValidator(date).isValid; }, - 'Incorrect credit card expiration month.' + $.mage.__('Incorrect credit card expiration month.') ], 'validate-card-cvv': [ /** @@ -74,7 +75,7 @@ var maxLength = creditCardData.creditCard ? creditCardData.creditCard.code.size : 3; return cvvValidator(cvv, maxLength).isValid; }, - 'Please enter a valid credit card verification number.' + $.mage.__('Please enter a valid credit card verification number.') ], 'validate-card-year': [ /** @@ -85,7 +86,7 @@ function (date) { return monthValidator(date).isValid; }, - 'Incorrect credit card expiration year.' + $.mage.__('Incorrect credit card expiration year.') ] }, function (i, rule) { diff --git a/app/code/Magento/Paypal/view/frontend/web/order-review.js b/app/code/Magento/Paypal/view/frontend/web/order-review.js index dc389493e46cc..4ce2d5a1b8f2f 100644 --- a/app/code/Magento/Paypal/view/frontend/web/order-review.js +++ b/app/code/Magento/Paypal/view/frontend/web/order-review.js @@ -132,7 +132,7 @@ define([ } } alert({ - content: $.mage.__(msg) + content: msg }); return false; } diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js index cd175bed11106..5885c157927bc 100644 --- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js +++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js @@ -6,7 +6,8 @@ define([ 'jquery', 'Magento_Ui/js/modal/alert', - 'jquery/ui' + 'jquery/ui', + 'mage/translate' ], function ($, alert) { 'use strict'; diff --git a/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php b/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php index 4b45f4f469e06..66bb7f45bc4b4 100644 --- a/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php +++ b/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php @@ -16,11 +16,12 @@ interface GuestBillingAddressManagementInterface * * @param string $cartId The cart ID. * @param \Magento\Quote\Api\Data\AddressInterface $address Billing address data. + * @param bool $useForShipping * @return int Address ID. * @throws \Magento\Framework\Exception\NoSuchEntityException The specified cart does not exist. * @throws \Magento\Framework\Exception\InputException The specified cart ID or address data is not valid. */ - public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address); + public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false); /** * Return the billing address for a specified quote. diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php index e74eac3f4dd59..bbbe775044d3d 100644 --- a/app/code/Magento/Quote/Model/BillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php @@ -40,6 +40,11 @@ class BillingAddressManagement implements BillingAddressManagementInterface */ protected $addressRepository; + /** + * @var \Magento\Quote\Model\ShippingAddressAssignment + */ + private $shippingAddressAssignment; + /** * Constructs a quote billing address service object. * @@ -71,6 +76,7 @@ public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $addres $quote->removeAddress($quote->getBillingAddress()->getId()); $quote->setBillingAddress($address); try { + $this->getShippingAddressAssignment()->setAddress($quote, $address, $useForShipping); $quote->setDataChanges(true); $this->quoteRepository->save($quote); } catch (\Exception $e) { @@ -88,4 +94,17 @@ public function get($cartId) $cart = $this->quoteRepository->getActive($cartId); return $cart->getBillingAddress(); } + + /** + * @return \Magento\Quote\Model\ShippingAddressAssignment + * @deprecated + */ + private function getShippingAddressAssignment() + { + if (!$this->shippingAddressAssignment) { + $this->shippingAddressAssignment = ObjectManager::getInstance() + ->get(\Magento\Quote\Model\ShippingAddressAssignment::class); + } + return $this->shippingAddressAssignment; + } } diff --git a/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php b/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php index 0a14aaaa0be20..05a1e7f7aaa68 100644 --- a/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php +++ b/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php @@ -42,11 +42,11 @@ public function __construct( /** * {@inheritDoc} */ - public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address) + public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false) { /** @var $quoteIdMask QuoteIdMask */ $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id'); - return $this->billingAddressManagement->assign($quoteIdMask->getQuoteId(), $address); + return $this->billingAddressManagement->assign($quoteIdMask->getQuoteId(), $address, $useForShipping); } /** diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php index 84c66140ee4c4..58130fe5d2239 100644 --- a/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php +++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php @@ -14,17 +14,20 @@ class Grand extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment * @param \Magento\Quote\Model\Quote\Address\Total $total * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function collect( \Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total ) { + $grandTotal = $total->getGrandTotal(); + $baseGrandTotal = $total->getBaseGrandTotal(); $totals = array_sum($total->getAllTotalAmounts()); $baseTotals = array_sum($total->getAllBaseTotalAmounts()); - $total->setGrandTotal($totals); - $total->setBaseGrandTotal($baseTotals); + $total->setGrandTotal($grandTotal + $totals); + $total->setBaseGrandTotal($baseGrandTotal + $baseTotals); return $this; } @@ -34,6 +37,7 @@ public function collect( * @param \Magento\Quote\Model\Quote $quote * @param \Magento\Quote\Model\Quote\Address\Total $total * @return $this + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total) { diff --git a/app/code/Magento/Quote/Model/ShippingAddressAssignment.php b/app/code/Magento/Quote/Model/ShippingAddressAssignment.php new file mode 100644 index 0000000000000..9a918f3f3fb4b --- /dev/null +++ b/app/code/Magento/Quote/Model/ShippingAddressAssignment.php @@ -0,0 +1,63 @@ +shippingAssignmentProcessor = $shippingAssignmentProcessor; + $this->cartExtensionFactory = $cartExtensionFactory; + } + + /** + * @param \Magento\Quote\Api\Data\CartInterface $quote + * @param \Magento\Quote\Api\Data\AddressInterface $address + * @param bool $useForShipping + * @return void + */ + public function setAddress( + \Magento\Quote\Api\Data\CartInterface $quote, + \Magento\Quote\Api\Data\AddressInterface $address, + $useForShipping = false + ) { + if ($useForShipping) { + $quote->removeAddress($quote->getShippingAddress()->getId()); + $address->setSameAsBilling(1); + $address->setCollectShippingRates(true); + } else { + $address = $quote->getShippingAddress()->setSameAsBilling(0); + } + + $quote->setShippingAddress($address); + $cartExtension = $quote->getExtensionAttributes(); + if ($cartExtension === null) { + $cartExtension = $this->cartExtensionFactory->create(); + } + /** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */ + $shippingAssignment = $this->shippingAssignmentProcessor->create($quote); + $cartExtension->setShippingAssignments([$shippingAssignment]); + $quote->setExtensionAttributes($cartExtension); + } +} diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php index 8db55ff0be6df..842106a4d134f 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php @@ -29,15 +29,24 @@ public function testCollect() $totalMock = $this->getMock( \Magento\Quote\Model\Quote\Address\Total::class, - ['getAllTotalAmounts', 'getAllBaseTotalAmounts', 'setGrandTotal', 'setBaseGrandTotal'], + [ + 'getAllTotalAmounts', + 'getAllBaseTotalAmounts', + 'setGrandTotal', + 'setBaseGrandTotal', + 'getGrandTotal', + 'getBaseGrandTotal' + ], [], '', false ); + $totalMock->expects($this->once())->method('getGrandTotal')->willReturn(2); + $totalMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(2); $totalMock->expects($this->once())->method('getAllTotalAmounts')->willReturn($totals); $totalMock->expects($this->once())->method('getAllBaseTotalAmounts')->willReturn($totalsBase); - $totalMock->expects($this->once())->method('setGrandTotal')->with($grandTotal); - $totalMock->expects($this->once())->method('setBaseGrandTotal')->with($grandTotalBase); + $totalMock->expects($this->once())->method('setGrandTotal')->with($grandTotal + 2); + $totalMock->expects($this->once())->method('setBaseGrandTotal')->with($grandTotalBase + 2); $this->model->collect( $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false), diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php new file mode 100644 index 0000000000000..1acf50a4d4b4f --- /dev/null +++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php @@ -0,0 +1,115 @@ +cartExtensionFactoryMock = $this->getMock( + \Magento\Quote\Api\Data\CartExtensionFactory::class, + ['create'], + [], + '', + false + ); + $this->shippingAssignmentProcessorMock = $this->getMock( + \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::class, + [], + [], + '', + false + ); + $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false); + $this->addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false); + $this->extensionAttributeMock = $this->getMock( + \Magento\Quote\Api\Data\CartExtension::class, + ['setShippingAssignments'], + [], + '', + false + ); + + $this->shippingAssignmentMock = $this->getMock(\Magento\Quote\Api\Data\ShippingAssignmentInterface::class); + //shipping assignment processing + $this->quoteMock->expects($this->once())->method('getExtensionAttributes')->willReturn(null); + $this->cartExtensionFactoryMock + ->expects($this->once()) + ->method('create') + ->willReturn($this->extensionAttributeMock); + $this->shippingAssignmentProcessorMock + ->expects($this->once()) + ->method('create') + ->willReturn($this->shippingAssignmentMock); + $this->extensionAttributeMock + ->expects($this->once()) + ->method('setShippingAssignments') + ->with([$this->shippingAssignmentMock]) + ->willReturnSelf(); + $this->quoteMock->expects($this->once())->method('setExtensionAttributes')->with($this->extensionAttributeMock); + $this->model = new \Magento\Quote\Model\ShippingAddressAssignment( + $this->cartExtensionFactoryMock, + $this->shippingAssignmentProcessorMock + ); + } + + public function testSetAddressUseForShippingTrue() + { + $addressId = 1; + $addressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); + $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($addressMock); + $addressMock->expects($this->once())->method('getId')->willReturn($addressId); + $this->addressMock->expects($this->once())->method('setSameAsBilling')->with(1); + $this->quoteMock->expects($this->once())->method('removeAddress')->with($addressId); + $this->quoteMock->expects($this->once())->method('setShippingAddress')->with($this->addressMock); + $this->model->setAddress($this->quoteMock, $this->addressMock, true); + } + + public function testSetAddressUseForShippingFalse() + { + $addressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class); + $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($addressMock); + $addressMock->expects($this->once())->method('setSameAsBilling')->with(0)->willReturnSelf(); + $this->quoteMock->expects($this->once())->method('setShippingAddress')->with($addressMock); + $this->model->setAddress($this->quoteMock, $this->addressMock, false); + } +} diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php index 33f1b07e4d567..e15f469dde0c3 100644 --- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php +++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php @@ -102,6 +102,7 @@ public function execute() $creditmemoManagement = $this->_objectManager->create( \Magento\Sales\Api\CreditmemoManagementInterface::class ); + $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email'])); $creditmemoManagement->refund($creditmemo, (bool)$data['do_offline']); if (!empty($data['send_email'])) { diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index 7f4f70350ab28..5deb24a068de1 100644 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -8,6 +8,7 @@ namespace Magento\Sales\Model\Order; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Sales\Model\Order\Payment\Info; @@ -105,6 +106,11 @@ class Payment extends Info implements OrderPaymentInterface */ protected $orderRepository; + /** + * @var OrderStateResolverInterface + */ + private $orderStateResolver; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -692,7 +698,12 @@ public function refund($creditmemo) } $message = $message = $this->prependMessage($message); $message = $this->_appendTransactionToMessage($transaction, $message); - $this->setOrderStateProcessing($message); + $orderState = $this->getOrderStateResolver()->getStateForOrder($this->getOrder()); + $this->getOrder() + ->addStatusHistoryComment( + $message, + $this->getOrder()->getConfig()->getStateDefaultStatus($orderState) + )->setIsCustomerNotified($creditmemo->getOrder()->getCustomerNoteNotify()); $this->_eventManager->dispatch( 'sales_order_payment_refund', ['payment' => $this, 'creditmemo' => $creditmemo] @@ -1388,6 +1399,19 @@ protected function _getInvoiceForTransactionId($transactionId) return false; } + /** + * @deprecated + * @return OrderStateResolverInterface + */ + private function getOrderStateResolver() + { + if ($this->orderStateResolver === null) { + $this->orderStateResolver = ObjectManager::getInstance()->get(OrderStateResolverInterface::class); + } + + return$this->orderStateResolver; + } + //@codeCoverageIgnoreStart /** * Returns account_status diff --git a/app/code/Magento/Sales/Model/RefundInvoice.php b/app/code/Magento/Sales/Model/RefundInvoice.php index 37bf915aa505c..ad9f89b29bff8 100644 --- a/app/code/Magento/Sales/Model/RefundInvoice.php +++ b/app/code/Magento/Sales/Model/RefundInvoice.php @@ -218,6 +218,7 @@ public function execute( $connection->beginTransaction(); try { $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED); + $order->setCustomerNoteNotify($notify); $order = $this->paymentAdapter->refund($creditmemo, $order, $isOnline); $order->setState( $this->orderStateResolver->getStateForOrder($order, []) diff --git a/app/code/Magento/Sales/Model/RefundOrder.php b/app/code/Magento/Sales/Model/RefundOrder.php index 65d81df0d1de9..4cfbe063ea81f 100644 --- a/app/code/Magento/Sales/Model/RefundOrder.php +++ b/app/code/Magento/Sales/Model/RefundOrder.php @@ -186,6 +186,7 @@ public function execute( $connection->beginTransaction(); try { $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED); + $order->setCustomerNoteNotify($notify); $order = $this->paymentAdapter->refund($creditmemo, $order); $order->setState( $this->orderStateResolver->getStateForOrder($order, []) diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php index 4889ccd3750d5..16c3021117043 100644 --- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php +++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php @@ -182,7 +182,7 @@ public function refund( $connection->commit(); } catch (\Exception $e) { $connection->rollBack(); - throw new \Magento\Framework\Exception\LocalizedException($e->getMessage()); + throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage())); } return $creditmemo; diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php index 07db0e445b8aa..f97e3be1dcb6d 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php @@ -19,8 +19,16 @@ class PaymentTest extends \PHPUnit_Framework_TestCase { const TRANSACTION_ID = 'ewr34fM49V0'; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ private $mockContext; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $orderStateResolverMock; + /** * @var Payment */ @@ -59,6 +67,9 @@ class PaymentTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Sales\Model\Order\Invoice | \PHPUnit_Framework_MockObject_MockObject $orderMock */ private $invoiceMock; + /** + * @var string + */ private $transactionId; /** @@ -271,14 +282,19 @@ function ($value) { 'getGrandTotal', 'getBaseGrandTotal', 'getDoTransaction', - 'getInvoice' + 'getInvoice', + 'getOrder' ], [], '', false ); - + $this->orderStateResolverMock = $this->getMockBuilder(Order\OrderStateResolverInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); $this->payment = $this->initPayment(); + $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $helper->setBackwardCompatibleProperty($this->payment, 'orderStateResolver', $this->orderStateResolverMock); $this->payment->setMethod('any'); $this->payment->setOrder($this->orderMock); $this->transactionId = self::TRANSACTION_ID; @@ -1465,6 +1481,9 @@ public function testRefund() $this->creditMemoMock->expects(static::once()) ->method('getInvoice') ->willReturn($this->invoiceMock); + $this->creditMemoMock->expects(static::once()) + ->method('getOrder') + ->willReturn($this->orderMock); $captureTranId = self::TRANSACTION_ID . '-' . Transaction::TYPE_CAPTURE; $captureTransaction = $this->getMockBuilder(Transaction::class) @@ -1499,7 +1518,10 @@ public function testRefund() $status = 'status'; $message = 'We refunded ' . $amount . ' online. Transaction ID: "' . $refundTranId . '"'; - $this->mockGetDefaultStatus(Order::STATE_PROCESSING, $status); + $this->orderStateResolverMock->expects($this->once())->method('getStateForOrder') + ->with($this->orderMock) + ->willReturn(Order::STATE_CLOSED); + $this->mockGetDefaultStatus(Order::STATE_CLOSED, $status); $this->assertOrderUpdated(Order::STATE_PROCESSING, $status, $message); static::assertSame($this->payment, $this->payment->refund($this->creditMemoMock)); diff --git a/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php index 1c4aab6dd2feb..d400c7e1c0d4e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php @@ -287,6 +287,7 @@ public function testOrderCreditmemo($invoiceId, $items, $notify, $appendComment) ->method('validate') ->with($this->creditmemoItemCreationMock) ->willReturn([]); + $this->orderMock->expects($this->once())->method('setCustomerNoteNotify')->with($notify); $this->paymentAdapterMock->expects($this->once()) ->method('refund') ->with($this->creditmemoMock, $this->orderMock) diff --git a/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php index 7d684695664ba..7cc2673981c03 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php @@ -238,6 +238,7 @@ public function testOrderCreditmemo($orderId, $notify, $appendComment) [CreationQuantityValidator::class], $this->orderMock )->willReturn([]); + $this->orderMock->expects($this->once())->method('setCustomerNoteNotify')->with($notify); $this->paymentAdapterMock->expects($this->once()) ->method('refund') ->with($this->creditmemoMock, $this->orderMock) @@ -246,41 +247,33 @@ public function testOrderCreditmemo($orderId, $notify, $appendComment) ->method('getStateForOrder') ->with($this->orderMock, []) ->willReturn(Order::STATE_CLOSED); - $this->orderMock->expects($this->once()) ->method('setState') ->with(Order::STATE_CLOSED) ->willReturnSelf(); - $this->orderMock->expects($this->once()) ->method('getState') ->willReturn(Order::STATE_CLOSED); - $this->configMock->expects($this->once()) ->method('getStateDefaultStatus') ->with(Order::STATE_CLOSED) ->willReturn('Closed'); - $this->orderMock->expects($this->once()) ->method('setStatus') ->with('Closed') ->willReturnSelf(); - $this->creditmemoMock->expects($this->once()) ->method('setState') ->with(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED) ->willReturnSelf(); - $this->creditmemoRepositoryMock->expects($this->once()) ->method('save') ->with($this->creditmemoMock) ->willReturn($this->creditmemoMock); - $this->orderRepositoryMock->expects($this->once()) ->method('save') ->with($this->orderMock) ->willReturn($this->orderMock); - if ($notify) { $this->notifierMock->expects($this->once()) ->method('notify') diff --git a/app/code/Magento/SalesRule/Model/CouponRepository.php b/app/code/Magento/SalesRule/Model/CouponRepository.php index ad9b43f90e1a2..ddc8e9eb50688 100644 --- a/app/code/Magento/SalesRule/Model/CouponRepository.php +++ b/app/code/Magento/SalesRule/Model/CouponRepository.php @@ -163,15 +163,9 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr $this->extensionAttributesJoinProcessor->process($collection, $couponInterfaceName); $this->collectionProcessor->process($searchCriteria, $collection); - $coupons = []; - /** @var \Magento\SalesRule\Model\Coupon $couponModel */ - foreach ($collection->getItems() as $couponModel) { - $coupons[] = $couponModel->getData(); - } - $searchResults = $this->searchResultFactory->create(); $searchResults->setSearchCriteria($searchCriteria); - $searchResults->setItems($coupons); + $searchResults->setItems($collection->getItems()); $searchResults->setTotalCount($collection->getSize()); return $searchResults; } diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php index 19dfc5e21c86e..39957d9d63f56 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php @@ -233,6 +233,7 @@ public function testDeleteById() public function testGetList() { $collectionSize = 1; + $couponMock = $this->getMock(\Magento\SalesRule\Api\Data\CouponInterface::class); /** * @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteriaMock */ @@ -254,8 +255,8 @@ public function testGetList() $this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock); $collectionMock->expects($this->once())->method('getSize')->willReturn($collectionSize); $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize); - $collectionMock->expects($this->once())->method('getItems')->willReturn([]); - $this->searchResultsMock->expects($this->once())->method('setItems')->with([]); + $collectionMock->expects($this->once())->method('getItems')->willReturn([$couponMock]); + $this->searchResultsMock->expects($this->once())->method('setItems')->with([$couponMock]); $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultsMock); $this->assertEquals($this->searchResultsMock, $this->model->getList($searchCriteriaMock)); diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js b/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js index c2f95f85b311d..8172d6d9a5f30 100644 --- a/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js +++ b/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js @@ -3,7 +3,8 @@ * See COPYING.txt for license details. */ require([ - 'jquery' + 'jquery', + 'mage/translate' ], function ($) { 'use strict'; diff --git a/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml index 8bfeda24a0d2a..2dacb6b70c1d9 100644 --- a/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml +++ b/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml @@ -33,7 +33,8 @@ require([ 'jquery', 'mage/template', 'jquery/file-uploader', - 'domReady!' + 'domReady!', + 'mage/translate' ], function ($, mageTemplate) { $('#fileupload').fileupload({ diff --git a/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html b/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html new file mode 100644 index 0000000000000..b02f5af71529d --- /dev/null +++ b/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html @@ -0,0 +1,20 @@ + +
> +
+
+ <% if(data.label){ %> + + <% } %> +
+ /> +
+
+
+
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js index 32247e03baa04..f4bde3969e006 100644 --- a/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js +++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js @@ -7,7 +7,8 @@ define([ 'jquery', 'mage/template', 'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html', - 'Magento_Ui/js/modal/modal' + 'Magento_Ui/js/modal/modal', + 'mage/translate' ], function (Column, $, mageTemplate, thumbnailPreviewTemplate) { 'use strict'; 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 aa30cf24805f0..1f031a3aefcbd 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 @@ -431,10 +431,10 @@ define([ var pass = $.trim(v); var result = pass.length >= passwordMinLength; if (result == false) { - validator.passwordErrorMessage = $.mage.__( - "Minimum length of this field must be equal or greater than %1 symbols." + - " Leading and trailing spaces will be ignored." - ).replace('%1', passwordMinLength); + /*eslint-disable max-len*/ + validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength); + + /*eslint-enable max-len*/ return result; } if (pass.match(/\d+/)) { @@ -451,10 +451,11 @@ define([ } if (counter < passwordMinCharacterSets) { result = false; - validator.passwordErrorMessage = $.mage.__( - "Minimum of different classes of characters in password is %1." + - " Classes of characters: Lower Case, Upper Case, Digits, Special Characters." - ).replace('%1', passwordMinCharacterSets); + + /*eslint-disable max-len*/ + validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets); + + /*eslint-enable max-len*/ } return result; }, function () { @@ -742,7 +743,8 @@ define([ } } return true; - }, "Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com." + }, + $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.') ], "validate-cc-number": [ /** diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js index 759ea3be5e624..ab9dc49751774 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js @@ -42,6 +42,7 @@ define([ */ $.widget('mage.modal', { options: { + id: null, type: 'popup', title: '', subTitle: '', @@ -121,6 +122,7 @@ define([ 'closeModal' ); + this.options.id = this.uuid; this.options.transitionEvent = transitionEvent; this._createWrapper(); this._renderModal(); diff --git a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js index 17e78c0ea311b..d32605d2db4f9 100644 --- a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js +++ b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js @@ -6,19 +6,24 @@ define([ 'jquery', 'underscore', + 'mage/template', + 'text!ui/template/modal/modal-prompt-content.html', 'jquery/ui', 'Magento_Ui/js/modal/modal', 'mage/translate' -], function ($, _) { +], function ($, _, template, promptContentTmpl) { 'use strict'; $.widget('mage.prompt', $.mage.modal, { options: { modalClass: 'prompt', + promptContentTmpl: promptContentTmpl, promptField: '[data-role="promptField"]', attributesForm: {}, attributesField: {}, value: '', + validation: false, + validationRules: [], actions: { /** @@ -64,61 +69,73 @@ define([ */ _create: function () { this.options.focus = this.options.promptField; + this.options.validation = this.options.validation && this.options.validationRules.length; this._super(); - this.modal.find(this.options.modalContent).append(this.getFieldTemplate()); + this.modal.find(this.options.modalContent).append(this.getFormTemplate()); this.modal.find(this.options.modalCloseBtn).off().on('click', _.bind(this.closeModal, this, false)); + + if (this.options.validation) { + this.setValidationClasses(); + } + this.openModal(); }, /** - * Field template getter. + * Form template getter. * - * @returns {Object} Field template + * @returns {Object} Form template. */ - getFieldTemplate: function () { - var input = '', - form = '
', - wrapper = '
', - $wrapper = $(wrapper), - $form = $(form), - $input = $(input), + getFormTemplate: function () { + var formTemplate, + formAttr = '', + inputAttr = '', attributeName; - for (attributeName in this.options.attributesField) { - if (this.options.attributesField.hasOwnProperty(attributeName)) { - $input.attr(attributeName, this.options.attributesField[attributeName]); + for (attributeName in this.options.attributesForm) { + if (this.options.attributesForm.hasOwnProperty(attributeName)) { + formAttr = formAttr + ' ' + attributeName + '="' + + this.options.attributesForm[attributeName] + '"'; } } - for (attributeName in this.options.attributesForm) { - if (this.options.attributesForm.hasOwnProperty(attributeName)) { - $form.attr(attributeName, this.options.attributesForm[attributeName]); + for (attributeName in this.options.attributesField) { + if (this.options.attributesField.hasOwnProperty(attributeName)) { + inputAttr = inputAttr + ' ' + attributeName + '="' + + this.options.attributesField[attributeName] + '"'; } } - $form.append($input); + formTemplate = $(template(this.options.promptContentTmpl, { + data: this.options, + formAttr: formAttr, + inputAttr: inputAttr + })); - return $wrapper.append($form); + return formTemplate; }, /** - * Compile template and append to wrapper. + * Remove widget */ - _renderModal: function () { - this._super(); - - if (this.options.label) { - this.element.append(this.options.label); - } + _remove: function () { + this.modal.remove(); + }, - this.element.wrap(''); + /** + * Validate prompt field + */ + validate: function () { + return $.validator.validateSingleElement(this.options.promptField); }, /** - * Remove widget + * Add validation classes to prompt field */ - _remove: function () { - this.modal.remove(); + setValidationClasses: function () { + this.modal.find(this.options.promptField).attr('class', $.proxy(function (i, val) { + return val + ' ' + this.options.validationRules.join(' '); + }, this)); }, /** @@ -136,11 +153,16 @@ define([ var value; if (result) { + if (this.options.validation && !this.validate()) { + return false; + } + value = this.modal.find(this.options.promptField).val(); - this.options.actions.confirm(value); + this.options.actions.confirm.call(this, value); } else { this.options.actions.cancel.call(this, result); } + this.options.actions.always(); this.element.bind('promptclosed', _.bind(this._remove, this)); @@ -149,6 +171,6 @@ define([ }); return function (config) { - return $('
').html(config.content).prompt(config); + return $('
').html(config.content).prompt(config); }; }); diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html new file mode 100644 index 0000000000000..b5b2693ef3664 --- /dev/null +++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html @@ -0,0 +1,20 @@ + +> +
+
+ <% if(data.label){ %> + + <% } %> +
+ /> +
+
+
+ diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less index 7e88ff91b857c..b6524e2d49bf5 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less @@ -69,7 +69,7 @@ .modal-popup { &.prompt { .prompt-message { - padding: @modal-prompt-message__padding 0; + padding-bottom: @modal-prompt-message__padding; input { width: 100%; 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 0571aa9ddad03..558c7a020f356 100644 --- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php @@ -142,8 +142,9 @@ public function testUpdate() 'attribute' => [ 'attribute_id' => $attribute['attribute_id'], 'attribute_code' => $attributeCode, + 'default_frontend_label' => 'default_label_new', 'frontend_labels' => [ - ['store_id' => 0, 'label' => 'front_lbl_new'], + ['store_id' => 1, 'label' => 'front_lbl_new'], ], "options" => [ //Update existing @@ -183,7 +184,7 @@ public function testUpdate() $this->assertEquals($attribute['attribute_id'], $result['attribute_id']); $this->assertEquals($attributeCode, $result['attribute_code']); - $this->assertEquals('front_lbl_new', $result['default_frontend_label']); + $this->assertEquals('default_label_new', $result['default_frontend_label']); //New option set as default $this->assertEquals($result['options'][3]['value'], $result['default_value']); $this->assertEquals("Default Blue Updated", $result['options'][1]['label']); diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php index fe811eb2dcd25..6a6d7073aca45 100644 --- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php @@ -88,8 +88,9 @@ public function testGetAddress() /** * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php + * @dataProvider setAddressDataProvider */ - public function testSetAddress() + public function testSetAddress($useForShipping) { /** @var \Magento\Quote\Model\Quote $quote */ $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class); @@ -125,8 +126,9 @@ public function testSetAddress() 'fax' => '44332255', ]; $requestData = [ - "cartId" => $cartId, + 'cartId' => $cartId, 'address' => $addressData, + 'useForShipping' => $useForShipping ]; $addressId = $this->_webApiCall($serviceInfo, $requestData); @@ -149,5 +151,27 @@ public function testSetAddress() foreach ($addressData as $key => $value) { $this->assertEquals($value, $savedData[$key]); } + $address = $quote->getShippingAddress(); + $address->getRegionCode(); + $savedData = $address->getData(); + if ($useForShipping) { + //check that shipping address set + $this->assertEquals('shipping', $savedData['address_type']); + $this->assertEquals(1, $savedData['same_as_billing']); + //check the rest of fields + foreach ($addressData as $key => $value) { + $this->assertEquals($value, $savedData[$key]); + } + } else { + $this->assertEquals(0, $savedData['same_as_billing']); + } + } + + public function setAddressDataProvider() + { + return [ + [true], + [false] + ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php index 2235122955a72..740f8f03fe639 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php @@ -21,6 +21,20 @@ class History extends Block */ protected $commentHistory = '.note-list-comment'; + /** + * Comment history status. + * + * @var string + */ + protected $commentHistoryStatus = '.note-list-status'; + + /** + * Comment history notified status. + * + * @var string + */ + protected $commentHistoryNotifiedStatus = '.note-list-customer'; + /** * Authorized Amount. * @@ -103,6 +117,28 @@ public function getRefundedAmount() return $result; } + /** + * Gets the status which presented in comment + * + * @return string + */ + public function getStatus() + { + $this->waitCommentsHistory(); + return $this->_rootElement->find($this->commentHistoryStatus, Locator::SELECTOR_CSS)->getText(); + } + + /** + * Gets the is customer notified status which presented in comment + * + * @return string + */ + public function getNotifiedStatus() + { + $this->waitCommentsHistory(); + return $this->_rootElement->find($this->commentHistoryNotifiedStatus, Locator::SELECTOR_CSS)->getText(); + } + /** * Wait for comments history is visible. * diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php new file mode 100644 index 0000000000000..013c3562b7090 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php @@ -0,0 +1,53 @@ +open(); + $salesOrder->getSalesOrderGrid()->searchAndOpen(['id' => $order->getId()]); + $sendMail = isset($data['form_data']['send_email']) ? filter_var( + $data['form_data']['send_email'], + FILTER_VALIDATE_BOOLEAN + ) : false; + \PHPUnit_Framework_Assert::assertContains( + $salesOrderView->getOrderHistoryBlock()->getNotifiedStatus(), + (bool)$sendMail ? 'Customer Notified' : 'Customer Not Notified' + ); + } + + /** + * Returns string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return "Message with appropriate notification status is available in Comments History section."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php new file mode 100644 index 0000000000000..89faffc8ec072 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php @@ -0,0 +1,48 @@ +open(); + $salesOrder->getSalesOrderGrid()->searchAndOpen(['id' => $order->getId()]); + \PHPUnit_Framework_Assert::assertContains( + $salesOrderView->getOrderForm()->getOrderInfoBlock()->getOrderStatus(), + $salesOrderView->getOrderHistoryBlock()->getStatus() + ); + } + + /** + * Returns string representation of successful assertion. + * + * @return string + */ + public function toString() + { + return "Message with appropriate order status is available in Comments History section."; + } +} diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml index 40f5c0aefc60a..80e1bfdf81e8f 100644 --- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml @@ -11,6 +11,7 @@ Assert items return to stock (partial refund) Yes 1 + Yes default catalogProductSimple::product_100_dollar partial_refund @@ -18,6 +19,8 @@ + + diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml index 595ce66010ed6..5d338af60555f 100644 --- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml +++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml @@ -60,7 +60,7 @@ - test_type:acceptance_test, stable:no, test_type:extended_acceptance_test + test_type:acceptance_test, test_type:extended_acceptance_test TaxIdentifier%isolation% US-CA-*-Rate 1 us_ny_rate_8_1 diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php index 3ec08a1692bbc..c970c90f20473 100644 --- a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php +++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php @@ -27,13 +27,33 @@ class DependencyTest extends \PHPUnit_Framework_TestCase protected $errors = []; /** - * Forbidden base namespaces + * Allowed sub namespaces * * @return array */ - protected function getForbiddenNamespaces() + protected function getAllowedNamespaces() { - return ['Magento']; + return [ + 'Framework', + 'SomeModule', + 'ModuleName', + 'Setup\Console\CommandList', + 'Setup\Console\CompilerPreparation', + 'Setup\Model\ObjectManagerProvider', + 'Setup\Mvc\Bootstrap\InitParamListener', + 'Store\Model\ScopeInterface', + 'Store\Model\StoreManagerInterface', + 'Directory\Model\CurrencyFactory', + 'PageCache\Model\Cache\Type', + 'Backup\Model\ResourceModel\Db', + 'Backend\Block\Widget\Button', + 'Ui\Component\Container', + 'SalesRule\Model\Rule', + 'SalesRule\Api\Data\RuleInterface', + 'SalesRule\Model\Rule\Interceptor', + 'SalesRule\Model\Rule\Proxy', + 'Theme\Model\View\Design' + ]; } public function testCheckDependencies() @@ -53,15 +73,15 @@ function ($file) { (new Injectable())->getDependencies($fileReflection), $tokens->getDependencies() ); - - $pattern = '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#'; + $allowedNamespaces = str_replace('\\', '\\\\', implode('|', $this->getAllowedNamespaces())); + $pattern = '#Magento\\\\(?!' . $allowedNamespaces . ').*#'; foreach ($dependencies as $dependency) { - $dependencyPaths = explode('/', $dependency); + $dependencyPaths = explode('\\', $dependency); $dependencyPaths = array_slice($dependencyPaths, 2); - $dependency = implode('\\', $dependencyPaths); + $dependencyPath = implode('\\', $dependencyPaths); $libraryPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY); foreach ($libraryPaths as $libraryPath) { - $filePath = str_replace('\\', '/', $libraryPath . '/' . $dependency . '.php'); + $filePath = str_replace('\\', '/', $libraryPath . '/' . $dependencyPath . '.php'); if (preg_match($pattern, $dependency) && !file_exists($filePath)) { $this->errors[$fileReflection->getFileName()][] = $dependency; } @@ -142,12 +162,11 @@ public function libraryDataProvider() $componentRegistrar = new ComponentRegistrar(); include_once $componentRegistrar->getPath(ComponentRegistrar::LIBRARY, 'magento/framework') . '/Option/ArrayInterface.php'; - $blackList = Files::init()->readLists(__DIR__ . '/_files/blacklist.txt'); + $blackList = Files::init()->readLists(__DIR__ . '/_files/blacklist*.txt'); $dataProvider = Files::init()->getPhpFiles(Files::INCLUDE_LIBS | Files::AS_DATA_SET); foreach ($dataProvider as $key => $data) { - $file = str_replace(BP . '/', '', $data[0]); - if (in_array($file, $blackList)) { + if (in_array($data[0], $blackList)) { unset($dataProvider[$key]); } else { include_once $data[0]; diff --git a/lib/internal/Magento/Framework/App/Router/Base.php b/lib/internal/Magento/Framework/App/Router/Base.php index 9be1788387323..91ae3fc3664ec 100644 --- a/lib/internal/Magento/Framework/App/Router/Base.php +++ b/lib/internal/Magento/Framework/App/Router/Base.php @@ -7,9 +7,6 @@ */ namespace Magento\Framework\App\Router; -use Magento\Framework\App\RequestInterface; -use Magento\Store\Model\ScopeInterface; - /** * @SuppressWarnings(PHPMD.TooManyFields) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php index af7f904418f26..5a47246ddd3f9 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php @@ -36,7 +36,7 @@ protected function setUp() ->setMethods(['setRefererOrBaseUrl']) ->disableOriginalConstructor() ->getMock(); - $this->redirectFactory = $this->getMockBuilder(\Magento\Backend\Model\View\Result\RedirectFactory::class) + $this->redirectFactory = $this->getMockBuilder(\Magento\Framework\Controller\Result\RedirectFactory::class) ->setMethods(['create']) ->disableOriginalConstructor() ->getMock(); diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php index bf49959b67007..e17e3990f8695 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php @@ -80,7 +80,7 @@ public function testMatch() $moduleFrontName = 'module front name'; $actionPath = 'action path'; $actionName = 'action name'; - $actionClassName = \Magento\Cms\Controller\Index\Index::class; + $actionClassName = \Magento\Framework\App\Action\Action::class; $moduleName = 'module name'; $moduleList = [$moduleName]; @@ -109,7 +109,7 @@ public function testMatchUseParams() $moduleFrontName = 'module front name'; $actionPath = 'action path'; $actionName = 'action name'; - $actionClassName = \Magento\Cms\Controller\Index\Index::class; + $actionClassName = \Magento\Framework\App\Action\Action::class; $moduleName = 'module name'; $moduleList = [$moduleName]; $paramList = $moduleFrontName . '/' . $actionPath . '/' . $actionName . '/key/val/key2/val2/'; @@ -137,7 +137,7 @@ public function testMatchUseDefaultPath() $moduleFrontName = 'module front name'; $actionPath = 'action path'; $actionName = 'action name'; - $actionClassName = \Magento\Cms\Controller\Index\Index::class; + $actionClassName = \Magento\Framework\App\Action\Action::class; $moduleName = 'module name'; $moduleList = [$moduleName]; @@ -169,7 +169,7 @@ public function testMatchEmptyModuleList() $moduleFrontName = 'module front name'; $actionPath = 'action path'; $actionName = 'action name'; - $actionClassName = \Magento\Cms\Controller\Index\Index::class; + $actionClassName = \Magento\Framework\App\Action\Action::class; $emptyModuleList = []; // Stubs @@ -192,7 +192,7 @@ public function testMatchEmptyActionInstance() $moduleFrontName = 'module front name'; $actionPath = 'action path'; $actionName = 'action name'; - $actionClassName = \Magento\Cms\Controller\Index\Index::class; + $actionClassName = \Magento\Framework\App\Action\Action::class; $moduleName = 'module name'; $moduleList = [$moduleName]; diff --git a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php index fe3a199da86a3..70cb79f950f28 100644 --- a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php +++ b/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php @@ -5,49 +5,24 @@ */ namespace Magento\Framework\EntityManager; -use Magento\Framework\Api\AttributeInterface; -use Magento\Framework\Api\CustomAttributesDataInterface; -use Magento\Eav\Api\AttributeRepositoryInterface; -use Magento\Framework\Api\SearchCriteriaBuilder; - /** * Class CustomAttributesMapper */ class CustomAttributesMapper implements MapperInterface { /** - * @var AttributeRepositoryInterface - */ - private $attributeRepository; - - /** - * @var MetadataPool - */ - private $metadataPool; - - /** - * @var SearchCriteriaBuilder - */ - private $searchCriteriaBuilder; - - /** - * @var array + * @var MapperInterface */ - private $attributes; + private $mapper; /** - * @param AttributeRepositoryInterface $attributeRepository - * @param MetadataPool $metadataPool - * @param SearchCriteriaBuilder $searchCriteriaBuilder + * CustomAttributesMapper constructor. + * + * @param MapperInterface $mapper */ - public function __construct( - AttributeRepositoryInterface $attributeRepository, - MetadataPool $metadataPool, - SearchCriteriaBuilder $searchCriteriaBuilder - ) { - $this->attributeRepository = $attributeRepository; - $this->metadataPool = $metadataPool; - $this->searchCriteriaBuilder = $searchCriteriaBuilder; + public function __construct(MapperInterface $mapper) + { + $this->mapper = $mapper; } /** @@ -55,67 +30,15 @@ public function __construct( */ public function entityToDatabase($entityType, $data) { - if (!$this->metadataPool->hasConfiguration($entityType) - || !$this->metadataPool->getMetadata($entityType)->getEavEntityType() - ) { - return $data; - } - if (isset($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES])) { - foreach ($this->getNonStaticAttributes($entityType) as $attribute) { - foreach ($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES] as $key => $customAttribute) { - if ($customAttribute[AttributeInterface::ATTRIBUTE_CODE] == $attribute->getAttributeCode()) { - unset($data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][$key]); - $data[$attribute->getAttributeCode()] = $customAttribute[AttributeInterface::VALUE]; - } - } - } - } - return $data; + return $this->mapper->entityToDatabase($entityType, $data); } /** * {@inheritdoc} + * @deprecated */ public function databaseToEntity($entityType, $data) { - $metadata = $this->metadataPool->getMetadata($entityType); - if (!$metadata->getEavEntityType()) { - return $data; - } - foreach ($this->getNonStaticAttributes($entityType) as $attribute) { - if (isset($data[$attribute->getAttributeCode()])) { - $data[CustomAttributesDataInterface::CUSTOM_ATTRIBUTES][] = [ - AttributeInterface::ATTRIBUTE_CODE => $attribute->getAttributeCode(), - AttributeInterface::VALUE => $data[$attribute->getAttributeCode()] - ]; - } - } - return $data; - } - - /** - * Get custom attributes - * - * @param string $entityType - * @return \Magento\Eav\Api\Data\AttributeInterface[] - * @throws \Exception - */ - private function getNonStaticAttributes($entityType) - { - if (!isset($this->attributes[$entityType])) { - $metadata = $this->metadataPool->getMetadata($entityType); - $searchResult = $this->attributeRepository->getList( - $metadata->getEavEntityType(), - $this->searchCriteriaBuilder->addFilter('attribute_set_id', null, 'neq')->create() - ); - $attributes = []; - foreach ($searchResult->getItems() as $attribute) { - if (!$attribute->isStatic()) { - $attributes[] = $attribute; - } - } - $this->attributes[$entityType] = $attributes; - } - return $this->attributes[$entityType]; + return $this->mapper->databaseToEntity($entityType, $data); } } diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php index 55f68f47407f5..f1c4d443bd756 100644 --- a/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php +++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php @@ -60,12 +60,12 @@ public function testGetAmount() ->with($this->equalTo($totalAmount), $this->equalTo($expectedAdjustments)) ->will($this->returnValue($amountBaseMock)); - $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + $productMock = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class) ->disableOriginalConstructor() ->setMethods(['getPriceInfo', '__wakeup']) - ->getMock(); + ->getMockForAbstractClass(); - $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Weee\Pricing\Adjustment::class) + $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class) ->disableOriginalConstructor() ->getMock(); $weeeAdjustmentMock->expects($this->once()) @@ -82,7 +82,7 @@ public function testGetAmount() ->with($this->equalTo($amountInclTax), $this->equalTo($productMock)) ->will($this->returnValue($weeeAdjustment + $amountInclTax)); - $taxAdjustmentMock = $this->getMockBuilder(\Magento\Tax\Pricing\Adjustment::class) + $taxAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class) ->disableOriginalConstructor() ->getMock(); $taxAdjustmentMock->expects($this->once()) @@ -127,12 +127,12 @@ public function testGetAmountExclude() $adjustment = 5; $expectedAdjustments = []; - $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + $productMock = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class) ->disableOriginalConstructor() ->setMethods(['getPriceInfo', '__wakeup']) - ->getMock(); + ->getMockForAbstractClass(); - $taxAdjustmentMock = $this->getMockBuilder(\Magento\Tax\Pricing\Adjustment::class) + $taxAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class) ->disableOriginalConstructor() ->getMock(); $taxAdjustmentMock->expects($this->once()) @@ -150,7 +150,7 @@ public function testGetAmountExclude() ->with($this->equalTo($fullamount), $this->equalTo($productMock)) ->will($this->returnValue($amount)); - $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Weee\Pricing\Adjustment::class) + $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class) ->disableOriginalConstructor() ->getMock(); $weeeAdjustmentMock->expects($this->once()) diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php index 1f6c7b98c129d..1bc82365bf168 100644 --- a/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php +++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php @@ -23,7 +23,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase protected $priceLayout; /** - * @var \Magento\Catalog\Pricing\Price\BasePrice|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\Price\PriceInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $price; @@ -33,7 +33,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase protected $amount; /** - * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Framework\Pricing\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $saleableItem; @@ -48,17 +48,17 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->price = $this->getMockBuilder(\Magento\Catalog\Pricing\Price\BasePrice::class) + $this->price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) ->disableOriginalConstructor() - ->getMock(); + ->getMockForAbstractClass(); $this->amount = $this->getMockBuilder(\Magento\Framework\Pricing\Amount\Base::class) ->disableOriginalConstructor() ->getMock(); - $this->saleableItem = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + $this->saleableItem = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class) ->disableOriginalConstructor() - ->getMock(); + ->getMockForAbstractClass(); $this->renderPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class) ->disableOriginalConstructor() diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml b/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml index 3be95e59dfa11..d92121ddb77be 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml +++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml @@ -33,7 +33,7 @@ Excel XML - Magento\Sales\Model\Order\Grid\Massaction\ItemsUpdater + Magento\Framework\View\Layout\Argument\UpdaterInterface Move to Archive */sales_archive/massAdd diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 9fab793b70b6c..3041a177185cf 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -545,10 +545,10 @@ var pass = $.trim(v); var result = pass.length >= passwordMinLength; if (result == false) { - validator.passwordErrorMessage = $.mage.__( - "Minimum length of this field must be equal or greater than %1 symbols." + - " Leading and trailing spaces will be ignored." - ).replace('%1', passwordMinLength); + /*eslint-disable max-len*/ + validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength); + + /*eslint-enable max-len*/ return result; } if (pass.match(/\d+/)) { @@ -565,10 +565,11 @@ } if (counter < passwordMinCharacterSets) { result = false; - validator.passwordErrorMessage = $.mage.__( - "Minimum of different classes of characters in password is %1." + - " Classes of characters: Lower Case, Upper Case, Digits, Special Characters." - ).replace('%1', passwordMinCharacterSets); + + /*eslint-disable max-len*/ + validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets); + + /*eslint-enable max-len*/ } return result; }, function () { @@ -984,7 +985,7 @@ return !!container.querySelectorAll(selector).length; }, - 'Please select one of the options.' + $.mage.__('Please select one of the options.') ], "less-than-equals-to": [ function (value, element, params) { @@ -1145,16 +1146,12 @@ if (name.match(reMax) && result) { length = name.split('-')[2]; result = (v.length <= length); - validator.validateMessage = $.mage.__( - "Please enter less or equal than %1 symbols." - ).replace('%1', length); + validator.validateMessage = $.mage.__('Please enter less or equal than %1 symbols.').replace('%1', length); } if (name.match(reMin) && result && !$.mage.isEmpty(v)) { length = name.split('-')[2]; result = v.length >= length; - validator.validateMessage = $.mage.__( - "Please enter more or equal than %1 symbols." - ).replace('%1', length); + validator.validateMessage = $.mage.__('Please enter more or equal than %1 symbols.').replace('%1', length); } }); return result;