diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php
index b1f99bb1fc05f..2ad96cfeab1d9 100644
--- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php
+++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPrice.php
@@ -3,15 +3,25 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+declare(strict_types=1);
+
namespace Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator;
use Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing;
+use Magento\CatalogImportExport\Model\Import\Product;
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
+use Magento\CatalogImportExport\Model\Import\Product\StoreResolver;
+use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
+use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractPrice;
+use Magento\Customer\Api\GroupRepositoryInterface;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Exception\LocalizedException;
-class TierPrice extends \Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractPrice
+class TierPrice extends AbstractPrice
{
/**
- * @var \Magento\CatalogImportExport\Model\Import\Product\StoreResolver
+ * @var StoreResolver
*/
protected $storeResolver;
@@ -27,21 +37,26 @@ class TierPrice extends \Magento\CatalogImportExport\Model\Import\Product\Valida
];
/**
- * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository
- * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
- * @param \Magento\CatalogImportExport\Model\Import\Product\StoreResolver $storeResolver
+ * @param GroupRepositoryInterface $groupRepository
+ * @param SearchCriteriaBuilder $searchCriteriaBuilder
+ * @param StoreResolver $storeResolver
*/
public function __construct(
- \Magento\Customer\Api\GroupRepositoryInterface $groupRepository,
- \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
- \Magento\CatalogImportExport\Model\Import\Product\StoreResolver $storeResolver
+ GroupRepositoryInterface $groupRepository,
+ SearchCriteriaBuilder $searchCriteriaBuilder,
+ StoreResolver $storeResolver
) {
$this->storeResolver = $storeResolver;
parent::__construct($groupRepository, $searchCriteriaBuilder);
}
/**
- * {@inheritdoc}
+ * Initialize method
+ *
+ * @param Product $context
+ *
+ * @return RowValidatorInterface|AbstractImportValidator|void
+ * @throws LocalizedException
*/
public function init($context)
{
@@ -52,7 +67,10 @@ public function init($context)
}
/**
+ * Add decimal error
+ *
* @param string $attribute
+ *
* @return void
*/
protected function addDecimalError($attribute)
@@ -83,12 +101,12 @@ public function getCustomerGroups()
}
/**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* Validation
*
* @param mixed $value
* @return bool
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
public function isValid($value)
{
@@ -133,6 +151,7 @@ public function isValid($value)
* Check if at list one value and length are valid
*
* @param array $value
+ *
* @return bool
*/
protected function isValidValueAndLength(array $value)
@@ -150,6 +169,7 @@ protected function isValidValueAndLength(array $value)
* Check if value has empty columns
*
* @param array $value
+ *
* @return bool
*/
protected function hasEmptyColumns(array $value)
diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php
index 6aa59e6227a05..71b5271a90fa2 100644
--- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php
+++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/TierPriceType.php
@@ -4,28 +4,24 @@
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator;
use Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing;
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
+use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
/**
* Class TierPriceType validates tier price type.
*/
-class TierPriceType extends \Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator
+class TierPriceType extends AbstractImportValidator
{
- /**
- * {@inheritdoc}
- */
- public function init($context)
- {
- return parent::init($context);
- }
-
/**
* Validate tier price type.
*
* @param array $value
+ *
* @return bool
*/
public function isValid($value)
diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/Website.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/Website.php
index 0f3f8b3389c7d..93c63dcbcab28 100644
--- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/Website.php
+++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing/Validator/Website.php
@@ -3,49 +3,47 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+declare(strict_types=1);
+
namespace Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing\Validator;
use Magento\AdvancedPricingImportExport\Model\Import\AdvancedPricing;
-use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
+use Magento\CatalogImportExport\Model\Import\Product\StoreResolver;
+use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
+use Magento\Store\Model\Website as WebsiteModel;
class Website extends AbstractImportValidator implements RowValidatorInterface
{
/**
- * @var \Magento\CatalogImportExport\Model\Import\Product\StoreResolver
+ * @var StoreResolver
*/
protected $storeResolver;
/**
- * @var \Magento\Store\Model\Website
+ * @var WebsiteModel
*/
protected $websiteModel;
/**
- * @param \Magento\CatalogImportExport\Model\Import\Product\StoreResolver $storeResolver
- * @param \Magento\Store\Model\Website $websiteModel
+ * @param StoreResolver $storeResolver
+ * @param WebsiteModel $websiteModel
*/
public function __construct(
- \Magento\CatalogImportExport\Model\Import\Product\StoreResolver $storeResolver,
- \Magento\Store\Model\Website $websiteModel
+ StoreResolver $storeResolver,
+ WebsiteModel $websiteModel
) {
$this->storeResolver = $storeResolver;
$this->websiteModel = $websiteModel;
}
- /**
- * {@inheritdoc}
- */
- public function init($context)
- {
- return parent::init($context);
- }
-
/**
* Validate by website type
*
* @param array $value
* @param string $websiteCode
+ *
* @return bool
*/
protected function isWebsiteValid($value, $websiteCode)
@@ -62,7 +60,8 @@ protected function isWebsiteValid($value, $websiteCode)
/**
* Validate value
*
- * @param mixed $value
+ * @param array $value
+ *
* @return bool
*/
public function isValid($value)
@@ -85,6 +84,7 @@ public function isValid($value)
*/
public function getAllWebsitesValue()
{
- return AdvancedPricing::VALUE_ALL_WEBSITES . ' ['.$this->websiteModel->getBaseCurrency()->getCurrencyCode().']';
+ return AdvancedPricing::VALUE_ALL_WEBSITES .
+ ' [' . $this->websiteModel->getBaseCurrency()->getCurrencyCode() . ']';
}
}
diff --git a/app/code/Magento/Authorization/Test/Unit/Model/ResourceModel/RulesTest.php b/app/code/Magento/Authorization/Test/Unit/Model/ResourceModel/RulesTest.php
index 6560b3be3b947..cbd9012e1a80d 100644
--- a/app/code/Magento/Authorization/Test/Unit/Model/ResourceModel/RulesTest.php
+++ b/app/code/Magento/Authorization/Test/Unit/Model/ResourceModel/RulesTest.php
@@ -182,7 +182,7 @@ public function testSaveRelNoResources()
/**
* Test LocalizedException throw case.
*/
- public function testLocalizedExceptionOccurance()
+ public function testLocalizedExceptionOccurrence()
{
$this->expectException(LocalizedException::class);
$this->expectExceptionMessage("TestException");
@@ -212,7 +212,7 @@ public function testLocalizedExceptionOccurance()
/**
* Test generic exception throw case.
*/
- public function testGenericExceptionOccurance()
+ public function testGenericExceptionOccurrence()
{
$exception = new \Exception('GenericException');
diff --git a/app/code/Magento/Backup/Test/Mftf/ActionGroup/deleteBackupActionGroup.xml b/app/code/Magento/Backup/Test/Mftf/ActionGroup/deleteBackupActionGroup.xml
deleted file mode 100644
index b879a2aa9647a..0000000000000
--- a/app/code/Magento/Backup/Test/Mftf/ActionGroup/deleteBackupActionGroup.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml
index 55038b0c68c44..3588bd360004d 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAddDefaultImageBundleProductTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml
index 06a05e7a29cd9..6bb4c3e0e1a5f 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminAttributeSetSelectionTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml
index b9fb1c72e079f..56dad8b214d0f 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminBasicBundleProductAttributesTest.xml
@@ -21,7 +21,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml
index 51c30ef86242c..e9b91a0efb595 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminDeleteABundleProductTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml
index 4ba5d0f66e096..61a9c7c975324 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminEditRelatedBundleProductTest.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml
index f8914656cc32b..45cbb7d83bb2d 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminFilterProductListByBundleProductTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProductsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProductsTest.xml
index 2c1fcb6d7de42..a995a629092c6 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProductsTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminMassDeleteBundleProductsTest.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml
index ab1d4bb5ce68a..e0e0fe571fe32 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/AdminRemoveDefaultImageBundleProductTest.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml
index b5812817b5640..def24c86e1730 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/BundleProductWithTierPriceInCartTest.xml
@@ -34,7 +34,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml
index ada91d068efcf..b25139835de59 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/CurrencyChangingBundleProductInCartTest.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml
index fd94ca93b1600..5ebb50b161284 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/MassEnableDisableBundleProductsTest.xml
@@ -29,7 +29,7 @@
-
+
@@ -130,8 +130,7 @@
-
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml
index efef033f9d974..e722caaf090c5 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/NewBundleProductSelectionTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml
index 8e8df1f4f16f0..1fe16f068e2e6 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontAdminEditDataTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml
index e6f8834336683..7231f61b28899 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleAddToCartSuccessTest.xml
@@ -24,7 +24,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml
index 966082739aa68..2152717fad8da 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleCartTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml
index 871bf71d1f876..3532e8f4fdd54 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontBundleProductShownInCategoryListAndGridTest.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml
index 77c561f311280..565af8b3dbfdb 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontCustomerSelectAndSetBundleOptionsTest.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml
index 161d308044b4a..262c216218c7f 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontEditBundleProductTest.xml
@@ -25,7 +25,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml
index add819e2d3f14..f0836229bb653 100644
--- a/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml
+++ b/app/code/Magento/Bundle/Test/Mftf/Test/StorefrontGoToDetailsPageWhenAddingToCartTest.xml
@@ -26,7 +26,7 @@
-
+
diff --git a/app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php b/app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php
index 2d86f130767c8..0092c894ac44a 100644
--- a/app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/Plugin/BundleTest.php
@@ -150,13 +150,13 @@ public function testAfterInitializeIfBundleAnsCustomOptionsAndBundleSelectionsEx
$this->productMock->expects($this->once())
->method('getBundleOptionsData')
->willReturn(['option_1' => ['delete' => 1]]);
- $extentionAttribute = $this->getMockBuilder(ProductExtensionInterface::class)
+ $extensionAttribute = $this->getMockBuilder(ProductExtensionInterface::class)
->disableOriginalConstructor()
->setMethods(['setBundleProductOptions'])
->getMockForAbstractClass();
- $extentionAttribute->expects($this->once())->method('setBundleProductOptions')->with([]);
- $this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extentionAttribute);
- $this->productMock->expects($this->once())->method('setExtensionAttributes')->with($extentionAttribute);
+ $extensionAttribute->expects($this->once())->method('setBundleProductOptions')->with([]);
+ $this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttribute);
+ $this->productMock->expects($this->once())->method('setExtensionAttributes')->with($extensionAttribute);
$this->model->afterInitialize($this->subjectMock, $this->productMock);
}
@@ -191,14 +191,14 @@ public function testAfterInitializeIfBundleOptionsNotExist(): void
['affect_bundle_product_selections', null, false],
];
$this->requestMock->expects($this->any())->method('getPost')->willReturnMap($valueMap);
- $extentionAttribute = $this->getMockBuilder(ProductExtensionInterface::class)
+ $extensionAttribute = $this->getMockBuilder(ProductExtensionInterface::class)
->disableOriginalConstructor()
->setMethods(['setBundleProductOptions'])
->getMockForAbstractClass();
- $extentionAttribute->expects($this->once())->method('setBundleProductOptions')->with([]);
+ $extensionAttribute->expects($this->once())->method('setBundleProductOptions')->with([]);
$this->productMock->expects($this->any())->method('getCompositeReadonly')->willReturn(false);
- $this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extentionAttribute);
- $this->productMock->expects($this->once())->method('setExtensionAttributes')->with($extentionAttribute);
+ $this->productMock->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttribute);
+ $this->productMock->expects($this->once())->method('setExtensionAttributes')->with($extensionAttribute);
$this->productMock->expects($this->once())->method('setCanSaveBundleSelections')->with(false);
$this->model->afterInitialize($this->subjectMock, $this->productMock);
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
index 771b5c53b3347..b7041051591d8 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php
@@ -11,6 +11,7 @@
use Magento\Bundle\Model\Product\Type;
use Magento\Bundle\Model\ResourceModel\BundleFactory;
use Magento\Bundle\Model\ResourceModel\Option\Collection;
+use Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor;
use Magento\Bundle\Model\ResourceModel\Selection\Collection as SelectionCollection;
use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory;
use Magento\Bundle\Model\Selection;
@@ -42,6 +43,8 @@
use PHPUnit\Framework\TestCase;
/**
+ * Test for bundle product type
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TypeTest extends TestCase
@@ -116,6 +119,11 @@ class TypeTest extends TestCase
*/
private $arrayUtility;
+ /**
+ * @var CollectionProcessor|MockObject
+ */
+ private $catalogRuleProcessor;
+
/**
* @return void
*/
@@ -172,20 +180,20 @@ protected function setUp(): void
->setMethods(['create'])
->disableOriginalConstructor()
->getMock();
-
$this->serializer = $this->getMockBuilder(Json::class)
->setMethods(null)
->disableOriginalConstructor()
->getMock();
-
$this->metadataPool = $this->getMockBuilder(MetadataPool::class)
->disableOriginalConstructor()
->getMock();
-
$this->arrayUtility = $this->getMockBuilder(ArrayUtils::class)
->setMethods(['flatten'])
->disableOriginalConstructor()
->getMock();
+ $this->catalogRuleProcessor = $this->getMockBuilder(CollectionProcessor::class)
+ ->disableOriginalConstructor()
+ ->getMock();
$objectHelper = new ObjectManager($this);
$this->model = $objectHelper->getObject(
@@ -1542,7 +1550,7 @@ public function testPrepareForCartAdvancedSpecifyProductOptions()
$this->parentClass($group, $option, $buyRequest, $product);
- $product->expects($this->once())
+ $product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$buyRequest->expects($this->once())
@@ -2424,9 +2432,6 @@ protected function parentClass($group, $option, $buyRequest, $product)
$group->expects($this->once())
->method('setProcessMode')
->willReturnSelf();
- $group->expects($this->once())
- ->method('validateUserValue')
- ->willReturnSelf();
$group->expects($this->once())
->method('prepareForCart')
->willReturn('someString');
diff --git a/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml b/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml
index bfea4e99996c3..9e99fa96ee766 100644
--- a/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml
+++ b/app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest/CaptchaWithDisabledGuestCheckoutTest.xml
@@ -34,9 +34,7 @@
-
-
-
+
diff --git a/app/code/Magento/Catalog/Api/ProductAttributeOptionUpdateInterface.php b/app/code/Magento/Catalog/Api/ProductAttributeOptionUpdateInterface.php
new file mode 100644
index 0000000000000..c783033b6d7b7
--- /dev/null
+++ b/app/code/Magento/Catalog/Api/ProductAttributeOptionUpdateInterface.php
@@ -0,0 +1,33 @@
+eavOptionManagement = $eavOptionManagement;
+ $this->eavOptionUpdate = $eavOptionUpdate;
}
/**
@@ -33,7 +47,7 @@ public function __construct(
public function getItems($attributeCode)
{
return $this->eavOptionManagement->getItems(
- \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode
);
}
@@ -44,8 +58,21 @@ public function getItems($attributeCode)
public function add($attributeCode, $option)
{
return $this->eavOptionManagement->add(
- \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
+ $attributeCode,
+ $option
+ );
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function update(string $attributeCode, int $optionId, AttributeOptionInterface $option): bool
+ {
+ return $this->eavOptionUpdate->update(
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
+ $optionId,
$option
);
}
@@ -60,7 +87,7 @@ public function delete($attributeCode, $optionId)
}
return $this->eavOptionManagement->delete(
- \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
$optionId
);
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
index 9f1eae207e116..425c81a5a9c43 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
@@ -16,8 +16,9 @@
/**
* Catalog product option file type
*
- * @author Magento Core Team
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class File extends \Magento\Catalog\Model\Product\Option\Type\DefaultType
{
@@ -181,6 +182,7 @@ protected function _getProcessingParams()
/**
* Returns file info array if we need to get file from already existing file.
+ *
* Or returns null, if we need to get file from uploaded array.
*
* @return null|array
@@ -262,7 +264,6 @@ public function validateUserValue($values)
. "Make sure the options are entered and try again."
)
);
- break;
default:
$this->setUserValue(null);
break;
@@ -330,7 +331,11 @@ public function prepareForCart()
public function getFormattedOptionValue($optionValue)
{
if ($this->_formattedOptionValue === null) {
- $value = $this->serializer->unserialize($optionValue);
+ try {
+ $value = $this->serializer->unserialize($optionValue);
+ } catch (\InvalidArgumentException $e) {
+ return $optionValue;
+ }
if ($value === null) {
return $optionValue;
}
@@ -476,13 +481,13 @@ public function copyQuoteToOrder()
try {
$value = $this->serializer->unserialize($quoteOption->getValue());
if (!isset($value['quote_path'])) {
- throw new \Exception();
+ return $this;
}
$quotePath = $value['quote_path'];
$orderPath = $value['order_path'];
if (!$this->mediaDirectory->isFile($quotePath) || !$this->mediaDirectory->isReadable($quotePath)) {
- throw new \Exception();
+ return $this;
}
if ($this->_coreFileStorageDatabase->checkDbUsage()) {
@@ -524,6 +529,8 @@ protected function _getOptionDownloadUrl($route, $params)
}
/**
+ * Prepare size
+ *
* @param array $value
* @return string
*/
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index e6804d9246faa..5afac9636d7b4 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -9,15 +9,18 @@
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\App\ObjectManager;
/**
- * @api
* Abstract model for product type implementation
+ *
+ * phpcs:disable Magento2.Classes.AbstractApi
+ * @api
+ * @since 100.0.2
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- * @since 100.0.2
*/
abstract class AbstractType
{
@@ -207,7 +210,7 @@ public function __construct(
$this->_filesystem = $filesystem;
$this->_logger = $logger;
$this->productRepository = $productRepository;
- $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance()
+ $this->serializer = $serializer ?: ObjectManager::getInstance()
->get(\Magento\Framework\Serialize\Serializer\Json::class);
}
@@ -355,6 +358,7 @@ public function isSalable($product)
/**
* Prepare product and its configuration to be added to some products list.
+ *
* Perform standard preparation process and then prepare options belonging to specific product type.
*
* @param \Magento\Framework\DataObject $buyRequest
@@ -440,6 +444,7 @@ public function processConfiguration(
/**
* Initialize product(s) for add to cart process.
+ *
* Advanced version of func to prepare product for cart - processMode can be specified there.
*
* @param \Magento\Framework\DataObject $buyRequest
@@ -476,6 +481,7 @@ public function prepareForCart(\Magento\Framework\DataObject $buyRequest, $produ
* @throws \Magento\Framework\Exception\LocalizedException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
+ * phpcs:disable Generic.Metrics.NestingLevel
*/
public function processFileQueue()
{
@@ -492,6 +498,7 @@ public function processFileQueue()
/** @var $uploader \Zend_File_Transfer_Adapter_Http */
$uploader = isset($queueOptions['uploader']) ? $queueOptions['uploader'] : null;
+ // phpcs:ignore Magento2.Functions.DiscouragedFunction
$path = dirname($dst);
try {
@@ -529,9 +536,11 @@ public function processFileQueue()
return $this;
}
+ //phpcs:enable
/**
* Add file to File Queue
+ *
* @param array $queueOptions Array of File Queue
* (eg. ['operation'=>'move',
* 'src_name'=>'filename',
@@ -572,6 +581,7 @@ public function getSpecifyOptionMessage()
* @param string $processMode
* @return array
* @throws LocalizedException
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $product, $processMode)
{
@@ -583,6 +593,7 @@ protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $p
}
if ($options !== null) {
$results = [];
+ $optionsFromRequest = $buyRequest->getOptions();
foreach ($options as $option) {
/* @var $option \Magento\Catalog\Model\Product\Option */
try {
@@ -590,8 +601,14 @@ protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $p
->setOption($option)
->setProduct($product)
->setRequest($buyRequest)
- ->setProcessMode($processMode)
- ->validateUserValue($buyRequest->getOptions());
+ ->setProcessMode($processMode);
+
+ if ($product->getSkipCheckRequiredOption() !== true) {
+ $group->validateUserValue($optionsFromRequest);
+ } elseif ($optionsFromRequest !== null && isset($optionsFromRequest[$option->getId()])) {
+ $transport->options[$option->getId()] = $optionsFromRequest[$option->getId()];
+ }
+
} catch (LocalizedException $e) {
$results[] = $e->getMessage();
continue;
@@ -643,8 +660,7 @@ public function checkProductBuyState($product)
}
/**
- * Prepare additional options/information for order item which will be
- * created from this product
+ * Prepare additional options/information for order item which will be created from this product
*
* @param \Magento\Catalog\Model\Product $product
* @return array
@@ -900,7 +916,7 @@ public function getStoreFilter($product)
/**
* Set store filter for associated products
*
- * @param $store int|\Magento\Store\Model\Store
+ * @param int|\Magento\Store\Model\Store $store
* @param \Magento\Catalog\Model\Product $product
* @return $this
*/
@@ -913,6 +929,7 @@ public function setStoreFilter($store, $product)
/**
* Allow for updates of children qty's
+ *
* (applicable for complicated product types. As default returns false)
*
* @param \Magento\Catalog\Model\Product $product
@@ -940,6 +957,7 @@ public function prepareQuoteItemQty($qty, $product)
/**
* Implementation of product specify logic of which product needs to be assigned to option.
+ *
* For example if product which was added to option already removed from catalog.
*
* @param \Magento\Catalog\Model\Product $optionProduct
@@ -979,6 +997,7 @@ public function setConfig($config)
/**
* Retrieve additional searchable data from type instance
+ *
* Using based on product id and store_id data
*
* @param \Magento\Catalog\Model\Product $product
@@ -999,6 +1018,7 @@ public function getSearchableData($product)
/**
* Retrieve products divided into groups required to purchase
+ *
* At least one product in each group has to be purchased
*
* @param \Magento\Catalog\Model\Product $product
@@ -1092,6 +1112,8 @@ public function getIdentities(\Magento\Catalog\Model\Product $product)
}
/**
+ * Get Associated Products
+ *
* @param \Magento\Catalog\Model\Product\Type\AbstractType $product
* @return array
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductCatalogPageOpenActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductCatalogPageOpenActionGroup.xml
new file mode 100644
index 0000000000000..f25f73977bf4e
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductCatalogPageOpenActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Goes to the Admin Product Catalog Page grid page.
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProperUrlIsShownActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProperUrlIsShownActionGroup.xml
new file mode 100644
index 0000000000000..6fb7f68f64320
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/StorefrontAssertProperUrlIsShownActionGroup.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+ Validate that the URL path is correct
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml
index 92f24fe76502d..110cfa0cd83a7 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageSimpleProductTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageVirtualProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageVirtualProductTest.xml
index 7cf388914207b..dc215ac51f075 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageVirtualProductTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddDefaultImageVirtualProductTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml
index 52da8c70a3bc8..a41d0836a2ded 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminAddInStockProductToTheCartTest.xml
@@ -78,9 +78,7 @@
-
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeGroupTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeGroupTest.xml
index 04955807d7618..68e6040277247 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeGroupTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminChangeProductAttributeGroupTest.xml
@@ -9,6 +9,7 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryFromProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryFromProductPageTest.xml
index b94c12d1d7a39..b96052d2d0685 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryFromProductPageTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCategoryFromProductPageTest.xml
@@ -27,7 +27,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCustomProductAttributeWithDropdownFieldTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCustomProductAttributeWithDropdownFieldTest.xml
index 7b2c67b205ea8..19df6e29f36a2 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCustomProductAttributeWithDropdownFieldTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateCustomProductAttributeWithDropdownFieldTest.xml
@@ -105,7 +105,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDatetimeProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDatetimeProductAttributeTest.xml
index 37dc7de910917..4c57504b60ad7 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDatetimeProductAttributeTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDatetimeProductAttributeTest.xml
@@ -29,8 +29,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
index fef69edde23e8..0bfa5b925483e 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDropdownProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
@@ -60,7 +60,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml
index f8346f5a9dd5c..bf9aa5509fa50 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryAndUpdateAsInactiveTest.xml
@@ -37,9 +37,8 @@
-
-
-
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml
index 0aa89bdfd45b6..3f54f60f382e4 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveFlatCategoryTest.xml
@@ -37,9 +37,8 @@
-
-
-
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml
index 171d15fe6ed4f..df9d28637f727 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateInactiveInMenuFlatCategoryTest.xml
@@ -37,9 +37,8 @@
-
-
-
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateMultipleSelectProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateMultipleSelectProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
index caacfde89d1cb..174bfc3e18ba5 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateMultipleSelectProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateMultipleSelectProductAttributeVisibleInStorefrontAdvancedSearchFormTest.xml
@@ -64,7 +64,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml
index 7fdab11d0a050..7154b7b27650d 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateProductAttributeFromProductPageTest.xml
@@ -100,7 +100,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithCountryOfManufactureAttributeSKUMaskTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithCountryOfManufactureAttributeSKUMaskTest.xml
index c378ca5b2c27a..5d88d687754e0 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithCountryOfManufactureAttributeSKUMaskTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateSimpleProductWithCountryOfManufactureAttributeSKUMaskTest.xml
@@ -31,8 +31,7 @@
-
-
+
@@ -49,8 +48,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductFillingRequiredFieldsOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductFillingRequiredFieldsOnlyTest.xml
index 9d3a47cd115aa..c82c038b75d74 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductFillingRequiredFieldsOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductFillingRequiredFieldsOnlyTest.xml
@@ -25,8 +25,7 @@
-
-
+
@@ -42,8 +41,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductOutOfStockWithTierPriceTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductOutOfStockWithTierPriceTest.xml
index 842f93b49c14a..9747ae6314b7d 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductOutOfStockWithTierPriceTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductOutOfStockWithTierPriceTest.xml
@@ -31,8 +31,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml
index 8bb3391b5240b..f119c995d3a61 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithCustomOptionsSuiteAndImportOptionsTest.xml
@@ -31,8 +31,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceTest.xml
index faae6a371db24..16da9c0642edc 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithTierPriceTest.xml
@@ -27,8 +27,7 @@
-
-
+
@@ -60,8 +59,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml
index 3b5a8d8e753da..14f228375bfaa 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateVirtualProductWithoutManageStockTest.xml
@@ -27,8 +27,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteSystemProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteSystemProductAttributeTest.xml
index 22c6bf061f274..b7e037b323ee2 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteSystemProductAttributeTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminDeleteSystemProductAttributeTest.xml
@@ -23,8 +23,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml
index ebbfdc4d72f40..f0d670cd35471 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminEditTextEditorProductAttributeTest.xml
@@ -50,8 +50,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml
index f6b2a74eca0f0..f10288bea36d9 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminGridPageNumberAfterSaveAndCloseActionTest.xml
@@ -23,8 +23,7 @@
-
-
+
@@ -37,8 +36,8 @@
-
-
+
+
@@ -49,8 +48,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassChangeProductsStatusTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassChangeProductsStatusTest.xml
index 0214f9141b903..abec993167fa9 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassChangeProductsStatusTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassChangeProductsStatusTest.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesMissingRequiredFieldTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesMissingRequiredFieldTest.xml
index e4d69e9169613..7809dbbe498da 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesMissingRequiredFieldTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesMissingRequiredFieldTest.xml
@@ -30,7 +30,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml
index 08b2d924e2a5e..6014176f0702c 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminMassUpdateProductAttributesStoreViewScopeTest/AdminMassUpdateProductAttributesStoreViewScopeTest.xml
@@ -31,7 +31,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridFilteringByDateAttributeTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridFilteringByDateAttributeTest.xml
index d47730a99308b..d4d32ae47b827 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridFilteringByDateAttributeTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductGridFilteringByDateAttributeTest.xml
@@ -26,8 +26,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductStatusAttributeDisabledByDefaultTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductStatusAttributeDisabledByDefaultTest.xml
index ae63158990b96..e681feb77c380 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductStatusAttributeDisabledByDefaultTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminProductStatusAttributeDisabledByDefaultTest.xml
@@ -23,8 +23,7 @@
-
-
+
@@ -37,8 +36,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageSimpleProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageSimpleProductTest.xml
index 00eaa623e2bca..1d216b6eda359 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageSimpleProductTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageSimpleProductTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageVirtualProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageVirtualProductTest.xml
index 6cc1b256e5ec9..2ff76520cee38 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageVirtualProductTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminRemoveDefaultImageVirtualProductTest.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleSetEditRelatedProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleSetEditRelatedProductsTest.xml
index 534924e0f70c9..2396bea2768a7 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleSetEditRelatedProductsTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSimpleSetEditRelatedProductsTest.xml
@@ -35,7 +35,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml
index 6a12b991bd225..3bbe8722d8bfc 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateCategoryUrlKeyWithStoreViewTest.xml
@@ -32,16 +32,12 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
@@ -50,34 +46,37 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
-
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml
index 1950b385c4a68..011eae0572a9a 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateFlatCategoryAndAddProductsTest.xml
@@ -38,9 +38,8 @@
-
-
-
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductNameToVerifyDataOverridingOnStoreViewLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductNameToVerifyDataOverridingOnStoreViewLevelTest.xml
index 6edffb923d540..1f4024f47bdf3 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductNameToVerifyDataOverridingOnStoreViewLevelTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductNameToVerifyDataOverridingOnStoreViewLevelTest.xml
@@ -42,8 +42,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductPriceToVerifyDataOverridingOnStoreViewLevelTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductPriceToVerifyDataOverridingOnStoreViewLevelTest.xml
index e954de90ef542..10b488c9848ba 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductPriceToVerifyDataOverridingOnStoreViewLevelTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductPriceToVerifyDataOverridingOnStoreViewLevelTest.xml
@@ -42,8 +42,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml
index f5b0fb8054dc1..522f0c712754f 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductTieredPriceTest.xml
@@ -40,8 +40,7 @@
-
-
+
@@ -85,8 +84,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockDisabledProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockDisabledProductTest.xml
index d20594461173b..74774f936cba8 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockDisabledProductTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockDisabledProductTest.xml
@@ -34,8 +34,7 @@
-
-
+
@@ -60,8 +59,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatTest.xml
index 5fa7acbeb8de9..9819ba61c21b7 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockEnabledFlatTest.xml
@@ -38,8 +38,7 @@
-
-
+
@@ -79,8 +78,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockNotVisibleIndividuallyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockNotVisibleIndividuallyTest.xml
index 4b21d1337e9b7..7dcad35c34d13 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockNotVisibleIndividuallyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockNotVisibleIndividuallyTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -70,8 +69,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml
index 4256f93ea41d1..3450a8fb6e017 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockUnassignFromCategoryTest.xml
@@ -34,8 +34,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml
index 58db163bed720..2a260c606c71f 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogAndSearchTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -70,8 +69,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml
index 5e9a48f659d6b..db7d0f7adbec6 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInCatalogOnlyTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -70,8 +69,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInSearchOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInSearchOnlyTest.xml
index 3d37b54dfa439..0a892b004f150 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInSearchOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockVisibleInSearchOnlyTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -70,8 +69,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml
index 855a2b1d9b0cc..48b223b1b0567 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceInStockWithCustomOptionsTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -83,8 +82,7 @@
-
-
+
@@ -150,9 +148,7 @@
-
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceOutOfStockTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceOutOfStockTest.xml
index af836efcf6be6..98096f2702e12 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceOutOfStockTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateSimpleProductWithRegularPriceOutOfStockTest.xml
@@ -36,8 +36,7 @@
-
-
+
@@ -69,8 +68,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml
index 595f9bcd489ec..f77138c6e2b8a 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockVisibleInCategoryOnlyTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -81,8 +80,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml
index 458d02d61426d..1bc66cca8d5fa 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceInStockWithCustomOptionsVisibleInSearchOnlyTest.xml
@@ -34,8 +34,7 @@
-
-
+
@@ -126,8 +125,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml
index 6d6ff0b3b1b89..8316d71f7b7da 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryAndSearchTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -62,8 +61,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml
index d5ae971d87695..6e346f38a2836 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInCategoryOnlyTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -70,8 +69,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml
index 314df67d43d00..57cf6f6e45d97 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithRegularPriceOutOfStockVisibleInSearchOnlyTest.xml
@@ -35,8 +35,7 @@
-
-
+
@@ -60,8 +59,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml
index d0f4fc8882e3f..d1aa7a31ed297 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceInStockVisibleInCategoryAndSearchTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -76,8 +75,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml
index 2234d6f338b62..ba8ccbe932bfa 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithSpecialPriceOutOfStockVisibleInCategoryAndSearchTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -75,8 +74,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml
index 8f0861fe33371..e43b04bb5e08b 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceInStockVisibleInCategoryOnlyTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -81,8 +80,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml
index f7f5385381590..52d8c08294e86 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminUpdateVirtualProductWithTierPriceOutOfStockVisibleInCategoryAndSearchTest.xml
@@ -37,8 +37,7 @@
-
-
+
@@ -81,8 +80,7 @@
-
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
index 437532b9baebf..26ff1bc45be9d 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDateTest.xml
@@ -39,7 +39,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownTest.xml
index 580a5bd4939bb..61787dcff0b91 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownTest.xml
@@ -33,7 +33,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownWithSingleQuoteTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownWithSingleQuoteTest.xml
index e24bf0d7b1115..73c8bafba0625 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownWithSingleQuoteTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityDropdownWithSingleQuoteTest.xml
@@ -33,7 +33,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityMultiSelectTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityMultiSelectTest.xml
index 0a84d9af3c918..9952f6a4a85fe 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityMultiSelectTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityMultiSelectTest.xml
@@ -32,7 +32,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityPriceTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityPriceTest.xml
index 97eff20b2d560..760cd5e0e488a 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityPriceTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityPriceTest.xml
@@ -33,7 +33,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityTextFieldTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityTextFieldTest.xml
index c0cff7b0b2bc9..ea94fc58400a6 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityTextFieldTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/CreateProductAttributeEntityTest/CreateProductAttributeEntityTextFieldTest.xml
@@ -33,7 +33,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/SimpleProductTwoCustomOptionsTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/SimpleProductTwoCustomOptionsTest.xml
index 7b2e004495fea..ea4d32b780f6e 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Test/SimpleProductTwoCustomOptionsTest.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/SimpleProductTwoCustomOptionsTest.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/OptionManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/OptionManagementTest.php
index edbbaebd0576b..05bd3ec2a3d33 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/OptionManagementTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/OptionManagementTest.php
@@ -10,10 +10,14 @@
use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Model\Product\Attribute\OptionManagement;
use Magento\Eav\Api\AttributeOptionManagementInterface;
+use Magento\Eav\Api\AttributeOptionUpdateInterface;
use Magento\Eav\Api\Data\AttributeOptionInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
+/**
+ * Class to test management of attribute options
+ */
class OptionManagementTest extends TestCase
{
/**
@@ -22,18 +26,28 @@ class OptionManagementTest extends TestCase
protected $model;
/**
- * @var MockObject
+ * @var AttributeOptionManagementInterface|MockObject
*/
protected $eavOptionManagementMock;
+ /**
+ * @var AttributeOptionUpdateInterface|MockObject
+ */
+ private $eavOptionUpdateMock;
+
protected function setUp(): void
{
$this->eavOptionManagementMock = $this->getMockForAbstractClass(AttributeOptionManagementInterface::class);
+ $this->eavOptionUpdateMock = $this->getMockForAbstractClass(AttributeOptionUpdateInterface::class);
$this->model = new OptionManagement(
- $this->eavOptionManagementMock
+ $this->eavOptionManagementMock,
+ $this->eavOptionUpdateMock
);
}
+ /**
+ * Test to Retrieve list of attribute options
+ */
public function testGetItems()
{
$attributeCode = 10;
@@ -44,6 +58,9 @@ public function testGetItems()
$this->assertEquals([], $this->model->getItems($attributeCode));
}
+ /**
+ * Test to Add option to attribute
+ */
public function testAdd()
{
$attributeCode = 42;
@@ -56,6 +73,9 @@ public function testAdd()
$this->assertTrue($this->model->add($attributeCode, $optionMock));
}
+ /**
+ * Test to delete attribute option
+ */
public function testDelete()
{
$attributeCode = 'atrCde';
@@ -68,6 +88,9 @@ public function testDelete()
$this->assertTrue($this->model->delete($attributeCode, $optionId));
}
+ /**
+ * Test to delete attribute option with invalid option id
+ */
public function testDeleteWithInvalidOption()
{
$this->expectException('Magento\Framework\Exception\InputException');
@@ -77,4 +100,24 @@ public function testDeleteWithInvalidOption()
$this->eavOptionManagementMock->expects($this->never())->method('delete');
$this->model->delete($attributeCode, $optionId);
}
+
+ /**
+ * Test to update attribute option
+ */
+ public function testUpdate()
+ {
+ $attributeCode = 'atrCde';
+ $optionId = 10;
+ $optionMock = $this->getMockForAbstractClass(AttributeOptionInterface::class);
+
+ $this->eavOptionUpdateMock->expects($this->once())
+ ->method('update')
+ ->with(
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
+ $attributeCode,
+ $optionId,
+ $optionMock
+ )->willReturn(true);
+ $this->assertTrue($this->model->update($attributeCode, $optionId, $optionMock));
+ }
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
index 539489f18f404..0e6fb8ececf03 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
@@ -24,6 +24,8 @@
use PHPUnit\Framework\TestCase;
/**
+ * Test file option type
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class FileTest extends TestCase
@@ -142,6 +144,14 @@ protected function getFileObject()
);
}
+ public function testGetFormattedOptionValueWithUnserializedValue()
+ {
+ $fileObject = $this->getFileObject();
+
+ $value = 'some unserialized value, 1, 2.test';
+ $this->assertEquals($value, $fileObject->getFormattedOptionValue($value));
+ }
+
public function testGetCustomizedView()
{
$fileObject = $this->getFileObject();
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 5a7a3135b4bfe..97a787c87bfa8 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -35,6 +35,7 @@
+
diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml
index 3f82175ab02eb..5e799cd9f426d 100644
--- a/app/code/Magento/Catalog/etc/webapi.xml
+++ b/app/code/Magento/Catalog/etc/webapi.xml
@@ -183,6 +183,12 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml
index d1f9ebd4c99a4..3aacc75d0b4a4 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminApplyCatalogRuleByCategoryTest.xml
@@ -42,7 +42,7 @@
-
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml
index fcae0065f1b53..61c5ab1795553 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleByPercentTest.xml
@@ -42,7 +42,7 @@
-
+
@@ -61,8 +61,7 @@
-
-
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleWithInvalidDataTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleWithInvalidDataTest.xml
index 90a0835508b06..77228dde8797f 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleWithInvalidDataTest.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest/AdminCreateCatalogPriceRuleWithInvalidDataTest.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml
index 6b34fd1e67e9b..6666e80f3ee04 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminDeleteCatalogPriceRuleEntityTest/AdminDeleteCatalogPriceRuleEntityFromConfigurableProductTest.xml
@@ -131,9 +131,7 @@
-
-
-
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml
index 1919f7d5cc544..56144b5908868 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogPriceRuleByProductAttributeTest.xml
@@ -232,9 +232,8 @@
-
-
-
+
+
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml
index 329f5e8cae3f6..ad426c4bc6c4c 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Mftf/Test/AdminUrlForProductRewrittenCorrectlyTest.xml
@@ -56,8 +56,7 @@
-
-
+
diff --git a/app/code/Magento/Checkout/Model/Cart.php b/app/code/Magento/Checkout/Model/Cart.php
index cec99909dc999..9f1ff991c93e3 100644
--- a/app/code/Magento/Checkout/Model/Cart.php
+++ b/app/code/Magento/Checkout/Model/Cart.php
@@ -18,6 +18,7 @@
* @api
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @deprecated 100.1.0 Use \Magento\Quote\Model\Quote instead
* @see \Magento\Quote\Api\Data\CartInterface
*/
@@ -272,6 +273,10 @@ public function addOrderItem($orderItem, $qtyFlag = null)
* with the same id may have different sets of order attributes.
*/
$product = $this->productRepository->getById($orderItem->getProductId(), false, $storeId, true);
+ if ($orderItem->getOrderId() !== null) {
+ //reorder existing order
+ $product->setSkipCheckRequiredOption(true);
+ }
} catch (NoSuchEntityException $e) {
return $this;
}
@@ -282,7 +287,14 @@ public function addOrderItem($orderItem, $qtyFlag = null)
} else {
$info->setQty(1);
}
-
+ $productOptions = $orderItem->getProductOptions();
+ if ($productOptions !== null && !empty($productOptions['options'])) {
+ $formattedOptions = [];
+ foreach ($productOptions['options'] as $option) {
+ $formattedOptions[$option['option_id']] = $option['option_value'];
+ }
+ $info->setData('options', $formattedOptions);
+ }
$this->addProduct($product, $info);
}
return $this;
@@ -291,8 +303,8 @@ public function addOrderItem($orderItem, $qtyFlag = null)
/**
* Get product object based on requested product information
*
- * @param Product|int|string $productInfo
- * @return Product
+ * @param Product|int|string $productInfo
+ * @return Product
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getProduct($productInfo)
@@ -332,8 +344,8 @@ protected function _getProduct($productInfo)
/**
* Get request for product add to cart procedure
*
- * @param \Magento\Framework\DataObject|int|array $requestInfo
- * @return \Magento\Framework\DataObject
+ * @param \Magento\Framework\DataObject|int|array $requestInfo
+ * @return \Magento\Framework\DataObject
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getProductRequest($requestInfo)
diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php
index 9b02050156cc7..f942e62588f0e 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepository/ValidationCompositeTest.php
@@ -43,7 +43,7 @@ public function testConstructorValidation($validators)
new ValidationComposite($this->subject, $validators);
}
- public function testSaveInvokesValidatorsWithSucess()
+ public function testSaveInvokesValidatorsWithSuccess()
{
$validator1 = $this->getMockForAbstractClass(ValidatorInterface::class);
$validator2 = $this->getMockForAbstractClass(ValidatorInterface::class);
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAddDefaultImageConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAddDefaultImageConfigurableTest.xml
index 0d83cc6610194..9628121348476 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAddDefaultImageConfigurableTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminAddDefaultImageConfigurableTest.xml
@@ -81,7 +81,7 @@
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckConfigurableProductAttributeValueUniquenessTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckConfigurableProductAttributeValueUniquenessTest.xml
index 8962efbb8dd26..43083ee13b0fc 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckConfigurableProductAttributeValueUniquenessTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckConfigurableProductAttributeValueUniquenessTest.xml
@@ -46,8 +46,7 @@
-
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest/AdminCreateConfigurableProductAfterGettingIncorrectSKUMessageTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest/AdminCreateConfigurableProductAfterGettingIncorrectSKUMessageTest.xml
index 274a75aedbc5f..d53cc5f34b967 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest/AdminCreateConfigurableProductAfterGettingIncorrectSKUMessageTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductCreateTest/AdminCreateConfigurableProductAfterGettingIncorrectSKUMessageTest.xml
@@ -60,8 +60,7 @@
-
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml
index e5456429373e1..abe4ce5e46661 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductBasedOnParentSkuTest.xml
@@ -68,8 +68,7 @@
-
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRelatedProductsTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRelatedProductsTest.xml
index b6b3d21c8a626..3ca6b21e7dbb9 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRelatedProductsTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRelatedProductsTest.xml
@@ -81,7 +81,7 @@
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRemoveDefaultImageConfigurableTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRemoveDefaultImageConfigurableTest.xml
index 86d4070a9a2c8..4a28e76851b25 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRemoveDefaultImageConfigurableTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminRemoveDefaultImageConfigurableTest.xml
@@ -81,7 +81,7 @@
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml
index fbf23597a3927..77579c4d90ad5 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml
@@ -117,8 +117,7 @@
-
-
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Product/Initialization/CleanConfigurationTmpImagesTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Product/Initialization/CleanConfigurationTmpImagesTest.php
index 0a014b9aeef99..bb79c13bba82a 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Product/Initialization/CleanConfigurationTmpImagesTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/Product/Initialization/CleanConfigurationTmpImagesTest.php
@@ -64,7 +64,7 @@ class CleanConfigurationTmpImagesTest extends TestCase
/**
* @var Json|MockObject
*/
- private $seralizer;
+ private $serializer;
/**
* @var ProductInitializationHelper|MockObject
@@ -87,7 +87,7 @@ protected function setUp(): void
$this->writeFolder = $this->getMockBuilder(Write::class)
->disableOriginalConstructor()
->getMock();
- $this->seralizer = $this->getMockBuilder(Json::class)
+ $this->serializer = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->getMock();
$this->subjectMock = $this->getMockBuilder(ProductInitializationHelper::class)
@@ -106,7 +106,7 @@ protected function setUp(): void
'fileStorageDb' => $this->fileStorageDb,
'mediaConfig' => $this->mediaConfig,
'filesystem' => $this->filesystem,
- 'seralizer' => $this->seralizer
+ 'serializer' => $this->serializer
]
);
}
diff --git a/app/code/Magento/Cookie/Test/Unit/Helper/CookieTest.php b/app/code/Magento/Cookie/Test/Unit/Helper/CookieTest.php
index 9e370a186d272..6522c3ad1dcaa 100644
--- a/app/code/Magento/Cookie/Test/Unit/Helper/CookieTest.php
+++ b/app/code/Magento/Cookie/Test/Unit/Helper/CookieTest.php
@@ -162,6 +162,6 @@ public function getConfigMethodStub($hashName)
return $defaultConfig[$hashName];
}
- throw new \InvalidArgumentException('Unknow id = ' . $hashName);
+ throw new \InvalidArgumentException('Unknown id = ' . $hashName);
}
}
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php b/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
index 0e2eb3e1d8e65..c7b44288bc85f 100644
--- a/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
+++ b/app/code/Magento/Customer/Model/ResourceModel/Address/Grid/Collection.php
@@ -185,7 +185,7 @@ public function addFieldToFilter($field, $condition = null)
{
if ($field === 'region') {
$conditionSql = $this->_getConditionSql(
- $this->getRegionNameExpresion(),
+ $this->getRegionNameExpression(),
$condition
);
$this->getSelect()->where($conditionSql);
@@ -211,7 +211,7 @@ public function addFullTextFilter(string $value)
$whereCondition = '';
foreach ($fields as $key => $field) {
$field = $field === 'region'
- ? $this->getRegionNameExpresion()
+ ? $this->getRegionNameExpression()
: 'main_table.' . $field;
$condition = $this->_getConditionSql(
$this->getConnection()->quoteIdentifier($field),
@@ -246,18 +246,18 @@ private function joinRegionNameTable()
)->joinLeft(
['rnt' => $this->getTable('directory_country_region_name')],
"rnt.region_id={$regionIdField} AND {$localeCondition}",
- ['region' => $this->getRegionNameExpresion()]
+ ['region' => $this->getRegionNameExpression()]
);
return $this;
}
/**
- * Get SQL Expresion to define Region Name field by locale
+ * Get SQL Expression to define Region Name field by locale
*
* @return \Zend_Db_Expr
*/
- private function getRegionNameExpresion(): \Zend_Db_Expr
+ private function getRegionNameExpression(): \Zend_Db_Expr
{
$connection = $this->getConnection();
$defaultNameExpr = $connection->getIfNullSql(
diff --git a/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php b/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php
index bf8ef767063bd..0fab27161ce25 100644
--- a/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php
+++ b/app/code/Magento/Customer/Model/ResourceModel/Grid/Collection.php
@@ -74,7 +74,7 @@ public function addFieldToFilter($field, $condition = null)
{
if ($field === 'billing_region') {
$conditionSql = $this->_getConditionSql(
- $this->getRegionNameExpresion(),
+ $this->getRegionNameExpression(),
$condition
);
$this->getSelect()->where($conditionSql);
@@ -100,7 +100,7 @@ public function addFullTextFilter(string $value)
$whereCondition = '';
foreach ($fields as $key => $field) {
$field = $field === 'billing_region'
- ? $this->getRegionNameExpresion()
+ ? $this->getRegionNameExpression()
: 'main_table.' . $field;
$condition = $this->_getConditionSql(
$this->getConnection()->quoteIdentifier($field),
@@ -152,18 +152,18 @@ private function joinRegionNameTable()
)->joinLeft(
['rnt' => $this->getTable('directory_country_region_name')],
"rnt.region_id={$regionIdField} AND {$localeCondition}",
- ['billing_region' => $this->getRegionNameExpresion()]
+ ['billing_region' => $this->getRegionNameExpression()]
);
return $this;
}
/**
- * Get SQL Expresion to define Region Name field by locale
+ * Get SQL Expression to define Region Name field by locale
*
* @return \Zend_Db_Expr
*/
- private function getRegionNameExpresion(): \Zend_Db_Expr
+ private function getRegionNameExpression(): \Zend_Db_Expr
{
$connection = $this->getConnection();
$defaultNameExpr = $connection->getIfNullSql(
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml
index 80cdeadb391da..85f4976c88572 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/StorefrontCheckTaxAddingValidVATIdTest.xml
@@ -83,9 +83,7 @@
-
-
-
+
diff --git a/app/code/Magento/Downloadable/Controller/Download/Sample.php b/app/code/Magento/Downloadable/Controller/Download/Sample.php
index e2561092a7592..839083b320878 100644
--- a/app/code/Magento/Downloadable/Controller/Download/Sample.php
+++ b/app/code/Magento/Downloadable/Controller/Download/Sample.php
@@ -3,14 +3,21 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
declare(strict_types=1);
namespace Magento\Downloadable\Controller\Download;
+use Magento\Downloadable\Controller\Download;
use Magento\Downloadable\Helper\Download as DownloadHelper;
+use Magento\Downloadable\Helper\File;
use Magento\Downloadable\Model\RelatedProductRetriever;
use Magento\Downloadable\Model\Sample as SampleModel;
+use Magento\Downloadable\Model\SampleFactory;
use Magento\Framework\App\Action\Context;
+use Magento\Catalog\Model\Product\Attribute\Source\Status;
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResponseInterface;
/**
@@ -18,24 +25,49 @@
*
* @SuppressWarnings(PHPMD.AllPurposeAction)
*/
-class Sample extends \Magento\Downloadable\Controller\Download
+class Sample extends Download
{
/**
* @var RelatedProductRetriever
*/
private $relatedProductRetriever;
+ /**
+ * @var File
+ */
+ private $file;
+
+ /**
+ * @var SampleFactory
+ */
+ private $sampleFactory;
+
+ /**
+ * @var StockConfigurationInterface
+ */
+ private $stockConfiguration;
+
/**
* @param Context $context
* @param RelatedProductRetriever $relatedProductRetriever
+ * @param File|null $file
+ * @param SampleFactory|null $sampleFactory
+ * @param StockConfigurationInterface|null $stockConfiguration
*/
public function __construct(
Context $context,
- RelatedProductRetriever $relatedProductRetriever
+ RelatedProductRetriever $relatedProductRetriever,
+ ?File $file = null,
+ ?SampleFactory $sampleFactory = null,
+ ?StockConfigurationInterface $stockConfiguration = null
) {
parent::__construct($context);
$this->relatedProductRetriever = $relatedProductRetriever;
+ $this->file = $file ?: ObjectManager::getInstance()->get(File::class);
+ $this->sampleFactory = $sampleFactory ?: ObjectManager::getInstance()->get(SampleFactory::class);
+ $this->stockConfiguration = $stockConfiguration
+ ?: ObjectManager::getInstance()->get(StockConfigurationInterface::class);
}
/**
@@ -47,43 +79,60 @@ public function execute()
{
$sampleId = $this->getRequest()->getParam('sample_id', 0);
/** @var SampleModel $sample */
- $sample = $this->_objectManager->create(SampleModel::class);
+ $sample = $this->sampleFactory->create();
$sample->load($sampleId);
- if ($sample->getId() && $this->isProductSalable($sample)) {
- $resource = '';
- $resourceType = '';
- if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
- $resource = $sample->getSampleUrl();
- $resourceType = DownloadHelper::LINK_TYPE_URL;
- } elseif ($sample->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
- /** @var \Magento\Downloadable\Helper\File $helper */
- $helper = $this->_objectManager->get(\Magento\Downloadable\Helper\File::class);
- $resource = $helper->getFilePath($sample->getBasePath(), $sample->getSampleFile());
- $resourceType = DownloadHelper::LINK_TYPE_FILE;
- }
- try {
- $this->_processDownload($resource, $resourceType);
- // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
- exit(0);
- } catch (\Exception $e) {
- $this->messageManager->addError(
- __('Sorry, there was an error getting requested content. Please contact the store owner.')
- );
- }
+ if ($this->isCanDownload($sample)) {
+ $this->download($sample);
}
return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
}
/**
- * Check is related product salable.
+ * Is sample can be downloaded
*
* @param SampleModel $sample
* @return bool
*/
- private function isProductSalable(SampleModel $sample): bool
+ private function isCanDownload(SampleModel $sample): bool
{
$product = $this->relatedProductRetriever->getProduct((int) $sample->getProductId());
- return $product ? $product->isSalable() : false;
+ if ($product && $sample->getId()) {
+ $isProductEnabled = (int) $product->getStatus() === Status::STATUS_ENABLED;
+
+ return $product->isSalable() || $this->stockConfiguration->isShowOutOfStock() && $isProductEnabled;
+ }
+
+ return false;
+ }
+
+ /**
+ * Download process
+ *
+ * @param SampleModel $sample
+ * @return void
+ */
+ private function download(SampleModel $sample): void
+ {
+ $resource = '';
+ $resourceType = '';
+
+ if ($sample->getSampleType() === DownloadHelper::LINK_TYPE_URL) {
+ $resource = $sample->getSampleUrl();
+ $resourceType = DownloadHelper::LINK_TYPE_URL;
+ } elseif ($sample->getSampleType() === DownloadHelper::LINK_TYPE_FILE) {
+ $resource = $this->file->getFilePath($sample->getBasePath(), $sample->getSampleFile());
+ $resourceType = DownloadHelper::LINK_TYPE_FILE;
+ }
+
+ try {
+ $this->_processDownload($resource, $resourceType);
+ // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage
+ exit(0);
+ } catch (\Exception $e) {
+ $this->messageManager->addErrorMessage(
+ __('Sorry, there was an error getting requested content. Please contact the store owner.')
+ );
+ }
}
}
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
index 2986532ef1138..9dca730dfd5c5 100644
--- a/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
+++ b/app/code/Magento/Downloadable/Test/Mftf/Data/ProductData.xml
@@ -105,4 +105,15 @@
downloadableLink1
downloadableLink2
+
+ downloadableproduct
+ downloadable
+ 4
+ DownloadableProduct
+ 99.99
+ 50
+ 1
+ 0
+ downloadableproduct
+
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml
index c634a8426eac0..59aae6f5f28a3 100644
--- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml
+++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminAddDefaultImageDownloadableProductTest.xml
@@ -27,7 +27,7 @@
-
+
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml
index 27d3d3d10a0b7..24917a8b332ed 100644
--- a/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml
+++ b/app/code/Magento/Downloadable/Test/Mftf/Test/AdminRemoveDefaultImageDownloadableProductTest.xml
@@ -24,7 +24,7 @@
-
+
diff --git a/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml
new file mode 100644
index 0000000000000..337d4c7dd38b5
--- /dev/null
+++ b/app/code/Magento/Downloadable/Test/Mftf/Test/VerifyOutOfStockDownloadableProductSamplesAreAccessibleTest.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php b/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php
index 84aefa700a52a..5359230c08c2a 100644
--- a/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php
+++ b/app/code/Magento/Eav/Api/AttributeOptionManagementInterface.php
@@ -15,8 +15,8 @@ interface AttributeOptionManagementInterface
/**
* Add option to attribute
*
- * @param string $attributeCode
* @param int $entityType
+ * @param string $attributeCode
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @throws \Magento\Framework\Exception\StateException
* @throws \Magento\Framework\Exception\InputException
diff --git a/app/code/Magento/Eav/Api/AttributeOptionUpdateInterface.php b/app/code/Magento/Eav/Api/AttributeOptionUpdateInterface.php
new file mode 100644
index 0000000000000..fd755a08fdf9a
--- /dev/null
+++ b/app/code/Magento/Eav/Api/AttributeOptionUpdateInterface.php
@@ -0,0 +1,35 @@
+attributeRepository = $attributeRepository;
$this->resourceModel = $resourceModel;
@@ -45,45 +50,100 @@ public function __construct(
*
* @param int $entityType
* @param string $attributeCode
- * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
+ * @param AttributeOptionInterface $option
* @return string
* @throws InputException
* @throws NoSuchEntityException
* @throws StateException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function add($entityType, $attributeCode, $option)
{
- if (empty($attributeCode)) {
- throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
+ $attribute = $this->loadAttribute($entityType, (string)$attributeCode);
+
+ $label = trim($option->getLabel() ?: '');
+ if (empty($label)) {
+ throw new InputException(__('The attribute option label is empty. Enter the value and try again.'));
}
- $attribute = $this->attributeRepository->get($entityType, $attributeCode);
- if (!$attribute->usesSource()) {
- throw new StateException(__('The "%1" attribute doesn\'t work with options.', $attributeCode));
+ if ($attribute->getSource()->getOptionId($label) !== null) {
+ throw new InputException(
+ __(
+ 'Admin store attribute option label "%1" is already exists.',
+ $option->getLabel()
+ )
+ );
}
- $optionLabel = $option->getLabel();
- $optionId = $this->getOptionId($option);
- $options = [];
- $options['value'][$optionId][0] = $optionLabel;
- $options['order'][$optionId] = $option->getSortOrder();
+ $optionId = $this->getNewOptionId($option);
+ $this->saveOption($attribute, $option, $optionId);
- if (is_array($option->getStoreLabels())) {
- foreach ($option->getStoreLabels() as $label) {
- $options['value'][$optionId][$label->getStoreId()] = $label->getLabel();
- }
- }
+ return $this->retrieveOptionId($attribute, $option);
+ }
- if (!$this->isAttributeOptionLabelExists($attribute, (string) $options['value'][$optionId][0])) {
+ /**
+ * @inheritdoc
+ */
+ public function update(
+ string $entityType,
+ string $attributeCode,
+ int $optionId,
+ AttributeOptionInterface $option
+ ): bool {
+ $attribute = $this->loadAttribute($entityType, (string)$attributeCode);
+ if (empty($optionId)) {
+ throw new InputException(__('The option id is empty. Enter the value and try again.'));
+ }
+ $label = trim($option->getLabel() ?: '');
+ if (empty($label)) {
+ throw new InputException(__('The attribute option label is empty. Enter the value and try again.'));
+ }
+ if ($attribute->getSource()->getOptionText($optionId) === false) {
throw new InputException(
__(
- 'Admin store attribute option label "%1" is already exists.',
- $options['value'][$optionId][0]
+ 'The \'%1\' attribute doesn\'t include an option id \'%2\'.',
+ $attribute->getAttributeCode(),
+ $optionId
+ )
+ );
+ }
+ $optionIdByLabel = $attribute->getSource()->getOptionId($label);
+ if (!empty($optionIdByLabel) && (int)$optionIdByLabel !== (int)$optionId) {
+ throw new InputException(
+ __(
+ 'Admin store attribute option label \'%1\' is already exists.',
+ $option->getLabel()
)
);
}
+ $this->saveOption($attribute, $option, $optionId);
+
+ return true;
+ }
+
+ /**
+ * Save attribute option
+ *
+ * @param EavAttributeInterface $attribute
+ * @param AttributeOptionInterface $option
+ * @param int|string $optionId
+ * @return AttributeOptionInterface
+ * @throws StateException
+ */
+ private function saveOption(
+ EavAttributeInterface $attribute,
+ AttributeOptionInterface $option,
+ $optionId
+ ): AttributeOptionInterface {
+ $optionLabel = trim($option->getLabel());
+ $options = [];
+ $options['value'][$optionId][0] = $optionLabel;
+ $options['order'][$optionId] = $option->getSortOrder();
+ if (is_array($option->getStoreLabels())) {
+ foreach ($option->getStoreLabels() as $label) {
+ $options['value'][$optionId][$label->getStoreId()] = $label->getLabel();
+ }
+ }
if ($option->getIsDefault()) {
$attribute->setDefault([$optionId]);
}
@@ -91,29 +151,35 @@ public function add($entityType, $attributeCode, $option)
$attribute->setOption($options);
try {
$this->resourceModel->save($attribute);
- if ($optionLabel && $attribute->getAttributeCode()) {
- $this->setOptionValue($option, $attribute, $optionLabel);
- }
} catch (\Exception $e) {
- throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
+ throw new StateException(__('The "%1" attribute can\'t be saved.', $attribute->getAttributeCode()));
}
- return $this->getOptionId($option);
+ return $option;
}
/**
- * @inheritdoc
+ * Get option id to create new option
+ *
+ * @param AttributeOptionInterface $option
+ * @return string
*/
- public function delete($entityType, $attributeCode, $optionId)
+ private function getNewOptionId(AttributeOptionInterface $option): string
{
- if (empty($attributeCode)) {
- throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
+ $optionId = trim($option->getValue() ?: '');
+ if (empty($optionId)) {
+ $optionId = 'new_option';
}
- $attribute = $this->attributeRepository->get($entityType, $attributeCode);
- if (!$attribute->usesSource()) {
- throw new StateException(__('The "%1" attribute has no option.', $attributeCode));
- }
+ return 'id_' . $optionId;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function delete($entityType, $attributeCode, $optionId)
+ {
+ $attribute = $this->loadAttribute($entityType, $attributeCode);
$this->validateOption($attribute, $optionId);
$removalMarker = [
@@ -173,63 +239,55 @@ protected function validateOption($attribute, $optionId)
}
/**
- * Returns option id
+ * Load attribute
*
- * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
- * @return string
+ * @param string|int $entityType
+ * @param string $attributeCode
+ * @return EavAttributeInterface
+ * @throws InputException
+ * @throws NoSuchEntityException
+ * @throws StateException
*/
- private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
+ private function loadAttribute($entityType, string $attributeCode): EavAttributeInterface
{
- return 'id_' . ($option->getValue() ?: 'new_option');
+ if (empty($attributeCode)) {
+ throw new InputException(__('The attribute code is empty. Enter the code and try again.'));
+ }
+
+ $attribute = $this->attributeRepository->get($entityType, $attributeCode);
+ if (!$attribute->usesSource()) {
+ throw new StateException(__('The "%1" attribute doesn\'t work with options.', $attributeCode));
+ }
+
+ $attribute->setStoreId(0);
+
+ return $attribute;
}
/**
- * Set option value
+ * Retrieve option id
*
- * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @param EavAttributeInterface $attribute
- * @param string $optionLabel
- * @return void
+ * @param AttributeOptionInterface $option
+ * @return string
*/
- private function setOptionValue(
- \Magento\Eav\Api\Data\AttributeOptionInterface $option,
+ private function retrieveOptionId(
EavAttributeInterface $attribute,
- string $optionLabel
- ) {
- $optionId = $attribute->getSource()->getOptionId($optionLabel);
+ AttributeOptionInterface $option
+ ) : string {
+ $label = trim($option->getLabel());
+ $optionId = $attribute->getSource()->getOptionId($label);
if ($optionId) {
- $option->setValue($attribute->getSource()->getOptionId($optionId));
+ $option->setValue($optionId);
} elseif (is_array($option->getStoreLabels())) {
foreach ($option->getStoreLabels() as $label) {
- if ($optionId = $attribute->getSource()->getOptionId($label->getLabel())) {
- $option->setValue($attribute->getSource()->getOptionId($optionId));
+ $optionId = $attribute->getSource()->getOptionId($label->getLabel());
+ if ($optionId) {
break;
}
}
}
- }
-
- /**
- * Checks if the incoming attribute option label for admin store is already exists.
- *
- * @param EavAttributeInterface $attribute
- * @param string $adminStoreLabel
- * @param int $storeId
- * @return bool
- */
- private function isAttributeOptionLabelExists(
- EavAttributeInterface $attribute,
- string $adminStoreLabel,
- int $storeId = 0
- ) :bool {
- $attribute->setStoreId($storeId);
-
- foreach ($attribute->getSource()->toOptionArray() as $existingAttributeOption) {
- if ($existingAttributeOption['label'] === $adminStoreLabel) {
- return false;
- }
- }
- return true;
+ return (string) $optionId;
}
}
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/OptionManagementTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/OptionManagementTest.php
index 2084db08a1afb..b96b1e26696cd 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/OptionManagementTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/OptionManagementTest.php
@@ -15,10 +15,17 @@
use Magento\Eav\Model\Entity\Attribute\Source\SourceInterface;
use Magento\Eav\Model\Entity\Attribute\Source\Table as EavAttributeSource;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
-use Magento\Framework\Model\AbstractModel;
-use PHPUnit\Framework\MockObject\MockObject;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\StateException;
+use PHPUnit\Framework\MockObject\MockObject as MockObject;
use PHPUnit\Framework\TestCase;
+/**
+ * Tests for Eav Option Management functionality
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
class OptionManagementTest extends TestCase
{
/**
@@ -27,15 +34,18 @@ class OptionManagementTest extends TestCase
protected $model;
/**
- * @var \PHPUnit\Framework\MockObject\MockObject
+ * @var MockObject|AttributeRepository
*/
protected $attributeRepositoryMock;
/**
- * @var \PHPUnit\Framework\MockObject\MockObject
+ * @var MockObject|Attribute
*/
protected $resourceModelMock;
+ /**
+ * @inheritdoc
+ */
protected function setUp(): void
{
$this->attributeRepositoryMock = $this->createMock(AttributeRepository::class);
@@ -47,124 +57,189 @@ protected function setUp(): void
);
}
+ /**
+ * Test to add attribute option
+ */
public function testAdd()
{
$entityType = 42;
+ $storeId = 4;
$attributeCode = 'atrCde';
- $attributeMock = $this->getAttribute();
- $optionMock = $this->getAttributeOption();
- $labelMock = $this->getAttributeOptionLabel();
- $option =
- ['value' => [
+ $label = 'optionLabel';
+ $storeLabel = 'labelLabel';
+ $sortOder = 'optionSortOrder';
+ $option = [
+ 'value' => [
'id_new_option' => [
- 0 => 'optionLabel',
- 42 => 'labelLabel',
+ 0 => $label,
+ $storeId => $storeLabel,
],
],
- 'order' => [
- 'id_new_option' => 'optionSortOrder',
- ],
- ];
+ 'order' => [
+ 'id_new_option' => $sortOder,
+ ]
+ ];
+ $newOptionId = 10;
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
- ->willReturn($attributeMock);
- $attributeMock->expects($this->once())->method('usesSource')->willReturn(true);
- $optionMock->expects($this->once())->method('getLabel')->willReturn('optionLabel');
- $optionMock->expects($this->once())->method('getSortOrder')->willReturn('optionSortOrder');
- $optionMock->expects($this->exactly(2))->method('getStoreLabels')->willReturn([$labelMock]);
- $labelMock->expects($this->once())->method('getStoreId')->willReturn(42);
- $labelMock->expects($this->once())->method('getLabel')->willReturn('labelLabel');
- $optionMock->expects($this->once())->method('getIsDefault')->willReturn(true);
+ $optionMock = $this->getAttributeOption();
+ $labelMock = $this->getAttributeOptionLabel();
+ /** @var SourceInterface|MockObject $sourceMock */
+ $sourceMock = $this->createMock(EavAttributeSource::class);
+ $sourceMock->method('getOptionId')
+ ->willReturnMap(
+ [
+ [$label, null],
+ [$storeLabel, $newOptionId],
+ [$newOptionId, $newOptionId],
+ ]
+ );
+
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['setDefault', 'setOption'])
+ ->onlyMethods(['usesSource', 'getSource'])
+ ->getMock();
+ $attributeMock->method('usesSource')->willReturn(true);
$attributeMock->expects($this->once())->method('setDefault')->with(['id_new_option']);
$attributeMock->expects($this->once())->method('setOption')->with($option);
+ $attributeMock->method('getSource')->willReturn($sourceMock);
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
+ ->willReturn($attributeMock);
+ $optionMock->method('getLabel')->willReturn($label);
+ $optionMock->method('getSortOrder')->willReturn($sortOder);
+ $optionMock->method('getIsDefault')->willReturn(true);
+ $optionMock->method('getStoreLabels')->willReturn([$labelMock]);
+ $labelMock->method('getStoreId')->willReturn($storeId);
+ $labelMock->method('getLabel')->willReturn($storeLabel);
$this->resourceModelMock->expects($this->once())->method('save')->with($attributeMock);
- $this->assertEquals('id_new_option', $this->model->add($entityType, $attributeCode, $optionMock));
+ $this->assertEquals(
+ $newOptionId,
+ $this->model->add($entityType, $attributeCode, $optionMock)
+ );
}
+ /**
+ * Test to add attribute option with empty attribute code
+ */
public function testAddWithEmptyAttributeCode()
{
- $this->expectException('Magento\Framework\Exception\InputException');
- $this->expectExceptionMessage('The attribute code is empty. Enter the code and try again.');
+ $this->expectExceptionMessage("The attribute code is empty. Enter the code and try again.");
+ $this->expectException(InputException::class);
$entityType = 42;
$attributeCode = '';
$optionMock = $this->getAttributeOption();
$this->resourceModelMock->expects($this->never())->method('save');
$this->model->add($entityType, $attributeCode, $optionMock);
}
-
+ /**
+ * Test to add attribute option without use source
+ */
public function testAddWithWrongOptions()
{
- $this->expectException('Magento\Framework\Exception\StateException');
$this->expectExceptionMessage('The "testAttribute" attribute doesn\'t work with options.');
+ $this->expectException(StateException::class);
$entityType = 42;
$attributeCode = 'testAttribute';
- $attributeMock = $this->getAttribute();
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['setDefault', 'setOption', 'setStoreId'])
+ ->onlyMethods(['usesSource', 'getSource'])
+ ->getMock();
$optionMock = $this->getAttributeOption();
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
$attributeMock->expects($this->once())->method('usesSource')->willReturn(false);
$this->resourceModelMock->expects($this->never())->method('save');
$this->model->add($entityType, $attributeCode, $optionMock);
}
+ /**
+ * Test to add attribute option wit save exception
+ */
public function testAddWithCannotSaveException()
{
- $this->expectException('Magento\Framework\Exception\StateException');
+ $this->expectException(StateException::class);
$this->expectExceptionMessage('The "atrCde" attribute can\'t be saved.');
+
$entityType = 42;
+ $storeId = 4;
$attributeCode = 'atrCde';
- $optionMock = $this->getAttributeOption();
- $attributeMock = $this->getAttribute();
- $labelMock = $this->getAttributeOptionLabel();
- $option =
- ['value' => [
+ $label = 'optionLabel';
+ $storeLabel = 'labelLabel';
+ $sortOder = 'optionSortOrder';
+ $option = [
+ 'value' => [
'id_new_option' => [
- 0 => 'optionLabel',
- 42 => 'labelLabel',
+ 0 => $label,
+ $storeId => $storeLabel,
],
],
- 'order' => [
- 'id_new_option' => 'optionSortOrder',
- ],
- ];
+ 'order' => [
+ 'id_new_option' => $sortOder,
+ ]
+ ];
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
- ->willReturn($attributeMock);
- $attributeMock->expects($this->once())->method('usesSource')->willReturn(true);
- $optionMock->expects($this->once())->method('getLabel')->willReturn('optionLabel');
- $optionMock->expects($this->once())->method('getSortOrder')->willReturn('optionSortOrder');
- $optionMock->expects($this->exactly(2))->method('getStoreLabels')->willReturn([$labelMock]);
- $labelMock->expects($this->once())->method('getStoreId')->willReturn(42);
- $labelMock->expects($this->once())->method('getLabel')->willReturn('labelLabel');
- $optionMock->expects($this->once())->method('getIsDefault')->willReturn(true);
+ $optionMock = $this->getAttributeOption();
+ $labelMock = $this->getAttributeOptionLabel();
+ /** @var SourceInterface|MockObject $sourceMock */
+ $sourceMock = $this->createMock(EavAttributeSource::class);
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['setDefault', 'setOption', 'setStoreId'])
+ ->onlyMethods(['usesSource', 'getSource', 'getAttributeCode'])
+ ->getMock();
+ $attributeMock->method('usesSource')->willReturn(true);
$attributeMock->expects($this->once())->method('setDefault')->with(['id_new_option']);
$attributeMock->expects($this->once())->method('setOption')->with($option);
+ $attributeMock->method('getSource')->willReturn($sourceMock);
+ $attributeMock->method('getAttributeCode')->willReturn($attributeCode);
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
+ ->willReturn($attributeMock);
+ $optionMock->method('getLabel')->willReturn($label);
+ $optionMock->method('getSortOrder')->willReturn($sortOder);
+ $optionMock->method('getIsDefault')->willReturn(true);
+ $optionMock->method('getStoreLabels')->willReturn([$labelMock]);
+ $labelMock->method('getStoreId')->willReturn($storeId);
+ $labelMock->method('getLabel')->willReturn($storeLabel);
+
$this->resourceModelMock->expects($this->once())->method('save')->with($attributeMock)
->willThrowException(new \Exception());
$this->model->add($entityType, $attributeCode, $optionMock);
}
+ /**
+ * Test to delete attribute option
+ */
public function testDelete()
{
$entityType = 42;
$attributeCode = 'atrCode';
$optionId = 'option';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['usesSource', 'getSource', 'getId', 'getOptionText', 'addData']
- );
+
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['getOptionText'])
+ ->onlyMethods(['usesSource', 'getSource', 'getId', 'addData'])
+ ->getMock();
$removalMarker = [
'option' => [
'value' => [$optionId => []],
'delete' => [$optionId => '1'],
],
];
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
$attributeMock->expects($this->once())->method('usesSource')->willReturn(true);
$attributeMock->expects($this->once())->method('getSource')->willReturnSelf();
@@ -175,22 +250,23 @@ public function testDelete()
$this->assertTrue($this->model->delete($entityType, $attributeCode, $optionId));
}
+ /**
+ * Test to delete attribute option with save exception
+ */
public function testDeleteWithCannotSaveException()
{
- $this->expectException('Magento\Framework\Exception\StateException');
$this->expectExceptionMessage('The "atrCode" attribute can\'t be saved.');
+ $this->expectException(StateException::class);
+
$entityType = 42;
$attributeCode = 'atrCode';
$optionId = 'option';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['usesSource', 'getSource', 'getId', 'getOptionText', 'addData']
- );
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['getOptionText'])
+ ->onlyMethods(['usesSource', 'getSource', 'getId', 'addData'])
+ ->getMock();
$removalMarker = [
'option' => [
'value' => [$optionId => []],
@@ -204,28 +280,29 @@ public function testDeleteWithCannotSaveException()
$attributeMock->expects($this->once())->method('getOptionText')->willReturn('optionText');
$attributeMock->expects($this->never())->method('getId');
$attributeMock->expects($this->once())->method('addData')->with($removalMarker);
- $this->resourceModelMock->expects($this->once())->method('save')->with($attributeMock)
+ $this->resourceModelMock->expects($this->once())
+ ->method('save')
+ ->with($attributeMock)
->willThrowException(new \Exception());
$this->model->delete($entityType, $attributeCode, $optionId);
}
+ /**
+ * Test to delete with wrong option
+ */
public function testDeleteWithWrongOption()
{
- $this->expectException('Magento\Framework\Exception\NoSuchEntityException');
$this->expectExceptionMessage('The "atrCode" attribute doesn\'t include an option with "option" ID.');
+ $this->expectException(NoSuchEntityException::class);
+
$entityType = 42;
$attributeCode = 'atrCode';
$optionId = 'option';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['usesSource', 'getSource', 'getAttributeCode']
- );
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->createMock(EavAbstractAttribute::class);
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
$sourceMock = $this->getMockForAbstractClass(SourceInterface::class);
$sourceMock->expects($this->once())->method('getOptionText')->willReturn(false);
@@ -236,33 +313,40 @@ public function testDeleteWithWrongOption()
$this->model->delete($entityType, $attributeCode, $optionId);
}
+ /**
+ * Test to delete with absent option
+ */
public function testDeleteWithAbsentOption()
{
- $this->expectException('Magento\Framework\Exception\StateException');
- $this->expectExceptionMessage('The "atrCode" attribute has no option.');
+ $this->expectExceptionMessage('The "atrCode" attribute doesn\'t work with options.');
+ $this->expectException(StateException::class);
+
$entityType = 42;
$attributeCode = 'atrCode';
$optionId = 'option';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['usesSource', 'getSource', 'getId', 'getOptionText', 'addData']
- );
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ /** @var EavAbstractAttribute|MockObject $attributeMock */
+ $attributeMock = $this->getMockBuilder(EavAbstractAttribute::class)
+ ->disableOriginalConstructor()
+ ->addMethods(['getOptionText'])
+ ->onlyMethods(['usesSource', 'getSource', 'getId', 'addData'])
+ ->getMock();
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
$attributeMock->expects($this->once())->method('usesSource')->willReturn(false);
$this->resourceModelMock->expects($this->never())->method('save');
$this->model->delete($entityType, $attributeCode, $optionId);
}
+ /**
+ * Test to delete with empty attribute code
+ */
public function testDeleteWithEmptyAttributeCode()
{
- $this->expectException('Magento\Framework\Exception\InputException');
- $this->expectExceptionMessage('The attribute code is empty. Enter the code and try again.');
+ $this->expectExceptionMessage("The attribute code is empty. Enter the code and try again.");
+ $this->expectException(InputException::class);
+
$entityType = 42;
$attributeCode = '';
$optionId = 'option';
@@ -270,86 +354,56 @@ public function testDeleteWithEmptyAttributeCode()
$this->model->delete($entityType, $attributeCode, $optionId);
}
+ /**
+ * Test to get items
+ */
public function testGetItems()
{
$entityType = 42;
$attributeCode = 'atrCode';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['getOptions']
- );
- $optionsMock = [$this->getMockForAbstractClass(EavAttributeOptionInterface::class)];
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ $attributeMock = $this->createMock(EavAbstractAttribute::class);
+ $optionsMock = [$this->createMock(EavAttributeOptionInterface::class)];
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
$attributeMock->expects($this->once())->method('getOptions')->willReturn($optionsMock);
$this->assertEquals($optionsMock, $this->model->getItems($entityType, $attributeCode));
}
+ /**
+ * Test to get items with load exception
+ */
public function testGetItemsWithCannotLoadException()
{
- $this->expectException('Magento\Framework\Exception\StateException');
$this->expectExceptionMessage('The options for "atrCode" attribute can\'t be loaded.');
+ $this->expectException(StateException::class);
$entityType = 42;
$attributeCode = 'atrCode';
- $attributeMock = $this->getMockForAbstractClass(
- AbstractModel::class,
- [],
- '',
- false,
- false,
- true,
- ['getOptions']
- );
- $this->attributeRepositoryMock->expects($this->once())->method('get')->with($entityType, $attributeCode)
+ $attributeMock = $this->createMock(EavAbstractAttribute::class);
+ $this->attributeRepositoryMock->expects($this->once())
+ ->method('get')
+ ->with($entityType, $attributeCode)
->willReturn($attributeMock);
- $attributeMock->expects($this->once())->method('getOptions')->willThrowException(new \Exception());
+ $attributeMock->expects($this->once())
+ ->method('getOptions')
+ ->willThrowException(new \Exception());
$this->model->getItems($entityType, $attributeCode);
}
+ /**
+ * Test to get items with empty attribute code
+ */
public function testGetItemsWithEmptyAttributeCode()
{
- $this->expectException('Magento\Framework\Exception\InputException');
- $this->expectExceptionMessage('The attribute code is empty. Enter the code and try again.');
+ $this->expectExceptionMessage("The attribute code is empty. Enter the code and try again.");
+ $this->expectException(InputException::class);
+
$entityType = 42;
$attributeCode = '';
$this->model->getItems($entityType, $attributeCode);
}
- /**
- * Returns attribute entity mock.
- *
- * @param array $attributeOptions attribute options for return
- * @return MockObject|EavAbstractAttribute
- */
- private function getAttribute(array $attributeOptions = [])
- {
- $attribute = $this->getMockBuilder(EavAbstractAttribute::class)
- ->disableOriginalConstructor()
- ->setMethods(
- [
- 'usesSource',
- 'setDefault',
- 'setOption',
- 'setStoreId',
- 'getSource',
- ]
- )
- ->getMock();
- $source = $this->getMockBuilder(EavAttributeSource::class)
- ->disableOriginalConstructor()
- ->getMock();
-
- $attribute->method('getSource')->willReturn($source);
- $source->method('toOptionArray')->willReturn($attributeOptions);
-
- return $attribute;
- }
-
/**
* Return attribute option entity mock.
*
diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml
index 21f248f1b1094..4f5d7d7112961 100644
--- a/app/code/Magento/Eav/etc/di.xml
+++ b/app/code/Magento/Eav/etc/di.xml
@@ -20,6 +20,7 @@
+
diff --git a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Client/Elasticsearch.php
index 8d8787a5eff72..1ea2b6958734c 100644
--- a/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Client/Elasticsearch.php
+++ b/app/code/Magento/Elasticsearch/Elasticsearch5/Model/Client/Elasticsearch.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Elasticsearch\Elasticsearch5\Model\Client;
use Magento\Framework\Exception\LocalizedException;
@@ -11,7 +12,7 @@
/**
* Elasticsearch client
*
- * @deprecated the Elasticsearch 5 doesn't supported due to EOL
+ * @deprecated 100.3.5 the Elasticsearch 5 doesn't supported due to EOL
*/
class Elasticsearch implements ClientInterface
{
@@ -48,8 +49,10 @@ public function __construct(
$options = [],
$elasticsearchClient = null
) {
- if (empty($options['hostname']) || ((!empty($options['enableAuth']) &&
- ($options['enableAuth'] == 1)) && (empty($options['username']) || empty($options['password'])))) {
+ if (empty($options['hostname'])
+ || ((!empty($options['enableAuth']) && ($options['enableAuth'] == 1))
+ && (empty($options['username']) || empty($options['password'])))
+ ) {
throw new LocalizedException(
__('The search failed because of a search engine misconfiguration.')
);
@@ -302,7 +305,15 @@ public function addFieldsMapping(array $fields, $index, $entityType)
]
),
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
@@ -323,7 +334,6 @@ public function addFieldsMapping(array $fields, $index, $entityType)
*/
private function prepareFieldInfo($fieldInfo)
{
-
if (strcmp($this->getServerVersion(), '5') < 0) {
if ($fieldInfo['type'] == 'keyword') {
$fieldInfo['type'] = 'string';
diff --git a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
index 245e4d494afe1..9fa001097df87 100644
--- a/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
+++ b/app/code/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapper.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper;
use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\DataProvider;
@@ -74,7 +75,7 @@ class ProductDataMapper implements BatchDataMapperInterface
private $attributesExcludedFromMerge = [
'status',
'visibility',
- 'tax_class_id'
+ 'tax_class_id',
];
/**
@@ -85,8 +86,11 @@ class ProductDataMapper implements BatchDataMapperInterface
];
/**
- * Construction for DocumentDataMapper
- *
+ * @var string[]
+ */
+ private $filterableAttributeTypes;
+
+ /**
* @param Builder $builder
* @param FieldMapperInterface $fieldMapper
* @param DateFieldType $dateFieldType
@@ -94,6 +98,7 @@ class ProductDataMapper implements BatchDataMapperInterface
* @param DataProvider $dataProvider
* @param array $excludedAttributes
* @param array $sortableAttributesValuesToImplode
+ * @param array $filterableAttributeTypes
*/
public function __construct(
Builder $builder,
@@ -102,7 +107,8 @@ public function __construct(
AdditionalFieldsProviderInterface $additionalFieldsProvider,
DataProvider $dataProvider,
array $excludedAttributes = [],
- array $sortableAttributesValuesToImplode = []
+ array $sortableAttributesValuesToImplode = [],
+ array $filterableAttributeTypes = []
) {
$this->builder = $builder;
$this->fieldMapper = $fieldMapper;
@@ -115,6 +121,7 @@ public function __construct(
$this->additionalFieldsProvider = $additionalFieldsProvider;
$this->dataProvider = $dataProvider;
$this->attributeOptionsCache = [];
+ $this->filterableAttributeTypes = $filterableAttributeTypes;
}
/**
@@ -212,7 +219,7 @@ private function convertAttribute(Attribute $attribute, array $attributeValues,
if ($retrievedValue !== null) {
$productAttributes[$attribute->getAttributeCode()] = $retrievedValue;
- if ($attribute->getIsSearchable()) {
+ if ($this->isAttributeLabelsShouldBeMapped($attribute)) {
$attributeLabels = $this->getValuesLabels($attribute, $attributeValues, $storeId);
$retrievedLabel = $this->retrieveFieldValue($attributeLabels);
if ($retrievedLabel) {
@@ -224,6 +231,26 @@ private function convertAttribute(Attribute $attribute, array $attributeValues,
return $productAttributes;
}
+ /**
+ * Check if an attribute has one of the next storefront properties enabled for mapping labels:
+ * - "Use in Search" (is_searchable)
+ * - "Visible in Advanced Search" (is_visible_in_advanced_search)
+ * - "Use in Layered Navigation" (is_filterable)
+ * - "Use in Search Results Layered Navigation" (is_filterable_in_search)
+ *
+ * @param Attribute $attribute
+ * @return bool
+ */
+ private function isAttributeLabelsShouldBeMapped(Attribute $attribute): bool
+ {
+ return (
+ $attribute->getIsSearchable()
+ || $attribute->getIsVisibleInAdvancedSearch()
+ || $attribute->getIsFilterable()
+ || $attribute->getIsFilterableInSearch()
+ );
+ }
+
/**
* Prepare attribute values.
*
@@ -249,6 +276,15 @@ private function prepareAttributeValues(
$attributeValues = $this->prepareMultiselectValues($attributeValues);
}
+ if (in_array($attribute->getFrontendInput(), $this->filterableAttributeTypes)) {
+ $attributeValues = array_map(
+ function (string $valueId) {
+ return (int)$valueId;
+ },
+ $attributeValues
+ );
+ }
+
if ($this->isAttributeDate($attribute)) {
foreach ($attributeValues as $key => $attributeValue) {
$attributeValues[$key] = $this->dateFieldType->formatDate($storeId, $attributeValue);
diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Client/ElasticsearchTest.php
index 575a64dc43abd..fc146e801124a 100644
--- a/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Client/ElasticsearchTest.php
+++ b/app/code/Magento/Elasticsearch/Test/Unit/Elasticsearch5/Model/Client/ElasticsearchTest.php
@@ -340,7 +340,7 @@ public function testAddFieldsMapping()
'match_mapping_type' => 'string',
'mapping' => [
'type' => 'integer',
- 'index' => true
+ 'index' => true,
],
],
],
@@ -354,6 +354,14 @@ public function testAddFieldsMapping()
],
],
],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
@@ -424,7 +432,15 @@ public function testAddFieldsMappingFailure()
'index' => true,
],
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
diff --git a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
index 2c87549da6075..9f1b59b1bfc81 100644
--- a/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
+++ b/app/code/Magento/Elasticsearch/Test/Unit/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
@@ -21,6 +21,8 @@
use PHPUnit\Framework\TestCase;
/**
+ * Unit tests for \Magento\Elasticsearch\Model\Adapter\BatchDataMapper\ProductDataMapper class.
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ProductDataMapperTest extends TestCase
@@ -56,12 +58,12 @@ class ProductDataMapperTest extends TestCase
private $additionalFieldsProvider;
/**
- * @var MockObject
+ * @var DataProvider|MockObject
*/
private $dataProvider;
/**
- * Set up test environment.
+ * @inheritdoc
*/
protected function setUp(): void
{
@@ -71,6 +73,11 @@ protected function setUp(): void
$this->attribute = $this->createMock(Attribute::class);
$this->additionalFieldsProvider = $this->getMockForAbstractClass(AdditionalFieldsProviderInterface::class);
$this->dateFieldTypeMock = $this->createMock(Date::class);
+ $filterableAttributeTypes = [
+ 'boolean' => 'boolean',
+ 'multiselect' => 'multiselect',
+ 'select' => 'select',
+ ];
$objectManager = new ObjectManagerHelper($this);
$this->model = $objectManager->getObject(
@@ -81,6 +88,7 @@ protected function setUp(): void
'dateFieldType' => $this->dateFieldTypeMock,
'dataProvider' => $this->dataProvider,
'additionalFieldsProvider' => $this->additionalFieldsProvider,
+ 'filterableAttributeTypes' => $filterableAttributeTypes,
]
);
}
@@ -159,8 +167,8 @@ public function testGetMap(int $productId, array $attributeData, $attributeValue
$productId => [$attributeId => $attributeValue],
];
$documents = $this->model->map($documentData, $storeId, $context);
- $returnAttributeData['store_id'] = $storeId;
- $this->assertEquals($returnAttributeData, $documents[$productId]);
+ $returnAttributeData = ['store_id' => $storeId] + $returnAttributeData;
+ $this->assertSame($returnAttributeData, $documents[$productId]);
}
/**
@@ -305,8 +313,8 @@ public static function mapProvider(): array
['value' => '2', 'label' => 'Disabled'],
],
],
- [10 => '1', 11 => '2'],
- ['status' => '1'],
+ [10 => '1', 11 => '2'],
+ ['status' => 1],
],
'select without options' => [
10,
@@ -318,7 +326,7 @@ public static function mapProvider(): array
'options' => [],
],
'44',
- ['color' => '44'],
+ ['color' => 44],
],
'unsearchable select with options' => [
10,
@@ -333,7 +341,7 @@ public static function mapProvider(): array
],
],
'44',
- ['color' => '44'],
+ ['color' => 44],
],
'searchable select with options' => [
10,
@@ -348,7 +356,7 @@ public static function mapProvider(): array
],
],
'44',
- ['color' => '44', 'color_value' => 'red'],
+ ['color' => 44, 'color_value' => 'red'],
],
'composite select with options' => [
10,
@@ -363,7 +371,7 @@ public static function mapProvider(): array
],
],
[10 => '44', 11 => '45'],
- ['color' => ['44', '45'], 'color_value' => ['red', 'black']],
+ ['color' => [44, 45], 'color_value' => ['red', 'black']],
],
'multiselect without options' => [
10,
@@ -430,10 +438,10 @@ public static function mapProvider(): array
'backend_type' => 'int',
'frontend_input' => 'int',
'is_searchable' => false,
- 'options' => []
+ 'options' => [],
],
15,
- []
+ [],
],
];
}
diff --git a/app/code/Magento/Elasticsearch/etc/di.xml b/app/code/Magento/Elasticsearch/etc/di.xml
index 633e67dfe698e..6c1a771958081 100644
--- a/app/code/Magento/Elasticsearch/etc/di.xml
+++ b/app/code/Magento/Elasticsearch/etc/di.xml
@@ -153,6 +153,11 @@
additionalFieldsProviderForElasticsearch
+
+ - boolean
+ - multiselect
+ - select
+
diff --git a/app/code/Magento/Elasticsearch6/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch6/Model/Client/Elasticsearch.php
index 0571b075aff28..e552d0067df84 100644
--- a/app/code/Magento/Elasticsearch6/Model/Client/Elasticsearch.php
+++ b/app/code/Magento/Elasticsearch6/Model/Client/Elasticsearch.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Elasticsearch6\Model\Client;
use Magento\AdvancedSearch\Model\Client\ClientInterface;
@@ -48,8 +49,10 @@ public function __construct(
$elasticsearchClient = null,
$fieldsMappingPreprocessors = []
) {
- if (empty($options['hostname']) || ((!empty($options['enableAuth']) &&
- ($options['enableAuth'] == 1)) && (empty($options['username']) || empty($options['password'])))) {
+ if (empty($options['hostname'])
+ || ((!empty($options['enableAuth']) && ($options['enableAuth'] == 1))
+ && (empty($options['username']) || empty($options['password'])))
+ ) {
throw new LocalizedException(
__('The search failed because of a search engine misconfiguration.')
);
@@ -303,7 +306,15 @@ public function addFieldsMapping(array $fields, $index, $entityType)
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
+ ],
+ ],
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
],
],
],
diff --git a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontElasticsearchSearchInvalidValueTest.xml b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontElasticsearchSearchInvalidValueTest.xml
index e173090bfa318..15aa599b93956 100644
--- a/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontElasticsearchSearchInvalidValueTest.xml
+++ b/app/code/Magento/Elasticsearch6/Test/Mftf/Test/StorefrontElasticsearchSearchInvalidValueTest.xml
@@ -41,11 +41,9 @@
-
-
+
-
-
+
@@ -53,7 +51,7 @@
-
+
diff --git a/app/code/Magento/Elasticsearch6/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch6/Test/Unit/Model/Client/ElasticsearchTest.php
index 2a7fa2ce8114a..427e630ac2099 100644
--- a/app/code/Magento/Elasticsearch6/Test/Unit/Model/Client/ElasticsearchTest.php
+++ b/app/code/Magento/Elasticsearch6/Test/Unit/Model/Client/ElasticsearchTest.php
@@ -461,10 +461,18 @@ public function testAddFieldsMapping()
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
],
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
@@ -531,10 +539,18 @@ public function testAddFieldsMappingFailure()
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
],
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
diff --git a/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php b/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php
index 4b318f987abfe..a16a70b1cd702 100644
--- a/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php
+++ b/app/code/Magento/Elasticsearch7/Model/Client/Elasticsearch.php
@@ -51,8 +51,10 @@ public function __construct(
$elasticsearchClient = null,
$fieldsMappingPreprocessors = []
) {
- if (empty($options['hostname']) || ((!empty($options['enableAuth']) &&
- ($options['enableAuth'] == 1)) && (empty($options['username']) || empty($options['password'])))) {
+ if (empty($options['hostname'])
+ || ((!empty($options['enableAuth']) && ($options['enableAuth'] == 1))
+ && (empty($options['username']) || empty($options['password'])))
+ ) {
throw new LocalizedException(
__('The search failed because of a search engine misconfiguration.')
);
@@ -71,7 +73,7 @@ public function __construct(
* @param array $query
* @return array
*/
- public function suggest(array $query) : array
+ public function suggest(array $query): array
{
return $this->getElasticsearchClient()->suggest($query);
}
@@ -96,7 +98,7 @@ private function getElasticsearchClient(): \Elasticsearch\Client
*
* @return bool
*/
- public function ping() : bool
+ public function ping(): bool
{
if ($this->pingResult === null) {
$this->pingResult = $this->getElasticsearchClient()
@@ -111,7 +113,7 @@ public function ping() : bool
*
* @return bool
*/
- public function testConnection() : bool
+ public function testConnection(): bool
{
return $this->ping();
}
@@ -122,7 +124,7 @@ public function testConnection() : bool
* @param array $options
* @return array
*/
- private function buildESConfig(array $options = []) : array
+ private function buildESConfig(array $options = []): array
{
$hostname = preg_replace('/http[s]?:\/\//i', '', $options['hostname']);
// @codingStandardsIgnoreStart
@@ -194,12 +196,13 @@ public function deleteIndex(string $index)
* @param string $index
* @return bool
*/
- public function isEmptyIndex(string $index) : bool
+ public function isEmptyIndex(string $index): bool
{
$stats = $this->getElasticsearchClient()->indices()->stats(['index' => $index, 'metric' => 'docs']);
- if ($stats['indices'][$index]['primaries']['docs']['count'] === 0) {
+ if ($stats['indices'][$index]['primaries']['docs']['count'] === 0) {
return true;
}
+
return false;
}
@@ -234,7 +237,7 @@ public function updateAlias(string $alias, string $newIndex, string $oldIndex =
* @param string $index
* @return bool
*/
- public function indexExists(string $index) : bool
+ public function indexExists(string $index): bool
{
return $this->getElasticsearchClient()->indices()->exists(['index' => $index]);
}
@@ -246,12 +249,13 @@ public function indexExists(string $index) : bool
* @param string $index
* @return bool
*/
- public function existsAlias(string $alias, string $index = '') : bool
+ public function existsAlias(string $alias, string $index = ''): bool
{
$params = ['name' => $alias];
if ($index) {
$params['index'] = $index;
}
+
return $this->getElasticsearchClient()->indices()->existsAlias($params);
}
@@ -261,7 +265,7 @@ public function existsAlias(string $alias, string $index = '') : bool
* @param string $alias
* @return array
*/
- public function getAlias(string $alias) : array
+ public function getAlias(string $alias): array
{
return $this->getElasticsearchClient()->indices()->getAlias(['name' => $alias]);
}
@@ -311,7 +315,15 @@ public function addFieldsMapping(array $fields, string $index, string $entityTyp
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
+ ],
+ ],
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
],
],
],
@@ -333,7 +345,7 @@ public function addFieldsMapping(array $fields, string $index, string $entityTyp
* @param array $query
* @return array
*/
- public function query(array $query) : array
+ public function query(array $query): array
{
return $this->getElasticsearchClient()->search($query);
}
diff --git a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php b/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php
index 091387f844d55..a31a1971a5acc 100644
--- a/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php
+++ b/app/code/Magento/Elasticsearch7/Test/Unit/Model/Client/ElasticsearchTest.php
@@ -460,10 +460,18 @@ public function testAddFieldsMapping()
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
],
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
@@ -531,10 +539,18 @@ public function testAddFieldsMappingFailure()
'mapping' => [
'type' => 'text',
'index' => true,
- 'copy_to' => '_search'
+ 'copy_to' => '_search',
],
],
- ]
+ ],
+ [
+ 'integer_mapping' => [
+ 'match_mapping_type' => 'long',
+ 'mapping' => [
+ 'type' => 'integer',
+ ],
+ ],
+ ],
],
],
],
diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminAddDefaultImageGroupedProductTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminAddDefaultImageGroupedProductTest.xml
index 04b704b9193ca..0371cdcd843f2 100644
--- a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminAddDefaultImageGroupedProductTest.xml
+++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminAddDefaultImageGroupedProductTest.xml
@@ -32,7 +32,7 @@
-
+
diff --git a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminRemoveDefaultImageGroupedProductTest.xml b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminRemoveDefaultImageGroupedProductTest.xml
index 053949fa20fb2..83f43c3a1cd8a 100644
--- a/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminRemoveDefaultImageGroupedProductTest.xml
+++ b/app/code/Magento/GroupedProduct/Test/Mftf/Test/AdminRemoveDefaultImageGroupedProductTest.xml
@@ -29,7 +29,7 @@
-
+
diff --git a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/UpdateIndexerOnSaveActionGroup.xml b/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/UpdateIndexerOnSaveActionGroup.xml
deleted file mode 100644
index efa6291d5de63..0000000000000
--- a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/IndexerActionGroup/UpdateIndexerOnSaveActionGroup.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
diff --git a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/StorefrontCreateNewSubscriberActionGroup.xml b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/StorefrontCreateNewSubscriberActionGroup.xml
index 0aee2cb9b2e3c..482ecec583552 100644
--- a/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/StorefrontCreateNewSubscriberActionGroup.xml
+++ b/app/code/Magento/Newsletter/Test/Mftf/ActionGroup/StorefrontCreateNewSubscriberActionGroup.xml
@@ -8,7 +8,8 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Newsletter/Test/Mftf/Section/NewsletterTemplateSection/BasicFrontendNewsletterFormSection.xml b/app/code/Magento/Newsletter/Test/Mftf/Section/NewsletterTemplateSection/BasicFrontendNewsletterFormSection.xml
index 8475fb4d55b9e..f4c685e730be3 100644
--- a/app/code/Magento/Newsletter/Test/Mftf/Section/NewsletterTemplateSection/BasicFrontendNewsletterFormSection.xml
+++ b/app/code/Magento/Newsletter/Test/Mftf/Section/NewsletterTemplateSection/BasicFrontendNewsletterFormSection.xml
@@ -8,8 +8,8 @@
diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingDeleteNewsletterSubscriberTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingDeleteNewsletterSubscriberTest.xml
index eea77a6be0784..c472d262a34c8 100644
--- a/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingDeleteNewsletterSubscriberTest.xml
+++ b/app/code/Magento/Newsletter/Test/Mftf/Test/AdminMarketingDeleteNewsletterSubscriberTest.xml
@@ -14,6 +14,7 @@
+
diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontNewsletterGuestSubscriptionWithDisallowedOptionTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontNewsletterGuestSubscriptionWithDisallowedOptionTest.xml
new file mode 100644
index 0000000000000..6c62434f1620e
--- /dev/null
+++ b/app/code/Magento/Newsletter/Test/Mftf/Test/StorefrontNewsletterGuestSubscriptionWithDisallowedOptionTest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifyRegistredLinkDisplayedForGuestSubscriptionNoTest.xml b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifyRegistredLinkDisplayedForGuestSubscriptionNoTest.xml
index cffce8da1d710..dbce742aa0eef 100644
--- a/app/code/Magento/Newsletter/Test/Mftf/Test/VerifyRegistredLinkDisplayedForGuestSubscriptionNoTest.xml
+++ b/app/code/Magento/Newsletter/Test/Mftf/Test/VerifyRegistredLinkDisplayedForGuestSubscriptionNoTest.xml
@@ -8,7 +8,8 @@
-
+
+
@@ -22,6 +23,11 @@
-
+
+
+
+
diff --git a/app/code/Magento/PageCache/Test/Mftf/Test/AdminFrontendAreaSessionMustNotAffectAdminAreaTest.xml b/app/code/Magento/PageCache/Test/Mftf/Test/AdminFrontendAreaSessionMustNotAffectAdminAreaTest.xml
index d2c738398aae1..fdf8ceef0d647 100644
--- a/app/code/Magento/PageCache/Test/Mftf/Test/AdminFrontendAreaSessionMustNotAffectAdminAreaTest.xml
+++ b/app/code/Magento/PageCache/Test/Mftf/Test/AdminFrontendAreaSessionMustNotAffectAdminAreaTest.xml
@@ -61,8 +61,7 @@
-
-
+
diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php
index 9e4f7693f4bfb..33fc7fcccf0db 100644
--- a/app/code/Magento/Paypal/Model/Api/Nvp.php
+++ b/app/code/Magento/Paypal/Model/Api/Nvp.php
@@ -1423,7 +1423,7 @@ protected function _validateResponse($method, $response)
*/
protected function _deformatNVP($nvpstr)
{
- $intial = 0;
+ $initial = 0;
$nvpArray = [];
$nvpstr = strpos($nvpstr, "\r\n\r\n") !== false ? substr($nvpstr, strpos($nvpstr, "\r\n\r\n") + 4) : $nvpstr;
@@ -1435,7 +1435,7 @@ protected function _deformatNVP($nvpstr)
$valuepos = strpos($nvpstr, '&') ? strpos($nvpstr, '&') : strlen($nvpstr);
/*getting the Key and Value values and storing in a Associative Array*/
- $keyval = substr($nvpstr, $intial, $keypos);
+ $keyval = substr($nvpstr, $initial, $keypos);
$valval = substr($nvpstr, $keypos + 1, $valuepos - $keypos - 1);
//decoding the response
$nvpArray[urldecode($keyval)] = urldecode($valval);
diff --git a/app/code/Magento/ProductAlert/Model/Email.php b/app/code/Magento/ProductAlert/Model/Email.php
index 3351166aa6a12..379ae29ef4649 100644
--- a/app/code/Magento/ProductAlert/Model/Email.php
+++ b/app/code/Magento/ProductAlert/Model/Email.php
@@ -1,9 +1,10 @@
_website = $website;
return $this;
@@ -275,7 +276,7 @@ public function clean()
*
* @return $this
*/
- public function addPriceProduct(\Magento\Catalog\Model\Product $product)
+ public function addPriceProduct(Product $product)
{
$this->_priceProducts[$product->getId()] = $product;
return $this;
@@ -288,7 +289,7 @@ public function addPriceProduct(\Magento\Catalog\Model\Product $product)
*
* @return $this
*/
- public function addStockProduct(\Magento\Catalog\Model\Product $product)
+ public function addStockProduct(Product $product)
{
$this->_stockProducts[$product->getId()] = $product;
return $this;
@@ -342,7 +343,7 @@ public function send()
return false;
}
- $storeId = $this->getStoreId() ?: (int) $this->_customer->getStoreId();
+ $storeId = (int) $this->getStoreId() ?: (int) $this->_customer->getStoreId();
$store = $this->getStore($storeId);
$this->_appEmulation->startEnvironmentEmulation($storeId);
@@ -378,12 +379,13 @@ public function send()
'customerName' => $customerName,
'alertGrid' => $alertGrid,
]
- )->setFrom(
+ )->setFromByScope(
$this->_scopeConfig->getValue(
self::XML_PATH_EMAIL_IDENTITY,
ScopeInterface::SCOPE_STORE,
$storeId
- )
+ ),
+ $storeId
)->addTo(
$this->_customer->getEmail(),
$customerName
diff --git a/app/code/Magento/Sales/Block/Order/Email/Items/DefaultItems.php b/app/code/Magento/Sales/Block/Order/Email/Items/DefaultItems.php
index 064405daf89a8..cbb79f188f231 100644
--- a/app/code/Magento/Sales/Block/Order/Email/Items/DefaultItems.php
+++ b/app/code/Magento/Sales/Block/Order/Email/Items/DefaultItems.php
@@ -3,8 +3,12 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Block\Order\Email\Items;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\View\Element\Template;
use Magento\Sales\Model\Order\Creditmemo\Item as CreditmemoItem;
use Magento\Sales\Model\Order\Invoice\Item as InvoiceItem;
use Magento\Sales\Model\Order\Item as OrderItem;
@@ -16,7 +20,7 @@
* @author Magento Core Team
* @since 100.0.2
*/
-class DefaultItems extends \Magento\Framework\View\Element\Template
+class DefaultItems extends Template
{
/**
* Retrieve current order model instance
@@ -92,6 +96,7 @@ public function getSku($item)
* Return product additional information block
*
* @return \Magento\Framework\View\Element\AbstractBlock
+ * @throws LocalizedException
*/
public function getProductAdditionalInformationBlock()
{
@@ -103,10 +108,13 @@ public function getProductAdditionalInformationBlock()
*
* @param OrderItem|InvoiceItem|CreditmemoItem $item
* @return string
+ * @throws LocalizedException
*/
public function getItemPrice($item)
{
$block = $this->getLayout()->getBlock('item_price');
+ $item->setRowTotal((float) $item->getPrice() * (float) $this->getItem()->getQty());
+ $item->setBaseRowTotal((float) $item->getBasePrice() * (float) $this->getItem()->getQty());
$block->setItem($item);
return $block->toHtml();
}
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index 67a533ea88550..e0b61e9bb150e 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -663,6 +663,14 @@ public function initFromOrderItem(\Magento\Sales\Model\Order\Item $orderItem, $q
if (is_numeric($qty)) {
$buyRequest->setQty($qty);
}
+ $productOptions = $orderItem->getProductOptions();
+ if ($productOptions !== null && !empty($productOptions['options'])) {
+ $formattedOptions = [];
+ foreach ($productOptions['options'] as $option) {
+ $formattedOptions[$option['option_id']] = $option['option_value'];
+ }
+ $buyRequest->setData('options', $formattedOptions);
+ }
$item = $this->getQuote()->addProduct($product, $buyRequest);
if (is_string($item)) {
return $item;
@@ -1369,7 +1377,6 @@ protected function _setQuoteAddress(\Magento\Quote\Model\Quote\Address $address,
$data = isset($data['region']) && is_array($data['region']) ? array_merge($data, $data['region']) : $data;
$addressForm = $this->_metadataFormFactory->create(
-
AddressMetadataInterface::ENTITY_TYPE_ADDRESS,
'adminhtml_customer_address',
$data,
diff --git a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
index 05164d1b7b5f3..d0247294e75a1 100644
--- a/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
+++ b/app/code/Magento/Sales/Model/Order/Email/Sender/InvoiceSender.php
@@ -3,18 +3,20 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Model\Order\Email\Sender;
+use Magento\Framework\DataObject;
+use Magento\Framework\Event\ManagerInterface;
use Magento\Payment\Helper\Data as PaymentHelper;
use Magento\Sales\Model\Order;
+use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Sales\Model\Order\Email\Container\InvoiceIdentity;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\Order\Email\Sender;
use Magento\Sales\Model\Order\Invoice;
use Magento\Sales\Model\ResourceModel\Order\Invoice as InvoiceResource;
-use Magento\Sales\Model\Order\Address\Renderer;
-use Magento\Framework\Event\ManagerInterface;
-use Magento\Framework\DataObject;
/**
* Sends order invoice email to the customer.
@@ -106,6 +108,12 @@ public function send(Invoice $invoice, $forceSyncMode = false)
$order = $invoice->getOrder();
$this->identityContainer->setStore($order->getStore());
+ if ($this->checkIfPartialInvoice($order, $invoice)) {
+ $order->setBaseSubtotal((float) $invoice->getBaseSubtotal());
+ $order->setBaseTaxAmount((float) $invoice->getBaseTaxAmount());
+ $order->setBaseShippingAmount((float) $invoice->getBaseShippingAmount());
+ }
+
$transport = [
'order' => $order,
'order_id' => $order->getId(),
@@ -165,4 +173,18 @@ protected function getPaymentHtml(Order $order)
$this->identityContainer->getStore()->getStoreId()
);
}
+
+ /**
+ * Check if the order contains partial invoice
+ *
+ * @param Order $order
+ * @param Invoice $invoice
+ * @return bool
+ */
+ private function checkIfPartialInvoice(Order $order, Invoice $invoice): bool
+ {
+ $totalQtyOrdered = (float) $order->getTotalQtyOrdered();
+ $totalQtyInvoiced = (float) $invoice->getTotalQty();
+ return $totalQtyOrdered !== $totalQtyInvoiced;
+ }
}
diff --git a/app/code/Magento/Sales/Model/Reorder/Reorder.php b/app/code/Magento/Sales/Model/Reorder/Reorder.php
index a1a8d6e8c9928..a5d40df07bd69 100644
--- a/app/code/Magento/Sales/Model/Reorder/Reorder.php
+++ b/app/code/Magento/Sales/Model/Reorder/Reorder.php
@@ -225,7 +225,8 @@ private function getOrderProducts(string $storeId, array $orderItemProductIds):
->addStoreFilter()
->addAttributeToSelect('*')
->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner')
- ->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
+ ->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner')
+ ->addOptionsToResult();
return $collection->getItems();
}
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderWithMinimumAmountEnabledTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderWithMinimumAmountEnabledTest.xml
index ade1f783c1309..1f6d7c40be99b 100644
--- a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderWithMinimumAmountEnabledTest.xml
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderWithMinimumAmountEnabledTest.xml
@@ -32,7 +32,7 @@
-
+
diff --git a/app/code/Magento/Sales/Test/Unit/Block/Order/Email/Items/DefaultItemsTest.php b/app/code/Magento/Sales/Test/Unit/Block/Order/Email/Items/DefaultItemsTest.php
index 4d8b8033f60da..7123a81306ef1 100644
--- a/app/code/Magento/Sales/Test/Unit/Block/Order/Email/Items/DefaultItemsTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Block/Order/Email/Items/DefaultItemsTest.php
@@ -11,7 +11,7 @@
use Magento\Backend\Block\Template\Context;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Framework\View\Layout;
-use Magento\Quote\Model\Quote\Item;
+use Magento\Quote\Model\Quote\Item as QuoteItem;
use Magento\Sales\Block\Order\Email\Items\DefaultItems;
use Magento\Sales\Model\Order\Item as OrderItem;
use PHPUnit\Framework\MockObject\MockObject;
@@ -20,7 +20,7 @@
class DefaultItemsTest extends TestCase
{
/**
- * @var MockObject|\Magento\Sales\Block\Order\Email\Items\DefaultItem
+ * @var MockObject|DefaultItems
*/
protected $block;
@@ -39,9 +39,16 @@ class DefaultItemsTest extends TestCase
*/
protected $objectManager;
- /** @var MockObject|Item */
+ /**
+ * @var MockObject|OrderItem
+ */
protected $itemMock;
+ /**
+ * @var MockObject|QuoteItem
+ */
+ protected $quoteItemMock;
+
/**
* Initialize required data
*/
@@ -54,16 +61,6 @@ protected function setUp(): void
->setMethods(['getBlock'])
->getMock();
- $this->block = $this->objectManager->getObject(
- DefaultItems::class,
- [
- 'context' => $this->objectManager->getObject(
- Context::class,
- ['layout' => $this->layoutMock]
- )
- ]
- );
-
$this->priceRenderBlock = $this->getMockBuilder(Template::class)
->disableOriginalConstructor()
->setMethods(['setItem', 'toHtml'])
@@ -72,16 +69,47 @@ protected function setUp(): void
$this->itemMock = $this->getMockBuilder(OrderItem::class)
->disableOriginalConstructor()
->getMock();
+
+ $this->quoteItemMock = $this->getMockBuilder(QuoteItem::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['getQty'])
+ ->getMock();
+
+ $this->block = $this->objectManager->getObject(
+ DefaultItems::class,
+ [
+ 'context' => $this->objectManager->getObject(
+ Context::class,
+ ['layout' => $this->layoutMock]
+ ),
+ 'data' => [
+ 'item' => $this->quoteItemMock
+ ]
+ ]
+ );
}
- public function testGetItemPrice()
+ /**
+ * @param float $price
+ * @param string $html
+ * @param float $quantity
+ * @dataProvider getItemPriceDataProvider
+ * */
+ public function testGetItemPrice($price, $html, $quantity)
{
- $html = '$34.28';
-
$this->layoutMock->expects($this->once())
->method('getBlock')
->with('item_price')
->willReturn($this->priceRenderBlock);
+ $this->quoteItemMock->expects($this->any())
+ ->method('getQty')
+ ->willReturn($quantity);
+ $this->itemMock->expects($this->any())
+ ->method('setRowTotal')
+ ->willReturn($price * $quantity);
+ $this->itemMock->expects($this->any())
+ ->method('setBaseRowTotal')
+ ->willReturn($price * $quantity);
$this->priceRenderBlock->expects($this->once())
->method('setItem')
@@ -93,4 +121,15 @@ public function testGetItemPrice()
$this->assertEquals($html, $this->block->getItemPrice($this->itemMock));
}
+
+ /**
+ * @return array
+ */
+ public function getItemPriceDataProvider()
+ {
+ return [
+ 'get default item price' => [34.28,'$34.28',1.0],
+ 'get item price with quantity 2.0' => [12.00,'$24.00',2.0]
+ ];
+ }
}
diff --git a/app/code/Magento/SalesRule/Model/Coupon/Quote/UpdateCouponUsages.php b/app/code/Magento/SalesRule/Model/Coupon/Quote/UpdateCouponUsages.php
new file mode 100644
index 0000000000000..0ee2ee09cad57
--- /dev/null
+++ b/app/code/Magento/SalesRule/Model/Coupon/Quote/UpdateCouponUsages.php
@@ -0,0 +1,64 @@
+couponUsageProcessor = $couponUsageProcessor;
+ $this->updateInfoFactory = $updateInfoFactory;
+ }
+
+ /**
+ * Executes the current command
+ *
+ * @param CartInterface $quote
+ * @param bool $increment
+ * @return void
+ */
+ public function execute(CartInterface $quote, bool $increment): void
+ {
+ if (!$quote->getAppliedRuleIds()) {
+ return;
+ }
+
+ /** @var UpdateInfo $updateInfo */
+ $updateInfo = $this->updateInfoFactory->create();
+ $updateInfo->setAppliedRuleIds(explode(',', $quote->getAppliedRuleIds()));
+ $updateInfo->setCouponCode((string)$quote->getCouponCode());
+ $updateInfo->setCustomerId((int)$quote->getCustomerId());
+ $updateInfo->setIsIncrement($increment);
+
+ $this->couponUsageProcessor->process($updateInfo);
+ }
+}
diff --git a/app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php b/app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php
index 3236c80e1b7ed..1645f205d1e55 100644
--- a/app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php
+++ b/app/code/Magento/SalesRule/Model/Coupon/UpdateCouponUsages.php
@@ -8,56 +8,39 @@
namespace Magento\SalesRule\Model\Coupon;
use Magento\Sales\Api\Data\OrderInterface;
-use Magento\SalesRule\Model\Coupon;
-use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
-use Magento\SalesRule\Model\Rule\CustomerFactory;
-use Magento\SalesRule\Model\RuleFactory;
+use Magento\SalesRule\Model\Coupon\Usage\Processor as CouponUsageProcessor;
+use Magento\SalesRule\Model\Coupon\Usage\UpdateInfo;
+use Magento\SalesRule\Model\Coupon\Usage\UpdateInfoFactory;
/**
- * Updates the coupon usages.
+ * Updates the coupon usages
*/
class UpdateCouponUsages
{
/**
- * @var RuleFactory
+ * @var CouponUsageProcessor
*/
- private $ruleFactory;
+ private $couponUsageProcessor;
/**
- * @var RuleFactory
+ * @var UpdateInfoFactory
*/
- private $ruleCustomerFactory;
+ private $updateInfoFactory;
/**
- * @var Coupon
- */
- private $coupon;
-
- /**
- * @var Usage
- */
- private $couponUsage;
-
- /**
- * @param RuleFactory $ruleFactory
- * @param CustomerFactory $ruleCustomerFactory
- * @param Coupon $coupon
- * @param Usage $couponUsage
+ * @param CouponUsageProcessor $couponUsageProcessor
+ * @param UpdateInfoFactory $updateInfoFactory
*/
public function __construct(
- RuleFactory $ruleFactory,
- CustomerFactory $ruleCustomerFactory,
- Coupon $coupon,
- Usage $couponUsage
+ CouponUsageProcessor $couponUsageProcessor,
+ UpdateInfoFactory $updateInfoFactory
) {
- $this->ruleFactory = $ruleFactory;
- $this->ruleCustomerFactory = $ruleCustomerFactory;
- $this->coupon = $coupon;
- $this->couponUsage = $couponUsage;
+ $this->couponUsageProcessor = $couponUsageProcessor;
+ $this->updateInfoFactory = $updateInfoFactory;
}
/**
- * Executes the current command.
+ * Executes the current command
*
* @param OrderInterface $subject
* @param bool $increment
@@ -68,86 +51,16 @@ public function execute(OrderInterface $subject, bool $increment): OrderInterfac
if (!$subject || !$subject->getAppliedRuleIds()) {
return $subject;
}
- // lookup rule ids
- $ruleIds = explode(',', $subject->getAppliedRuleIds());
- $ruleIds = array_unique($ruleIds);
- $customerId = (int)$subject->getCustomerId();
- // use each rule (and apply to customer, if applicable)
- foreach ($ruleIds as $ruleId) {
- if (!$ruleId) {
- continue;
- }
- $this->updateRuleUsages($increment, (int)$ruleId, $customerId);
- }
- $this->updateCouponUsages($subject, $increment, $customerId);
-
- return $subject;
- }
- /**
- * Update the number of rule usages.
- *
- * @param bool $increment
- * @param int $ruleId
- * @param int $customerId
- */
- private function updateRuleUsages(bool $increment, int $ruleId, int $customerId)
- {
- /** @var \Magento\SalesRule\Model\Rule $rule */
- $rule = $this->ruleFactory->create();
- $rule->load($ruleId);
- if ($rule->getId()) {
- $rule->loadCouponCode();
- if ($increment || $rule->getTimesUsed() > 0) {
- $rule->setTimesUsed($rule->getTimesUsed() + ($increment ? 1 : -1));
- $rule->save();
- }
- if ($customerId) {
- $this->updateCustomerRuleUsages($increment, $ruleId, $customerId);
- }
- }
- }
+ /** @var UpdateInfo $updateInfo */
+ $updateInfo = $this->updateInfoFactory->create();
+ $updateInfo->setAppliedRuleIds(explode(',', $subject->getAppliedRuleIds()));
+ $updateInfo->setCouponCode((string)$subject->getCouponCode());
+ $updateInfo->setCustomerId((int)$subject->getCustomerId());
+ $updateInfo->setIsIncrement($increment);
- /**
- * Update the number of rule usages per customer.
- *
- * @param bool $increment
- * @param int $ruleId
- * @param int $customerId
- */
- private function updateCustomerRuleUsages(bool $increment, int $ruleId, int $customerId): void
- {
- /** @var \Magento\SalesRule\Model\Rule\Customer $ruleCustomer */
- $ruleCustomer = $this->ruleCustomerFactory->create();
- $ruleCustomer->loadByCustomerRule($customerId, $ruleId);
- if ($ruleCustomer->getId()) {
- if ($increment || $ruleCustomer->getTimesUsed() > 0) {
- $ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + ($increment ? 1 : -1));
- }
- } elseif ($increment) {
- $ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(1);
- }
- $ruleCustomer->save();
- }
+ $this->couponUsageProcessor->process($updateInfo);
- /**
- * Update the number of coupon usages.
- *
- * @param OrderInterface $subject
- * @param bool $increment
- * @param int $customerId
- */
- private function updateCouponUsages(OrderInterface $subject, bool $increment, int $customerId): void
- {
- $this->coupon->load($subject->getCouponCode(), 'code');
- if ($this->coupon->getId()) {
- if ($increment || $this->coupon->getTimesUsed() > 0) {
- $this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($increment ? 1 : -1));
- $this->coupon->save();
- }
- if ($customerId) {
- $this->couponUsage->updateCustomerCouponTimesUsed($customerId, $this->coupon->getId(), $increment);
- }
- }
+ return $subject;
}
}
diff --git a/app/code/Magento/SalesRule/Model/Coupon/Usage/Processor.php b/app/code/Magento/SalesRule/Model/Coupon/Usage/Processor.php
new file mode 100644
index 0000000000000..90a456d5ff833
--- /dev/null
+++ b/app/code/Magento/SalesRule/Model/Coupon/Usage/Processor.php
@@ -0,0 +1,149 @@
+ruleFactory = $ruleFactory;
+ $this->ruleCustomerFactory = $ruleCustomerFactory;
+ $this->coupon = $coupon;
+ $this->couponUsage = $couponUsage;
+ }
+
+ /**
+ * Update coupon usage
+ *
+ * @param UpdateInfo $updateInfo
+ */
+ public function process(UpdateInfo $updateInfo): void
+ {
+ if (empty($updateInfo->getAppliedRuleIds())) {
+ return;
+ }
+
+ if (!empty($updateInfo->getCouponCode())) {
+ $this->updateCouponUsages($updateInfo);
+ }
+ $isIncrement = $updateInfo->isIncrement();
+ $customerId = $updateInfo->getCustomerId();
+ // use each rule (and apply to customer, if applicable)
+ foreach (array_unique($updateInfo->getAppliedRuleIds()) as $ruleId) {
+ if (!(int)$ruleId) {
+ continue;
+ }
+ $this->updateRuleUsages($isIncrement, (int)$ruleId);
+ if ($customerId) {
+ $this->updateCustomerRuleUsages($isIncrement, (int)$ruleId, $customerId);
+ }
+ }
+ }
+
+ /**
+ * Update the number of coupon usages
+ *
+ * @param UpdateInfo $updateInfo
+ */
+ private function updateCouponUsages(UpdateInfo $updateInfo): void
+ {
+ $isIncrement = $updateInfo->isIncrement();
+ $this->coupon->load($updateInfo->getCouponCode(), 'code');
+ if ($this->coupon->getId()) {
+ if ($updateInfo->isIncrement() || $this->coupon->getTimesUsed() > 0) {
+ $this->coupon->setTimesUsed($this->coupon->getTimesUsed() + ($isIncrement ? 1 : -1));
+ $this->coupon->save();
+ }
+ if ($updateInfo->getCustomerId()) {
+ $this->couponUsage->updateCustomerCouponTimesUsed(
+ $updateInfo->getCustomerId(),
+ $this->coupon->getId(),
+ $isIncrement
+ );
+ }
+ }
+ }
+
+ /**
+ * Update the number of rule usages
+ *
+ * @param bool $isIncrement
+ * @param int $ruleId
+ */
+ private function updateRuleUsages(bool $isIncrement, int $ruleId): void
+ {
+ $rule = $this->ruleFactory->create();
+ $rule->load($ruleId);
+ if ($rule->getId()) {
+ $rule->loadCouponCode();
+ if ($isIncrement || $rule->getTimesUsed() > 0) {
+ $rule->setTimesUsed($rule->getTimesUsed() + ($isIncrement ? 1 : -1));
+ $rule->save();
+ }
+ }
+ }
+
+ /**
+ * Update the number of rule usages per customer
+ *
+ * @param bool $isIncrement
+ * @param int $ruleId
+ * @param int $customerId
+ */
+ private function updateCustomerRuleUsages(bool $isIncrement, int $ruleId, int $customerId): void
+ {
+ $ruleCustomer = $this->ruleCustomerFactory->create();
+ $ruleCustomer->loadByCustomerRule($customerId, $ruleId);
+ if ($ruleCustomer->getId()) {
+ if ($isIncrement || $ruleCustomer->getTimesUsed() > 0) {
+ $ruleCustomer->setTimesUsed($ruleCustomer->getTimesUsed() + ($isIncrement ? 1 : -1));
+ }
+ } elseif ($isIncrement) {
+ $ruleCustomer->setCustomerId($customerId)->setRuleId($ruleId)->setTimesUsed(1);
+ }
+ $ruleCustomer->save();
+ }
+}
diff --git a/app/code/Magento/SalesRule/Model/Coupon/Usage/UpdateInfo.php b/app/code/Magento/SalesRule/Model/Coupon/Usage/UpdateInfo.php
new file mode 100644
index 0000000000000..328093ca1af0e
--- /dev/null
+++ b/app/code/Magento/SalesRule/Model/Coupon/Usage/UpdateInfo.php
@@ -0,0 +1,107 @@
+getData(self::APPLIED_RULE_IDS_KEY);
+ }
+
+ /**
+ * Set applied rule ids
+ *
+ * @param array $value
+ * @return void
+ */
+ public function setAppliedRuleIds(array $value): void
+ {
+ $this->setData(self::APPLIED_RULE_IDS_KEY, $value);
+ }
+
+ /**
+ * Get coupon code
+ *
+ * @return string
+ */
+ public function getCouponCode(): string
+ {
+ return (string)$this->getData(self::COUPON_CODE_KEY);
+ }
+
+ /**
+ * Set coupon code
+ *
+ * @param string $value
+ * @return void
+ */
+ public function setCouponCode(string $value): void
+ {
+ $this->setData(self::COUPON_CODE_KEY, $value);
+ }
+
+ /**
+ * Get customer id
+ *
+ * @return int|null
+ */
+ public function getCustomerId(): ?int
+ {
+ return $this->getData(self::CUSTOMER_ID_KEY) !== null
+ ? (int) $this->getData(self::CUSTOMER_ID_KEY)
+ : null;
+ }
+
+ /**
+ * Set customer id
+ *
+ * @param int|null $value
+ * @return void
+ */
+ public function setCustomerId(?int $value): void
+ {
+ $this->setData(self::CUSTOMER_ID_KEY, $value);
+ }
+
+ /**
+ * Get update mode: increment - true, decrement - false
+ *
+ * @return bool
+ */
+ public function isIncrement(): bool
+ {
+ return (bool)$this->getData(self::IS_INCREMENT_KEY);
+ }
+
+ /**
+ * Set update mode: increment - true, decrement - false
+ *
+ * @param bool $value
+ * @return void
+ */
+ public function setIsIncrement(bool $value): void
+ {
+ $this->setData(self::IS_INCREMENT_KEY, $value);
+ }
+}
diff --git a/app/code/Magento/SalesRule/Observer/AssignCouponDataAfterOrderCustomerAssignObserver.php b/app/code/Magento/SalesRule/Observer/AssignCouponDataAfterOrderCustomerAssignObserver.php
index 2d771e4560fcf..1d416fbcf4f52 100644
--- a/app/code/Magento/SalesRule/Observer/AssignCouponDataAfterOrderCustomerAssignObserver.php
+++ b/app/code/Magento/SalesRule/Observer/AssignCouponDataAfterOrderCustomerAssignObserver.php
@@ -45,9 +45,10 @@ public function execute(Observer $observer)
$event = $observer->getEvent();
/** @var OrderInterface $order */
$order = $event->getData(self::EVENT_KEY_ORDER);
-
- if ($order->getCustomerId()) {
- $this->updateCouponUsages->execute($order, true);
+ if (!$order->getCustomerId()) {
+ return;
}
+
+ $this->updateCouponUsages->execute($order, true);
}
}
diff --git a/app/code/Magento/SalesRule/Observer/CouponUsagesDecrement.php b/app/code/Magento/SalesRule/Observer/CouponUsagesDecrement.php
new file mode 100644
index 0000000000000..d0c7199405879
--- /dev/null
+++ b/app/code/Magento/SalesRule/Observer/CouponUsagesDecrement.php
@@ -0,0 +1,42 @@
+updateCouponUsages = $updateCouponUsages;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function execute(EventObserver $observer)
+ {
+ /** @var CartInterface $quote */
+ $quote = $observer->getQuote();
+ $this->updateCouponUsages->execute($quote, false);
+ }
+}
diff --git a/app/code/Magento/SalesRule/Plugin/CouponUsagesDecrement.php b/app/code/Magento/SalesRule/Plugin/CouponUsagesDecrement.php
index 87a7c2ed1bd38..3be801a288479 100644
--- a/app/code/Magento/SalesRule/Plugin/CouponUsagesDecrement.php
+++ b/app/code/Magento/SalesRule/Plugin/CouponUsagesDecrement.php
@@ -49,11 +49,13 @@ public function __construct(
*/
public function afterCancel(OrderService $subject, bool $result, $orderId): bool
{
- $order = $this->orderRepository->get($orderId);
- if ($result) {
- $this->updateCouponUsages->execute($order, false);
+ if (!$result) {
+ return $result;
}
+ $order = $this->orderRepository->get($orderId);
+ $this->updateCouponUsages->execute($order, false);
+
return $result;
}
}
diff --git a/app/code/Magento/SalesRule/Plugin/CouponUsagesIncrement.php b/app/code/Magento/SalesRule/Plugin/CouponUsagesIncrement.php
index 14bbb5fce02a5..66a32f37eee2f 100644
--- a/app/code/Magento/SalesRule/Plugin/CouponUsagesIncrement.php
+++ b/app/code/Magento/SalesRule/Plugin/CouponUsagesIncrement.php
@@ -7,12 +7,13 @@
namespace Magento\SalesRule\Plugin;
-use Magento\Sales\Api\Data\OrderInterface;
-use Magento\Sales\Model\Service\OrderService;
-use Magento\SalesRule\Model\Coupon\UpdateCouponUsages;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Quote\Model\Quote;
+use Magento\Quote\Model\QuoteManagement;
+use Magento\SalesRule\Model\Coupon\Quote\UpdateCouponUsages;
/**
- * Increments number of coupon usages after placing order.
+ * Increments number of coupon usages before placing order
*/
class CouponUsagesIncrement
{
@@ -24,24 +25,28 @@ class CouponUsagesIncrement
/**
* @param UpdateCouponUsages $updateCouponUsages
*/
- public function __construct(
- UpdateCouponUsages $updateCouponUsages
- ) {
+ public function __construct(UpdateCouponUsages $updateCouponUsages)
+ {
$this->updateCouponUsages = $updateCouponUsages;
}
/**
- * Increments number of coupon usages after placing order.
+ * Increments number of coupon usages before placing order
*
- * @param OrderService $subject
- * @param OrderInterface $result
- * @return OrderInterface
+ * @param QuoteManagement $subject
+ * @param Quote $quote
+ * @param array $orderData
+ * @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @throws NoSuchEntityException
*/
- public function afterPlace(OrderService $subject, OrderInterface $result): OrderInterface
+ public function beforeSubmit(QuoteManagement $subject, Quote $quote, $orderData = [])
{
- $this->updateCouponUsages->execute($result, true);
+ /* if coupon code has been canceled then need to notify the customer */
+ if (!$quote->getCouponCode() && $quote->dataHasChangedFor('coupon_code')) {
+ throw new NoSuchEntityException(__("The coupon code isn't valid. Verify the code and try again."));
+ }
- return $result;
+ $this->updateCouponUsages->execute($quote, true);
}
}
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml
index 221f80b887fe5..f32442ca5bc98 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleEmptyFromDateTest.xml
@@ -83,9 +83,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml
index e2a65685bd97e..557a585858868 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForCouponCodeTest.xml
@@ -75,9 +75,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml
index 9f4168575595a..e18a9eaadcd23 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/AdminCreateCartPriceRuleForGeneratedCouponTest.xml
@@ -79,9 +79,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml
index bc608c0e06086..ad1ff69a60901 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/CartPriceRuleForConfigurableProductTest.xml
@@ -126,15 +126,11 @@
-
-
-
+
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml
index 51e25d3a7e255..eef5dadfbe5d8 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleCountryTest.xml
@@ -66,9 +66,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml
index 420bc37d5c1b2..69097e3269fcb 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRulePostcodeTest.xml
@@ -70,9 +70,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml
index 279747f87d66d..18057965c28e1 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleQuantityTest.xml
@@ -68,9 +68,7 @@
-
-
-
+
@@ -81,9 +79,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml
index a3f32c0781a52..c13b74b6990d0 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleStateTest.xml
@@ -66,9 +66,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml
index 39ac14315110e..97b75ae772f08 100644
--- a/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml
+++ b/app/code/Magento/SalesRule/Test/Mftf/Test/StorefrontCartPriceRuleSubtotalTest.xml
@@ -66,9 +66,7 @@
-
-
-
+
@@ -79,9 +77,7 @@
-
-
-
+
diff --git a/app/code/Magento/SalesRule/etc/di.xml b/app/code/Magento/SalesRule/etc/di.xml
index c4bc9c3a6decb..05bd801c3b99f 100644
--- a/app/code/Magento/SalesRule/etc/di.xml
+++ b/app/code/Magento/SalesRule/etc/di.xml
@@ -191,6 +191,8 @@
+
+
+
+
+
diff --git a/app/code/Magento/SalesRule/view/frontend/requirejs-config.js b/app/code/Magento/SalesRule/view/frontend/requirejs-config.js
index 21f49fb3080fc..484020a573f07 100644
--- a/app/code/Magento/SalesRule/view/frontend/requirejs-config.js
+++ b/app/code/Magento/SalesRule/view/frontend/requirejs-config.js
@@ -11,6 +11,9 @@ var config = {
},
'Magento_Checkout/js/model/shipping-save-processor': {
'Magento_SalesRule/js/model/shipping-save-processor-mixin': true
+ },
+ 'Magento_Checkout/js/action/place-order': {
+ 'Magento_SalesRule/js/model/place-order-mixin': true
}
}
}
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/model/place-order-mixin.js b/app/code/Magento/SalesRule/view/frontend/web/js/model/place-order-mixin.js
new file mode 100644
index 0000000000000..da4de3fa19c5e
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/model/place-order-mixin.js
@@ -0,0 +1,42 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+ 'jquery',
+ 'mage/utils/wrapper',
+ 'Magento_Checkout/js/model/quote',
+ 'Magento_SalesRule/js/model/coupon',
+ 'Magento_Checkout/js/action/get-totals'
+], function ($, wrapper, quote, coupon, getTotalsAction) {
+ 'use strict';
+
+ return function (placeOrderAction) {
+ return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) {
+ var result;
+
+ $.when(
+ result = originalAction(paymentData, messageContainer)
+ ).fail(
+ function () {
+ var deferred = $.Deferred(),
+
+ /**
+ * Update coupon form
+ */
+ updateCouponCallback = function () {
+ if (quote.totals() && !quote.totals()['coupon_code']) {
+ coupon.setCouponCode('');
+ coupon.setIsApplied(false);
+ }
+ };
+
+ getTotalsAction([], deferred);
+ $.when(deferred).done(updateCouponCallback);
+ }
+ );
+
+ return result;
+ });
+ };
+});
diff --git a/app/code/Magento/Swatches/Plugin/Eav/Model/Entity/Attribute/OptionManagement.php b/app/code/Magento/Swatches/Plugin/Eav/Model/Entity/Attribute/OptionManagement.php
index 795c48f12ebcc..43a44534aa942 100644
--- a/app/code/Magento/Swatches/Plugin/Eav/Model/Entity/Attribute/OptionManagement.php
+++ b/app/code/Magento/Swatches/Plugin/Eav/Model/Entity/Attribute/OptionManagement.php
@@ -8,6 +8,9 @@
namespace Magento\Swatches\Plugin\Eav\Model\Entity\Attribute;
use Magento\Catalog\Api\Data\ProductAttributeInterface;
+use Magento\Catalog\Model\Product\Attribute\OptionManagement as CatalogOptionManagement;
+use Magento\Eav\Api\Data\AttributeInterface;
+use Magento\Eav\Api\Data\AttributeOptionInterface;
use Magento\Eav\Model\AttributeRepository;
use Magento\Store\Model\Store;
use Magento\Swatches\Helper\Data;
@@ -41,28 +44,61 @@ public function __construct(
/**
* Add swatch value to the attribute option
*
- * @param \Magento\Catalog\Model\Product\Attribute\OptionManagement $subject
+ * @param CatalogOptionManagement $subject
* @param string $attributeCode
- * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
+ * @param AttributeOptionInterface $option
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function beforeAdd(
- \Magento\Catalog\Model\Product\Attribute\OptionManagement $subject,
+ CatalogOptionManagement $subject,
?string $attributeCode,
- \Magento\Eav\Api\Data\AttributeOptionInterface $option
+ AttributeOptionInterface $option
) {
- if (empty($attributeCode)) {
+ $attribute = $this->initAttribute($attributeCode);
+ if (!$attribute) {
return;
}
- $attribute = $this->attributeRepository->get(
- ProductAttributeInterface::ENTITY_TYPE_CODE,
- $attributeCode
- );
- if (!$attribute || !$this->swatchHelper->isSwatchAttribute($attribute)) {
+
+ $optionId = $this->getNewOptionId($option);
+ $this->setSwatchAttributeOption($attribute, $option, $optionId);
+ }
+
+ /**
+ * Update swatch value of attribute option
+ *
+ * @param CatalogOptionManagement $subject
+ * @param string $attributeCode
+ * @param int $optionId
+ * @param AttributeOptionInterface $option
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ public function beforeUpdate(
+ CatalogOptionManagement $subject,
+ $attributeCode,
+ $optionId,
+ AttributeOptionInterface $option
+ ) {
+ $attribute = $this->initAttribute($attributeCode);
+ if (!$attribute) {
return;
}
- $optionId = $this->getOptionId($option);
- $optionsValue = $option->getValue();
+
+ $this->setSwatchAttributeOption($attribute, $option, (string)$optionId);
+ }
+
+ /**
+ * Set attribute swatch option
+ *
+ * @param AttributeInterface $attribute
+ * @param AttributeOptionInterface $option
+ * @param string $optionId
+ */
+ private function setSwatchAttributeOption(
+ AttributeInterface $attribute,
+ AttributeOptionInterface $option,
+ string $optionId
+ ): void {
+ $optionsValue = trim($option->getValue() ?: '');
if ($this->swatchHelper->isVisualSwatch($attribute)) {
$attribute->setData('swatchvisual', ['value' => [$optionId => $optionsValue]]);
} else {
@@ -80,13 +116,40 @@ public function beforeAdd(
}
/**
- * Returns option id
+ * Init swatch attribute
*
- * @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
+ * @param string $attributeCode
+ * @return bool|AttributeInterface
+ */
+ private function initAttribute($attributeCode)
+ {
+ if (empty($attributeCode)) {
+ return false;
+ }
+ $attribute = $this->attributeRepository->get(
+ ProductAttributeInterface::ENTITY_TYPE_CODE,
+ $attributeCode
+ );
+ if (!$attribute || !$this->swatchHelper->isSwatchAttribute($attribute)) {
+ return false;
+ }
+
+ return $attribute;
+ }
+
+ /**
+ * Get option id to create new option
+ *
+ * @param AttributeOptionInterface $option
* @return string
*/
- private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
+ private function getNewOptionId(AttributeOptionInterface $option): string
{
- return 'id_' . ($option->getValue() ?: 'new_option');
+ $optionId = trim($option->getValue() ?: '');
+ if (empty($optionId)) {
+ $optionId = 'new_option';
+ }
+
+ return 'id_' . $optionId;
}
}
diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml
index 1a6c0341c0704..62a3c668fcf07 100644
--- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml
+++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminCreateVisualSwatchTest.xml
@@ -24,8 +24,7 @@
-
-
+
@@ -39,8 +38,7 @@
-
-
+
diff --git a/app/code/Magento/Swatches/Test/Mftf/Test/AdminDisablingSwatchTooltipsTest.xml b/app/code/Magento/Swatches/Test/Mftf/Test/AdminDisablingSwatchTooltipsTest.xml
index 8fd21acbd51d9..4075d89e0894f 100644
--- a/app/code/Magento/Swatches/Test/Mftf/Test/AdminDisablingSwatchTooltipsTest.xml
+++ b/app/code/Magento/Swatches/Test/Mftf/Test/AdminDisablingSwatchTooltipsTest.xml
@@ -26,8 +26,7 @@
-
-
+
@@ -48,8 +47,7 @@
-
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml
index b1e91886960c5..9359f7348e8a2 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestSimpleTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml
index 8a04156f3d857..4dea418c8321e 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartGuestVirtualTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml
index b76f015679ae2..018594c39ba67 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInSimpleTest.xml
@@ -84,7 +84,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml
index 5f98093ec874f..09ffca716e318 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCartTest/StorefrontTaxQuoteCartLoggedInVirtualTest.xml
@@ -83,7 +83,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml
index d005f4b657448..3c72b5177e692 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestSimpleTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml
index d1fc0654fc496..4cd508b03d156 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutGuestVirtualTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml
index 18a1a11d35fd2..43d12bf848f13 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInSimpleTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml
index 35a483da7f690..949d9a89b656f 100644
--- a/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml
+++ b/app/code/Magento/Tax/Test/Mftf/Test/StorefrontTaxQuoteCheckoutTest/StorefrontTaxQuoteCheckoutLoggedInVirtualTest.xml
@@ -70,7 +70,7 @@
-
+
diff --git a/app/code/Magento/Ui/Test/Mftf/ActionGroup/StorefrontAssertErrorMessageActionGroup.xml b/app/code/Magento/Ui/Test/Mftf/ActionGroup/StorefrontAssertErrorMessageActionGroup.xml
new file mode 100644
index 0000000000000..fa9b7c377e32b
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Mftf/ActionGroup/StorefrontAssertErrorMessageActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Ui/Test/Mftf/Section/StorefrontMessagesSection.xml b/app/code/Magento/Ui/Test/Mftf/Section/StorefrontMessagesSection.xml
index c58479a7b73e5..f46e25a832134 100644
--- a/app/code/Magento/Ui/Test/Mftf/Section/StorefrontMessagesSection.xml
+++ b/app/code/Magento/Ui/Test/Mftf/Section/StorefrontMessagesSection.xml
@@ -12,5 +12,6 @@
+
diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml
index a70065dc1d307..2dd7df9cbb548 100644
--- a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml
+++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUrlRewritesForProductAfterImportTest.xml
@@ -43,7 +43,7 @@
-
+
diff --git a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
index 61d444f786ca8..b10b62ec21167 100644
--- a/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
+++ b/app/code/Magento/Wishlist/Model/ResourceModel/Item/Collection.php
@@ -575,10 +575,15 @@ protected function _joinProductNameTable()
$storeId = $this->_storeManager->getStore(\Magento\Store\Model\Store::ADMIN_CODE)->getId();
$entityMetadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
+ $linkField = $entityMetadata->getLinkField();
$this->getSelect()->join(
+ ['product_entity' => $this->getTable('catalog_product_entity')],
+ 'product_entity.entity_id = main_table.product_id',
+ []
+ )->join(
['product_name_table' => $attribute->getBackendTable()],
- 'product_name_table.' . $entityMetadata->getLinkField() . ' = main_table.product_id' .
+ 'product_name_table.' . $linkField . ' = product_entity.' . $linkField .
' AND product_name_table.store_id = ' .
$storeId .
' AND product_name_table.attribute_id = ' .
@@ -588,6 +593,7 @@ protected function _joinProductNameTable()
$this->_isProductNameJoined = true;
}
+
return $this;
}
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminDeleteCustomerWishListItemTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminDeleteCustomerWishListItemTest.xml
index af229b3507077..32bec763b2fd6 100644
--- a/app/code/Magento/Wishlist/Test/Mftf/Test/AdminDeleteCustomerWishListItemTest.xml
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/AdminDeleteCustomerWishListItemTest.xml
@@ -14,6 +14,7 @@
+
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDisabledCustomerWishlistFunctionalityTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDisabledCustomerWishlistFunctionalityTest.xml
index 17d3ff1009b9b..65cce1dcfc1c3 100644
--- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDisabledCustomerWishlistFunctionalityTest.xml
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontDisabledCustomerWishlistFunctionalityTest.xml
@@ -15,6 +15,7 @@
+
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedEmailsQtyTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedEmailsQtyTest.xml
index 7ec06e3f3cf4d..281272293e6a9 100644
--- a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedEmailsQtyTest.xml
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedEmailsQtyTest.xml
@@ -15,6 +15,7 @@
+
diff --git a/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedTextLengthLimitTest.xml b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedTextLengthLimitTest.xml
new file mode 100644
index 0000000000000..65e67f75eb7e8
--- /dev/null
+++ b/app/code/Magento/Wishlist/Test/Mftf/Test/StorefrontShareWishlistWithMoreThanMaximumAllowedTextLengthLimitTest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/ResourceModel/Item/CollectionTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/ResourceModel/Item/CollectionTest.php
index 72705acb8cd06..28705d54e6e20 100644
--- a/app/code/Magento/Wishlist/Test/Unit/Model/ResourceModel/Item/CollectionTest.php
+++ b/app/code/Magento/Wishlist/Test/Unit/Model/ResourceModel/Item/CollectionTest.php
@@ -54,7 +54,8 @@ class CollectionTest extends TestCase
/** @var string */
protected $sql = "SELECT `main_table`.* FROM `testMainTableName` AS `main_table`
- INNER JOIN `testBackendTableName` AS `product_name_table` ON product_name_table.entity_id = main_table.product_id
+ INNER JOIN `testEntityTableName` AS `product_entity` ON product_entity.entity_id = main_table.product_id
+ INNER JOIN `testBackendTableName` AS `product_name_table` ON product_name_table.entity_id = product_entity.entity_id
AND product_name_table.store_id = 1
AND product_name_table.attribute_id = 12
WHERE (INSTR(product_name_table.value, 'TestProductName'))";
@@ -90,18 +91,13 @@ protected function setUp(): void
->expects($this->any())
->method('getConnection')
->willReturn($connection);
- $resource
- ->expects($this->any())
- ->method('getMainTable')
- ->willReturn('testMainTableName');
- $resource
- ->expects($this->any())
- ->method('getTableName')
- ->willReturn('testMainTableName');
$resource
->expects($this->any())
->method('getTable')
- ->willReturn('testMainTableName');
+ ->willReturnOnConsecutiveCalls(
+ 'testMainTableName',
+ 'testEntityTableName'
+ );
$catalogConfFactory = $this->createPartialMock(
ConfigFactory::class,
diff --git a/composer.json b/composer.json
index 1b260cc122865..765cad085df47 100644
--- a/composer.json
+++ b/composer.json
@@ -88,7 +88,7 @@
"friendsofphp/php-cs-fixer": "~2.16.0",
"lusitanian/oauth": "~0.8.10",
"magento/magento-coding-standard": "*",
- "magento/magento2-functional-testing-framework": "3.0.0-RC5",
+ "magento/magento2-functional-testing-framework": "^3.0",
"pdepend/pdepend": "~2.7.1",
"phpcompatibility/php-compatibility": "^9.3",
"phpmd/phpmd": "^2.8.0",
diff --git a/composer.lock b/composer.lock
index e5614cfd0ac99..fdb3a8a3708b7 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": "f3674961f96b48fdd025a6c94610c8eb",
+ "content-hash": "68246e4c5ac6555ff2d3d013c81c3537",
"packages": [
{
"name": "colinmollenhour/cache-backend-file",
@@ -206,16 +206,6 @@
"ssl",
"tls"
],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/composer/composer",
- "type": "tidelift"
- }
- ],
"time": "2020-04-08T08:27:21+00:00"
},
{
@@ -462,12 +452,6 @@
"Xdebug",
"performance"
],
- "funding": [
- {
- "url": "https://packagist.com",
- "type": "custom"
- }
- ],
"time": "2020-03-01T12:26:26+00:00"
},
{
@@ -3924,20 +3908,6 @@
"x.509",
"x509"
],
- "funding": [
- {
- "url": "https://github.com/terrafrost",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/phpseclib",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
- "type": "tidelift"
- }
- ],
"time": "2020-04-04T23:17:33+00:00"
},
{
@@ -4474,20 +4444,6 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-20T17:43:50+00:00"
},
{
@@ -4666,20 +4622,6 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-30T20:35:19+00:00"
},
{
@@ -4729,20 +4671,6 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-20T17:43:50+00:00"
},
{
@@ -5939,12 +5867,6 @@
"functional testing",
"unit testing"
],
- "funding": [
- {
- "url": "https://opencollective.com/codeception",
- "type": "open_collective"
- }
- ],
"time": "2020-05-24T13:58:47+00:00"
},
{
@@ -6517,20 +6439,6 @@
"redis",
"xcache"
],
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
- "type": "tidelift"
- }
- ],
"time": "2020-05-27T16:24:54+00:00"
},
{
@@ -6654,20 +6562,6 @@
"constructor",
"instantiate"
],
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
- "type": "tidelift"
- }
- ],
"time": "2020-05-29T17:27:14+00:00"
},
{
@@ -6730,20 +6624,6 @@
"parser",
"php"
],
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
- "type": "tidelift"
- }
- ],
"time": "2020-05-25T17:44:05+00:00"
},
{
@@ -7203,16 +7083,16 @@
},
{
"name": "magento/magento2-functional-testing-framework",
- "version": "3.0.0-RC5",
+ "version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/magento/magento2-functional-testing-framework.git",
- "reference": "e5126f4eb476e227e3b668b622159c917f123175"
+ "reference": "8d98efa7434a30ab9e82ef128c430ef8e3a50699"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/e5126f4eb476e227e3b668b622159c917f123175",
- "reference": "e5126f4eb476e227e3b668b622159c917f123175",
+ "url": "https://api.github.com/repos/magento/magento2-functional-testing-framework/zipball/8d98efa7434a30ab9e82ef128c430ef8e3a50699",
+ "reference": "8d98efa7434a30ab9e82ef128c430ef8e3a50699",
"shasum": ""
},
"require": {
@@ -7237,6 +7117,7 @@
"spomky-labs/otphp": "^10.0",
"symfony/console": "^4.4",
"symfony/finder": "^5.0",
+ "symfony/http-foundation": "^5.0",
"symfony/mime": "^5.0",
"symfony/process": "^4.4",
"vlucas/phpdotenv": "^2.4",
@@ -7288,7 +7169,7 @@
"magento",
"testing"
],
- "time": "2020-06-15T19:51:46+00:00"
+ "time": "2020-07-09T21:26:19+00:00"
},
{
"name": "mikey179/vfsstream",
@@ -9855,20 +9736,6 @@
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-27T08:34:37+00:00"
},
{
@@ -9930,20 +9797,6 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-24T12:18:07+00:00"
},
{
@@ -10007,20 +9860,6 @@
"mime",
"mime-type"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-25T12:33:44+00:00"
},
{
@@ -10196,20 +10035,6 @@
"portable",
"shim"
],
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-12T16:47:27+00:00"
},
{
@@ -10323,20 +10148,6 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
"time": "2020-05-20T17:43:50+00:00"
},
{
@@ -10703,8 +10514,7 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
- "magento/composer": 20,
- "magento/magento2-functional-testing-framework": 5
+ "magento/composer": 20
},
"prefer-stable": true,
"prefer-lowest": false,
@@ -10727,6 +10537,5 @@
"ext-zip": "*",
"lib-libxml": "*"
},
- "platform-dev": [],
- "plugin-api-version": "1.1.0"
+ "platform-dev": []
}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
index 64f51b93cde50..2b628c05ae736 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
@@ -7,14 +7,21 @@
use Magento\Eav\Api\Data\AttributeOptionInterface;
use Magento\Eav\Api\Data\AttributeOptionLabelInterface;
+use Magento\Framework\Webapi\Rest\Request;
use Magento\TestFramework\TestCase\WebapiAbstract;
+/**
+ * Class to test Eav Option Management functionality
+ */
class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
{
const SERVICE_NAME = 'catalogProductAttributeOptionManagementV1';
const SERVICE_VERSION = 'V1';
const RESOURCE_PATH = '/V1/products/attributes';
+ /**
+ * Test to get attribute options
+ */
public function testGetItems()
{
$testAttributeCode = 'quantity_and_stock_status';
@@ -29,64 +36,56 @@ public function testGetItems()
],
];
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
- ],
- 'soap' => [
- 'service' => self::SERVICE_NAME,
- 'serviceVersion' => self::SERVICE_VERSION,
- 'operation' => self::SERVICE_NAME . 'getItems',
- ],
- ];
-
- $response = $this->_webApiCall($serviceInfo, ['attributeCode' => $testAttributeCode]);
+ $response = $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_GET,
+ 'getItems',
+ ['attributeCode' => $testAttributeCode]
+ );
$this->assertIsArray($response);
$this->assertEquals($expectedOptions, $response);
}
/**
+ * Test to add attribute option
+ *
+ * @param array $optionData
* @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
* @dataProvider addDataProvider
*/
- public function testAdd($optionData)
+ public function testAdd(array $optionData)
{
$testAttributeCode = 'select_attribute';
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
- ],
- 'soap' => [
- 'service' => self::SERVICE_NAME,
- 'serviceVersion' => self::SERVICE_VERSION,
- 'operation' => self::SERVICE_NAME . 'add',
- ],
- ];
-
- $response = $this->_webApiCall(
- $serviceInfo,
+ $response = $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_POST,
+ 'add',
[
'attributeCode' => $testAttributeCode,
'option' => $optionData,
]
);
- $this->assertNotNull($response);
- $updatedData = $this->getAttributeOptions($testAttributeCode);
- $lastOption = array_pop($updatedData);
- $this->assertEquals(
- $optionData[AttributeOptionInterface::STORE_LABELS][0][AttributeOptionLabelInterface::LABEL],
- $lastOption['label']
- );
+ $this->assertTrue(is_numeric($response));
+ /* Check new option labels by stores */
+ $expectedStoreLabels = [
+ 'all' => $optionData[AttributeOptionLabelInterface::LABEL],
+ 'default' => $optionData[AttributeOptionInterface::STORE_LABELS][0][AttributeOptionLabelInterface::LABEL],
+ ];
+ foreach ($expectedStoreLabels as $store => $label) {
+ $option = $this->getAttributeOption($testAttributeCode, $label, $store);
+ $this->assertNotNull($option);
+ $this->assertEquals($response, $option['value']);
+ }
}
/**
+ * Data provider for adding attribute option
+ *
* @return array
*/
- public function addDataProvider()
+ public function addDataProvider(): array
{
$optionPayload = [
AttributeOptionInterface::LABEL => 'new color',
@@ -114,62 +113,111 @@ public function addDataProvider()
'option_with_value_node_that_is_a_number' => [
array_merge($optionPayload, [AttributeOptionInterface::VALUE => '123'])
],
-
];
}
/**
+ * Test to delete attribute option
+ *
* @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
*/
public function testDelete()
{
$attributeCode = 'select_attribute';
- //get option Id
$optionList = $this->getAttributeOptions($attributeCode);
$this->assertGreaterThan(0, count($optionList));
$lastOption = array_pop($optionList);
$this->assertNotEmpty($lastOption['value']);
$optionId = $lastOption['value'];
- $serviceInfo = [
- 'rest' => [
- 'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode . '/options/' . $optionId,
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE,
- ],
- 'soap' => [
- 'service' => self::SERVICE_NAME,
- 'serviceVersion' => self::SERVICE_VERSION,
- 'operation' => self::SERVICE_NAME . 'delete',
- ],
- ];
- $this->assertTrue($this->_webApiCall(
- $serviceInfo,
+ $response = $this->webApiCallAttributeOptions(
+ $attributeCode,
+ Request::HTTP_METHOD_DELETE,
+ 'delete',
[
'attributeCode' => $attributeCode,
'optionId' => $optionId,
- ]
- ));
+ ],
+ $optionId
+ );
+ $this->assertTrue($response);
$updatedOptions = $this->getAttributeOptions($attributeCode);
$this->assertEquals($optionList, $updatedOptions);
}
/**
- * @param $testAttributeCode
+ * Perform Web API call to the system under test
+ *
+ * @param string $attributeCode
+ * @param string $httpMethod
+ * @param string $soapMethod
+ * @param array $arguments
+ * @param null $storeCode
+ * @param null $optionId
* @return array|bool|float|int|string
*/
- private function getAttributeOptions($testAttributeCode)
- {
+ private function webApiCallAttributeOptions(
+ string $attributeCode,
+ string $httpMethod,
+ string $soapMethod,
+ array $arguments = [],
+ $optionId = null,
+ $storeCode = null
+ ) {
$serviceInfo = [
'rest' => [
- 'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
- 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+ 'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode . '/options'
+ . ($optionId ? '/' .$optionId : ''),
+ 'httpMethod' => $httpMethod,
],
'soap' => [
'service' => self::SERVICE_NAME,
'serviceVersion' => self::SERVICE_VERSION,
- 'operation' => self::SERVICE_NAME . 'getItems',
+ 'operation' => self::SERVICE_NAME . $soapMethod,
],
];
- return $this->_webApiCall($serviceInfo, ['attributeCode' => $testAttributeCode]);
+
+ return $this->_webApiCall($serviceInfo, $arguments, null, $storeCode);
+ }
+
+ /**
+ * @param string $testAttributeCode
+ * @param string|null $storeCode
+ * @return array|bool|float|int|string
+ */
+ private function getAttributeOptions(string $testAttributeCode, ?string $storeCode = null)
+ {
+ return $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_GET,
+ 'getItems',
+ ['attributeCode' => $testAttributeCode],
+ null,
+ $storeCode
+ );
+ }
+
+ /**
+ * @param string $attributeCode
+ * @param string $optionLabel
+ * @param string|null $storeCode
+ * @return array|null
+ */
+ private function getAttributeOption(
+ string $attributeCode,
+ string $optionLabel,
+ ?string $storeCode = null
+ ): ?array {
+ $attributeOptions = $this->getAttributeOptions($attributeCode, $storeCode);
+ $option = null;
+ /** @var array $attributeOption */
+ foreach ($attributeOptions as $attributeOption) {
+ if ($attributeOption['label'] === $optionLabel) {
+ $option = $attributeOption;
+ break;
+ }
+ }
+
+ return $option;
}
}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionUpdateInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionUpdateInterfaceTest.php
new file mode 100644
index 0000000000000..dc3648f68b10c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionUpdateInterfaceTest.php
@@ -0,0 +1,234 @@
+ 'Fixture Option Changed',
+ AttributeOptionInterface::VALUE => 'option_value',
+ AttributeOptionInterface::STORE_LABELS => [
+ [
+ AttributeOptionLabelInterface::LABEL => 'Store Label Changed',
+ AttributeOptionLabelInterface::STORE_ID => 1,
+ ],
+ ],
+ ];
+
+ $existOptionLabel = 'Fixture Option';
+ $existAttributeOption = $this->getAttributeOption($testAttributeCode, $existOptionLabel, 'all');
+ $optionId = $existAttributeOption['value'];
+
+ $response = $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_PUT,
+ 'update',
+ [
+ 'attributeCode' => $testAttributeCode,
+ 'optionId' => $optionId,
+ 'option' => $optionData,
+ ],
+ $optionId
+ );
+
+ $this->assertTrue($response);
+
+ /* Check update option labels by stores */
+ $expectedStoreLabels = [
+ 'all' => $optionData[AttributeOptionLabelInterface::LABEL],
+ 'default' => $optionData[AttributeOptionInterface::STORE_LABELS][0][AttributeOptionLabelInterface::LABEL],
+ ];
+ foreach ($expectedStoreLabels as $store => $label) {
+ $this->assertNotNull($this->getAttributeOption($testAttributeCode, $label, $store));
+ }
+ }
+
+ /**
+ * Test to update option with already exist exception
+ *
+ * Test to except case when the two options has a same label
+ *
+ * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
+ */
+ public function testUpdateWithAlreadyExistsException()
+ {
+ $this->expectExceptionMessage("Admin store attribute option label '%1' is already exists.");
+ $testAttributeCode = 'select_attribute';
+
+ $newOptionData = [
+ AttributeOptionInterface::LABEL => 'New Option',
+ AttributeOptionInterface::VALUE => 'new_option_value',
+ ];
+ $newOptionId = $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_POST,
+ 'add',
+ [
+ 'attributeCode' => $testAttributeCode,
+ 'option' => $newOptionData,
+ ]
+ );
+
+ $editOptionData = [
+ AttributeOptionInterface::LABEL => 'Fixture Option',
+ AttributeOptionInterface::VALUE => $newOptionId,
+ ];
+ $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_PUT,
+ 'update',
+ [
+ 'attributeCode' => $testAttributeCode,
+ 'optionId' => $newOptionId,
+ 'option' => $editOptionData,
+ ],
+ $newOptionId
+ );
+ }
+
+ /**
+ * Test to update option with not exist exception
+ *
+ * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
+ */
+ public function testUpdateWithNotExistsException()
+ {
+ $this->expectExceptionMessage("The '%1' attribute doesn't include an option id '%2'.");
+ $testAttributeCode = 'select_attribute';
+
+ $newOptionData = [
+ AttributeOptionInterface::LABEL => 'New Option',
+ AttributeOptionInterface::VALUE => 'new_option_value'
+ ];
+ $newOptionId = (int)$this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_POST,
+ 'add',
+ [
+ 'attributeCode' => $testAttributeCode,
+ 'option' => $newOptionData,
+ ]
+ );
+
+ $newOptionId++;
+ $editOptionData = [
+ AttributeOptionInterface::LABEL => 'New Option Changed',
+ AttributeOptionInterface::VALUE => $newOptionId
+ ];
+ $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_PUT,
+ 'update',
+ [
+ 'attributeCode' => $testAttributeCode,
+ 'optionId' => $newOptionId,
+ 'option' => $editOptionData,
+ ],
+ $newOptionId
+ );
+ }
+
+ /**
+ * Perform Web API call to the system under test
+ *
+ * @param string $attributeCode
+ * @param string $httpMethod
+ * @param string $soapMethod
+ * @param array $arguments
+ * @param null $storeCode
+ * @param null $optionId
+ * @return array|bool|float|int|string
+ */
+ private function webApiCallAttributeOptions(
+ string $attributeCode,
+ string $httpMethod,
+ string $soapMethod,
+ array $arguments = [],
+ $optionId = null,
+ $storeCode = null
+ ) {
+ $resourcePath = self::RESOURCE_PATH . "/{$attributeCode}/options";
+ if ($optionId) {
+ $resourcePath .= '/' . $optionId;
+ }
+ $serviceName = $soapMethod === 'update' ? self::SERVICE_NAME_UPDATE : self::SERVICE_NAME;
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => $resourcePath,
+ 'httpMethod' => $httpMethod,
+ ],
+ 'soap' => [
+ 'service' => $serviceName,
+ 'serviceVersion' => self::SERVICE_VERSION,
+ 'operation' => $serviceName . $soapMethod,
+ ],
+ ];
+
+ return $this->_webApiCall($serviceInfo, $arguments, null, $storeCode);
+ }
+
+ /**
+ * @param string $attributeCode
+ * @param string $optionLabel
+ * @param string|null $storeCode
+ * @return array|null
+ */
+ private function getAttributeOption(
+ string $attributeCode,
+ string $optionLabel,
+ ?string $storeCode = null
+ ): ?array {
+ $attributeOptions = $this->getAttributeOptions($attributeCode, $storeCode);
+ $option = null;
+ /** @var array $attributeOption */
+ foreach ($attributeOptions as $attributeOption) {
+ if ($attributeOption['label'] === $optionLabel) {
+ $option = $attributeOption;
+ break;
+ }
+ }
+
+ return $option;
+ }
+
+ /**
+ * @param string $testAttributeCode
+ * @param string|null $storeCode
+ * @return array|bool|float|int|string
+ */
+ private function getAttributeOptions(string $testAttributeCode, ?string $storeCode = null)
+ {
+ return $this->webApiCallAttributeOptions(
+ $testAttributeCode,
+ Request::HTTP_METHOD_GET,
+ 'getItems',
+ ['attributeCode' => $testAttributeCode],
+ null,
+ $storeCode
+ );
+ }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/SpecialPriceStorageTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/SpecialPriceStorageTest.php
index ef374dc1873cf..90fe075f91e30 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/SpecialPriceStorageTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/SpecialPriceStorageTest.php
@@ -68,6 +68,35 @@ public function testGet()
$this->assertEquals($product->getSpecialPrice(), $response[0]['price']);
}
+ /**
+ * Test get method when special price is 0.
+ *
+ * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+ */
+ public function testGetZeroValue()
+ {
+ $specialPrice = 0;
+ $productRepository = $this->objectManager->create(ProductRepositoryInterface::class);
+ $product = $productRepository->get(self::SIMPLE_PRODUCT_SKU, true);
+ $product->setData('special_price', $specialPrice);
+ $productRepository->save($product);
+
+ $serviceInfo = [
+ 'rest' => [
+ 'resourcePath' => '/V1/products/special-price-information',
+ 'httpMethod' => Request::HTTP_METHOD_POST
+ ],
+ 'soap' => [
+ 'service' => self::SERVICE_NAME,
+ 'serviceVersion' => self::SERVICE_VERSION,
+ 'operation' => self::SERVICE_NAME . 'Get',
+ ],
+ ];
+ $response = $this->_webApiCall($serviceInfo, ['skus' => [self::SIMPLE_PRODUCT_SKU]]);
+ $this->assertNotEmpty($response);
+ $this->assertEquals($specialPrice, $response[0]['price']);
+ }
+
/**
* Test update method.
*
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/ReorderTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/ReorderTest.php
index 7bece410a06f8..0baee2797bf5d 100644
--- a/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/ReorderTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Sales/ReorderTest.php
@@ -108,7 +108,7 @@ public function testSimpleProductOutOfStock()
/** @var \Magento\Catalog\Api\ProductRepositoryInterface $repository */
$productRepository = Bootstrap::getObjectManager()
->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
- $productSku = 'simple';
+ $productSku = 'simple-2';
/** @var \Magento\Catalog\Api\Data\ProductInterface $product */
$product = $productRepository->get($productSku);
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
index dadc2caef7a13..c43cb81683aac 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
@@ -116,7 +116,7 @@ protected function _getWsdlContent($wsdlUrl)
$responseDom->loadXML($responseContent),
"Valid XML is always expected as a response for WSDL request."
);
- return $responseContent;
+ return $responseDom->saveXML();
}
/**
@@ -207,7 +207,7 @@ protected function _checkComplexTypesDeclaration($wsdlContent)
-
+
@@ -231,7 +231,7 @@ protected function _checkComplexTypesDeclaration($wsdlContent)
-
+
@@ -266,7 +266,7 @@ protected function _checkComplexTypesDeclaration($wsdlContent)
-
+
testModule5AllSoapAndRestV2Item
@@ -290,7 +290,7 @@ protected function _checkComplexTypesDeclaration($wsdlContent)
-
+
testModule5AllSoapAndRestV1Item
@@ -331,7 +331,7 @@ protected function _checkReferencedTypeDeclaration($wsdlContent)
-
+
@@ -835,7 +835,7 @@ protected function _checkFaultsComplexTypeSection($wsdlContent)
-
+
@@ -843,7 +843,7 @@ protected function _checkFaultsComplexTypeSection($wsdlContent)
-
+
@@ -865,7 +865,7 @@ protected function _checkFaultsComplexTypeSection($wsdlContent)
-
+
@@ -888,7 +888,7 @@ protected function _checkFaultsComplexTypeSection($wsdlContent)
-
+
diff --git a/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForFrontendObserverTest.php b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForFrontendObserverTest.php
index c0acf3344f60f..33c42d794bd78 100644
--- a/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForFrontendObserverTest.php
+++ b/dev/tests/integration/testsuite/Magento/Captcha/Observer/ResetAttemptForFrontendObserverTest.php
@@ -34,7 +34,7 @@ protected function setUp(): void
/**
* @magentoDataFixture Magento/Captcha/_files/failed_logins_frontend.php
*/
- public function testSuccesfulLoginRemovesFailedAttempts()
+ public function testSuccessfulLoginRemovesFailedAttempts()
{
$customerEmail = 'mageuser@dummy.com';
$customerFactory = $this->objectManager->get(CustomerFactory::class);
diff --git a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
index a5c88fc7571a2..2bff6f5ce82f6 100644
--- a/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
+++ b/dev/tests/integration/testsuite/Magento/Elasticsearch/Model/Adapter/BatchDataMapper/ProductDataMapperTest.php
@@ -54,7 +54,7 @@ protected function setUp(): void
$this->model = $this->objectManager->create(
ProductDataMapper::class,
[
- 'additionalFieldsProvider' => $additionalFieldsProvider
+ 'additionalFieldsProvider' => $additionalFieldsProvider,
]
);
$this->eavConfig = $this->objectManager->get(Config::class);
@@ -83,24 +83,24 @@ public function testMapSelectAttributeWithDifferentStoreLabels(): void
$defaultStoreMap = [
$productId => [
'store_id' => $defaultStore->getId(),
- 'select_attribute' => $attributeValue,
+ 'select_attribute' => (int)$attributeValue,
'select_attribute_value' => 'Table_default',
- ]
+ ],
];
$secondStoreMap = [
$productId => [
'store_id' => $secondStore->getId(),
- 'select_attribute' => $attributeValue,
+ 'select_attribute' => (int)$attributeValue,
'select_attribute_value' => 'Table_fixture_second_store',
- ]
+ ],
];
$data = [
$productId => [
- $attributeId => $attributeValue
- ]
+ $attributeId => $attributeValue,
+ ],
];
- $this->assertEquals($defaultStoreMap, $this->model->map($data, $defaultStore->getId(), []));
- $this->assertEquals($secondStoreMap, $this->model->map($data, $secondStore->getId(), []));
+ $this->assertSame($defaultStoreMap, $this->model->map($data, $defaultStore->getId(), []));
+ $this->assertSame($secondStoreMap, $this->model->map($data, $secondStore->getId(), []));
}
/**
diff --git a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php
index 5f2cee2368c98..94fe0e85a8ddf 100644
--- a/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php
+++ b/dev/tests/integration/testsuite/Magento/ProductAlert/Model/EmailTest.php
@@ -3,24 +3,32 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
namespace Magento\ProductAlert\Model;
use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Catalog\Model\Product;
use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
+use Magento\Customer\Helper\View;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Store\Model\StoreManagerInterface;
use Magento\Store\Model\Website;
+use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Mail\Template\TransportBuilderMock;
+use Magento\TestFramework\ObjectManager;
+use PHPUnit\Framework\TestCase;
/**
* Test for Magento\ProductAlert\Model\Email class.
*
* @magentoAppIsolation enabled
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
-class EmailTest extends \PHPUnit\Framework\TestCase
+class EmailTest extends TestCase
{
/**
* @var Email
@@ -28,7 +36,7 @@ class EmailTest extends \PHPUnit\Framework\TestCase
protected $_emailModel;
/**
- * @var \Magento\TestFramework\ObjectManager
+ * @var ObjectManager
*/
protected $_objectManager;
@@ -38,7 +46,7 @@ class EmailTest extends \PHPUnit\Framework\TestCase
protected $customerAccountManagement;
/**
- * @var \Magento\Customer\Helper\View
+ * @var View
*/
protected $_customerViewHelper;
@@ -62,11 +70,11 @@ class EmailTest extends \PHPUnit\Framework\TestCase
*/
protected function setUp(): void
{
- $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+ $this->_objectManager = Bootstrap::getObjectManager();
$this->customerAccountManagement = $this->_objectManager->create(
AccountManagementInterface::class
);
- $this->_customerViewHelper = $this->_objectManager->create(\Magento\Customer\Helper\View::class);
+ $this->_customerViewHelper = $this->_objectManager->create(View::class);
$this->transportBuilder = $this->_objectManager->get(TransportBuilderMock::class);
$this->customerRepository = $this->_objectManager->create(CustomerRepositoryInterface::class);
$this->productRepository = $this->_objectManager->create(ProductRepositoryInterface::class);
@@ -100,7 +108,7 @@ public function testSend($isCustomerIdUsed)
$this->_emailModel->setCustomerData($customer);
}
- /** @var \Magento\Catalog\Model\Product $product */
+ /** @var Product $product */
$product = $this->productRepository->getById(1);
$this->_emailModel->addPriceProduct($product);
@@ -165,4 +173,36 @@ public function testEmailForDifferentCustomers(): void
);
}
}
+
+ /**
+ * @magentoAppArea frontend
+ * @magentoDataFixture Magento/Customer/_files/customer.php
+ * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+ * @magentoDataFixture Magento/Store/_files/second_store_with_second_identity.php
+ */
+ public function testScopedMessageIdentity()
+ {
+ /** @var Website $website */
+ $website = $this->_objectManager->create(Website::class);
+ $website->load(1);
+ $this->_emailModel->setWebsite($website);
+
+ /** @var StoreManagerInterface $storeManager */
+ $storeManager = $this->_objectManager->create(StoreManagerInterface::class);
+ $store = $storeManager->getStore('fixture_second_store');
+ $this->_emailModel->setStoreId($store->getId());
+
+ $customer = $this->customerRepository->getById(1);
+ $this->_emailModel->setCustomerData($customer);
+
+ /** @var Product $product */
+ $product = $this->productRepository->getById(1);
+
+ $this->_emailModel->addPriceProduct($product);
+ $this->_emailModel->send();
+
+ $from = $this->transportBuilder->getSentMessage()->getFrom()[0];
+ $this->assertEquals('Fixture Store Owner', $from->getName());
+ $this->assertEquals('fixture.store.owner@example.com', $from->getEmail());
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php
index 6605d43c84264..3919f91a3241e 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/CustomerData/LastOrderedItemsTest.php
@@ -42,7 +42,7 @@ public function testDefaultFormatterIsAppliedWhenBasicIntegration()
$this->assertEquals(
LastOrderedItems::SIDEBAR_ORDER_LIMIT,
count($data['items']),
- 'Section items count should not be greater then ' . LastOrderedItems::SIDEBAR_ORDER_LIMIT
+ 'Section items count should not be greater than ' . LastOrderedItems::SIDEBAR_ORDER_LIMIT
);
}
}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Email/Sender/InvoiceSenderTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Email/Sender/InvoiceSenderTest.php
index 60021c7086267..55af8e9d2ee62 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Email/Sender/InvoiceSenderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Order/Email/Sender/InvoiceSenderTest.php
@@ -3,6 +3,8 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+declare(strict_types=1);
+
namespace Magento\Sales\Model\Order\Email\Sender;
use Magento\Customer\Api\CustomerRepositoryInterface;
@@ -11,6 +13,7 @@
use Magento\Sales\Model\Order\Email\Container\InvoiceIdentity;
use Magento\Sales\Model\Order\Invoice;
use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Area;
use PHPUnit\Framework\TestCase;
class InvoiceSenderTest extends TestCase
@@ -39,27 +42,33 @@ protected function setUp(): void
*/
public function testSend()
{
- \Magento\TestFramework\Helper\Bootstrap::getInstance()
- ->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND);
- $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
- ->create(\Magento\Sales\Model\Order::class);
+ Bootstrap::getInstance()
+ ->loadArea(Area::AREA_FRONTEND);
+ $order = Bootstrap::getObjectManager()
+ ->create(Order::class);
$order->loadByIncrementId('100000001');
$order->setCustomerEmail('customer@example.com');
- $invoice = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\Sales\Model\Order\Invoice::class
+ $invoice = Bootstrap::getObjectManager()->create(
+ Invoice::class
);
$invoice->setOrder($order);
-
+ $invoice->setTotalQty(1);
+ $invoice->setBaseSubtotal(50);
+ $invoice->setBaseTaxAmount(10);
+ $invoice->setBaseShippingAmount(5);
/** @var InvoiceSender $invoiceSender */
- $invoiceSender = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
- ->create(\Magento\Sales\Model\Order\Email\Sender\InvoiceSender::class);
+ $invoiceSender = Bootstrap::getObjectManager()
+ ->create(InvoiceSender::class);
$this->assertEmpty($invoice->getEmailSent());
$result = $invoiceSender->send($invoice, true);
$this->assertTrue($result);
$this->assertNotEmpty($invoice->getEmailSent());
+ $this->assertEquals($invoice->getBaseSubtotal(), $order->getBaseSubtotal());
+ $this->assertEquals($invoice->getBaseTaxAmount(), $order->getBaseTaxAmount());
+ $this->assertEquals($invoice->getBaseShippingAmount(), $order->getBaseShippingAmount());
}
/**
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock.php
index 9bd4c9b303cb9..e93e4143311b5 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock.php
@@ -4,25 +4,82 @@
* See COPYING.txt for license details.
*/
-use Magento\Sales\Api\Data\OrderInterfaceFactory;
+use Magento\Catalog\Api\ProductRepositoryInterface;
+use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
-use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Sales\Model\Order\Address as OrderAddress;
+use Magento\Sales\Model\Order\Item as OrderItem;
+use Magento\Sales\Model\Order\Payment;
+use Magento\Store\Model\StoreManagerInterface;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
+use Magento\Catalog\Model\Product;
+use Magento\TestFramework\Helper\Bootstrap;
-Resolver::getInstance()->requireDataFixture(
- 'Magento/Sales/_files/customer_order_item_with_product_and_custom_options.php'
-);
+Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/default_rollback.php');
+Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer.php');
+Resolver::getInstance()->requireDataFixture('Magento/Catalog/_files/product_simple_without_custom_options.php');
$objectManager = Bootstrap::getObjectManager();
+/** @var ProductRepositoryInterface $productRepository */
+$productRepository = $objectManager->create(ProductRepositoryInterface::class);
+$product = $productRepository->get('simple-2');
+$billingAddress = $objectManager->create(
+ OrderAddress::class,
+ [
+ 'data' => [
+ 'region' => 'CA',
+ 'region_id' => '12',
+ 'postcode' => '11111',
+ 'lastname' => 'lastname',
+ 'firstname' => 'firstname',
+ 'street' => 'street',
+ 'city' => 'Los Angeles',
+ 'email' => 'admin@example.com',
+ 'telephone' => '11111111',
+ 'country_id' => 'US',
+ ],
+ ],
+);
+$billingAddress->setAddressType('billing');
+$shippingAddress = clone $billingAddress;
+$shippingAddress->setId(null)->setAddressType('shipping');
+
+/** @var Payment $payment */
+$payment = $objectManager->create(\Magento\Sales\Model\Order\Payment::class);
+$payment->setMethod('checkmo');
+
+/** @var OrderItem $orderItem */
+$orderItem = $objectManager->create(OrderItem::class);
+$orderItem->setProductId($product->getId())
+ ->setQtyOrdered(2)
+ ->setBasePrice($product->getPrice())
+ ->setPrice($product->getPrice())
+ ->setRowTotal($product->getPrice())
+ ->setProductType('simple-2')
+ ->setName($product->getName())
+ ->setSku($product->getSku())
+ ->setProductOptions(['info_buyRequest' => ['qty' => 1]]);
+
/** @var Order $order */
-$order = $objectManager->get(OrderInterfaceFactory::class)->create()->loadByIncrementId('100000001');
-$order->setCustomerId(1)->setCustomerIsGuest(false)->save();
+$order = $objectManager->create(Order::class);
+$order->setIncrementId('100000001')
+ ->setCustomerIsGuest(false)
+ ->setCustomerId(1)
+ ->setCustomerEmail('customer@null.com')
+ ->setBillingAddress($billingAddress)
+ ->setShippingAddress($shippingAddress)
+ ->setStoreId($objectManager->get(StoreManagerInterface::class)->getStore()->getId())
+ ->addItem($orderItem)
+ ->setPayment($payment);
+/** @var OrderRepositoryInterface $orderRepository */
+$orderRepository = $objectManager->create(OrderRepositoryInterface::class);
+$orderRepository->save($order);
// load product and set it out of stock
-/** @var \Magento\Catalog\Api\ProductRepositoryInterface $repository */
-$productRepository = Bootstrap::getObjectManager()->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
-$productSku = 'simple';
-/** @var \Magento\Catalog\Model\Product $product */
+/** @var ProductRepositoryInterface $repository */
+$productRepository = Bootstrap::getObjectManager()->create(ProductRepositoryInterface::class);
+$productSku = 'simple-2';
+/** @var Product $product */
$product = $productRepository->get($productSku);
// set product as out of stock
$product->setStockData(
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock_rollback.php
index c4b3a1a18b03a..e6ff6de159a17 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_product_out_of_stock_rollback.php
@@ -5,6 +5,8 @@
*/
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
+Resolver::getInstance()->requireDataFixture('Magento/Customer/_files/customer_rollback.php');
Resolver::getInstance()->requireDataFixture(
- 'Magento/Sales/_files/customer_order_item_with_product_and_custom_options_rollback.php'
+ 'Magento/Catalog/_files/product_simple_without_custom_options_rollback.php'
);
+Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/default_rollback.php');
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Plugin/CouponUsagesTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Plugin/CouponUsagesTest.php
index f9a8b96ab1f2f..4ed096fa4418a 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/Plugin/CouponUsagesTest.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Plugin/CouponUsagesTest.php
@@ -3,35 +3,34 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
namespace Magento\SalesRule\Plugin;
use Magento\Framework\DataObject;
use Magento\Framework\ObjectManagerInterface;
-use Magento\Sales\Model\Order;
+use Magento\Quote\Model\Quote;
+use Magento\Quote\Model\QuoteManagement;
+use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Model\Service\OrderService;
use Magento\SalesRule\Model\Coupon;
use Magento\SalesRule\Model\ResourceModel\Coupon\Usage;
use Magento\TestFramework\Helper\Bootstrap;
+use PHPUnit\Framework\MockObject\MockObject;
+use PHPUnit\Framework\TestCase;
/**
- * Test increasing coupon usages after after order placing and decreasing after order cancellation.
+ * Test increasing coupon usages after order placing and decreasing after order cancellation.
*
+ * @magentoAppArea frontend
* @magentoDbIsolation enabled
* @magentoAppIsolation enabled
*/
-class CouponUsagesTest extends \PHPUnit\Framework\TestCase
+class CouponUsagesTest extends TestCase
{
/**
* @var ObjectManagerInterface
*/
private $objectManager;
- /**
- * @var Coupon
- */
- private $coupon;
-
/**
* @var Usage
*/
@@ -43,9 +42,9 @@ class CouponUsagesTest extends \PHPUnit\Framework\TestCase
private $couponUsage;
/**
- * @var Order
+ * @var QuoteManagement
*/
- private $order;
+ private $quoteManagement;
/**
* @var OrderService
@@ -58,36 +57,38 @@ class CouponUsagesTest extends \PHPUnit\Framework\TestCase
protected function setUp(): void
{
$this->objectManager = Bootstrap::getObjectManager();
- $this->coupon = $this->objectManager->get(Coupon::class);
$this->usage = $this->objectManager->get(Usage::class);
$this->couponUsage = $this->objectManager->get(DataObject::class);
- $this->order = $this->objectManager->get(Order::class);
+ $this->quoteManagement = $this->objectManager->get(QuoteManagement::class);
$this->orderService = $this->objectManager->get(OrderService::class);
}
/**
* Test increasing coupon usages after after order placing and decreasing after order cancellation.
*
- * @magentoDataFixture Magento/Customer/_files/customer.php
* @magentoDataFixture Magento/SalesRule/_files/coupons_limited_order.php
*/
- public function testOrderCancellation()
+ public function testSubmitQuoteAndCancelOrder()
{
$customerId = 1;
$couponCode = 'one_usage';
- $orderId = '100000001';
+ $reservedOrderId = 'test01';
- $this->coupon->loadByCode($couponCode);
- $this->order->loadByIncrementId($orderId);
+ /** @var Coupon $coupon */
+ $coupon = $this->objectManager->get(Coupon::class);
+ $coupon->loadByCode($couponCode);
+ /** @var Quote $quote */
+ $quote = $this->objectManager->get(Quote::class);
+ $quote->load($reservedOrderId, 'reserved_order_id');
// Make sure coupon usages value is incremented then order is placed.
- $this->orderService->place($this->order);
- $this->usage->loadByCustomerCoupon($this->couponUsage, $customerId, $this->coupon->getId());
- $this->coupon->loadByCode($couponCode);
+ $order = $this->quoteManagement->submit($quote);
+ $this->usage->loadByCustomerCoupon($this->couponUsage, $customerId, $coupon->getId());
+ $coupon->loadByCode($couponCode);
self::assertEquals(
1,
- $this->coupon->getTimesUsed()
+ $coupon->getTimesUsed()
);
self::assertEquals(
1,
@@ -95,17 +96,66 @@ public function testOrderCancellation()
);
// Make sure order coupon usages value is decremented then order is cancelled.
- $this->orderService->cancel($this->order->getId());
- $this->usage->loadByCustomerCoupon($this->couponUsage, $customerId, $this->coupon->getId());
- $this->coupon->loadByCode($couponCode);
+ $this->orderService->cancel($order->getId());
+ $this->usage->loadByCustomerCoupon($this->couponUsage, $customerId, $coupon->getId());
+ $coupon->loadByCode($couponCode);
self::assertEquals(
0,
- $this->coupon->getTimesUsed()
+ $coupon->getTimesUsed()
);
self::assertEquals(
0,
$this->couponUsage->getTimesUsed()
);
}
+
+ /**
+ * Test to decrement coupon usages after exception on order placing
+ *
+ * @magentoDataFixture Magento/SalesRule/_files/coupons_limited_order.php
+ */
+ public function testSubmitQuoteWithError()
+ {
+ $customerId = 1;
+ $couponCode = 'one_usage';
+ $reservedOrderId = 'test01';
+ $exceptionMessage = 'Some test exception';
+
+ /** @var Coupon $coupon */
+ $coupon = $this->objectManager->get(Coupon::class);
+ $coupon->loadByCode($couponCode);
+ /** @var Quote $quote */
+ $quote = $this->objectManager->get(Quote::class);
+ $quote->load($reservedOrderId, 'reserved_order_id');
+
+ /** @var OrderManagementInterface|MockObject $orderManagement */
+ $orderManagement = $this->createMock(OrderManagementInterface::class);
+ $orderManagement->expects($this->once())
+ ->method('place')
+ ->willThrowException(new \Exception($exceptionMessage));
+
+ /** @var QuoteManagement $quoteManagement */
+ $quoteManagement = $this->objectManager->create(
+ QuoteManagement::class,
+ ['orderManagement' => $orderManagement]
+ );
+
+ try {
+ $quoteManagement->submit($quote);
+ } catch (\Exception $exception) {
+ $this->assertEquals($exceptionMessage, $exception->getMessage());
+
+ $this->usage->loadByCustomerCoupon($this->couponUsage, $customerId, $coupon->getId());
+ $coupon->loadByCode($couponCode);
+ self::assertEquals(
+ 0,
+ $coupon->getTimesUsed()
+ );
+ self::assertEquals(
+ 0,
+ $this->couponUsage->getTimesUsed()
+ );
+ }
+ }
}
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited.php
index ee477318f52b8..164f8c0d5b7c2 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited.php
@@ -3,26 +3,34 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
use Magento\SalesRule\Model\Coupon;
+use Magento\SalesRule\Model\ResourceModel\Rule\Collection;
+use Magento\SalesRule\Model\Rule;
+use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
Resolver::getInstance()->requireDataFixture('Magento/SalesRule/_files/rules.php');
-$collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- \Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
+$collection = Bootstrap::getObjectManager()->create(
+ Collection::class
);
$items = array_values($collection->getItems());
+/** @var Rule $rule */
+foreach ($items as $rule) {
+ $rule->setSimpleAction('by_percent')
+ ->setDiscountAmount(10)
+ ->save();
+}
/** @var Coupon $coupon */
-$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Coupon::class);
+$coupon = Bootstrap::getObjectManager()->create(Coupon::class);
$coupon->setRuleId($items[0]->getId())
->setCode('one_usage')
->setType(0)
->setUsageLimit(1)
->save();
-$coupon = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(Coupon::class);
+$coupon = Bootstrap::getObjectManager()->create(Coupon::class);
$coupon->setRuleId($items[1]->getId())
->setCode('one_usage_per_customer')
->setType(0)
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order.php
index 79ee6ffb91f14..83f17ef0d9d46 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order.php
@@ -3,25 +3,28 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-
-use Magento\Sales\Model\Order;
+use Magento\Quote\Model\Quote;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
Resolver::getInstance()->requireDataFixture('Magento/SalesRule/_files/coupons_limited.php');
-Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order.php');
+Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/quote_with_customer.php');
$collection = Bootstrap::getObjectManager()->create(
\Magento\SalesRule\Model\ResourceModel\Rule\Collection::class
);
$items = array_values($collection->getItems());
-/** @var Order $order */
-$order = Bootstrap::getObjectManager()->create(Order::class);
+/** @var Quote $quote */
+$quote = Bootstrap::getObjectManager()->create(Quote::class);
+$quote->load('test01', 'reserved_order_id');
+$quote->getShippingAddress()
+ ->setShippingMethod('flatrate_flatrate')
+ ->setShippingDescription('Flat Rate - Fixed')
+ ->setCollectShippingRates(true)
+ ->collectShippingRates()
+ ->save();
-$order->loadByIncrementId('100000001')
- ->setCouponCode('one_usage')
+$quote->setCouponCode('one_usage')
->setAppliedRuleIds("{$items[0]->getId()}")
- ->setCreatedAt('2014-10-25 10:10:10')
- ->setCustomerId(1)
->save();
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order_rollback.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order_rollback.php
index f44b6d3a75c97..15e58a3e53da5 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/coupons_limited_order_rollback.php
@@ -5,5 +5,5 @@
*/
use Magento\TestFramework\Workaround\Override\Fixture\Resolver;
+Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/quote_with_customer_rollback.php');
Resolver::getInstance()->requireDataFixture('Magento/SalesRule/_files/coupons_limited_rollback.php');
-Resolver::getInstance()->requireDataFixture('Magento/Sales/_files/order_rollback.php');
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php
index 5643ef10782e8..3152b4a6e0efb 100644
--- a/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Setup/Console/Command/_files/root/lib/internal/Magento/Framework/Test/Unit/View/Element/UiComponentFactoryTest.php
@@ -115,7 +115,7 @@ public function testNonRootComponent()
$name = "fieldset";
$context = $this->createMock(\Magento\Framework\View\Element\UiComponent\ContextInterface::class);
$arguments = ['context' => $context];
- $defintionArguments = [
+ $definitionArguments = [
'componentType' => 'select',
'attributes' => [
'class' => '\Some\Class',
@@ -132,7 +132,7 @@ public function testNonRootComponent()
$this->dataMock->expects($this->once())
->method('get')
->with($name)
- ->willReturn($defintionArguments);
+ ->willReturn($definitionArguments);
$this->objectManagerMock->expects($this->once())
->method('create')
->with('\Some\Class', $expectedArguments);
diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity.php
new file mode 100644
index 0000000000000..495992a38c1fe
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity.php
@@ -0,0 +1,38 @@
+requireDataFixture('Magento/Store/_files/second_store.php');
+
+$objectManager = Bootstrap::getObjectManager();
+$store = $objectManager->create(Store::class);
+if ($storeId = $store->load('fixture_second_store', 'code')->getId()) {
+ /** @var Config $configResource */
+ $configResource = $objectManager->get(Config::class);
+ $configResource->saveConfig(
+ 'trans_email/ident_general/name',
+ 'Fixture Store Owner',
+ ScopeInterface::SCOPE_STORES,
+ $storeId
+ );
+ $configResource->saveConfig(
+ 'trans_email/ident_general/email',
+ 'fixture.store.owner@example.com',
+ ScopeInterface::SCOPE_STORES,
+ $storeId
+ );
+ $scopeConfig = $objectManager->get(ScopeConfigInterface::class);
+ $scopeConfig->clean();
+}
diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity_rollback.php b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity_rollback.php
new file mode 100644
index 0000000000000..6769a640a13d1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Store/_files/second_store_with_second_identity_rollback.php
@@ -0,0 +1,32 @@
+create(Store::class);
+$storeId = $store->load('fixture_second_store', 'code')->getId();
+
+if ($storeId) {
+ $configResource = $objectManager->get(Config::class);
+ $configResource->deleteConfig(
+ 'trans_email/ident_general/name',
+ ScopeInterface::SCOPE_STORES,
+ $storeId
+ );
+ $configResource->deleteConfig(
+ 'trans_email/ident_general/email',
+ ScopeInterface::SCOPE_STORES,
+ $storeId
+ );
+}
+
+Resolver::getInstance()->requireDataFixture('Magento/Store/_files/second_store_rollback.php');
diff --git a/lib/internal/Magento/Framework/App/Utility/Files.php b/lib/internal/Magento/Framework/App/Utility/Files.php
index 901bbbde3dc9f..5f5814c5c6568 100644
--- a/lib/internal/Magento/Framework/App/Utility/Files.php
+++ b/lib/internal/Magento/Framework/App/Utility/Files.php
@@ -1116,7 +1116,7 @@ public function getJsFilesForArea($area)
} else {
$frontendPaths = [BP . "/lib/web/mage"];
/* current structure of /lib/web/mage directory contains frontend javascript in the root,
- backend javascript in subdirectories. That's why script shouldn't go recursive throught subdirectories
+ backend javascript in subdirectories. That's why script shouldn't go recursive through subdirectories
to get js files for frontend */
$files = array_merge($files, self::getFiles($frontendPaths, '*.js', false));
}
diff --git a/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php b/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
index f04300eeeb5ab..664540d33f7ad 100644
--- a/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
+++ b/lib/internal/Magento/Framework/Locale/Test/Unit/CurrencyTest.php
@@ -41,8 +41,8 @@ class CurrencyTest extends TestCase
const TEST_NONCACHED_CURRENCY_LOCALE = 'en_US';
const TEST_CACHED_CURRENCY = 'CAD';
const TEST_CACHED_CURRENCY_LOCALE = 'en_CA';
- const TEST_NONEXISTANT_CURRENCY = 'QQQ';
- const TEST_NONEXISTANT_CURRENCY_LOCALE = 'fr_FR';
+ const TEST_NONEXISTENT_CURRENCY = 'QQQ';
+ const TEST_NONEXISTENT_CURRENCY_LOCALE = 'fr_FR';
const TEST_EXCEPTION_CURRENCY = 'ZZZ';
const TEST_EXCEPTION_CURRENCY_LOCALE = 'es_ES';
@@ -146,9 +146,9 @@ public function testGetCurrencyCached()
$this->assertEquals([self::TEST_CACHED_CURRENCY], $retrievedCurrencyObject->getCurrencyList());
}
- public function testGetNonExistantCurrency()
+ public function testGetNonExistentCurrency()
{
- $options = new \Zend_Currency(null, self::TEST_NONEXISTANT_CURRENCY_LOCALE);
+ $options = new \Zend_Currency(null, self::TEST_NONEXISTENT_CURRENCY_LOCALE);
$this->mockCurrencyFactory
->expects($this->once())
@@ -164,10 +164,10 @@ public function testGetNonExistantCurrency()
->method('dispatch');
$retrievedCurrencyObject = $this->testCurrencyObject
- ->getCurrency(self::TEST_NONEXISTANT_CURRENCY);
+ ->getCurrency(self::TEST_NONEXISTENT_CURRENCY);
$this->assertInstanceOf('Zend_Currency', $retrievedCurrencyObject);
- $this->assertEquals(self::TEST_NONEXISTANT_CURRENCY_LOCALE, $retrievedCurrencyObject->getLocale());
+ $this->assertEquals(self::TEST_NONEXISTENT_CURRENCY_LOCALE, $retrievedCurrencyObject->getLocale());
$this->assertEquals('euro', $retrievedCurrencyObject->getName());
$this->assertEquals(['EUR'], $retrievedCurrencyObject->getCurrencyList());
}