diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml
index 852e0095f2f66..a04e366a43a2d 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/text.phtml
@@ -7,6 +7,7 @@
// @codingStandardsIgnoreFile
?>
+
getOption();
$class = ($_option->getIsRequire()) ? ' required' : '';
@@ -17,7 +18,7 @@ $class = ($_option->getIsRequire()) ? ' required' : '';
} ?>= /* @escapeNotVerified */ $class ?>">
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
index 8fcac2f9f1d65..83e91d3c3d4c7 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
@@ -49,6 +49,23 @@ define([
});
},
+ /**
+ * @private
+ */
+ _redirect: function (url) {
+ var urlParts, locationParts, forceReload;
+
+ urlParts = url.split('#');
+ locationParts = window.location.href.split('#');
+ forceReload = urlParts[0] === locationParts[0];
+
+ window.location.assign(url);
+
+ if (forceReload) {
+ window.location.reload();
+ }
+ },
+
/**
* @return {Boolean}
*/
@@ -62,34 +79,28 @@ define([
* @param {Object} form
*/
submitForm: function (form) {
- var addToCartButton, self = this;
-
- if (form.has('input[type="file"]').length && form.find('input[type="file"]').val() !== '') {
- self.element.off('submit');
- // disable 'Add to Cart' button
- addToCartButton = $(form).find(this.options.addToCartButtonSelector);
- addToCartButton.prop('disabled', true);
- addToCartButton.addClass(this.options.addToCartButtonDisabledClass);
- form.submit();
- } else {
- self.ajaxSubmit(form);
- }
+ this.ajaxSubmit(form);
},
/**
* @param {String} form
*/
ajaxSubmit: function (form) {
- var self = this;
+ var self = this,
+ formData;
$(self.options.minicartSelector).trigger('contentLoading');
self.disableAddToCartButton(form);
+ formData = new FormData(form[0]);
$.ajax({
url: form.attr('action'),
- data: form.serialize(),
+ data: formData,
type: 'post',
dataType: 'json',
+ cache: false,
+ contentType: false,
+ processData: false,
/** @inheritdoc */
beforeSend: function () {
@@ -125,7 +136,8 @@ define([
parameters.push(eventData.redirectParameters.join('&'));
res.backUrl = parameters.join('#');
}
- window.location = res.backUrl;
+
+ self._redirect(res.backUrl);
return;
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
index a1f581743a645..ebd8671de02fb 100644
--- a/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
+++ b/app/code/Magento/CatalogGraphQl/Model/AttributesJoiner.php
@@ -28,6 +28,10 @@ public function join(FieldNode $fieldNode, AbstractCollection $collection) : voi
/** @var FieldNode $field */
foreach ($query as $field) {
+ if ($field->kind === 'InlineFragment') {
+ continue;
+ }
+
if (!$collection->isAttributeAdded($field->name->value)) {
$collection->addAttributeToSelect($field->name->value);
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php b/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
index baa456c7821ed..dbe58a9c77cd0 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Category/DepthCalculator.php
@@ -26,6 +26,10 @@ public function calculate(FieldNode $fieldNode) : int
$depth = count($selections) ? 1 : 0;
$childrenDepth = [0];
foreach ($selections as $node) {
+ if ($node->kind === 'InlineFragment') {
+ continue;
+ }
+
$childrenDepth[] = $this->calculate($node);
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/LevelCalculator.php b/app/code/Magento/CatalogGraphQl/Model/Category/LevelCalculator.php
index eb57873850b80..0401e1c42331e 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Category/LevelCalculator.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Category/LevelCalculator.php
@@ -37,7 +37,7 @@ public function calculate(int $rootCategoryId) : int
{
$connection = $this->resourceConnection->getConnection();
$select = $connection->select()
- ->from($connection->getTableName('catalog_category_entity'), 'level')
+ ->from($this->resourceConnection->getTableName('catalog_category_entity'), 'level')
->where($this->resourceCategory->getLinkField() . " = ?", $rootCategoryId);
return (int) $connection->fetchOne($select);
}
diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
index 3c01579410638..da457279728bb 100644
--- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
+++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Products/DataProvider/CategoryTree.php
@@ -24,9 +24,9 @@
class CategoryTree
{
/**
- * In depth we need to calculate only children nodes, so 2 first wrapped nodes should be ignored
+ * In depth we need to calculate only children nodes, so the first wrapped node should be ignored
*/
- const DEPTH_OFFSET = 2;
+ const DEPTH_OFFSET = 1;
/**
* @var CollectionFactory
@@ -143,6 +143,10 @@ private function joinAttributesRecursively(Collection $collection, FieldNode $fi
/** @var FieldNode $node */
foreach ($subSelection as $node) {
+ if ($node->kind === 'InlineFragment') {
+ continue;
+ }
+
$this->joinAttributesRecursively($collection, $node);
}
}
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php
index 5de9d3880b5d2..db5b07279ed1c 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php
@@ -75,6 +75,7 @@ protected function initCategories()
$collection->addAttributeToSelect('name')
->addAttributeToSelect('url_key')
->addAttributeToSelect('url_path');
+ $collection->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID);
/* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
foreach ($collection as $category) {
$structure = explode(self::DELIMITER_CATEGORY, $category->getPath());
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
index dd33b94423696..afd018f077d20 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php
@@ -28,6 +28,13 @@ abstract class AbstractType
*/
public static $commonAttributesCache = [];
+ /**
+ * Maintain a list of invisible attributes
+ *
+ * @var array
+ */
+ public static $invAttributesCache = [];
+
/**
* Attribute Code to Id cache
*
@@ -278,7 +285,14 @@ protected function _initAttributes()
}
}
foreach ($absentKeys as $attributeSetName => $attributeIds) {
- $this->attachAttributesById($attributeSetName, $attributeIds);
+ $unknownAttributeIds = array_diff(
+ $attributeIds,
+ array_keys(self::$commonAttributesCache),
+ self::$invAttributesCache
+ );
+ if ($unknownAttributeIds || $this->_forcedAttributesCodes) {
+ $this->attachAttributesById($attributeSetName, $attributeIds);
+ }
}
foreach ($entityAttributes as $attributeRow) {
if (isset(self::$commonAttributesCache[$attributeRow['attribute_id']])) {
@@ -303,37 +317,45 @@ protected function _initAttributes()
protected function attachAttributesById($attributeSetName, $attributeIds)
{
foreach ($this->_prodAttrColFac->create()->addFieldToFilter(
- 'main_table.attribute_id',
- ['in' => $attributeIds]
+ ['main_table.attribute_id', 'main_table.attribute_code'],
+ [
+ ['in' => $attributeIds],
+ ['in' => $this->_forcedAttributesCodes]
+ ]
) as $attribute) {
$attributeCode = $attribute->getAttributeCode();
$attributeId = $attribute->getId();
if ($attribute->getIsVisible() || in_array($attributeCode, $this->_forcedAttributesCodes)) {
- self::$commonAttributesCache[$attributeId] = [
- 'id' => $attributeId,
- 'code' => $attributeCode,
- 'is_global' => $attribute->getIsGlobal(),
- 'is_required' => $attribute->getIsRequired(),
- 'is_unique' => $attribute->getIsUnique(),
- 'frontend_label' => $attribute->getFrontendLabel(),
- 'is_static' => $attribute->isStatic(),
- 'apply_to' => $attribute->getApplyTo(),
- 'type' => \Magento\ImportExport\Model\Import::getAttributeType($attribute),
- 'default_value' => strlen(
- $attribute->getDefaultValue()
- ) ? $attribute->getDefaultValue() : null,
- 'options' => $this->_entityModel->getAttributeOptions(
- $attribute,
- $this->_indexValueAttributes
- ),
- ];
+ if (!isset(self::$commonAttributesCache[$attributeId])) {
+ self::$commonAttributesCache[$attributeId] = [
+ 'id' => $attributeId,
+ 'code' => $attributeCode,
+ 'is_global' => $attribute->getIsGlobal(),
+ 'is_required' => $attribute->getIsRequired(),
+ 'is_unique' => $attribute->getIsUnique(),
+ 'frontend_label' => $attribute->getFrontendLabel(),
+ 'is_static' => $attribute->isStatic(),
+ 'apply_to' => $attribute->getApplyTo(),
+ 'type' => \Magento\ImportExport\Model\Import::getAttributeType($attribute),
+ 'default_value' => strlen(
+ $attribute->getDefaultValue()
+ ) ? $attribute->getDefaultValue() : null,
+ 'options' => $this->_entityModel->getAttributeOptions(
+ $attribute,
+ $this->_indexValueAttributes
+ ),
+ ];
+ }
+
self::$attributeCodeToId[$attributeCode] = $attributeId;
$this->_addAttributeParams(
$attributeSetName,
self::$commonAttributesCache[$attributeId],
$attribute
);
+ } else {
+ self::$invAttributesCache[] = $attributeId;
}
}
}
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php
index 0939acabbd5fd..e7ffe408cc732 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php
@@ -170,14 +170,25 @@ public function move($fileName, $renameFileOff = false)
}
}
+ if ($this->getTmpDir()) {
+ $filePath = $this->getTmpDir() . '/';
+ } else {
+ $filePath = '';
+ }
$fileName = preg_replace('/[^a-z0-9\._-]+/i', '', $fileName);
+ $filePath = $this->_directory->getRelativePath($filePath . $fileName);
$this->_directory->writeFile(
- $this->_directory->getRelativePath($this->getTmpDir() . '/' . $fileName),
+ $filePath,
$read->readAll()
);
}
- $filePath = $this->_directory->getRelativePath($this->getTmpDir() . '/' . $fileName);
+ if ($this->getTmpDir()) {
+ $filePath = $this->getTmpDir() . '/';
+ } else {
+ $filePath = '';
+ }
+ $filePath = $this->_directory->getRelativePath($filePath . $fileName);
$this->_setUploadFile($filePath);
$destDir = $this->_directory->getAbsolutePath($this->getDestDir());
$result = $this->save($destDir);
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/AbstractTypeTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/AbstractTypeTest.php
index 70ac3a4fa2e97..bd2fe896b8c0a 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/AbstractTypeTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/AbstractTypeTest.php
@@ -134,8 +134,28 @@ protected function setUp()
->expects($this->any())
->method('addFieldToFilter')
->with(
- 'main_table.attribute_id',
- ['in' => ['attribute_id', 'boolean_attribute']]
+ ['main_table.attribute_id', 'main_table.attribute_code'],
+ [
+ [
+ 'in' =>
+ [
+ 'attribute_id',
+ 'boolean_attribute',
+ ],
+ ],
+ [
+ 'in' =>
+ [
+ 'related_tgtr_position_behavior',
+ 'related_tgtr_position_limit',
+ 'upsell_tgtr_position_behavior',
+ 'upsell_tgtr_position_limit',
+ 'thumbnail_label',
+ 'small_image_label',
+ 'image_label',
+ ],
+ ],
+ ]
)
->willReturn([$attribute1, $attribute2]);
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php
index ed95d5a0212c9..262593377aa2c 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php
@@ -103,7 +103,7 @@ protected function setUp()
public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName)
{
$destDir = 'var/dest/dir';
- $expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $expectedFileName;
+ $expectedRelativeFilePath = $expectedFileName;
$this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true);
$this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath);
$this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir)
@@ -139,7 +139,7 @@ public function testMoveFileName()
{
$destDir = 'var/dest/dir';
$fileName = 'test_uploader_file';
- $expectedRelativeFilePath = $this->uploader->getTmpDir() . '/' . $fileName;
+ $expectedRelativeFilePath = $fileName;
$this->directoryMock->expects($this->once())->method('isWritable')->with($destDir)->willReturn(true);
$this->directoryMock->expects($this->any())->method('getRelativePath')->with($expectedRelativeFilePath);
$this->directoryMock->expects($this->once())->method('getAbsolutePath')->with($destDir)
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml
new file mode 100644
index 0000000000000..ad92af9bb3b1b
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Mftf/ActionGroup/CatalogPriceRuleActionGroup.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml b/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml
index 2b11a4db0578d..3199a53026a92 100644
--- a/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Data/CatalogRuleData.xml
@@ -21,4 +21,46 @@
by_percent
10
+
+
+ CatalogPriceRule
+ Catalog Price Rule Description
+ 1
+
+ - 0
+
+
+ - 1
+
+ by_fixed
+ 10
+
+
+
+ CatalogPriceRule
+ Catalog Price Rule Description
+ 1
+
+ - 0
+
+
+ - 1
+
+ to_percent
+ 90
+
+
+
+ CatalogPriceRule
+ Catalog Price Rule Description
+ 1
+
+ - 0
+
+
+ - 1
+
+ to_fixed
+ 100
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Page/CatalogRulePage.xml b/app/code/Magento/CatalogRule/Test/Mftf/Page/CatalogRulePage.xml
new file mode 100644
index 0000000000000..e080a252e7855
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Page/CatalogRulePage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml
new file mode 100644
index 0000000000000..b60a4c6516a82
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Section/AdminNewCatalogPriceRuleSection.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml
new file mode 100644
index 0000000000000..a68965d97e879
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/AdminCreateCatalogPriceRuleTest.xml
@@ -0,0 +1,240 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml
new file mode 100644
index 0000000000000..77a9a48074c29
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Mftf/Test/StorefrontInactiveCatalogRuleTest.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php
index e266e67804e88..beff1c66d4f61 100644
--- a/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php
+++ b/app/code/Magento/CatalogSearch/Setup/Patch/Data/SetInitialSearchWeightForAttributes.php
@@ -6,6 +6,7 @@
namespace Magento\CatalogSearch\Setup\Patch\Data;
+use Magento\Framework\App\State;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
use Magento\Framework\Indexer\IndexerInterfaceFactory;
@@ -27,17 +28,25 @@ class SetInitialSearchWeightForAttributes implements DataPatchInterface, PatchVe
*/
private $attributeRepository;
+ /**
+ * @var State
+ */
+ private $state;
+
/**
* SetInitialSearchWeightForAttributes constructor.
* @param IndexerInterfaceFactory $indexerFactory
* @param ProductAttributeRepositoryInterface $attributeRepository
+ * @param State $state
*/
public function __construct(
IndexerInterfaceFactory $indexerFactory,
- ProductAttributeRepositoryInterface $attributeRepository
+ ProductAttributeRepositoryInterface $attributeRepository,
+ State $state
) {
$this->indexerFactory = $indexerFactory;
$this->attributeRepository = $attributeRepository;
+ $this->state = $state;
}
/**
@@ -47,6 +56,13 @@ public function apply()
{
$this->setWeight('sku', 6);
$this->setWeight('name', 5);
+ $indexer = $this->indexerFactory->create()->load('catalogsearch_fulltext');
+ $this->state->emulateAreaCode(
+ \Magento\Framework\App\Area::AREA_CRONTAB,
+ function () use ($indexer) {
+ $indexer->reindexAll();
+ }
+ );
}
/**
@@ -76,8 +92,9 @@ public function getAliases()
/**
* Set attribute search weight.
*
- * @param $attributeCode
- * @param $weight
+ * @param string $attributeCode
+ * @param int $weight
+ * @return void
*/
private function setWeight($attributeCode, $weight)
{
diff --git a/app/code/Magento/CatalogSearch/Setup/RecurringData.php b/app/code/Magento/CatalogSearch/Setup/RecurringData.php
deleted file mode 100644
index 0c2aee800b6f1..0000000000000
--- a/app/code/Magento/CatalogSearch/Setup/RecurringData.php
+++ /dev/null
@@ -1,62 +0,0 @@
-indexerInterfaceFactory = $indexerInterfaceFactory;
- $this->state = $state;
- }
-
- /**
- * {@inheritdoc}
- */
- public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
- {
- $this->state->emulateAreaCode(
- \Magento\Framework\App\Area::AREA_CRONTAB,
- [$this, 'reindex']
- );
- }
-
- /**
- * Run reindex.
- *
- * @return void
- */
- public function reindex()
- {
- $this->indexerInterfaceFactory->create()->load('catalogsearch_fulltext')->reindexAll();
- }
-}
diff --git a/app/code/Magento/Checkout/Setup/Patch/Data/PrepareInitialCheckoutConfiguration.php b/app/code/Magento/Checkout/Setup/Patch/Data/PrepareInitialCheckoutConfiguration.php
index bc38809d070b2..47a19fb3234fd 100644
--- a/app/code/Magento/Checkout/Setup/Patch/Data/PrepareInitialCheckoutConfiguration.php
+++ b/app/code/Magento/Checkout/Setup/Patch/Data/PrepareInitialCheckoutConfiguration.php
@@ -817,7 +817,7 @@ public function apply()
$connection->commit();
} catch (\Exception $e) {
- $connection->rollback();
+ $connection->rollBack();
throw $e;
}
}
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml
index 35ddfdaefe050..33b83fe63fdc1 100644
--- a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontProductCartActionGroup.xml
@@ -21,6 +21,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/AdminDataGridHeaderSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/AdminDataGridHeaderSection.xml
new file mode 100644
index 0000000000000..56062f96152c2
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/AdminDataGridHeaderSection.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
index c20309814d51d..136658cc59106 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/CheckoutShippingSection.xml
@@ -31,5 +31,6 @@
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
index 0fa5dc8a42341..0da16a34134b8 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
@@ -23,5 +23,7 @@
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml
new file mode 100644
index 0000000000000..add1a1b1cf9be
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/AddressStateFieldShouldNotAcceptJustIntegerValuesTest.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/CollectQuoteTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/CollectQuoteTest.php
new file mode 100644
index 0000000000000..14410578b12e4
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/CollectQuoteTest.php
@@ -0,0 +1,178 @@
+customerSessionMock = $this->createMock(CustomerSession::class);
+ $this->customerRepositoryMock = $this->getMockForAbstractClass(
+ CustomerRepositoryInterface::class,
+ [],
+ '',
+ false,
+ true,
+ true,
+ ['getById']
+ );
+ $this->addressRepositoryMock = $this->createMock(AddressRepositoryInterface::class);
+ $this->estimateAddressMock = $this->createMock(EstimateAddressInterface::class);
+ $this->estimateAddressFactoryMock =
+ $this->createPartialMock(EstimateAddressInterfaceFactory::class, ['create']);
+ $this->shippingMethodManagerMock = $this->createMock(ShippingMethodManagementInterface::class);
+ $this->quoteRepositoryMock = $this->createMock(CartRepositoryInterface::class);
+ $this->quoteMock = $this->createMock(Quote::class);
+ $this->customerMock = $this->createMock(CustomerInterface::class);
+ $this->addressMock = $this->createMock(AddressInterface::class);
+
+ $this->model = new CollectQuote(
+ $this->customerSessionMock,
+ $this->customerRepositoryMock,
+ $this->addressRepositoryMock,
+ $this->estimateAddressFactoryMock,
+ $this->shippingMethodManagerMock,
+ $this->quoteRepositoryMock
+ );
+ }
+
+ /**
+ * Test collect method
+ */
+ public function testCollect()
+ {
+ $customerId = 1;
+ $defaultAddressId = 999;
+ $countryId = 'USA';
+ $regionId = 'CA';
+ $regionMock = $this->createMock(RegionInterface::class);
+
+ $this->customerSessionMock->expects(self::once())
+ ->method('isLoggedIn')
+ ->willReturn(true);
+ $this->customerSessionMock->expects(self::once())
+ ->method('getCustomerId')
+ ->willReturn($customerId);
+ $this->customerRepositoryMock->expects(self::once())
+ ->method('getById')
+ ->willReturn($this->customerMock);
+ $this->customerMock->expects(self::once())
+ ->method('getDefaultShipping')
+ ->willReturn($defaultAddressId);
+ $this->addressMock->expects(self::once())
+ ->method('getCountryId')
+ ->willReturn($countryId);
+ $regionMock->expects(self::once())
+ ->method('getRegion')
+ ->willReturn($regionId);
+ $this->addressMock->expects(self::once())
+ ->method('getRegion')
+ ->willReturn($regionMock);
+ $this->addressRepositoryMock->expects(self::once())
+ ->method('getById')
+ ->with($defaultAddressId)
+ ->willReturn($this->addressMock);
+ $this->estimateAddressFactoryMock->expects(self::once())
+ ->method('create')
+ ->willReturn($this->estimateAddressMock);
+ $this->quoteRepositoryMock->expects(self::once())
+ ->method('save')
+ ->with($this->quoteMock);
+
+ $this->model->collect($this->quoteMock);
+ }
+
+ /**
+ * Test with a not logged in customer
+ */
+ public function testCollectWhenCustomerIsNotLoggedIn()
+ {
+ $this->customerSessionMock->expects(self::once())
+ ->method('isLoggedIn')
+ ->willReturn(false);
+ $this->customerRepositoryMock->expects(self::never())
+ ->method('getById');
+
+ $this->model->collect($this->quoteMock);
+ }
+}
diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml
index 6947e1162600a..11e3ba5f3ed9a 100644
--- a/app/code/Magento/Checkout/etc/adminhtml/system.xml
+++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml
@@ -41,6 +41,10 @@
+
+
+ Magento\Config\Model\Config\Source\Yesno
+
diff --git a/app/code/Magento/Checkout/etc/config.xml b/app/code/Magento/Checkout/etc/config.xml
index 3c24c38ecf85b..e1ba4381f2230 100644
--- a/app/code/Magento/Checkout/etc/config.xml
+++ b/app/code/Magento/Checkout/etc/config.xml
@@ -17,6 +17,7 @@
30
0
20
+ 1
1
diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv
index 53fdebb8a2995..a6ea2c13579a7 100644
--- a/app/code/Magento/Checkout/i18n/en_US.csv
+++ b/app/code/Magento/Checkout/i18n/en_US.csv
@@ -177,3 +177,8 @@ Payment,Payment
"We received your order!","We received your order!"
"Thank you for your purchase!","Thank you for your purchase!"
"Password", "Password"
+"Something went wrong while saving the page. Please refresh the page and try again.","Something went wrong while saving the page. Please refresh the page and try again."
+"Item in Cart","Item in Cart"
+"Items in Cart","Items in Cart"
+"Close","Close"
+"Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart"
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
index ff4c6dbd35ff2..69d2523d88dfb 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_index.xml
@@ -186,7 +186,7 @@
-
+
crosssell
diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithAllValuesActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithAllValuesActionGroup.xml
new file mode 100644
index 0000000000000..2225d3d34a655
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/CreateNewPageWithAllValuesActionGroup.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml
new file mode 100644
index 0000000000000..690ad9881c7fc
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Mftf/ActionGroup/DeletePageByUrlKeyActionGroup.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPageHierarchySection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPageHierarchySection.xml
new file mode 100644
index 0000000000000..e2c4f48f4ff9b
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPageHierarchySection.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePiwSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePiwSection.xml
new file mode 100644
index 0000000000000..456de55b49171
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsNewPagePiwSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Cms/Test/Mftf/Section/CmsPagesPageActionsSection.xml b/app/code/Magento/Cms/Test/Mftf/Section/CmsPagesPageActionsSection.xml
index b27fb84e98a08..2f28aa46af65b 100644
--- a/app/code/Magento/Cms/Test/Mftf/Section/CmsPagesPageActionsSection.xml
+++ b/app/code/Magento/Cms/Test/Mftf/Section/CmsPagesPageActionsSection.xml
@@ -25,5 +25,7 @@
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigSalesTaxClassActionGroup.xml b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigSalesTaxClassActionGroup.xml
new file mode 100644
index 0000000000000..7bb2441a6a529
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/ActionGroup/ConfigSalesTaxClassActionGroup.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml
index e517f6ef62c7a..c24e578c9109c 100644
--- a/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml
+++ b/app/code/Magento/Config/Test/Mftf/Page/AdminConfigPage.xml
@@ -12,4 +12,7 @@
+
+
+
diff --git a/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml b/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml
new file mode 100644
index 0000000000000..f1520f5813e6d
--- /dev/null
+++ b/app/code/Magento/Config/Test/Mftf/Section/SalesConfigSection.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 29583231a764a..19de63b7a976c 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -926,6 +926,8 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
return $result;
}
}
+ } elseif (is_string($result)) {
+ return __($result)->render();
}
}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
index 3d42217de5f91..5581fcc07b861 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
@@ -64,7 +64,7 @@ public function resolvePrice(\Magento\Framework\Pricing\SaleableInterface $produ
foreach ($this->lowestPriceOptionsProvider->getProducts($product) as $subProduct) {
$productPrice = $this->priceResolver->resolvePrice($subProduct);
- $price = $price ? min($price, $productPrice) : $productPrice;
+ $price = isset($price) ? min($price, $productPrice) : $productPrice;
}
return (float)$price;
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml
index e04dbf274d932..77759043a0500 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminCreateProductConfigurationsPanelSection.xml
@@ -18,6 +18,7 @@
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml
index f42a1f4d8dbd7..31787ca75f199 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminNewAttributePanelSection.xml
@@ -14,6 +14,7 @@
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml
index 6b278237b6599..8a2cd192a20e3 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Section/AdminProductFormConfigurationsSection.xml
@@ -9,6 +9,7 @@
+
@@ -31,11 +32,6 @@
-
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml
index f1fae2218301f..c612431ec7044 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminConfigurableProductOutOfStockTest.xml
@@ -8,12 +8,13 @@
-
+
+
@@ -87,7 +88,7 @@
-
+
@@ -103,12 +104,11 @@
-
-
+
@@ -124,11 +124,222 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml
new file mode 100644
index 0000000000000..c0e7c886d0cc1
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductChildSearchTest.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml
new file mode 100644
index 0000000000000..e7091dbfae215
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/StorefrontConfigurableProductWithFileCustomOptionTest.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
index 99c31420473f5..189730e18080c 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php
@@ -55,24 +55,31 @@ protected function setUp()
* situation: one product is supplying the price, which could be a price of zero (0)
*
* @dataProvider resolvePriceDataProvider
+ *
+ * @param $variantPrices
+ * @param $expectedPrice
*/
- public function testResolvePrice($expectedValue)
+ public function testResolvePrice($variantPrices, $expectedPrice)
{
- $price = $expectedValue;
-
$product = $this->getMockBuilder(
\Magento\Catalog\Model\Product::class
)->disableOriginalConstructor()->getMock();
$product->expects($this->never())->method('getSku');
- $this->lowestPriceOptionsProvider->expects($this->once())->method('getProducts')->willReturn([$product]);
- $this->priceResolver->expects($this->once())
+ $products = array_map(function () {
+ return $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }, $variantPrices);
+
+ $this->lowestPriceOptionsProvider->expects($this->once())->method('getProducts')->willReturn($products);
+ $this->priceResolver
->method('resolvePrice')
- ->with($product)
- ->willReturn($price);
+ ->willReturnOnConsecutiveCalls(...$variantPrices);
- $this->assertEquals($expectedValue, $this->resolver->resolvePrice($product));
+ $actualPrice = $this->resolver->resolvePrice($product);
+ self::assertSame($expectedPrice, $actualPrice);
}
/**
@@ -81,8 +88,40 @@ public function testResolvePrice($expectedValue)
public function resolvePriceDataProvider()
{
return [
- 'price of zero' => [0.00],
- 'price of five' => [5],
+ 'Single variant at price 0.00 (float), should return 0.00 (float)' => [
+ $variantPrices = [
+ 0.00,
+ ],
+ $expectedPrice = 0.00,
+ ],
+ 'Single variant at price 5 (integer), should return 5.00 (float)' => [
+ $variantPrices = [
+ 5,
+ ],
+ $expectedPrice = 5.00,
+ ],
+ 'Single variants at price null (null), should return 0.00 (float)' => [
+ $variantPrices = [
+ null,
+ ],
+ $expectedPrice = 0.00,
+ ],
+ 'Multiple variants at price 0, 10, 20, should return 0.00 (float)' => [
+ $variantPrices = [
+ 0,
+ 10,
+ 20,
+ ],
+ $expectedPrice = 0.00,
+ ],
+ 'Multiple variants at price 10, 0, 20, should return 0.00 (float)' => [
+ $variantPrices = [
+ 10,
+ 0,
+ 20,
+ ],
+ $expectedPrice = 0.00,
+ ],
];
}
}
diff --git a/app/code/Magento/ConfigurableProduct/etc/adminhtml/system.xml b/app/code/Magento/ConfigurableProduct/etc/adminhtml/system.xml
index ba52b51d6b077..86baea3c0d296 100644
--- a/app/code/Magento/ConfigurableProduct/etc/adminhtml/system.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/adminhtml/system.xml
@@ -9,7 +9,7 @@
-
+
Magento\Catalog\Model\Config\Source\Product\Thumbnail
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/templates/product/view/type/options/configurable.phtml b/app/code/Magento/ConfigurableProduct/view/frontend/templates/product/view/type/options/configurable.phtml
index 9b8e2c0c8c0bd..f5ed067967547 100644
--- a/app/code/Magento/ConfigurableProduct/view/frontend/templates/product/view/type/options/configurable.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/templates/product/view/type/options/configurable.phtml
@@ -38,6 +38,9 @@ $_attributes = $block->decorateArray($block->getAllowAttributes());
"gallerySwitchStrategy": "getVar('gallery_switch_strategy',
'Magento_ConfigurableProduct') ?: 'replace'; ?>"
}
+ },
+ "*" : {
+ "Magento_ConfigurableProduct/js/catalog-add-to-cart": {}
}
}
diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/catalog-add-to-cart.js
new file mode 100644
index 0000000000000..3e6a611c268af
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/catalog-add-to-cart.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require([
+ 'jquery'
+], function ($) {
+ 'use strict';
+
+ /**
+ * Add selected configurable attributes to redirect url
+ *
+ * @see Magento_Catalog/js/catalog-add-to-cart
+ */
+ $('body').on('catalogCategoryAddToCartRedirect', function (event, data) {
+ $(data.form).find('select[name*="super"]').each(function (index, item) {
+ data.redirectParameters.push(item.config.id + '=' + $(item).val());
+ });
+ });
+});
diff --git a/app/code/Magento/Customer/Model/Address/Validator/Country.php b/app/code/Magento/Customer/Model/Address/Validator/Country.php
index ff1020eba70ef..d7fb51dbbd442 100644
--- a/app/code/Magento/Customer/Model/Address/Validator/Country.php
+++ b/app/code/Magento/Customer/Model/Address/Validator/Country.php
@@ -88,6 +88,8 @@ private function validateCountry(AbstractAddress $address)
*
* @param AbstractAddress $address
* @return array
+ * @throws \Zend_Validate_Exception
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function validateRegion(AbstractAddress $address)
{
@@ -107,7 +109,7 @@ private function validateRegion(AbstractAddress $address)
//If country actually has regions and requires you to
//select one then it must be selected.
$errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'regionId']);
- } elseif ($regionId && !in_array($regionId, $allowedRegions, true)) {
+ } elseif ($allowedRegions && $regionId && !in_array($regionId, $allowedRegions, true)) {
//If a region is selected then checking if it exists.
$errors[] = __(
'Invalid value of "%value" provided for the %fieldName field.',
diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml
index 531e0f4b23b91..de8418774f794 100644
--- a/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml
+++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/SignUpNewUserFromStorefrontActionGroup.xml
@@ -12,6 +12,7 @@
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
index 19194ae2e5423..a1f0277ec40ec 100644
--- a/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Data/AddressData.xml
@@ -83,4 +83,8 @@
Yes
RegionCA
+
+
+ GB
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml
index 0d443172e0c66..21205c6d5d91e 100644
--- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontCustomerDashboardAccountInformationSection.xml
@@ -22,6 +22,6 @@
-
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml
index d1a3e44416349..65e7aa7a12113 100644
--- a/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Section/StorefrontPanelHeaderSection.xml
@@ -10,6 +10,6 @@
xsi:noNamespaceSchemaLocation="../../../../../../../dev/tests/acceptance/vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd">
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml
index adca5b7ec4d2d..bde15b31ff1e6 100644
--- a/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Test/AdminCreateCustomerTest.xml
@@ -25,6 +25,7 @@
+
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php b/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php
index 9ab35f2d301d4..d8148543a55db 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Address/Validator/CountryTest.php
@@ -161,7 +161,13 @@ public function validateDataProvider()
'region_id2' => [
array_merge($data, ['country_id' => $countryId, 'region_id' => 2]),
[$countryId++],
- [1],
+ [],
+ [],
+ ],
+ 'region_id3' => [
+ array_merge($data, ['country_id' => $countryId, 'region_id' => 2]),
+ [$countryId++],
+ [1, 3],
['Invalid value of "2" provided for the regionId field.'],
],
'validated' => [
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
index f3070c46ebb7b..50c21379054bf 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
@@ -1269,7 +1269,7 @@ public function testGetDataWithVisibleAttributesWithAccountEdit()
$helper = new ObjectManager($this);
$context = $this->getMockBuilder(\Magento\Framework\View\Element\UiComponent\ContextInterface::class)
->setMethods(['getRequestParam'])
- ->getMockforAbstractClass();
+ ->getMockForAbstractClass();
$context->expects($this->any())
->method('getRequestParam')
->with('request-field-name')
diff --git a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml
index 10223df489e90..24657a6846cae 100644
--- a/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/account/link/authorization.phtml
@@ -13,7 +13,7 @@ if ($block->isLoggedIn()) {
$dataPostParam = sprintf(" data-post='%s'", $block->getPostParams());
}
?>
-
+
getLinkAttributes() ?>= /* @noEscape */ $dataPostParam ?>>
= $block->escapeHtml($block->getLabel()) ?>
diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
index 1f1f078504524..6a129a3aa4b44 100644
--- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
@@ -112,7 +112,7 @@
name="region"
value="= $block->escapeHtmlAttr($block->getRegion()) ?>"
title="= $block->escapeHtmlAttr(__('State/Province')) ?>"
- class="input-text = $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>"= !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : '' ?>/>
+ class="input-text validate-not-number-first = $block->escapeHtmlAttr($this->helper('Magento\Customer\Helper\Address')->getAttributeValidationClass('region')) ?>"= !$block->getConfig('general/region/display_all') ? ' disabled="disabled"' : '' ?>/>