{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html b/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html index bc7c079d7f21b..b7411d80d2ba6 100644 --- a/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/creditmemo_update_guest.html @@ -10,7 +10,7 @@ "var creditmemo.increment_id":"Credit Memo Id", "var billing.getName()":"Guest Customer Name", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_update.html b/app/code/Magento/Sales/view/frontend/email/invoice_update.html index cafdd65ff5208..4043e59f9d7d6 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_update.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_update.html @@ -11,7 +11,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html b/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html index fafb533301efb..40cdec7fb4cab 100644 --- a/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/invoice_update_guest.html @@ -10,7 +10,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/order_update.html b/app/code/Magento/Sales/view/frontend/email/order_update.html index a709a9ed8a7f1..a8f0068b70e87 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_update.html +++ b/app/code/Magento/Sales/view/frontend/email/order_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/order_update_guest.html b/app/code/Magento/Sales/view/frontend/email/order_update_guest.html index 5a39b01810c18..749fa3b60ad59 100644 --- a/app/code/Magento/Sales/view/frontend/email/order_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/order_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -22,7 +22,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_update.html b/app/code/Magento/Sales/view/frontend/email/shipment_update.html index 6d9efc37004bc..9d1c93287549a 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_update.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
{{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html b/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html index 4896a00b7bc5a..0d2dccd3377d2 100644 --- a/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html +++ b/app/code/Magento/Sales/view/frontend/email/shipment_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}
diff --git a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php
index f62c07b149c0e..4532479c482b5 100644
--- a/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php
+++ b/app/code/Magento/Search/Test/Unit/Model/SynonymGroupRepositoryTest.php
@@ -53,7 +53,7 @@ public function testSaveCreate()
/**
* @expectedException \Magento\Search\Model\Synonym\MergeConflictException
- * @expecteExceptionMessage (c,d,e)
+ * @expectedExceptionMessage Merge conflict with existing synonym group(s): (a,b,c)
*/
public function testSaveCreateMergeConflict()
{
@@ -138,7 +138,7 @@ public function testSaveUpdate()
/**
* @expectedException \Magento\Search\Model\Synonym\MergeConflictException
- * @expecteExceptionMessage (d,h,i)
+ * @expectedExceptionMessage (d,h,i)
*/
public function testSaveUpdateMergeConflict()
{
diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
index 4c9df6ef657d7..9534e039380d4 100644
--- a/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
+++ b/app/code/Magento/Swatches/view/adminhtml/web/js/product-attributes.js
@@ -439,6 +439,9 @@ define([
activePanel.find('table input')
.each(function () {
+ if ($(this).is(':radio') && !$(this).prop('checked')) {
+ return;
+ }
swatchValues.push(this.name + '=' + $(this).val());
});
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
index 682378cd870f9..39220ae0fac66 100644
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
@@ -14,7 +14,7 @@ define([
'Magento_Checkout/js/model/totals',
'jquery',
'mage/translate'
-], function (ko, Component, quote, totals, $) {
+], function (ko, Component, quote, totals, $, $t) {
'use strict';
var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal,
@@ -24,7 +24,7 @@ define([
return Component.extend({
defaults: {
isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,
- notCalculatedMessage: $.mage.__('Not yet calculated'),
+ notCalculatedMessage: $t('Not yet calculated'),
template: 'Magento_Tax/checkout/summary/tax'
},
totals: quote.getTotals(),
diff --git a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php
index 5cb265d3d628b..c06e2626034a7 100644
--- a/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php
+++ b/app/code/Magento/Theme/Test/Unit/Model/Theme/Source/ThemeTest.php
@@ -10,7 +10,6 @@
class ThemeTest extends \PHPUnit\Framework\TestCase
{
/**
- * @true
* @return void
* @covers \Magento\Theme\Model\Theme\Source\Theme::__construct
* @covers \Magento\Theme\Model\Theme\Source\Theme::getAllOptions
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php
index f91401e43ea80..50d82b19d1045 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php
@@ -66,7 +66,8 @@ public function testNotApplyFilterModifier()
/**
* @return void
- * @assertException \Magento\Framework\Exception\LocalizedException
+ * @expectedException \Magento\Framework\Exception\LocalizedException
+ * @expectedExceptionMessage Condition type "not_allowed" is not allowed
*/
public function testApplyFilterModifierWithNotAllowedCondition()
{
@@ -78,7 +79,7 @@ public function testApplyFilterModifierWithNotAllowedCondition()
]
]);
$this->dataProvider->expects($this->never())->method('addFilter');
- $this->unit->applyFilterModifier($this->dataProvider, 'test');
+ $this->unit->applyFilterModifier($this->dataProvider, 'filter');
}
/**
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
index c21e0ba7845a7..7aa0d2368f67b 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
@@ -11,6 +11,8 @@
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\State\UserLockedException;
use Magento\Security\Model\SecurityCookie;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Authorization\Model\Role as RoleModel;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -74,10 +76,9 @@ public function execute()
$rid = $this->getRequest()->getParam('role_id', false);
$resource = $this->getRequest()->getParam('resource', false);
- $roleUsers = $this->getRequest()->getParam('in_role_user', null);
- parse_str($roleUsers, $roleUsers);
- $roleUsers = array_keys($roleUsers);
+ $oldRoleUsers = $this->parseRequestVariable('in_role_user_old');
+ $roleUsers = $this->parseRequestVariable('in_role_user');
$isAll = $this->getRequest()->getParam('all');
if ($isAll) {
$resource = [$this->_objectManager->get(\Magento\Framework\Acl\RootResource::class)->getId()];
@@ -104,12 +105,9 @@ public function execute()
$this->_rulesFactory->create()->setRoleId($role->getId())->setResources($resource)->saveRel();
- $this->processPreviousUsers($role);
-
- foreach ($roleUsers as $nRuid) {
- $this->_addUserToRole($nRuid, $role->getId());
- }
- $this->messageManager->addSuccess(__('You saved the role.'));
+ $this->processPreviousUsers($role, $oldRoleUsers);
+ $this->processCurrentUsers($role, $roleUsers);
+ $this->messageManager->addSuccessMessage(__('You saved the role.'));
} catch (UserLockedException $e) {
$this->_auth->logout();
$this->getSecurityCookie()->setLogoutReasonCookie(
@@ -119,10 +117,10 @@ public function execute()
} catch (\Magento\Framework\Exception\AuthenticationException $e) {
$this->messageManager->addError(__('You have entered an invalid password for current user.'));
return $this->saveDataToSessionAndRedirect($role, $this->getRequest()->getPostValue(), $resultRedirect);
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->messageManager->addError($e->getMessage());
+ } catch (LocalizedException $e) {
+ $this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
- $this->messageManager->addError(__('An error occurred while saving this role.'));
+ $this->messageManager->addErrorMessage(__('An error occurred while saving this role.'));
}
return $resultRedirect->setPath('*/*/');
@@ -147,16 +145,27 @@ protected function validateUser()
}
/**
- * @param \Magento\Authorization\Model\Role $role
+ * Parse request value from string
+ *
+ * @param string $paramName
+ * @return array
+ */
+ private function parseRequestVariable(string $paramName): array
+ {
+ $value = $this->getRequest()->getParam($paramName, null);
+ parse_str($value, $value);
+ $value = array_keys($value);
+ return $value;
+ }
+
+ /**
+ * @param RoleModel $role
+ * @param array $oldRoleUsers
* @return $this
* @throws \Exception
*/
- protected function processPreviousUsers(\Magento\Authorization\Model\Role $role)
+ protected function processPreviousUsers(RoleModel $role, array $oldRoleUsers): self
{
- $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old');
- parse_str($oldRoleUsers, $oldRoleUsers);
- $oldRoleUsers = array_keys($oldRoleUsers);
-
foreach ($oldRoleUsers as $oUid) {
$this->_deleteUserFromRole($oUid, $role->getId());
}
@@ -164,12 +173,33 @@ protected function processPreviousUsers(\Magento\Authorization\Model\Role $role)
return $this;
}
+ /**
+ * Processes users to be assigned to roles
+ *
+ * @param RoleModel $role
+ * @param array $roleUsers
+ * @return $this
+ */
+ private function processCurrentUsers(RoleModel $role, array $roleUsers): self
+ {
+ foreach ($roleUsers as $nRuid) {
+ try {
+ $this->_addUserToRole($nRuid, $role->getId());
+ } catch (LocalizedException $e) {
+ $this->messageManager->addErrorMessage($e->getMessage());
+ }
+ }
+
+ return $this;
+ }
+
/**
* Assign user to role
*
* @param int $userId
* @param int $roleId
* @return bool
+ * @throws LocalizedException
*/
protected function _addUserToRole($userId, $roleId)
{
@@ -203,7 +233,7 @@ protected function _deleteUserFromRole($userId, $roleId)
}
/**
- * @param \Magento\Authorization\Model\Role $role
+ * @param RoleModel $role
* @param array $data
* @param \Magento\Backend\Model\View\Result\Redirect $resultRedirect
* @return \Magento\Backend\Model\View\Result\Redirect
diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php
index fa71e81281763..62019426feb37 100644
--- a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php
+++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php
@@ -70,4 +70,17 @@ public function getTotalsForDisplay()
return $totals;
}
+
+ /**
+ * Check if we can display Weee total information in PDF
+ *
+ * @return bool
+ */
+ public function canDisplay()
+ {
+ $items = $this->getSource()->getAllItems();
+ $store = $this->getSource()->getStore();
+ $amount = $this->_weeeData->getTotalAmounts($items, $store);
+ return $this->getDisplayZero() === 'true' || $amount != 0;
+ }
}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
index 10b917635bd40..1015bb584ff7b 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
@@ -630,12 +630,9 @@
width: 1%;
}
- &-item-details {
- padding-bottom: 35px;
- }
-
&-item-details {
display: table-cell;
+ padding-bottom: 35px;
vertical-align: top;
white-space: normal;
width: 99%;
diff --git a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml
index 1f8c162ef923a..4b08bf28ece9f 100644
--- a/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml
+++ b/app/design/frontend/Magento/luma/Magento_Customer/layout/default.xml
@@ -15,11 +15,6 @@
-
diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update.html b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update.html index a739c9f54b08f..8ec54f1e64d9c 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update.html @@ -11,7 +11,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}} {{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update_guest.html index a56ee6da9fa25..6028db7b97730 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/invoice_update_guest.html @@ -10,7 +10,7 @@ "var comment":"Invoice Comment", "var invoice.increment_id":"Invoice Id", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/order_update.html b/app/design/frontend/Magento/luma/Magento_Sales/email/order_update.html index 3e4bf8df2f107..fa16ac2196bf4 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/order_update.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/order_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}} {{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/order_update_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/order_update_guest.html index 1075608db4341..8ead615fe01ca 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/order_update_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/order_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status" +"var order.getFrontendStatusLabel()":"Order Status" } @--> {{template config_path="design/email/header_template"}} @@ -22,7 +22,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update.html b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update.html index 37bf92b866c74..4f9b7286f3ae4 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update.html @@ -10,7 +10,7 @@ "var order.getCustomerName()":"Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -24,7 +24,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}} {{trans 'You can check the status of your order by logging into your account.' account_url=$this.getUrl($store,'customer/account/',[_nosid:1]) |raw}}
diff --git a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update_guest.html b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update_guest.html index 954819949860b..3ef26463ea755 100644 --- a/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update_guest.html +++ b/app/design/frontend/Magento/luma/Magento_Sales/email/shipment_update_guest.html @@ -9,7 +9,7 @@ "var billing.getName()":"Guest Customer Name", "var comment":"Order Comment", "var order.increment_id":"Order Id", -"var order.getStatusLabel()":"Order Status", +"var order.getFrontendStatusLabel()":"Order Status", "var shipment.increment_id":"Shipment Id" } @--> {{template config_path="design/email/header_template"}} @@ -23,7 +23,7 @@ "Your order #%increment_id has been updated with a status of %order_status." increment_id=$order.increment_id - order_status=$order.getStatusLabel() + order_status=$order.getFrontendStatusLabel() |raw}}diff --git a/composer.json b/composer.json index 5a35f7c94a209..891667b6ee942 100644 --- a/composer.json +++ b/composer.json @@ -74,7 +74,7 @@ "ramsey/uuid": "~3.7.3" }, "require-dev": { - "magento/magento2-functional-testing-framework": "2.3.6", + "magento/magento2-functional-testing-framework": "2.3.11", "phpunit/phpunit": "~6.2.0", "squizlabs/php_codesniffer": "3.2.2", "phpmd/phpmd": "@stable", diff --git a/composer.lock b/composer.lock index c765d467dfd0c..98c4846dc228a 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": "c9603f6f68dc6d6cc1ca6b6be242da74", + "content-hash": "d101565e8093f4857dc138911992d64b", "packages": [ { "name": "braintree/braintree_php", @@ -5972,16 +5972,16 @@ }, { "name": "magento/magento2-functional-testing-framework", - "version": "2.3.6", + "version": "2.3.11", "source": { "type": "git", "url": "https://github.com/magento/magento2-functional-testing-framework.git", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce" + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/57021e12ded213a0031c4d4f6293e06ce6f144ce", - "reference": "57021e12ded213a0031c4d4f6293e06ce6f144ce", + "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/3ca1bd74228a61bd05520bed1ef88b5a19764d92", + "reference": "3ca1bd74228a61bd05520bed1ef88b5a19764d92", "shasum": "" }, "require": { @@ -6039,7 +6039,7 @@ "magento", "testing" ], - "time": "2018-09-05T15:17:20+00:00" + "time": "2018-11-13T18:22:25+00:00" }, { "name": "moontoast/math", diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php index d951d84bab78d..d16da19cfe8b8 100644 --- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php +++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestStep/SelectCheckoutMethodStep.php @@ -107,6 +107,7 @@ private function processLogin() if ($this->checkoutMethod === 'login') { if ($this->checkoutOnepage->getAuthenticationPopupBlock()->isVisible()) { $this->checkoutOnepage->getAuthenticationPopupBlock()->loginCustomer($this->customer); + sleep(5); $this->clickProceedToCheckoutStep->run(); } else { $this->checkoutOnepage->getLoginBlock()->loginCustomer($this->customer); diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php index 8147818135edc..a2767f76cfecb 100644 --- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php +++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CategoryUrlRewriteTest.php @@ -85,6 +85,7 @@ public function test(Store $storeView, Category $childCategory, Category $parent $this->catalogCategoryEdit->getFormPageActions()->selectStoreView($storeView->getName()); $this->catalogCategoryEdit->getEditForm()->fill($categoryUpdates); $this->catalogCategoryEdit->getFormPageActions()->save(); + $this->catalogCategoryEdit->getFormPageActions()->selectStoreView('All Store Views'); $this->catalogCategoryIndex->getTreeCategories()->assignCategory( $parentCategory->getName(), $childCategory->getName() 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 e01f4aec401a2..4761f13175d81 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php @@ -9,6 +9,8 @@ use Magento\Framework\Data\Form\FormKey; use Magento\Framework\Message\Manager; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Framework\Message\MessageInterface; /** * @magentoAppArea adminhtml @@ -21,7 +23,7 @@ public function testSaveActionWithDangerRequest() $this->dispatch('backend/catalog/product/save'); $this->assertSessionMessages( $this->equalTo(['Unable to save product']), - \Magento\Framework\Message\MessageInterface::TYPE_ERROR + MessageInterface::TYPE_ERROR ); $this->assertRedirect($this->stringContains('/backend/catalog/product/new')); } @@ -38,7 +40,7 @@ public function testSaveActionAndNew() $this->assertRedirect($this->stringStartsWith('http://localhost/index.php/backend/catalog/product/new/')); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -61,11 +63,11 @@ public function testSaveActionAndDuplicate() ); $this->assertSessionMessages( $this->contains('You saved the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); $this->assertSessionMessages( $this->contains('You duplicated the product.'), - \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS + MessageInterface::TYPE_SUCCESS ); } @@ -236,4 +238,104 @@ public function saveActionWithAlreadyExistingUrlKeyDataProvider() ] ]; } + + /** + * Test product save with selected tier price + * + * @dataProvider saveActionTierPriceDataProvider + * @param array $postData + * @param array $tierPrice + * @magentoDataFixture Magento/Catalog/_files/product_has_tier_price_show_as_low_as.php + * @magentoConfigFixture current_store catalog/price/scope 1 + */ + public function testSaveActionTierPrice(array $postData, array $tierPrice) + { + $postData['product'] = $this->getProductData($tierPrice); + $this->getRequest()->setPostValue($postData); + $this->dispatch('backend/catalog/product/save/id/' . $postData['id']); + $this->assertSessionMessages( + $this->contains('You saved the product.'), + MessageInterface::TYPE_SUCCESS + ); + } + + /** + * Provide test data for testSaveActionWithAlreadyExistingUrlKey(). + * + * @return array + */ + public function saveActionTierPriceDataProvider() + { + return [ + [ + 'post_data' => [ + 'id' => '1', + 'type' => 'simple', + 'store' => '0', + 'set' => '4', + 'back' => 'edit', + 'product' => [], + 'is_downloadable' => '0', + 'affect_configurable_product_attributes' => '1', + 'new_variation_attribute_set_id' => '4', + 'use_default' => [ + 'gift_message_available' => '0', + 'gift_wrapping_available' => '0' + ], + 'configurable_matrix_serialized' => '[]', + 'associated_product_ids_serialized' => '[]' + ], + 'tier_price_for_request' => [ + [ + 'price_id' => '1', + 'website_id' => '0', + 'cust_group' => '32000', + 'price' => '111.00', + 'price_qty' => '100', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '1', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '2', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '222.00', + 'price_qty' => '200', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '2', + 'value_type' => 'fixed' + ], + [ + 'price_id' => '3', + 'website_id' => '1', + 'cust_group' => '32000', + 'price' => '333.00', + 'price_qty' => '300', + 'website_price' => '111.0000', + 'initialize' => 'true', + 'record_id' => '3', + 'value_type' => 'fixed' + ] + ] + ] + ]; + } + + /** + * Return product data for test without entity_id for further save + * + * @param array $tierPrice + * @return array + */ + private function getProductData(array $tierPrice) + { + $productRepositoryInterface = $this->_objectManager->get(ProductRepositoryInterface::class); + $product = $productRepositoryInterface->get('tier_prices')->getData(); + $product['tier_price'] = $tierPrice; + unset($product['entity_id']); + return $product; + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php index 33f26302394f4..38960ab66399a 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/DesignTest.php @@ -32,8 +32,12 @@ public function testApplyCustomDesign($theme) $design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Framework\View\DesignInterface::class ); + $translate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\Framework\TranslateInterface::class + ); $this->assertEquals('package', $design->getDesignTheme()->getPackageCode()); $this->assertEquals('theme', $design->getDesignTheme()->getThemeCode()); + $this->assertEquals('themepackage/theme', $translate->getTheme()); } /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php new file mode 100644 index 0000000000000..cff2e83ed002e --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock.php @@ -0,0 +1,20 @@ +create(\Magento\Catalog\Model\Product::class); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL) + ->setId(31) + ->setAttributeSetId(4) + ->setWebsiteIds([1]) + ->setName('Virtual Product Out') + ->setSku('virtual-product-out') + ->setPrice(10) + ->setTaxClassId(0) + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setStockData(['is_in_stock' => 0]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php new file mode 100644 index 0000000000000..8055ca4a25569 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_out_of_stock_rollback.php @@ -0,0 +1,26 @@ +get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +try { + $product = $productRepository->get('virtual-product-out', false, null, true); + $productRepository->delete($product); +} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) { + //Product already removed +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php index e777313f13fe8..1ac785148c280 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/CustomerRepositoryTest.php @@ -8,8 +8,24 @@ use Magento\Customer\Api\AccountManagementInterface; use Magento\Customer\Api\CustomerRepositoryInterface; +use Magento\Customer\Api\Data\CustomerInterfaceFactory; +use Magento\Customer\Api\Data\AddressInterfaceFactory; +use Magento\Customer\Api\Data\RegionInterfaceFactory; +use Magento\Framework\Api\ExtensibleDataObjectConverter; +use Magento\Framework\Api\DataObjectHelper; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Customer\Api\Data\CustomerInterface; +use Magento\Customer\Model\CustomerRegistry; use Magento\Framework\Api\SortOrder; +use Magento\Framework\Config\CacheInterface; +use Magento\Framework\ObjectManagerInterface; use Magento\TestFramework\Helper\Bootstrap; +use Magento\Customer\Api\Data\AddressInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; +use Magento\Framework\Api\FilterBuilder; +use Magento\Framework\Api\SortOrderBuilder; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Customer\Model\Customer; /** * Checks Customer insert, update, search with repository @@ -25,60 +41,65 @@ class CustomerRepositoryTest extends \PHPUnit\Framework\TestCase /** @var CustomerRepositoryInterface */ private $customerRepository; - /** @var \Magento\Framework\ObjectManagerInterface */ + /** @var ObjectManagerInterface */ private $objectManager; - /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory */ + /** @var CustomerInterfaceFactory */ private $customerFactory; - /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */ + /** @var AddressInterfaceFactory */ private $addressFactory; - /** @var \Magento\Customer\Api\Data\RegionInterfaceFactory */ + /** @var RegionInterfaceFactory */ private $regionFactory; - /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter */ + /** @var ExtensibleDataObjectConverter */ private $converter; - /** @var \Magento\Framework\Api\DataObjectHelper */ + /** @var DataObjectHelper */ protected $dataObjectHelper; - /** @var \Magento\Framework\Encryption\EncryptorInterface */ + /** @var EncryptorInterface */ protected $encryptor; - /** @var \Magento\Customer\Model\CustomerRegistry */ + /** @var CustomerRegistry */ protected $customerRegistry; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = Bootstrap::getObjectManager(); - $this->customerRepository = - $this->objectManager->create(\Magento\Customer\Api\CustomerRepositoryInterface::class); - $this->customerFactory = - $this->objectManager->create(\Magento\Customer\Api\Data\CustomerInterfaceFactory::class); - $this->addressFactory = $this->objectManager->create(\Magento\Customer\Api\Data\AddressInterfaceFactory::class); - $this->regionFactory = $this->objectManager->create(\Magento\Customer\Api\Data\RegionInterfaceFactory::class); - $this->accountManagement = - $this->objectManager->create(\Magento\Customer\Api\AccountManagementInterface::class); - $this->converter = $this->objectManager->create(\Magento\Framework\Api\ExtensibleDataObjectConverter::class); - $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class); - $this->encryptor = $this->objectManager->create(\Magento\Framework\Encryption\EncryptorInterface::class); - $this->customerRegistry = $this->objectManager->create(\Magento\Customer\Model\CustomerRegistry::class); - - /** @var \Magento\Framework\Config\CacheInterface $cache */ - $cache = $this->objectManager->create(\Magento\Framework\Config\CacheInterface::class); + $this->customerRepository = $this->objectManager->create(CustomerRepositoryInterface::class); + $this->customerFactory = $this->objectManager->create(CustomerInterfaceFactory::class); + $this->addressFactory = $this->objectManager->create(AddressInterfaceFactory::class); + $this->regionFactory = $this->objectManager->create(RegionInterfaceFactory::class); + $this->accountManagement = $this->objectManager->create(AccountManagementInterface::class); + $this->converter = $this->objectManager->create(ExtensibleDataObjectConverter::class); + $this->dataObjectHelper = $this->objectManager->create(DataObjectHelper::class); + $this->encryptor = $this->objectManager->create(EncryptorInterface::class); + $this->customerRegistry = $this->objectManager->create(CustomerRegistry::class); + + /** @var CacheInterface $cache */ + $cache = $this->objectManager->create(CacheInterface::class); $cache->remove('extension_attributes_config'); } + /** + * @inheritdoc + */ protected function tearDown() { - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $objectManager = Bootstrap::getObjectManager(); /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */ - $customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class); + $customerRegistry = $objectManager->get(CustomerRegistry::class); $customerRegistry->remove(1); } /** + * Check if first name update was successful + * * @magentoDbIsolation enabled */ public function testCreateCustomerNewThenUpdateFirstName() @@ -100,7 +121,7 @@ public function testCreateCustomerNewThenUpdateFirstName() $newCustomerFirstname = 'New First Name'; $updatedCustomer = $this->customerFactory->create(); $this->dataObjectHelper->mergeDataObjects( - \Magento\Customer\Api\Data\CustomerInterface::class, + CustomerInterface::class, $updatedCustomer, $customer ); @@ -113,6 +134,8 @@ public function testCreateCustomerNewThenUpdateFirstName() } /** + * Test create new customer + * * @magentoDbIsolation enabled */ public function testCreateNewCustomer() @@ -140,6 +163,8 @@ public function testCreateNewCustomer() } /** + * Test update customer + * * @dataProvider updateCustomerDataProvider * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php @@ -169,7 +194,7 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $this->dataObjectHelper->populateWithArray( $customerDetails, $customerData, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $this->customerRepository->save($customerDetails, $newPasswordHash); $customerAfter = $this->customerRepository->getById($existingCustomerId); @@ -188,12 +213,12 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) $attributesBefore = $this->converter->toFlatArray( $customerBefore, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $attributesAfter = $this->converter->toFlatArray( $customerAfter, [], - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); // ignore 'updated_at' unset($attributesBefore['updated_at']); @@ -216,6 +241,8 @@ public function testUpdateCustomer($defaultBilling, $defaultShipping) } /** + * Test update customer address + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -234,14 +261,14 @@ public function testUpdateCustomerAddress() $this->dataObjectHelper->populateWithArray( $newAddressDataObject, $newAddress, - \Magento\Customer\Api\Data\AddressInterface::class + AddressInterface::class ); $newAddressDataObject->setRegion($addresses[0]->getRegion()); $newCustomerEntity = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customerId) ->setAddresses([$newAddressDataObject, $addresses[1]]); @@ -257,6 +284,8 @@ public function testUpdateCustomerAddress() } /** + * Test preserve all addresses after customer update + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -270,7 +299,7 @@ public function testUpdateCustomerPreserveAllAddresses() $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses(null); @@ -282,6 +311,8 @@ public function testUpdateCustomerPreserveAllAddresses() } /** + * Test update delete all addresses with empty arrays + * * @magentoAppArea frontend * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -295,7 +326,7 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() $this->dataObjectHelper->populateWithArray( $newCustomerEntity, $customerDetails, - \Magento\Customer\Api\Data\CustomerInterface::class + CustomerInterface::class ); $newCustomerEntity->setId($customer->getId()) ->setAddresses([]); @@ -307,6 +338,51 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() } /** + * Test customer update with new address + * + * @magentoAppArea frontend + * @magentoDataFixture Magento/Customer/_files/customer.php + * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php + */ + public function testUpdateCustomerWithNewAddress() + { + $customerId = 1; + $customer = $this->customerRepository->getById($customerId); + $customerDetails = $customer->__toArray(); + unset($customerDetails['default_billing']); + unset($customerDetails['default_shipping']); + + $beforeSaveCustomer = $this->customerFactory->create(); + $this->dataObjectHelper->populateWithArray( + $beforeSaveCustomer, + $customerDetails, + CustomerInterface::class + ); + + $addresses = $customer->getAddresses(); + $beforeSaveAddress = $addresses[0]->__toArray(); + unset($beforeSaveAddress['id']); + $newAddressDataObject = $this->addressFactory->create(); + $this->dataObjectHelper->populateWithArray( + $newAddressDataObject, + $beforeSaveAddress, + AddressInterface::class + ); + + $beforeSaveCustomer->setAddresses([$newAddressDataObject]); + $this->customerRepository->save($beforeSaveCustomer); + + $newCustomer = $this->customerRepository->getById($customerId); + $newCustomerAddresses = $newCustomer->getAddresses(); + $addressId = $newCustomerAddresses[0]->getId(); + + $this->assertEquals($newCustomer->getDefaultBilling(), $addressId, "Default billing invalid value"); + $this->assertEquals($newCustomer->getDefaultShipping(), $addressId, "Default shipping invalid value"); + } + + /** + * Test search customers + * * @param \Magento\Framework\Api\Filter[] $filters * @param \Magento\Framework\Api\Filter[] $filterGroup * @param array $expectedResult array of expected results indexed by ID @@ -318,9 +394,8 @@ public function testUpdateCustomerDeleteAllAddressesWithEmptyArray() */ public function testSearchCustomers($filters, $filterGroup, $expectedResult) { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ - $searchBuilder = Bootstrap::getObjectManager() - ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + /** @var SearchCriteriaBuilder $searchBuilder */ + $searchBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class); foreach ($filters as $filter) { $searchBuilder->addFilters([$filter]); } @@ -347,19 +422,19 @@ public function testSearchCustomers($filters, $filterGroup, $expectedResult) */ public function testSearchCustomersOrder() { - /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ + /** @var SearchCriteriaBuilder $searchBuilder */ $objectManager = Bootstrap::getObjectManager(); - $searchBuilder = $objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); + $searchBuilder = $objectManager->create(SearchCriteriaBuilder::class); // Filter for 'firstname' like 'First' - $filterBuilder = $objectManager->create(\Magento\Framework\Api\FilterBuilder::class); + $filterBuilder = $objectManager->create(FilterBuilder::class); $firstnameFilter = $filterBuilder->setField('firstname') ->setConditionType('like') ->setValue('First%') ->create(); $searchBuilder->addFilters([$firstnameFilter]); // Search ascending order - $sortOrderBuilder = $objectManager->create(\Magento\Framework\Api\SortOrderBuilder::class); + $sortOrderBuilder = $objectManager->create(SortOrderBuilder::class); $sortOrder = $sortOrderBuilder ->setField('lastname') ->setDirection(SortOrder::SORT_ASC) @@ -384,6 +459,8 @@ public function testSearchCustomersOrder() } /** + * Test delete + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -395,13 +472,15 @@ public function testDelete() $this->customerRepository->delete($customer); /** Ensure that customer was deleted */ $this->expectException( - \Magento\Framework\Exception\NoSuchEntityException::class, + NoSuchEntityException::class, 'No such entity with email = customer@example.com, websiteId = 1' ); $this->customerRepository->get($fixtureCustomerEmail); } /** + * Test delete by id + * * @magentoAppArea adminhtml * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoAppIsolation enabled @@ -413,7 +492,7 @@ public function testDeleteById() $this->customerRepository->deleteById($fixtureCustomerId); /** Ensure that customer was deleted */ $this->expectException( - \Magento\Framework\Exception\NoSuchEntityException::class, + NoSuchEntityException::class, 'No such entity with email = customer@example.com, websiteId = 1' ); $this->customerRepository->get($fixtureCustomerEmail); @@ -438,9 +517,14 @@ public function updateCustomerDataProvider() ]; } + /** + * Search customer data provider + * + * @return array + */ public function searchCustomersDataProvider() { - $builder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class); + $builder = Bootstrap::getObjectManager()->create(FilterBuilder::class); return [ 'Customer with specific email' => [ [$builder->setField('email')->setValue('customer@search.example.com')->create()], @@ -490,9 +574,9 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( $defaultShipping ) { /** - * @var \Magento\Customer\Model\Customer $customer + * @var Customer $customer */ - $customer = $this->objectManager->create(\Magento\Customer\Model\Customer::class); + $customer = $this->objectManager->create(Customer::class); /** @var \Magento\Customer\Model\Customer $customer */ $customer->load($customerId); $this->assertEquals( @@ -508,6 +592,8 @@ protected function expectedDefaultShippingsInCustomerModelAttributes( } /** + * Test update default shipping and default billing address + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDbIsolation enabled */ @@ -535,13 +621,13 @@ public function testUpdateDefaultShippingAndDefaultBillingTest() $this->assertEquals( $savedCustomer->getDefaultBilling(), $oldDefaultBilling, - 'Default billing shoud not be overridden' + 'Default billing should not be overridden' ); $this->assertEquals( $savedCustomer->getDefaultShipping(), $oldDefaultShipping, - 'Default shipping shoud not be overridden' + 'Default shipping should not be overridden' ); } } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php index 419a7d04b778a..2ee0953dcdbf1 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/Model/ResourceModel/Db/Collection/AbstractTest.php @@ -72,4 +72,42 @@ public function testGetAllIdsWithBind() $this->_model->addBindParam('code', 'admin'); $this->assertEquals(['0'], $this->_model->getAllIds()); } + + /** + * Check add field to select doesn't remove expression field from select. + * + * @return void + */ + public function testAddExpressionFieldToSelectWithAdditionalFields() + { + $expectedColumns = ['code', 'test_field']; + $actualColumns = []; + + $testExpression = new \Zend_Db_Expr('(sort_order + group_id)'); + $this->_model->addExpressionFieldToSelect('test_field', $testExpression, ['sort_order', 'group_id']); + $this->_model->addFieldToSelect('code', 'code'); + $columns = $this->_model->getSelect()->getPart(\Magento\Framework\DB\Select::COLUMNS); + foreach ($columns as $columnEntry) { + $actualColumns[] = $columnEntry[2]; + } + + $this->assertEquals($expectedColumns, $actualColumns); + } + + /** + * Check add expression field doesn't remove all fields from select. + * + * @return void + */ + public function testAddExpressionFieldToSelectWithoutAdditionalFields() + { + $expectedColumns = ['*', 'test_field']; + + $testExpression = new \Zend_Db_Expr('(sort_order + group_id)'); + $this->_model->addExpressionFieldToSelect('test_field', $testExpression, ['sort_order', 'group_id']); + $columns = $this->_model->getSelect()->getPart(\Magento\Framework\DB\Select::COLUMNS); + $actualColumns = [$columns[0][1], $columns[1][2]]; + + $this->assertEquals($expectedColumns, $actualColumns); + } } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php index dcf4565873ea5..ed283d196e69c 100644 --- a/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php @@ -5,8 +5,19 @@ */ namespace Magento\GroupedProduct\Model\Product\Type; +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Model\Configuration; +use Magento\Framework\App\Config\ReinitableConfigInterface; +use Magento\Framework\App\Config\Value; + class GroupedTest extends \PHPUnit\Framework\TestCase { + /** + * @var ReinitableConfigInterface + */ + private $reinitableConfig; + /** * @var \Magento\Framework\ObjectManagerInterface */ @@ -20,16 +31,21 @@ class GroupedTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $this->_productType = $this->objectManager->get(\Magento\Catalog\Model\Product\Type::class); + $this->reinitableConfig = $this->objectManager->get(ReinitableConfigInterface::class); + } + + protected function tearDown() + { + $this->dropConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK); } public function testFactory() { $product = new \Magento\Framework\DataObject(); - $product->setTypeId(\Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE); + $product->setTypeId(Grouped::TYPE_CODE); $type = $this->_productType->factory($product); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); } /** @@ -38,12 +54,12 @@ public function testFactory() */ public function testGetAssociatedProducts() { - $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); - /** @var \Magento\Catalog\Model\Product $product */ + /** @var Product $product */ $product = $productRepository->get('grouped-product'); $type = $product->getTypeInstance(); - $this->assertInstanceOf(\Magento\GroupedProduct\Model\Product\Type\Grouped::class, $type); + $this->assertInstanceOf(Grouped::class, $type); $associatedProducts = $type->getAssociatedProducts($product); $this->assertCount(2, $associatedProducts); @@ -53,7 +69,7 @@ public function testGetAssociatedProducts() } /** - * @param \Magento\Catalog\Model\Product $product + * @param Product $product */ private function assertProductInfo($product) { @@ -92,25 +108,25 @@ public function testPrepareProduct() \Magento\Framework\DataObject::class, ['data' => ['value' => ['qty' => 2]]] ); - /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ - $productRepository = $this->objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + /** @var ProductRepositoryInterface $productRepository */ + $productRepository = $this->objectManager->get(ProductRepositoryInterface::class); $product = $productRepository->get('grouped-product'); - /** @var \Magento\GroupedProduct\Model\Product\Type\Grouped $type */ - $type = $this->objectManager->get(\Magento\GroupedProduct\Model\Product\Type\Grouped::class); + /** @var Grouped $type */ + $type = $this->objectManager->get(Grouped::class); $processModes = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL, - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE + Grouped::PROCESS_MODE_FULL, + Grouped::PROCESS_MODE_LITE ]; $expectedData = [ - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_FULL => [ + Grouped::PROCESS_MODE_FULL => [ 1 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', 21 => '{"super_product_config":{"product_type":"grouped","product_id":"' . $product->getId() . '"}}', ], - \Magento\GroupedProduct\Model\Product\Type\Grouped::PROCESS_MODE_LITE => [ + Grouped::PROCESS_MODE_LITE => [ $product->getId() => '{"value":{"qty":2}}', ] ]; @@ -127,4 +143,152 @@ public function testPrepareProduct() } } } + + /** + * Test adding grouped product to cart when one of subproducts is out of stock. + * + * @magentoDataFixture Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php + * @magentoAppArea frontend + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + * @dataProvider outOfStockSubProductDataProvider + * @param bool $outOfStockShown + * @param array $data + * @param array $expected + */ + public function testOutOfStockSubProduct(bool $outOfStockShown, array $data, array $expected) + { + $this->changeConfigValue(Configuration::XML_PATH_SHOW_OUT_OF_STOCK, $outOfStockShown); + $buyRequest = new \Magento\Framework\DataObject($data); + $productRepository = $this->objectManager->create(ProductRepositoryInterface::class); + /** @var Product $product */ + $product = $productRepository->get('grouped-product'); + /** @var Grouped $groupedProduct */ + $groupedProduct = $this->objectManager->get(Grouped::class); + $actual = $groupedProduct->prepareForCartAdvanced($buyRequest, $product, Grouped::PROCESS_MODE_FULL); + self::assertEquals( + count($expected), + count($actual) + ); + /** @var Product $product */ + foreach ($actual as $product) { + $sku = $product->getSku(); + self::assertEquals( + $expected[$sku], + $product->getCartQty(), + "Failed asserting that Product Cart Quantity matches expected" + ); + } + } + + /** + * Data provider for testOutOfStockSubProduct. + * + * @return array + */ + public function outOfStockSubProductDataProvider() + { + return [ + 'Out of stock product are shown #1' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4 + ], + ], + 'Out of stock product are shown #2' => [ + true, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + 'Out of stock product are hidden #1' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 4, + 21 => 5, + ], + ], + [ + 'virtual-product' => 5, + 'simple' => 4, + ], + ], + 'Out of stock product are hidden #2' => [ + false, + [ + 'product' => 3, + 'qty' => 1, + 'super_group' => [ + 1 => 0, + ], + ], + [ + 'virtual-product' => 2.5, // This is a default quantity. + ], + ], + ]; + } + + /** + * Write config value to database. + * + * @param string $path + * @param string $value + * @param string $scope + * @param int $scopeId + */ + private function changeConfigValue(string $path, string $value, string $scope = 'default', int $scopeId = 0) + { + $configValue = $this->objectManager->create(Value::class); + $configValue->setPath($path) + ->setValue($value) + ->setScope($scope) + ->setScopeId($scopeId) + ->save(); + $this->reinitConfig(); + } + + /** + * Delete config value from database. + * + * @param string $path + */ + private function dropConfigValue(string $path) + { + $configValue = $this->objectManager->create(Value::class); + try { + $configValue->load($path, 'path'); + $configValue->delete(); + } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { + // do nothing + } + $this->reinitConfig(); + } + + /** + * Reinit config. + */ + private function reinitConfig() + { + $this->reinitableConfig->reinit(); + } } diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php new file mode 100644 index 0000000000000..7aa62b149b8c0 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock.php @@ -0,0 +1,75 @@ +\get(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId( + \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE +)->setAttributeSetId( + 4 +)->setWebsiteIds( + [1] +)->setName( + 'Grouped Product' +)->setSku( + 'grouped-product' +)->setPrice( + 100 +)->setTaxClassId( + 0 +)->setVisibility( + \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH +)->setStatus( + \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED +); + +$newLinks = []; +$productLinkFactory = $objectManager->get(\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory::class); + +/** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ +$productLink = $productLinkFactory->create(); +$linkedProduct = $productRepository->getById(1); +$productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($linkedProduct->getSku()) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->setPosition(1) + ->getExtensionAttributes() + ->setQty(1); +$newLinks[] = $productLink; + +$subProductsSkus = ['virtual-product', 'virtual-product-out']; +foreach ($subProductsSkus as $sku) { + /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $productLink */ + $productLink = $productLinkFactory->create(); + $linkedProduct = $productRepository->get($sku); + $productLink->setSku($product->getSku()) + ->setLinkType('associated') + ->setLinkedProductSku($sku) + ->setLinkedProductType($linkedProduct->getTypeId()) + ->getExtensionAttributes() + ->setQty(2.5); + $newLinks[] = $productLink; +} +$product->setProductLinks($newLinks); +$product->save(); + +/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */ +$categoryLinkManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); + +$categoryLinkManagement->assignProductToCategories( + $product->getSku(), + [2] +); diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php new file mode 100644 index 0000000000000..48e7d495f8985 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_with_out_of_stock_rollback.php @@ -0,0 +1,10 @@ +\setValue( 'general/country/allow', 'US', - \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES + \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); $quote = $this->objectManager->create(Quote::class); $quote->load('quote123', 'reserved_order_id'); diff --git a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php index a7f859b23dfa2..b44ef7aa20c6a 100644 --- a/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Review/Model/ResourceModel/Review/Product/CollectionTest.php @@ -3,20 +3,89 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Review\Model\ResourceModel\Review\Product; +use Magento\Review\Model\Review; +use Magento\TestFramework\Helper\Bootstrap; + +/** + * Tests some functionality of the Product Review collection + */ class CollectionTest extends \PHPUnit\Framework\TestCase { /** + * Checks resulting ids count + * + * @param int $status + * @param int $expectedCount + * @param string $sortAttribute + * @param string $dir + * @param callable $assertion + * @dataProvider sortOrderAssertionsDataProvider * @magentoDataFixture Magento/Review/_files/different_reviews.php */ - public function testGetResultingIds() - { - $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - \Magento\Review\Model\ResourceModel\Review\Product\Collection::class - ); - $collection->addStatusFilter(\Magento\Review\Model\Review::STATUS_APPROVED); + public function testGetResultingIds( + int $status, + int $expectedCount, + string $sortAttribute, + string $dir, + callable $assertion + ) { + $collection = Bootstrap::getObjectManager()->create(Collection::class); + if ($status > 0) { + $collection->addStatusFilter($status); + } + $collection->setOrder($sortAttribute, $dir); $actual = $collection->getResultingIds(); - $this->assertCount(2, $actual); + $this->assertCount($expectedCount, $actual); + $assertion($actual); + } + + /** + * Sort order assertions data provider + * + * @return array + */ + public function sortOrderAssertionsDataProvider(): array + { + return [ + [ + Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'DESC', + function (array $actual) { + $this->assertLessThan($actual[0], $actual[1]); + } + ], + [ + Review::STATUS_APPROVED, + 2, + 'rt.review_id', + 'ASC', + function (array $actual) { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + Review::STATUS_APPROVED, + 2, + 'rt.created_at', + 'ASC', + function (array $actual) { + $this->assertLessThan($actual[1], $actual[0]); + } + ], + [ + 0, + 3, + 'rt.review_id', + 'ASC', + function (array $actual) { + $this->assertLessThan($actual[1], $actual[0]); + } + ] + ]; } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php index 4b904cc2b55bd..bba4d67ddd108 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ErrorHandlerTest.php @@ -56,9 +56,9 @@ public function testHandlerException($errorNo, $errorPhrase) $errorFile = 'test_file'; $errorLine = 'test_error_line'; - $exceptedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); + $expectedExceptionMessage = sprintf('%s: %s in %s on line %s', $errorPhrase, $errorStr, $errorFile, $errorLine); $this->expectException('Exception'); - $this->expectExceptionMessage($exceptedExceptionMessage); + $this->expectExceptionMessage($expectedExceptionMessage); $this->object->handler($errorNo, $errorStr, $errorFile, $errorLine); } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php index d6b8f677860cc..3b7aacc1afba1 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/Http/FileFactoryTest.php @@ -67,7 +67,7 @@ public function testCreateIfContentDoesntHaveRequiredKeys() /** * @expectedException \Exception - * @exceptedExceptionMessage File not found + * @expectedExceptionMessage File not found */ public function testCreateIfFileNotExist() { diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php index 807a70ecd7599..f39a91161c1f5 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ViewTest.php @@ -122,7 +122,7 @@ public function testGetLayout() /** * @expectedException \RuntimeException - * @exceptedExceptionMessage 'Layout must be loaded only once.' + * @expectedExceptionMessage Layout must be loaded only once. */ public function testLoadLayoutWhenLayoutAlreadyLoaded() { diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php index 66b1299b98696..90482ab55fc71 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Fieldset.php @@ -43,7 +43,8 @@ public function __construct( */ public function getElementHtml() { - $html = '