diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
index 5f8be83872021..a32379b8c0a67 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
@@ -34,13 +34,6 @@ class TableBuilder
*/
private $tableBuilderFactory;
- /**
- * Check whether builder was executed
- *
- * @var bool
- */
- protected $_isExecuted = false;
-
/**
* Constructor
*
@@ -70,9 +63,6 @@ public function __construct(
*/
public function build($storeId, $changedIds, $valueFieldSuffix)
{
- if ($this->_isExecuted) {
- return;
- }
$entityTableName = $this->_productIndexerHelper->getTable('catalog_product_entity');
$attributes = $this->_productIndexerHelper->getAttributes();
$eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
@@ -117,7 +107,6 @@ public function build($storeId, $changedIds, $valueFieldSuffix)
//Fill temporary tables with attributes grouped by it type
$this->_fillTemporaryTable($tableName, $columns, $changedIds, $valueFieldSuffix, $storeId);
}
- $this->_isExecuted = true;
}
/**
diff --git a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
index de996bed02439..bf0884a8c83ea 100644
--- a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
+++ b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
@@ -6,10 +6,14 @@
namespace Magento\Checkout\Block\Checkout;
use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;
+use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Helper\Address as AddressHelper;
use Magento\Customer\Model\Session;
use Magento\Directory\Helper\Data as DirectoryHelper;
+/**
+ * Fields attribute merger.
+ */
class AttributeMerger
{
/**
@@ -46,6 +50,7 @@ class AttributeMerger
'alpha' => 'validate-alpha',
'numeric' => 'validate-number',
'alphanumeric' => 'validate-alphanum',
+ 'alphanum-with-spaces' => 'validate-alphanum-with-spaces',
'url' => 'validate-url',
'email' => 'email2',
'length' => 'validate-length',
@@ -67,7 +72,7 @@ class AttributeMerger
private $customerRepository;
/**
- * @var \Magento\Customer\Api\Data\CustomerInterface
+ * @var CustomerInterface
*/
private $customer;
@@ -309,6 +314,8 @@ protected function getMultilineFieldConfig($attributeCode, array $attributeConfi
}
/**
+ * Returns default attribute value.
+ *
* @param string $attributeCode
* @return null|string
*/
@@ -346,7 +353,9 @@ protected function getDefaultValue($attributeCode)
}
/**
- * @return \Magento\Customer\Api\Data\CustomerInterface|null
+ * Returns logged customer.
+ *
+ * @return CustomerInterface|null
*/
protected function getCustomer()
{
diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
index d8142d033f78c..d6fe3ece473df 100644
--- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
@@ -98,8 +98,8 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
* @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
* @param \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector
- * @param CartExtensionFactory|null $cartExtensionFactory,
- * @param ShippingAssignmentFactory|null $shippingAssignmentFactory,
+ * @param CartExtensionFactory|null $cartExtensionFactory
+ * @param ShippingAssignmentFactory|null $shippingAssignmentFactory
* @param ShippingFactory|null $shippingFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
@@ -150,6 +150,10 @@ public function saveAddressInformation(
$address->setCustomerAddressId(null);
}
+ if ($billingAddress && !$billingAddress->getCustomerAddressId()) {
+ $billingAddress->setCustomerAddressId(null);
+ }
+
if (!$address->getCountryId()) {
throw new StateException(__('Shipping address is not set'));
}
@@ -203,6 +207,8 @@ protected function validateQuote(\Magento\Quote\Model\Quote $quote)
}
/**
+ * Prepare shipping assignment.
+ *
* @param CartInterface $quote
* @param AddressInterface $address
* @param string $method
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillingShippingSectionActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillingShippingSectionActionGroup.xml
index 8ff84e7a436e5..19aeeef8e2bc0 100644
--- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillingShippingSectionActionGroup.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/GuestCheckoutFillingShippingSectionActionGroup.xml
@@ -32,4 +32,13 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/LoggedInUserCheckoutAddNewAddressInShippingSectionActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/LoggedInUserCheckoutAddNewAddressInShippingSectionActionGroup.xml
index 722e6f1ee49ab..9c4d16ff500a0 100644
--- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/LoggedInUserCheckoutAddNewAddressInShippingSectionActionGroup.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/LoggedInUserCheckoutAddNewAddressInShippingSectionActionGroup.xml
@@ -7,7 +7,7 @@
-->
+ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
@@ -21,6 +21,14 @@
-
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
index e0e9ec638a763..70640ea8cd3ec 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutPaymentSection.xml
@@ -42,5 +42,6 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
index 2a7437c44eccf..55d8362e27483 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml
new file mode 100644
index 0000000000000..a4583fb7fa50c
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontCustomerCheckoutTestWithRestrictedCountriesForPaymentTest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml
new file mode 100644
index 0000000000000..354974bf1ef53
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/StorefrontGuestCheckoutTestWithRestrictedCountriesForPaymentTest.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Checkout/AttributeMergerTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/AttributeMergerTest.php
new file mode 100644
index 0000000000000..bff2243f30d03
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/AttributeMergerTest.php
@@ -0,0 +1,122 @@
+customerRepositoryMock = $this->createMock(CustomerRepository::class);
+ $this->customerSessionMock = $this->createMock(CustomerSession::class);
+ $this->addressHelperMock = $this->createMock(AddressHelper::class);
+ $this->directoryHelperMock = $this->createMock(DirectoryHelper::class);
+
+ $this->attributeMerger = new AttributeMerger(
+ $this->addressHelperMock,
+ $this->customerSessionMock,
+ $this->customerRepositoryMock,
+ $this->directoryHelperMock
+ );
+ }
+
+ /**
+ * Tests of element attributes merging.
+ *
+ * @param string $validationRule
+ * @param string $expectedValidation
+ * @return void
+ * @dataProvider validationRulesDataProvider
+ */
+ public function testMerge($validationRule, $expectedValidation)
+ {
+ $elements = [
+ 'field' => [
+ 'visible' => true,
+ 'formElement' => 'input',
+ 'label' => __('City'),
+ 'value' => null,
+ 'sortOrder' => 1,
+ 'validation' => [
+ 'input_validation' => $validationRule,
+ ],
+ ]
+ ];
+
+ $actualResult = $this->attributeMerger->merge(
+ $elements,
+ 'provider',
+ 'dataScope',
+ [
+ 'field' =>
+ [
+ 'validation' => ['length' => true],
+ ],
+ ]
+ );
+
+ $expectedResult = [
+ $expectedValidation => true,
+ 'length' => true,
+ ];
+
+ $this->assertEquals($expectedResult, $actualResult['field']['validation']);
+ }
+
+ /**
+ * Provides possible validation types.
+ *
+ * @return array
+ */
+ public function validationRulesDataProvider(): array
+ {
+ return [
+ ['alpha', 'validate-alpha'],
+ ['numeric', 'validate-number'],
+ ['alphanumeric', 'validate-alphanum'],
+ ['alphanum-with-spaces', 'validate-alphanum-with-spaces'],
+ ['url', 'validate-url'],
+ ['email', 'email2'],
+ ['length', 'validate-length'],
+ ];
+ }
+}
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
index df50a5ae94ae9..b4997f9664c81 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
@@ -247,6 +247,7 @@ define([
*/
setShippingInformation: function () {
if (this.validateShippingInformation()) {
+ quote.billingAddress(null);
checkoutDataResolver.resolveBillingAddress();
setShippingInformationAction().done(
function () {
diff --git a/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/tier_price.phtml b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/tier_price.phtml
index 18f96cfaaf398..325ee1d5d79b3 100644
--- a/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/tier_price.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/tier_price.phtml
@@ -15,10 +15,13 @@
+ ''
+ ''; %>
- <%= $t('Buy %1 for %2 each and').replace('%1', item.qty).replace('%2', priceStr) %>
-
- <%= $t('save') %> <%= item.percentage %>%
-
+ <%= '= $block->escapeHtml(__('Buy %1 for %2 each and', '%1', '%2')) ?>'
+ .replace('%1', item.qty)
+ .replace('%2', priceStr) %>
+
+ = $block->escapeHtml(__('save')) ?> <%= item.percentage %>%
+
<% }); %>
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php b/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
index f28cce0ea2ae1..0e4fc68503122 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
@@ -1,7 +1,5 @@
setMessage(__('"%1" invalid type entered.', $label), \Zend_Validate_Alnum::INVALID);
$validator->setMessage(
__('"%1" contains non-alphabetic or non-numeric characters.', $label),
diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
index 4eea31665fe69..b55f9bf3df021 100644
--- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
@@ -101,6 +101,7 @@
SE1 7RW
GB
+ United Kingdom
444-44-444-44
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/AbstractDataTest.php b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/AbstractDataTest.php
index e4dc22ba40e31..667fc87b6a82b 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/AbstractDataTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Metadata/Form/AbstractDataTest.php
@@ -205,6 +205,8 @@ public function applyOutputFilterDataProvider()
}
/**
+ * Tests input validation rules.
+ *
* @param null|string $value
* @param null|string $label
* @param null|string $inputValidation
@@ -217,25 +219,18 @@ public function testValidateInputRule($value, $label, $inputValidation, $expecte
->disableOriginalConstructor()
->setMethods(['getName', 'getValue'])
->getMockForAbstractClass();
- $validationRule->expects($this->any())
- ->method('getName')
- ->will($this->returnValue('input_validation'));
- $validationRule->expects($this->any())
- ->method('getValue')
- ->will($this->returnValue($inputValidation));
-
- $this->_attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue($label));
- $this->_attributeMock->expects(
- $this->any()
- )->method(
- 'getValidationRules'
- )->will(
- $this->returnValue(
- [
- $validationRule,
- ]
- )
- );
+
+ $validationRule->method('getName')
+ ->willReturn('input_validation');
+
+ $validationRule->method('getValue')
+ ->willReturn($inputValidation);
+
+ $this->_attributeMock->method('getStoreLabel')
+ ->willReturn($label);
+
+ $this->_attributeMock->method('getValidationRules')
+ ->willReturn([$validationRule]);
$this->assertEquals($expectedOutput, $this->_model->validateInputRule($value));
}
@@ -256,6 +251,16 @@ public function validateInputRuleDataProvider()
\Zend_Validate_Alnum::NOT_ALNUM => '"mylabel" contains non-alphabetic or non-numeric characters.'
]
],
+ [
+ 'abc qaz',
+ 'mylabel',
+ 'alphanumeric',
+ [
+ \Zend_Validate_Alnum::NOT_ALNUM => '"mylabel" contains non-alphabetic or non-numeric characters.',
+ ],
+ ],
+ ['abcqaz', 'mylabel', 'alphanumeric', true],
+ ['abc qaz', 'mylabel', 'alphanum-with-spaces', true],
[
'!@#$',
'mylabel',
diff --git a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ValidationRulesTest.php b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ValidationRulesTest.php
index 130b3acd11e76..b57bc53ef09f9 100644
--- a/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ValidationRulesTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Ui/Component/Listing/Column/ValidationRulesTest.php
@@ -18,12 +18,6 @@ class ValidationRulesTest extends \PHPUnit\Framework\TestCase
protected function setUp()
{
- $this->validationRules = $this->getMockBuilder(
- \Magento\Customer\Ui\Component\Listing\Column\ValidationRules::class
- )
- ->disableOriginalConstructor()
- ->getMock();
-
$this->validationRule = $this->getMockBuilder(\Magento\Customer\Api\Data\ValidationRuleInterface::class)
->disableOriginalConstructor()
->getMock();
@@ -31,18 +25,25 @@ protected function setUp()
$this->validationRules = new ValidationRules();
}
- public function testGetValidationRules()
+ /**
+ * Tests input validation rules.
+ *
+ * @param string $validationRule
+ * @param string $validationClass
+ * @return void
+ * @dataProvider validationRulesDataProvider
+ */
+ public function testGetValidationRules(string $validationRule, string $validationClass)
{
$expectsRules = [
'required-entry' => true,
- 'validate-number' => true,
+ $validationClass => true,
];
- $this->validationRule->expects($this->atLeastOnce())
- ->method('getName')
+ $this->validationRule->method('getName')
->willReturn('input_validation');
- $this->validationRule->expects($this->atLeastOnce())
- ->method('getValue')
- ->willReturn('numeric');
+
+ $this->validationRule->method('getValue')
+ ->willReturn($validationRule);
$this->assertEquals(
$expectsRules,
@@ -66,4 +67,21 @@ public function testGetValidationRulesWithOnlyRequiredRule()
$this->validationRules->getValidationRules(true, [])
);
}
+
+ /**
+ * Provides possible validation rules.
+ *
+ * @return array
+ */
+ public function validationRulesDataProvider(): array
+ {
+ return [
+ ['alpha', 'validate-alpha'],
+ ['numeric', 'validate-number'],
+ ['alphanumeric', 'validate-alphanum'],
+ ['alphanum-with-spaces', 'validate-alphanum-with-spaces'],
+ ['url', 'validate-url'],
+ ['email', 'validate-email'],
+ ];
+ }
}
diff --git a/app/code/Magento/Customer/Ui/Component/Listing/Column/ValidationRules.php b/app/code/Magento/Customer/Ui/Component/Listing/Column/ValidationRules.php
index b8f83421a6d62..6befec8e942a1 100644
--- a/app/code/Magento/Customer/Ui/Component/Listing/Column/ValidationRules.php
+++ b/app/code/Magento/Customer/Ui/Component/Listing/Column/ValidationRules.php
@@ -7,6 +7,9 @@
use Magento\Customer\Api\Data\ValidationRuleInterface;
+/**
+ * Provides validation classes according to corresponding rules.
+ */
class ValidationRules
{
/**
@@ -16,6 +19,7 @@ class ValidationRules
'alpha' => 'validate-alpha',
'numeric' => 'validate-number',
'alphanumeric' => 'validate-alphanum',
+ 'alphanum-with-spaces' => 'validate-alphanum-with-spaces',
'url' => 'validate-url',
'email' => 'validate-email',
];
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
index 12023acc3b33b..f4bcdf7764d95 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
@@ -144,7 +144,8 @@ public function setRequestScope($scope)
}
/**
- * Set scope visibility
+ * Set scope visibility.
+ *
* Search value only in scope or search value in scope and global
*
* @param bool $flag
@@ -313,9 +314,13 @@ protected function _validateInputRule($value)
if (!empty($validateRules['input_validation'])) {
$label = $this->getAttribute()->getStoreLabel();
+ $allowWhiteSpace = false;
switch ($validateRules['input_validation']) {
+ case 'alphanum-with-spaces':
+ $allowWhiteSpace = true;
+ // continue to alphanumeric validation
case 'alphanumeric':
- $validator = new \Zend_Validate_Alnum(true);
+ $validator = new \Zend_Validate_Alnum($allowWhiteSpace);
$validator->setMessage(__('"%1" invalid type entered.', $label), \Zend_Validate_Alnum::INVALID);
$validator->setMessage(
__('"%1" contains non-alphabetic or non-numeric characters.', $label),
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Frontend/AbstractFrontend.php b/app/code/Magento/Eav/Model/Entity/Attribute/Frontend/AbstractFrontend.php
index 13c0b7a627edb..cd7639080509f 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Frontend/AbstractFrontend.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Frontend/AbstractFrontend.php
@@ -20,6 +20,8 @@
use Magento\Eav\Model\Entity\Attribute\Source\BooleanFactory;
/**
+ * EAV entity attribute form renderer.
+ *
* @api
* @since 100.0.2
*/
@@ -234,6 +236,9 @@ protected function _getInputValidateClass()
case 'alphanumeric':
$class = 'validate-alphanum';
break;
+ case 'alphanum-with-spaces':
+ $class = 'validate-alphanum-with-spaces';
+ break;
case 'numeric':
$class = 'validate-digits';
break;
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
index 217a04045b939..8b16d286471b4 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Attribute/Data/TextTest.php
@@ -6,22 +6,24 @@
namespace Magento\Eav\Test\Unit\Model\Attribute\Data;
+use Magento\Framework\Stdlib\StringUtils;
+
class TextTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Magento\Eav\Model\Attribute\Data\Text
*/
- protected $_model;
+ private $model;
protected function setUp()
{
$locale = $this->createMock(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class);
$localeResolver = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class);
$logger = $this->createMock(\Psr\Log\LoggerInterface::class);
- $helper = $this->createMock(\Magento\Framework\Stdlib\StringUtils::class);
+ $helper = new StringUtils;
- $this->_model = new \Magento\Eav\Model\Attribute\Data\Text($locale, $logger, $localeResolver, $helper);
- $this->_model->setAttribute(
+ $this->model = new \Magento\Eav\Model\Attribute\Data\Text($locale, $logger, $localeResolver, $helper);
+ $this->model->setAttribute(
$this->createAttribute(
[
'store_label' => 'Test',
@@ -35,24 +37,39 @@ protected function setUp()
protected function tearDown()
{
- $this->_model = null;
+ $this->model = null;
}
+ /**
+ * Test of string validation.
+ *
+ * @return void
+ */
public function testValidateValueString()
{
$inputValue = '0';
$expectedResult = true;
- $this->assertEquals($expectedResult, $this->_model->validateValue($inputValue));
+ $this->assertEquals($expectedResult, $this->model->validateValue($inputValue));
}
+ /**
+ * Test of integer validation.
+ *
+ * @return void
+ */
public function testValidateValueInteger()
{
$inputValue = 0;
$expectedResult = ['"Test" is a required value.'];
- $result = $this->_model->validateValue($inputValue);
+ $result = $this->model->validateValue($inputValue);
$this->assertEquals($expectedResult, [(string)$result[0]]);
}
+ /**
+ * Test without length validation.
+ *
+ * @return void
+ */
public function testWithoutLengthValidation()
{
$expectedResult = true;
@@ -64,12 +81,109 @@ public function testWithoutLengthValidation()
];
$defaultAttributeData['validate_rules']['min_text_length'] = 2;
- $this->_model->setAttribute($this->createAttribute($defaultAttributeData));
- $this->assertEquals($expectedResult, $this->_model->validateValue('t'));
+ $this->model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->model->validateValue('t'));
$defaultAttributeData['validate_rules']['max_text_length'] = 3;
- $this->_model->setAttribute($this->createAttribute($defaultAttributeData));
- $this->assertEquals($expectedResult, $this->_model->validateValue('test'));
+ $this->model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->model->validateValue('test'));
+ }
+
+ /**
+ * Test of alphanumeric validation.
+ *
+ * @param string $value
+ * @param bool|array $expectedResult
+ * @return void
+ * @dataProvider alphanumDataProvider
+ */
+ public function testAlphanumericValidation(string $value, $expectedResult)
+ {
+ $defaultAttributeData = [
+ 'store_label' => 'Test',
+ 'attribute_code' => 'test',
+ 'is_required' => 1,
+ 'validate_rules' => [
+ 'min_text_length' => 0,
+ 'max_text_length' => 10,
+ 'input_validation' => 'alphanumeric',
+ ],
+ ];
+
+ $this->model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->model->validateValue($value));
+ }
+
+ /**
+ * Provides possible input values.
+ *
+ * @return array
+ */
+ public function alphanumDataProvider(): array
+ {
+ return [
+ ['QazWsx', true],
+ ['QazWsx123', true],
+ [
+ 'QazWsx 123',
+ [\Zend_Validate_Alnum::NOT_ALNUM => '"Test" contains non-alphabetic or non-numeric characters.'],
+ ],
+ [
+ 'QazWsx_123',
+ [\Zend_Validate_Alnum::NOT_ALNUM => '"Test" contains non-alphabetic or non-numeric characters.'],
+ ],
+ [
+ 'QazWsx12345',
+ [__('"%1" length must be equal or less than %2 characters.', 'Test', 10)],
+ ],
+ ];
+ }
+
+ /**
+ * Test of alphanumeric validation with spaces.
+ *
+ * @param string $value
+ * @param bool|array $expectedResult
+ * @return void
+ * @dataProvider alphanumWithSpacesDataProvider
+ */
+ public function testAlphanumericValidationWithSpaces(string $value, $expectedResult)
+ {
+ $defaultAttributeData = [
+ 'store_label' => 'Test',
+ 'attribute_code' => 'test',
+ 'is_required' => 1,
+ 'validate_rules' => [
+ 'min_text_length' => 0,
+ 'max_text_length' => 10,
+ 'input_validation' => 'alphanum-with-spaces',
+ ],
+ ];
+
+ $this->model->setAttribute($this->createAttribute($defaultAttributeData));
+ $this->assertEquals($expectedResult, $this->model->validateValue($value));
+ }
+
+ /**
+ * Provides possible input values.
+ *
+ * @return array
+ */
+ public function alphanumWithSpacesDataProvider(): array
+ {
+ return [
+ ['QazWsx', true],
+ ['QazWsx123', true],
+ ['QazWsx 123', true],
+ [
+ 'QazWsx_123',
+ [\Zend_Validate_Alnum::NOT_ALNUM => '"Test" contains non-alphabetic or non-numeric characters.'],
+ ],
+ [
+ 'QazWsx12345',
+ [__('"%1" length must be equal or less than %2 characters.', 'Test', 10)],
+ ],
+ ];
}
/**
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Frontend/DefaultFrontendTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Frontend/DefaultFrontendTest.php
index a61c9ef447458..2c5b1aeb7bbfd 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Frontend/DefaultFrontendTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Frontend/DefaultFrontendTest.php
@@ -13,41 +13,42 @@
use Magento\Framework\App\CacheInterface;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Eav\Model\Entity\Attribute\Source\AbstractSource;
+use PHPUnit\Framework\MockObject\MockObject;
class DefaultFrontendTest extends \PHPUnit\Framework\TestCase
{
/**
* @var DefaultFrontend
*/
- protected $model;
+ private $model;
/**
- * @var BooleanFactory|\PHPUnit_Framework_MockObject_MockObject
+ * @var BooleanFactory|MockObject
*/
- protected $booleanFactory;
+ private $booleanFactory;
/**
- * @var Serializer|\PHPUnit_Framework_MockObject_MockObject
+ * @var Serializer|MockObject
*/
private $serializerMock;
/**
- * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var StoreManagerInterface|MockObject
*/
private $storeManagerMock;
/**
- * @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var StoreInterface|MockObject
*/
private $storeMock;
/**
- * @var CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+ * @var CacheInterface|MockObject
*/
private $cacheMock;
/**
- * @var AbstractAttribute|\PHPUnit_Framework_MockObject_MockObject
+ * @var AbstractAttribute|MockObject
*/
private $attributeMock;
@@ -57,7 +58,7 @@ class DefaultFrontendTest extends \PHPUnit\Framework\TestCase
private $cacheTags;
/**
- * @var AbstractSource|\PHPUnit_Framework_MockObject_MockObject
+ * @var AbstractSource|MockObject
*/
private $sourceMock;
@@ -76,44 +77,31 @@ protected function setUp()
->getMockForAbstractClass();
$this->cacheMock = $this->getMockBuilder(CacheInterface::class)
->getMockForAbstractClass();
- $this->attributeMock = $this->getMockBuilder(AbstractAttribute::class)
- ->disableOriginalConstructor()
- ->setMethods(['getAttributeCode', 'getSource'])
- ->getMockForAbstractClass();
+ $this->attributeMock = $this->createAttributeMock();
$this->sourceMock = $this->getMockBuilder(AbstractSource::class)
->disableOriginalConstructor()
->setMethods(['getAllOptions'])
->getMockForAbstractClass();
- $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
- $this->model = $objectManager->getObject(
- DefaultFrontend::class,
- [
- '_attrBooleanFactory' => $this->booleanFactory,
- 'cache' => $this->cacheMock,
- 'storeManager' => $this->storeManagerMock,
- 'serializer' => $this->serializerMock,
- '_attribute' => $this->attributeMock,
- 'cacheTags' => $this->cacheTags
- ]
+ $this->model = new DefaultFrontend(
+ $this->booleanFactory,
+ $this->cacheMock,
+ null,
+ $this->cacheTags,
+ $this->storeManagerMock,
+ $this->serializerMock
);
+
+ $this->model->setAttribute($this->attributeMock);
}
public function testGetClassEmpty()
{
- $attributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
- ->disableOriginalConstructor()
- ->setMethods([
- 'getIsRequired',
- 'getFrontendClass',
- 'getValidateRules',
- ])
- ->getMock();
- $attributeMock->expects($this->once())
- ->method('getIsRequired')
+ /** @var AbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->createAttributeMock();
+ $attributeMock->method('getIsRequired')
->willReturn(false);
- $attributeMock->expects($this->once())
- ->method('getFrontendClass')
+ $attributeMock->method('getFrontendClass')
->willReturn('');
$attributeMock->expects($this->exactly(2))
->method('getValidateRules')
@@ -123,26 +111,26 @@ public function testGetClassEmpty()
$this->assertEmpty($this->model->getClass());
}
- public function testGetClass()
+ /**
+ * Validates generated html classes.
+ *
+ * @param string $validationRule
+ * @param string $expectedClass
+ * @return void
+ * @dataProvider validationRulesDataProvider
+ */
+ public function testGetClass(string $validationRule, string $expectedClass)
{
- $attributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
- ->disableOriginalConstructor()
- ->setMethods([
- 'getIsRequired',
- 'getFrontendClass',
- 'getValidateRules',
- ])
- ->getMock();
- $attributeMock->expects($this->once())
- ->method('getIsRequired')
+ /** @var AbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->createAttributeMock();
+ $attributeMock->method('getIsRequired')
->willReturn(true);
- $attributeMock->expects($this->once())
- ->method('getFrontendClass')
+ $attributeMock->method('getFrontendClass')
->willReturn('');
$attributeMock->expects($this->exactly(3))
->method('getValidateRules')
->willReturn([
- 'input_validation' => 'alphanumeric',
+ 'input_validation' => $validationRule,
'min_text_length' => 1,
'max_text_length' => 2,
]);
@@ -150,7 +138,7 @@ public function testGetClass()
$this->model->setAttribute($attributeMock);
$result = $this->model->getClass();
- $this->assertContains('validate-alphanum', $result);
+ $this->assertContains($expectedClass, $result);
$this->assertContains('minimum-length-1', $result);
$this->assertContains('maximum-length-2', $result);
$this->assertContains('validate-length', $result);
@@ -158,19 +146,11 @@ public function testGetClass()
public function testGetClassLength()
{
- $attributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
- ->disableOriginalConstructor()
- ->setMethods([
- 'getIsRequired',
- 'getFrontendClass',
- 'getValidateRules',
- ])
- ->getMock();
- $attributeMock->expects($this->once())
- ->method('getIsRequired')
+ /** @var AbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->createAttributeMock();
+ $attributeMock->method('getIsRequired')
->willReturn(true);
- $attributeMock->expects($this->once())
- ->method('getFrontendClass')
+ $attributeMock->method('getFrontendClass')
->willReturn('');
$attributeMock->expects($this->exactly(3))
->method('getValidateRules')
@@ -196,33 +176,62 @@ public function testGetSelectOptions()
$options = ['option1', 'option2'];
$serializedOptions = "{['option1', 'option2']}";
- $this->storeManagerMock->expects($this->once())
- ->method('getStore')
+ $this->storeManagerMock->method('getStore')
->willReturn($this->storeMock);
- $this->storeMock->expects($this->once())
- ->method('getId')
+ $this->storeMock->method('getId')
->willReturn($storeId);
- $this->attributeMock->expects($this->once())
- ->method('getAttributeCode')
+ $this->attributeMock->method('getAttributeCode')
->willReturn($attributeCode);
- $this->cacheMock->expects($this->once())
- ->method('load')
+ $this->cacheMock->method('load')
->with($cacheKey)
->willReturn(false);
- $this->attributeMock->expects($this->once())
- ->method('getSource')
+ $this->attributeMock->method('getSource')
->willReturn($this->sourceMock);
- $this->sourceMock->expects($this->once())
- ->method('getAllOptions')
+ $this->sourceMock->method('getAllOptions')
->willReturn($options);
- $this->serializerMock->expects($this->once())
- ->method('serialize')
+ $this->serializerMock->method('serialize')
->with($options)
->willReturn($serializedOptions);
- $this->cacheMock->expects($this->once())
- ->method('save')
+ $this->cacheMock->method('save')
->with($serializedOptions, $cacheKey, $this->cacheTags);
$this->assertSame($options, $this->model->getSelectOptions());
}
+
+ /**
+ * Provides possible validation types.
+ *
+ * @return array
+ */
+ public function validationRulesDataProvider(): array
+ {
+ return [
+ ['alphanumeric', 'validate-alphanum'],
+ ['alphanum-with-spaces', 'validate-alphanum-with-spaces'],
+ ['alpha', 'validate-alpha'],
+ ['numeric', 'validate-digits'],
+ ['url', 'validate-url'],
+ ['email', 'validate-email'],
+ ['length', 'validate-length'],
+ ];
+ }
+
+ /**
+ * Entity attribute factory.
+ *
+ * @return AbstractAttribute|MockObject
+ */
+ private function createAttributeMock()
+ {
+ return $this->getMockBuilder(AbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->setMethods([
+ 'getIsRequired',
+ 'getFrontendClass',
+ 'getValidateRules',
+ 'getAttributeCode',
+ 'getSource'
+ ])
+ ->getMockForAbstractClass();
+ }
}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php
index 12038ee375059..88e05a80f3797 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php
@@ -9,17 +9,27 @@
use Magento\Backend\App\Action;
use Magento\Sales\Model\Order\Email\Sender\OrderCommentSender;
+/**
+ * Controller to execute Adding Comments.
+ */
class AddComment extends \Magento\Sales\Controller\Adminhtml\Order
{
/**
- * Authorization level of a basic admin session
+ * Authorization level of a basic admin session.
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Magento_Sales::comment';
/**
- * Add order comment action
+ * ACL resource needed to send comment email notification.
+ *
+ * @see _isAllowed()
+ */
+ const ADMIN_SALES_EMAIL_RESOURCE = 'Magento_Sales::emails';
+
+ /**
+ * Add order comment action.
*
* @return \Magento\Framework\Controller\ResultInterface
*/
@@ -33,8 +43,12 @@ public function execute()
throw new \Magento\Framework\Exception\LocalizedException(__('Please enter a comment.'));
}
- $notify = isset($data['is_customer_notified']) ? $data['is_customer_notified'] : false;
- $visible = isset($data['is_visible_on_front']) ? $data['is_visible_on_front'] : false;
+ $notify = $data['is_customer_notified'] ?? false;
+ $visible = $data['is_visible_on_front'] ?? false;
+
+ if ($notify && !$this->_authorization->isAllowed(self::ADMIN_SALES_EMAIL_RESOURCE)) {
+ $notify = false;
+ }
$history = $order->addStatusHistoryComment($data['comment'], $data['status']);
$history->setIsVisibleOnFront($visible);
@@ -59,9 +73,11 @@ public function execute()
if (is_array($response)) {
$resultJson = $this->resultJsonFactory->create();
$resultJson->setData($response);
+
return $resultJson;
}
}
+
return $this->resultRedirectFactory->create()->setPath('sales/*/');
}
}
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 72e90e290f1de..1972aa71080c8 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -12,6 +12,7 @@
use Magento\Framework\Locale\ResolverInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Api\Data\OrderItemInterface;
use Magento\Sales\Api\Data\OrderStatusHistoryInterface;
use Magento\Sales\Model\Order\Payment;
use Magento\Sales\Model\Order\ProductOption;
@@ -750,7 +751,7 @@ public function canComment()
}
/**
- * Retrieve order shipment availability
+ * Retrieve order shipment availability.
*
* @return bool
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -770,13 +771,29 @@ public function canShip()
}
foreach ($this->getAllItems() as $item) {
- if ($item->getQtyToShip() > 0 && !$item->getIsVirtual() && !$item->getLockedDoShip()) {
+ if ($item->getQtyToShip() > 0
+ && !$item->getIsVirtual()
+ && !$item->getLockedDoShip()
+ && !$this->isRefunded($item)
+ ) {
return true;
}
}
+
return false;
}
+ /**
+ * Check if item is refunded.
+ *
+ * @param OrderItemInterface $item
+ * @return bool
+ */
+ private function isRefunded(OrderItemInterface $item): bool
+ {
+ return $item->getQtyRefunded() == $item->getQtyOrdered();
+ }
+
/**
* Retrieve order edit availability
*
diff --git a/app/code/Magento/Sales/Model/ResourceModel/Order/Handler/State.php b/app/code/Magento/Sales/Model/ResourceModel/Order/Handler/State.php
index 3b127abbda732..f18118447f95f 100644
--- a/app/code/Magento/Sales/Model/ResourceModel/Order/Handler/State.php
+++ b/app/code/Magento/Sales/Model/ResourceModel/Order/Handler/State.php
@@ -9,12 +9,12 @@
use Magento\Sales\Model\Order;
/**
- * Class State
+ * Class to check order State.
*/
class State
{
/**
- * Check order status before save
+ * Check order status and adjust the status before save.
*
* @param Order $order
* @return $this
@@ -23,25 +23,23 @@ class State
*/
public function check(Order $order)
{
- if (!$order->isCanceled() && !$order->canUnhold() && !$order->canInvoice() && !$order->canShip()) {
- if (0 == $order->getBaseGrandTotal() || $order->canCreditmemo()) {
- if ($order->getState() !== Order::STATE_COMPLETE) {
- $order->setState(Order::STATE_COMPLETE)
- ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_COMPLETE));
- }
- } elseif ((float)$order->getTotalRefunded()
- || !$order->getTotalRefunded() && $order->hasForcedCanCreditmemo()
- ) {
- if ($order->getState() !== Order::STATE_CLOSED) {
- $order->setState(Order::STATE_CLOSED)
- ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_CLOSED));
- }
- }
- }
- if ($order->getState() == Order::STATE_NEW && $order->getIsInProcess()) {
+ $currentState = $order->getState();
+ if ($currentState == Order::STATE_NEW && $order->getIsInProcess()) {
$order->setState(Order::STATE_PROCESSING)
->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING));
+ $currentState = Order::STATE_PROCESSING;
+ }
+
+ if (!$order->isCanceled() && !$order->canUnhold() && !$order->canInvoice()) {
+ if (in_array($currentState, [Order::STATE_PROCESSING, Order::STATE_COMPLETE]) && !$order->canCreditmemo()) {
+ $order->setState(Order::STATE_CLOSED)
+ ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_CLOSED));
+ } elseif ($currentState === Order::STATE_PROCESSING && !$order->canShip()) {
+ $order->setState(Order::STATE_COMPLETE)
+ ->setStatus($order->getConfig()->getStateDefaultStatus(Order::STATE_COMPLETE));
+ }
}
+
return $this;
}
}
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontSearchGuestOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontSearchGuestOrderActionGroup.xml
new file mode 100644
index 0000000000000..5a5943da91ce6
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/StorefrontSearchGuestOrderActionGroup.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Data/ConstData.xml b/app/code/Magento/Sales/Test/Mftf/Data/ConstData.xml
new file mode 100644
index 0000000000000..523b13ae99c38
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Data/ConstData.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ Complete
+ Closed
+ Pending
+ Processing
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml
index 157b17940fbb7..9244b77541d2d 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminAbleToShipPartiallyInvoicedItemsTest.xml
@@ -62,6 +62,7 @@
+
@@ -82,6 +83,7 @@
+
@@ -101,6 +103,7 @@
+
@@ -120,6 +123,7 @@
+
@@ -141,6 +145,7 @@
+
@@ -159,6 +164,7 @@
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreditMemoTotalAfterShippingDiscountTest.xml
similarity index 94%
rename from app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml
rename to app/code/Magento/Sales/Test/Mftf/Test/AdminCreditMemoTotalAfterShippingDiscountTest.xml
index 260ed8226f321..2f4271d56038b 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/CreditMemoTotalAfterShippingDiscountTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreditMemoTotalAfterShippingDiscountTest.xml
@@ -7,8 +7,8 @@
-->
-
+ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
+
@@ -97,7 +97,9 @@
-
+
+
+
@@ -115,6 +117,7 @@
+
diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php
new file mode 100644
index 0000000000000..d72121878e350
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/AddCommentTest.php
@@ -0,0 +1,186 @@
+contextMock = $this->createMock(\Magento\Backend\App\Action\Context::class);
+ $this->requestMock = $this->createMock(\Magento\Framework\App\Request\Http::class);
+ $this->orderRepositoryMock = $this->createMock(\Magento\Sales\Api\OrderRepositoryInterface::class);
+ $this->orderMock = $this->createMock(\Magento\Sales\Model\Order::class);
+ $this->resultRedirectFactoryMock = $this->createMock(\Magento\Backend\Model\View\Result\RedirectFactory::class);
+ $this->resultRedirectMock = $this->createMock(\Magento\Backend\Model\View\Result\Redirect::class);
+ $this->authorizationMock = $this->createMock(\Magento\Framework\AuthorizationInterface::class);
+ $this->statusHistoryCommentMock = $this->createMock(\Magento\Sales\Model\Order\Status\History::class);
+ $this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class);
+
+ $this->contextMock->expects($this->once())->method('getRequest')->willReturn($this->requestMock);
+
+ $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+ $this->addCommentController = $objectManagerHelper->getObject(
+ \Magento\Sales\Controller\Adminhtml\Order\AddComment::class,
+ [
+ 'context' => $this->contextMock,
+ 'orderRepository' => $this->orderRepositoryMock,
+ '_authorization' => $this->authorizationMock,
+ '_objectManager' => $this->objectManagerMock,
+ ]
+ );
+ }
+
+ /**
+ * Test for execute method with different data.
+ *
+ * @param array $historyData
+ * @param bool $userHasResource
+ * @param bool $expectedNotify
+ *
+ * @return void
+ * @dataProvider executeWillNotifyCustomerDataProvider
+ */
+ public function testExecuteWillNotifyCustomer(array $historyData, bool $userHasResource, bool $expectedNotify)
+ {
+ $orderId = 30;
+ $this->requestMock->expects($this->once())->method('getParam')->with('order_id')->willReturn($orderId);
+ $this->orderRepositoryMock->expects($this->once())
+ ->method('get')
+ ->willReturn($this->orderMock);
+ $this->requestMock->expects($this->once())->method('getPost')->with('history')->willReturn($historyData);
+ $this->authorizationMock->expects($this->any())->method('isAllowed')->willReturn($userHasResource);
+ $this->orderMock->expects($this->once())
+ ->method('addStatusHistoryComment')
+ ->willReturn($this->statusHistoryCommentMock);
+ $this->statusHistoryCommentMock->expects($this->once())->method('setIsCustomerNotified')->with($expectedNotify);
+ $this->objectManagerMock->expects($this->once())->method('create')->willReturn(
+ $this->createMock(\Magento\Sales\Model\Order\Email\Sender\OrderCommentSender::class)
+ );
+
+ $this->addCommentController->execute();
+ }
+
+ /**
+ * Data provider for testExecuteWillNotifyCustomer method.
+ *
+ * @return array
+ */
+ public function executeWillNotifyCustomerDataProvider(): array
+ {
+ return [
+ 'User Has Access - Notify True' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'is_customer_notified' => true,
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => true,
+ 'expectedNotify' => true,
+ ],
+ 'User Has Access - Notify False' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'is_customer_notified' => false,
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => true,
+ 'expectedNotify' => false,
+ ],
+ 'User Has Access - Notify Unset' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => true,
+ 'expectedNotify' => false,
+ ],
+ 'User No Access - Notify True' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'is_customer_notified' => true,
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => false,
+ 'expectedNotify' => false,
+ ],
+ 'User No Access - Notify False' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'is_customer_notified' => false,
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => false,
+ 'expectedNotify' => false,
+ ],
+ 'User No Access - Notify Unset' => [
+ 'postData' => [
+ 'comment' => 'Great Product!',
+ 'status' => 'Processing',
+ ],
+ 'userHasResource' => false,
+ 'expectedNotify' => false,
+ ],
+ ];
+ }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Handler/StateTest.php b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Handler/StateTest.php
index e120d613e323c..48f4a282a2be2 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Handler/StateTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/ResourceModel/Order/Handler/StateTest.php
@@ -8,7 +8,7 @@
use Magento\Sales\Model\Order;
/**
- * Class StateTest
+ * Tests for State.
*/
class StateTest extends \PHPUnit\Framework\TestCase
{
@@ -22,9 +22,14 @@ class StateTest extends \PHPUnit\Framework\TestCase
*/
protected $orderMock;
+ /**
+ * @inheritdoc
+ */
protected function setUp()
{
- $this->orderMock = $this->createPartialMock(\Magento\Sales\Model\Order::class, [
+ $this->orderMock = $this->createPartialMock(
+ \Magento\Sales\Model\Order::class,
+ [
'__wakeup',
'getId',
'hasCustomerNoteNotify',
@@ -35,13 +40,12 @@ protected function setUp()
'canShip',
'getBaseGrandTotal',
'canCreditmemo',
- 'getState',
- 'setState',
'getTotalRefunded',
'hasForcedCanCreditmemo',
'getIsInProcess',
'getConfig',
- ]);
+ ]
+ );
$this->orderMock->expects($this->any())
->method('getConfig')
->willReturnSelf();
@@ -53,127 +57,96 @@ protected function setUp()
}
/**
- * test check order - order without id
+ * Test for check method with different states.
+ *
+ * @param bool $isCanceled
+ * @param bool $canUnhold
+ * @param bool $canInvoice
+ * @param bool $canShip
+ * @param int $callCanSkipNum
+ * @param bool $canCreditmemo
+ * @param int $callCanCreditmemoNum
+ * @param string $currentState
+ * @param string $expectedState
+ * @param int $callSetStateNum
+ * @return void
+ * @dataProvider stateCheckDataProvider
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
- public function testCheckOrderEmpty()
- {
- $this->orderMock->expects($this->once())
- ->method('getBaseGrandTotal')
- ->willReturn(100);
- $this->orderMock->expects($this->never())
- ->method('setState');
-
- $this->state->check($this->orderMock);
- }
-
- /**
- * test check order - set state complete
- */
- public function testCheckSetStateComplete()
- {
+ public function testCheck(
+ bool $canCreditmemo,
+ int $callCanCreditmemoNum,
+ bool $canShip,
+ int $callCanSkipNum,
+ string $currentState,
+ string $expectedState = '',
+ bool $isInProcess = false,
+ int $callGetIsInProcessNum = 0,
+ bool $isCanceled = false,
+ bool $canUnhold = false,
+ bool $canInvoice = false
+ ) {
+ $this->orderMock->setState($currentState);
$this->orderMock->expects($this->any())
- ->method('getId')
- ->will($this->returnValue(1));
- $this->orderMock->expects($this->once())
->method('isCanceled')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canUnhold')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canInvoice')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canShip')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('getBaseGrandTotal')
- ->will($this->returnValue(100));
- $this->orderMock->expects($this->once())
- ->method('canCreditmemo')
- ->will($this->returnValue(true));
- $this->orderMock->expects($this->exactly(2))
- ->method('getState')
- ->will($this->returnValue(Order::STATE_PROCESSING));
- $this->orderMock->expects($this->once())
- ->method('setState')
- ->with(Order::STATE_COMPLETE)
- ->will($this->returnSelf());
- $this->assertEquals($this->state, $this->state->check($this->orderMock));
- }
-
- /**
- * test check order - set state closed
- */
- public function testCheckSetStateClosed()
- {
+ ->willReturn($isCanceled);
$this->orderMock->expects($this->any())
- ->method('getId')
- ->will($this->returnValue(1));
- $this->orderMock->expects($this->once())
- ->method('isCanceled')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
->method('canUnhold')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
+ ->willReturn($canUnhold);
+ $this->orderMock->expects($this->any())
->method('canInvoice')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
+ ->willReturn($canInvoice);
+ $this->orderMock->expects($this->exactly($callCanSkipNum))
->method('canShip')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('getBaseGrandTotal')
- ->will($this->returnValue(100));
- $this->orderMock->expects($this->once())
+ ->willReturn($canShip);
+ $this->orderMock->expects($this->exactly($callCanCreditmemoNum))
->method('canCreditmemo')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->exactly(2))
- ->method('getTotalRefunded')
- ->will($this->returnValue(null));
- $this->orderMock->expects($this->once())
- ->method('hasForcedCanCreditmemo')
- ->will($this->returnValue(true));
- $this->orderMock->expects($this->exactly(2))
- ->method('getState')
- ->will($this->returnValue(Order::STATE_PROCESSING));
- $this->orderMock->expects($this->once())
- ->method('setState')
- ->with(Order::STATE_CLOSED)
- ->will($this->returnSelf());
- $this->assertEquals($this->state, $this->state->check($this->orderMock));
+ ->willReturn($canCreditmemo);
+ $this->orderMock->expects($this->exactly($callGetIsInProcessNum))
+ ->method('getIsInProcess')
+ ->willReturn($isInProcess);
+ $this->state->check($this->orderMock);
+ $this->assertEquals($expectedState, $this->orderMock->getState());
}
/**
- * test check order - set state processing
+ * Data provider for testCheck method.
+ *
+ * @return array
*/
- public function testCheckSetStateProcessing()
+ public function stateCheckDataProvider(): array
{
- $this->orderMock->expects($this->any())
- ->method('getId')
- ->will($this->returnValue(1));
- $this->orderMock->expects($this->once())
- ->method('isCanceled')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canUnhold')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canInvoice')
- ->will($this->returnValue(false));
- $this->orderMock->expects($this->once())
- ->method('canShip')
- ->will($this->returnValue(true));
- $this->orderMock->expects($this->once())
- ->method('getState')
- ->will($this->returnValue(Order::STATE_NEW));
- $this->orderMock->expects($this->once())
- ->method('getIsInProcess')
- ->will($this->returnValue(true));
- $this->orderMock->expects($this->once())
- ->method('setState')
- ->with(Order::STATE_PROCESSING)
- ->will($this->returnSelf());
- $this->assertEquals($this->state, $this->state->check($this->orderMock));
+ return [
+ 'processing - !canCreditmemo!canShip -> closed' =>
+ [false, 1, false, 0, Order::STATE_PROCESSING, Order::STATE_CLOSED],
+ 'complete - !canCreditmemo,!canShip -> closed' =>
+ [false, 1, false, 0, Order::STATE_COMPLETE, Order::STATE_CLOSED],
+ 'processing - !canCreditmemo,canShip -> closed' =>
+ [false, 1, true, 0, Order::STATE_PROCESSING, Order::STATE_CLOSED],
+ 'complete - !canCreditmemo,canShip -> closed' =>
+ [false, 1, true, 0, Order::STATE_COMPLETE, Order::STATE_CLOSED],
+ 'processing - canCreditmemo,!canShip -> complete' =>
+ [true, 1, false, 1, Order::STATE_PROCESSING, Order::STATE_COMPLETE],
+ 'complete - canCreditmemo,!canShip -> complete' =>
+ [true, 1, false, 0, Order::STATE_COMPLETE, Order::STATE_COMPLETE],
+ 'processing - canCreditmemo, canShip -> processing' =>
+ [true, 1, true, 1, Order::STATE_PROCESSING, Order::STATE_PROCESSING],
+ 'complete - canCreditmemo, canShip -> complete' =>
+ [true, 1, true, 0, Order::STATE_COMPLETE, Order::STATE_COMPLETE],
+ 'new - canCreditmemo, canShip, IsInProcess -> processing' =>
+ [true, 1, true, 1, Order::STATE_NEW, Order::STATE_PROCESSING, true, 1],
+ 'new - canCreditmemo, !canShip, IsInProcess -> processing' =>
+ [true, 1, false, 1, Order::STATE_NEW, Order::STATE_COMPLETE, true, 1],
+ 'new - canCreditmemo, canShip, !IsInProcess -> new' =>
+ [true, 0, true, 0, Order::STATE_NEW, Order::STATE_NEW, false, 1],
+ 'hold - canUnhold -> hold' =>
+ [true, 0, true, 0, Order::STATE_HOLDED, Order::STATE_HOLDED, false, 0, false, true],
+ 'payment_review - canUnhold -> payment_review' =>
+ [true, 0, true, 0, Order::STATE_PAYMENT_REVIEW, Order::STATE_PAYMENT_REVIEW, false, 0, false, true],
+ 'pending_payment - canUnhold -> pending_payment' =>
+ [true, 0, true, 0, Order::STATE_PENDING_PAYMENT, Order::STATE_PENDING_PAYMENT, false, 0, false, true],
+ 'cancelled - isCanceled -> cancelled' =>
+ [true, 0, true, 0, Order::STATE_HOLDED, Order::STATE_HOLDED, false, 0, true],
+ ];
}
}
diff --git a/app/code/Magento/Sales/etc/webapi.xml b/app/code/Magento/Sales/etc/webapi.xml
index cee245e348393..492dff8057039 100644
--- a/app/code/Magento/Sales/etc/webapi.xml
+++ b/app/code/Magento/Sales/etc/webapi.xml
@@ -10,271 +10,271 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index 1e8faf3cc9614..afe34cac575ac 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -1246,7 +1246,7 @@ protected function _getCountryName($countryId)
'FO' => 'Faroe Islands',
'FR' => 'France',
'GA' => 'Gabon',
- 'GB' => 'Great Britain and Northern Ireland',
+ 'GB' => 'United Kingdom of Great Britain and Northern Ireland',
'GD' => 'Grenada',
'GE' => 'Georgia, Republic of',
'GF' => 'French Guiana',
@@ -1364,7 +1364,7 @@ protected function _getCountryName($countryId)
'ST' => 'Sao Tome and Principe',
'SV' => 'El Salvador',
'SY' => 'Syrian Arab Republic',
- 'SZ' => 'Swaziland',
+ 'SZ' => 'Eswatini',
'TC' => 'Turks and Caicos Islands',
'TD' => 'Chad',
'TG' => 'Togo',
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php
index eae0e600434a6..2b9c539f64e66 100644
--- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditMemoCreateRefundTest.php
@@ -10,7 +10,7 @@
use Magento\TestFramework\TestCase\WebapiAbstract;
/**
- * Class CreditMemoCreateRefundTest
+ * API tests for CreditMemoCreateRefund.
*/
class CreditMemoCreateRefundTest extends WebapiAbstract
{
@@ -25,12 +25,17 @@ class CreditMemoCreateRefundTest extends WebapiAbstract
*/
protected $objectManager;
+ /**
+ * @inheritdoc
+ */
protected function setUp()
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
}
/**
+ * Test for Invoke method.
+ *
* @magentoApiDataFixture Magento/Sales/_files/invoice.php
*/
public function testInvoke()
@@ -115,8 +120,7 @@ public function testInvoke()
);
$this->assertNotEmpty($result);
$order = $this->objectManager->get(OrderRepositoryInterface::class)->get($order->getId());
- //Totally refunded orders still can be processed and shipped.
- $this->assertEquals(Order::STATE_PROCESSING, $order->getState());
+ $this->assertEquals(Order::STATE_CLOSED, $order->getState());
}
private function getItemsForRest($order)
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php
index aacda763ca2aa..69bbecc1317a7 100644
--- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/RefundOrderTest.php
@@ -5,8 +5,10 @@
*/
namespace Magento\Sales\Service\V1;
+use Magento\Sales\Model\Order;
+
/**
- * API test for creation of Creditmemo for certain Order.
+ * API tests for creation of Creditmemo for certain Order.
*/
class RefundOrderTest extends \Magento\TestFramework\TestCase\WebapiAbstract
{
@@ -23,6 +25,9 @@ class RefundOrderTest extends \Magento\TestFramework\TestCase\WebapiAbstract
*/
private $creditmemoRepository;
+ /**
+ * @inheritdoc
+ */
protected function setUp()
{
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
@@ -86,9 +91,8 @@ public function testShortRequest()
'Failed asserting that proper shipping amount of the Order was refunded'
);
- //Totally refunded orders can be processed.
$this->assertEquals(
- $existingOrder->getStatus(),
+ Order::STATE_COMPLETE,
$updatedOrder->getStatus(),
'Failed asserting that order status has not changed'
);
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
index 38ef02ff49441..39f4fd08bb922 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/TestCase/CreateGroupedProductEntityTest.xml
@@ -8,7 +8,7 @@
- test_type:acceptance_test, test_type:extended_acceptance_test, stable:no
+ test_type:acceptance_test, test_type:extended_acceptance_test
test-grouped-product-%isolation%
GroupedProduct %isolation%
GroupedProduct_sku%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/AbstractForm.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/AbstractForm.php
index 5572c06816a39..bc7ee4372d61b 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/AbstractForm.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/AbstractForm.php
@@ -6,7 +6,9 @@
namespace Magento\Sales\Test\Block\Adminhtml\Order;
+use function GuzzleHttp\Psr7\str;
use Magento\Mtf\Block\Form;
+use Magento\Mtf\Client\Locator;
/**
* Abstract Form block.
@@ -42,6 +44,27 @@ function () {
);
}
+ /**
+ * Wait for element is enabled.
+ *
+ * @param string $selector
+ * @param string $strategy
+ * @return bool|null
+ */
+ protected function waitForElementEnabled(string $selector, string $strategy = Locator::SELECTOR_CSS)
+ {
+ $browser = $this->browser;
+
+ return $browser->waitUntil(
+ function () use ($browser, $selector, $strategy) {
+ $element = $browser->find($selector, $strategy);
+ $class = $element->getAttribute('class');
+
+ return (!$element->isDisabled() && !strpos($class, 'disabled')) ? true : null;
+ }
+ );
+ }
+
/**
* Fill form data.
*
@@ -113,7 +136,7 @@ abstract protected function getItemsBlock();
*/
public function submit()
{
- $this->waitLoader();
+ $this->waitForElementEnabled($this->send);
$this->_rootElement->find($this->send)->click();
}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php
index 6d3b99ce81a04..9f4181b70e801 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCancelMassActionFailMessage.php
@@ -11,17 +11,17 @@
/**
* Class AssertOrderCancelMassActionFailMessage
- * Assert cancel fail message is displayed on order index page
+ * Assert cancel fail message is displayed on order index page.
*/
class AssertOrderCancelMassActionFailMessage extends AbstractConstraint
{
/**
- * Text value to be checked
+ * Text value to be checked.
*/
- const FAIL_CANCEL_MESSAGE = '1 order(s) cannot be canceled.';
+ const FAIL_CANCEL_MESSAGE = 'You cannot cancel the order(s).';
/**
- * Assert cancel fail message is displayed on order index page
+ * Assert cancel fail message is displayed on order index page.
*
* @param OrderIndex $orderIndex
* @return void
@@ -35,7 +35,7 @@ public function processAssert(OrderIndex $orderIndex)
}
/**
- * Returns a string representation of the object
+ * Returns a string representation of the object.
*
* @return string
*/
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderStatusIsCorrect.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderStatusIsCorrect.php
index 46f6ebba51fe1..7a46d0c5ef820 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderStatusIsCorrect.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderStatusIsCorrect.php
@@ -39,8 +39,8 @@ public function processAssert(
/** @var \Magento\Sales\Test\Block\Adminhtml\Order\View\Tab\Info $infoTab */
$infoTab = $salesOrderView->getOrderForm()->openTab('info')->getTab('info');
\PHPUnit_Framework_Assert::assertEquals(
- $infoTab->getOrderStatus(),
- $orderStatus
+ $orderStatus,
+ $infoTab->getOrderStatus()
);
}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
index eddc321e9ca52..1f75b07c8ca1e 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/MassOrdersUpdateTest.xml
@@ -8,7 +8,6 @@
- stable:no
cancel orders in status Pending and Processing
-
Cancel
@@ -18,20 +17,20 @@
- try to cancel orders in status Complete, Canceled
+ try to cancel orders in status Complete, Closed
invoice, shipment|invoice, credit memo
Cancel
2
- Complete,Canceled
+ Complete,Closed
- try to cancel orders in status Pending, Closed
+ try to cancel orders in status Processing, Closed
invoice|invoice, credit memo
Cancel
2
- Processing,Canceled
+ Processing,Closed
@@ -45,7 +44,6 @@
- stable:no
Try to put order in status Complete on Hold
invoice, shipment
Hold
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php
index 6b92338e9932a..3c126bcdc2c5b 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php
@@ -64,7 +64,7 @@ public function testProcessIpnRequestFullRefund()
$creditmemoItems = $order->getCreditmemosCollection()->getItems();
$creditmemo = current($creditmemoItems);
- $this->assertEquals(Order::STATE_PROCESSING, $order->getState());
+ $this->assertEquals(Order::STATE_CLOSED, $order->getState());
$this->assertEquals(1, count($creditmemoItems));
$this->assertEquals(Creditmemo::STATE_REFUNDED, $creditmemo->getState());
$this->assertEquals(10, $order->getSubtotalRefunded());
@@ -146,7 +146,7 @@ public function testProcessIpnRequestRestRefund()
$creditmemoItems = $order->getCreditmemosCollection()->getItems();
- $this->assertEquals(Order::STATE_PROCESSING, $order->getState());
+ $this->assertEquals(Order::STATE_CLOSED, $order->getState());
$this->assertEquals(1, count($creditmemoItems));
$this->assertEquals(10, $order->getSubtotalRefunded());
$this->assertEquals(10, $order->getBaseSubtotalRefunded());
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice.php
index a889235ea1862..61d8be98bdd22 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice.php
@@ -3,6 +3,9 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+use Magento\Sales\Model\Order\ShipmentFactory;
+
require 'order.php';
$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
@@ -36,4 +39,11 @@
$order->setIsInProcess(true);
-$transaction->addObject($invoice)->addObject($order)->save();
+$items = [];
+foreach ($order->getItems() as $orderItem) {
+ $items[$orderItem->getId()] = $orderItem->getQtyOrdered();
+}
+$shipment = $objectManager->get(ShipmentFactory::class)->create($order, $items);
+$shipment->register();
+
+$transaction->addObject($invoice)->addObject($shipment)->addObject($order)->save();