diff --git a/CHANGELOG.md b/CHANGELOG.md
index a35f820d3a573..7237ebfacf5e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -626,7 +626,7 @@ Tests:
* Fixed an issue where filters were not shown on product reviews report grid
* Fixed an issue where second customer address was not deleted from customer account
* Fixed an issue where custom options pop-up was still displayed after submit
- * Fixed an issue where Second Product was not added to Shopping Cart from Wishlist at first atempt
+ * Fixed an issue where Second Product was not added to Shopping Cart from Wishlist at first attempt
* Fixed an issue where customer invalid email message was not displayed
* Fixed an issue where All Access Tokens for Customer without Tokens could not be revoked
* Fixed an issue where it was impossible to add Product to Shopping Cart from shared Wishlist
diff --git a/README.md b/README.md
index e73da84d66f46..9e3cf448f99fb 100644
--- a/README.md
+++ b/README.md
@@ -5,14 +5,14 @@
Welcome
Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting-edge, feature-rich eCommerce solution that gets results.
-## Magento system requirements
-[Magento system requirements](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html).
+## Magento System Requirements
+[Magento System Requirements](https://devdocs.magento.com/guides/v2.3/install-gde/system-requirements2.html).
## Install Magento
-* [Installation guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html).
+* [Installation Guide](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html).
-Contributing to the Magento 2 code base
+Contributing to the Magento 2 Code Base
Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions.
To learn about how to make a contribution, click [here][1].
@@ -39,11 +39,11 @@ Magento is thankful for any contribution that can improve our code base, documen
-### Labels applied by the Magento team
+### Labels Applied by the Magento Team
We apply labels to public Pull Requests and Issues to help other participants retrieve additional information about current progress, component assignments, Magento release lines, and much more.
Please review the [Code Contributions guide](https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#labels) for detailed information on labels used in Magento 2 repositories.
-## Reporting security issues
+## Reporting Security Issues
To report security vulnerabilities in Magento software or web sites, please create a Bugcrowd researcher account [there](https://bugcrowd.com/magento) to submit and follow-up your issue. Learn more about reporting security issues [here](https://magento.com/security/reporting-magento-security-issue).
diff --git a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php
index 7bda179a11131..591e648547d61 100644
--- a/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php
+++ b/app/code/Magento/AdvancedPricingImportExport/Model/Import/AdvancedPricing.php
@@ -185,6 +185,7 @@ class AdvancedPricing extends \Magento\ImportExport\Model\Import\Entity\Abstract
* @param AdvancedPricing\Validator\Website $websiteValidator
* @param AdvancedPricing\Validator\TierPrice $tierPriceValidator
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @throws \Exception
*/
public function __construct(
\Magento\Framework\Json\Helper\Data $jsonHelper,
@@ -255,6 +256,7 @@ public function getEntityTypeCode()
* @param array $rowData
* @param int $rowNum
* @return bool
+ * @throws \Zend_Validate_Exception
*/
public function validateRow(array $rowData, $rowNum)
{
@@ -308,6 +310,7 @@ protected function _importData()
* Save advanced pricing
*
* @return $this
+ * @throws \Exception
*/
public function saveAdvancedPricing()
{
@@ -319,6 +322,7 @@ public function saveAdvancedPricing()
* Deletes Advanced price data from raw data.
*
* @return $this
+ * @throws \Exception
*/
public function deleteAdvancedPricing()
{
@@ -347,6 +351,7 @@ public function deleteAdvancedPricing()
* Replace advanced pricing
*
* @return $this
+ * @throws \Exception
*/
public function replaceAdvancedPricing()
{
@@ -360,6 +365,7 @@ public function replaceAdvancedPricing()
* @return $this
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
+ * @throws \Exception
*/
protected function saveAndReplaceAdvancedPrices()
{
@@ -368,8 +374,8 @@ protected function saveAndReplaceAdvancedPrices()
$this->_cachedSkuToDelete = null;
}
$listSku = [];
+ $tierPrices = [];
while ($bunch = $this->_dataSourceModel->getNextBunch()) {
- $tierPrices = [];
foreach ($bunch as $rowNum => $rowData) {
if (!$this->validateRow($rowData, $rowNum)) {
$this->addRowError(ValidatorInterface::ERROR_SKU_IS_EMPTY, $rowNum);
@@ -397,15 +403,8 @@ protected function saveAndReplaceAdvancedPrices()
];
}
}
- if (\Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE == $behavior) {
- if ($listSku) {
- $this->processCountNewPrices($tierPrices);
- if ($this->deleteProductTierPrices(array_unique($listSku), self::TABLE_TIER_PRICE)) {
- $this->saveProductPrices($tierPrices, self::TABLE_TIER_PRICE);
- $this->setUpdatedAt($listSku);
- }
- }
- } elseif (\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND == $behavior) {
+
+ if (\Magento\ImportExport\Model\Import::BEHAVIOR_APPEND == $behavior) {
$this->processCountExistingPrices($tierPrices, self::TABLE_TIER_PRICE)
->processCountNewPrices($tierPrices);
@@ -415,6 +414,17 @@ protected function saveAndReplaceAdvancedPrices()
}
}
}
+
+ if (\Magento\ImportExport\Model\Import::BEHAVIOR_REPLACE == $behavior) {
+ if ($listSku) {
+ $this->processCountNewPrices($tierPrices);
+ if ($this->deleteProductTierPrices(array_unique($listSku), self::TABLE_TIER_PRICE)) {
+ $this->saveProductPrices($tierPrices, self::TABLE_TIER_PRICE);
+ $this->setUpdatedAt($listSku);
+ }
+ }
+ }
+
return $this;
}
@@ -424,6 +434,7 @@ protected function saveAndReplaceAdvancedPrices()
* @param array $priceData
* @param string $table
* @return $this
+ * @throws \Exception
*/
protected function saveProductPrices(array $priceData, $table)
{
@@ -455,6 +466,7 @@ protected function saveProductPrices(array $priceData, $table)
* @param array $listSku
* @param string $table
* @return boolean
+ * @throws \Exception
*/
protected function deleteProductTierPrices(array $listSku, $table)
{
@@ -532,6 +544,7 @@ protected function getCustomerGroupId($customerGroup)
* Retrieve product skus
*
* @return array
+ * @throws \Exception
*/
protected function retrieveOldSkus()
{
@@ -552,6 +565,7 @@ protected function retrieveOldSkus()
* @param array $prices
* @param string $table
* @return $this
+ * @throws \Exception
*/
protected function processCountExistingPrices($prices, $table)
{
diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php
index 5bc9335d24439..946ec8ba01a0e 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost.php
@@ -546,15 +546,16 @@ public function setResponseData(array $postData)
public function validateResponse()
{
$response = $this->getResponse();
- //md5 check
- if (!$this->getConfigData('trans_md5')
- || !$this->getConfigData('login')
- || !$response->isValidHash($this->getConfigData('trans_md5'), $this->getConfigData('login'))
+ $hashConfigKey = !empty($response->getData('x_SHA2_Hash')) ? 'signature_key' : 'trans_md5';
+
+ //hash check
+ if (!$response->isValidHash($this->getConfigData($hashConfigKey), $this->getConfigData('login'))
) {
throw new \Magento\Framework\Exception\LocalizedException(
__('The transaction was declined because the response hash validation failed.')
);
}
+
return true;
}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Request.php b/app/code/Magento/Authorizenet/Model/Directpost/Request.php
index 357385e5c8c79..d518af4e04f55 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost/Request.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Request.php
@@ -8,6 +8,8 @@
namespace Magento\Authorizenet\Model\Directpost;
use Magento\Authorizenet\Model\Request as AuthorizenetRequest;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Intl\DateTimeFactory;
/**
* Authorize.net request model for DirectPost model
@@ -20,10 +22,35 @@ class Request extends AuthorizenetRequest
*/
protected $_transKey = null;
+ /**
+ * Hexadecimal signature key.
+ *
+ * @var string
+ */
+ private $signatureKey = '';
+
+ /**
+ * @var DateTimeFactory
+ */
+ private $dateTimeFactory;
+
+ /**
+ * @param array $data
+ * @param DateTimeFactory $dateTimeFactory
+ */
+ public function __construct(
+ array $data = [],
+ DateTimeFactory $dateTimeFactory = null
+ ) {
+ $this->dateTimeFactory = $dateTimeFactory ?? ObjectManager::getInstance()
+ ->get(DateTimeFactory::class);
+ parent::__construct($data);
+ }
+
/**
* Return merchant transaction key.
*
- * Needed to generate sign.
+ * Needed to generate MD5 sign.
*
* @return string
*/
@@ -35,7 +62,7 @@ protected function _getTransactionKey()
/**
* Set merchant transaction key.
*
- * Needed to generate sign.
+ * Needed to generate MD5 sign.
*
* @param string $transKey
* @return $this
@@ -47,7 +74,7 @@ protected function _setTransactionKey($transKey)
}
/**
- * Generates the fingerprint for request.
+ * Generates the MD5 fingerprint for request.
*
* @param string $merchantApiLoginId
* @param string $merchantTransactionKey
@@ -67,7 +94,7 @@ public function generateRequestSign(
) {
return hash_hmac(
"md5",
- $merchantApiLoginId . "^" . $fpSequence . "^" . $fpTimestamp . "^" . $amount . "^" . $currencyCode,
+ $merchantApiLoginId . '^' . $fpSequence . '^' . $fpTimestamp . '^' . $amount . '^' . $currencyCode,
$merchantTransactionKey
);
}
@@ -82,7 +109,7 @@ public function setConstantData(\Magento\Authorizenet\Model\Directpost $paymentM
{
$this->setXVersion('3.1')->setXDelimData('FALSE')->setXRelayResponse('TRUE');
- $this->setXTestRequest($paymentMethod->getConfigData('test') ? 'TRUE' : 'FALSE');
+ $this->setSignatureKey($paymentMethod->getConfigData('signature_key'));
$this->setXLogin($paymentMethod->getConfigData('login'))
->setXMethod(\Magento\Authorizenet\Model\Authorizenet::REQUEST_METHOD_CC)
@@ -173,17 +200,81 @@ public function setDataFromOrder(
*/
public function signRequestData()
{
- $fpTimestamp = time();
- $hash = $this->generateRequestSign(
- $this->getXLogin(),
- $this->_getTransactionKey(),
- $this->getXAmount(),
- $this->getXCurrencyCode(),
- $this->getXFpSequence(),
- $fpTimestamp
- );
+ $fpDate = $this->dateTimeFactory->create('now', new \DateTimeZone('UTC'));
+ $fpTimestamp = $fpDate->getTimestamp();
+
+ if (!empty($this->getSignatureKey())) {
+ $hash = $this->generateSha2RequestSign(
+ (string)$this->getXLogin(),
+ (string)$this->getSignatureKey(),
+ (string)$this->getXAmount(),
+ (string)$this->getXCurrencyCode(),
+ (string)$this->getXFpSequence(),
+ $fpTimestamp
+ );
+ } else {
+ $hash = $this->generateRequestSign(
+ $this->getXLogin(),
+ $this->_getTransactionKey(),
+ $this->getXAmount(),
+ $this->getXCurrencyCode(),
+ $this->getXFpSequence(),
+ $fpTimestamp
+ );
+ }
+
$this->setXFpTimestamp($fpTimestamp);
$this->setXFpHash($hash);
+
return $this;
}
+
+ /**
+ * Generates the SHA2 fingerprint for request.
+ *
+ * @param string $merchantApiLoginId
+ * @param string $merchantSignatureKey
+ * @param string $amount
+ * @param string $currencyCode
+ * @param string $fpSequence An invoice number or random number.
+ * @param int $fpTimestamp
+ * @return string The fingerprint.
+ */
+ private function generateSha2RequestSign(
+ string $merchantApiLoginId,
+ string $merchantSignatureKey,
+ string $amount,
+ string $currencyCode,
+ string $fpSequence,
+ int $fpTimestamp
+ ): string {
+ $message = $merchantApiLoginId . '^' . $fpSequence . '^' . $fpTimestamp . '^' . $amount . '^' . $currencyCode;
+
+ return strtoupper(hash_hmac('sha512', $message, pack('H*', $merchantSignatureKey)));
+ }
+
+ /**
+ * Return merchant hexadecimal signature key.
+ *
+ * Needed to generate SHA2 sign.
+ *
+ * @return string
+ */
+ private function getSignatureKey(): string
+ {
+ return $this->signatureKey;
+ }
+
+ /**
+ * Set merchant hexadecimal signature key.
+ *
+ * Needed to generate SHA2 sign.
+ *
+ * @param string $signatureKey
+ * @return void
+ */
+ private function setSignatureKey(string $signatureKey)
+ {
+ $this->signatureKey = $signatureKey;
+ }
}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Response.php b/app/code/Magento/Authorizenet/Model/Directpost/Response.php
index 1c713a159c3ad..b5604a78cb9cd 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost/Response.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Response.php
@@ -27,25 +27,31 @@ class Response extends AuthorizenetResponse
*/
public function generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId)
{
- if (!$amount) {
- $amount = '0.00';
- }
-
return strtoupper(md5($merchantMd5 . $merchantApiLogin . $transactionId . $amount));
}
/**
* Return if is valid order id.
*
- * @param string $merchantMd5
+ * @param string $storedHash
* @param string $merchantApiLogin
* @return bool
*/
- public function isValidHash($merchantMd5, $merchantApiLogin)
+ public function isValidHash($storedHash, $merchantApiLogin)
{
- $hash = $this->generateHash($merchantMd5, $merchantApiLogin, $this->getXAmount(), $this->getXTransId());
+ if (empty($this->getData('x_amount'))) {
+ $this->setData('x_amount', '0.00');
+ }
- return Security::compareStrings($hash, $this->getData('x_MD5_Hash'));
+ if (!empty($this->getData('x_SHA2_Hash'))) {
+ $hash = $this->generateSha2Hash($storedHash);
+ return Security::compareStrings($hash, $this->getData('x_SHA2_Hash'));
+ } elseif (!empty($this->getData('x_MD5_Hash'))) {
+ $hash = $this->generateHash($storedHash, $merchantApiLogin, $this->getXAmount(), $this->getXTransId());
+ return Security::compareStrings($hash, $this->getData('x_MD5_Hash'));
+ }
+
+ return false;
}
/**
@@ -57,4 +63,54 @@ public function isApproved()
{
return $this->getXResponseCode() == \Magento\Authorizenet\Model\Directpost::RESPONSE_CODE_APPROVED;
}
+
+ /**
+ * Generates an SHA2 hash to compare against AuthNet's.
+ *
+ * @param string $signatureKey
+ * @return string
+ * @see https://support.authorize.net/s/article/MD5-Hash-End-of-Life-Signature-Key-Replacement
+ */
+ private function generateSha2Hash(string $signatureKey): string
+ {
+ $hashFields = [
+ 'x_trans_id',
+ 'x_test_request',
+ 'x_response_code',
+ 'x_auth_code',
+ 'x_cvv2_resp_code',
+ 'x_cavv_response',
+ 'x_avs_code',
+ 'x_method',
+ 'x_account_number',
+ 'x_amount',
+ 'x_company',
+ 'x_first_name',
+ 'x_last_name',
+ 'x_address',
+ 'x_city',
+ 'x_state',
+ 'x_zip',
+ 'x_country',
+ 'x_phone',
+ 'x_fax',
+ 'x_email',
+ 'x_ship_to_company',
+ 'x_ship_to_first_name',
+ 'x_ship_to_last_name',
+ 'x_ship_to_address',
+ 'x_ship_to_city',
+ 'x_ship_to_state',
+ 'x_ship_to_zip',
+ 'x_ship_to_country',
+ 'x_invoice_num',
+ ];
+
+ $message = '^';
+ foreach ($hashFields as $field) {
+ $message .= ($this->getData($field) ?? '') . '^';
+ }
+
+ return strtoupper(hash_hmac('sha512', $message, pack('H*', $signatureKey)));
+ }
}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php
new file mode 100644
index 0000000000000..94d8f3a0d27a7
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/RequestTest.php
@@ -0,0 +1,80 @@
+dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $dateTime = new \DateTime('2016-07-05 00:00:00', new \DateTimeZone('UTC'));
+ $this->dateTimeFactory->method('create')
+ ->willReturn($dateTime);
+
+ $this->requestModel = new Request([], $this->dateTimeFactory);
+ }
+
+ /**
+ * @param string $signatureKey
+ * @param string $expectedHash
+ * @dataProvider signRequestDataProvider
+ */
+ public function testSignRequestData(string $signatureKey, string $expectedHash)
+ {
+ /** @var \Magento\Authorizenet\Model\Directpost $paymentMethod */
+ $paymentMethod = $this->createMock(\Magento\Authorizenet\Model\Directpost::class);
+ $paymentMethod->method('getConfigData')
+ ->willReturnMap(
+ [
+ ['test', null, true],
+ ['login', null, 'login'],
+ ['trans_key', null, 'trans_key'],
+ ['signature_key', null, $signatureKey],
+ ]
+ );
+
+ $this->requestModel->setConstantData($paymentMethod);
+ $this->requestModel->signRequestData();
+ $signHash = $this->requestModel->getXFpHash();
+
+ $this->assertEquals($expectedHash, $signHash);
+ }
+
+ /**
+ * @return array
+ */
+ public function signRequestDataProvider()
+ {
+ return [
+ [
+ 'signatureKey' => '3EAFCE5697C1B4B9748385C1FCD29D86F3B9B41C7EED85A3A01DFF65' .
+ '70C8C29373C2A153355C3313CDF4AF723C0036DBF244A0821713A910024EE85547CEF37F',
+ 'expectedHash' => '719ED94DF5CF3510CB5531E8115462C8F12CBCC8E917BD809E8D40B4FF06' .
+ '1E14953554403DD9813CCCE0F31B184EB4DEF558E9C0747505A0C25420372DB00BE1'
+ ],
+ [
+ 'signatureKey' => '',
+ 'expectedHash' => '3656211f2c41d1e4c083606f326c0460'
+ ],
+ ];
+ }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php
index 15c7eecb09a69..ff4aa8b5ee361 100644
--- a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php
@@ -13,53 +13,16 @@ class ResponseTest extends \PHPUnit\Framework\TestCase
/**
* @var \Magento\Authorizenet\Model\Directpost\Response
*/
- protected $responseModel;
+ private $responseModel;
protected function setUp()
{
$objectManager = new ObjectManager($this);
- $this->responseModel = $objectManager->getObject(\Magento\Authorizenet\Model\Directpost\Response::class);
- }
-
- /**
- * @param string $merchantMd5
- * @param string $merchantApiLogin
- * @param float|null $amount
- * @param float|string $amountTestFunc
- * @param string $transactionId
- * @dataProvider generateHashDataProvider
- */
- public function testGenerateHash($merchantMd5, $merchantApiLogin, $amount, $amountTestFunc, $transactionId)
- {
- $this->assertEquals(
- $this->generateHash($merchantMd5, $merchantApiLogin, $amountTestFunc, $transactionId),
- $this->responseModel->generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId)
+ $this->responseModel = $objectManager->getObject(
+ \Magento\Authorizenet\Model\Directpost\Response::class
);
}
- /**
- * @return array
- */
- public function generateHashDataProvider()
- {
- return [
- [
- 'merchantMd5' => 'FCD7F001E9274FDEFB14BFF91C799306',
- 'merchantApiLogin' => 'Magento',
- 'amount' => null,
- 'amountTestFunc' => '0.00',
- 'transactionId' => '1'
- ],
- [
- 'merchantMd5' => '8AEF4E508261A287C3E2F544720FCA3A',
- 'merchantApiLogin' => 'Magento2',
- 'amount' => 100.50,
- 'amountTestFunc' => 100.50,
- 'transactionId' => '2'
- ]
- ];
- }
-
/**
* @param $merchantMd5
* @param $merchantApiLogin
@@ -73,7 +36,8 @@ protected function generateHash($merchantMd5, $merchantApiLogin, $amount, $trans
}
/**
- * @param string $merchantMd5
+ * @param string $storedHash
+ * @param string $hashKey
* @param string $merchantApiLogin
* @param float|null $amount
* @param string $transactionId
@@ -81,12 +45,21 @@ protected function generateHash($merchantMd5, $merchantApiLogin, $amount, $trans
* @param bool $expectedValue
* @dataProvider isValidHashDataProvider
*/
- public function testIsValidHash($merchantMd5, $merchantApiLogin, $amount, $transactionId, $hash, $expectedValue)
- {
+ public function testIsValidHash(
+ string $storedHash,
+ string $hashKey,
+ string $merchantApiLogin,
+ $amount,
+ string $transactionId,
+ string $hash,
+ bool $expectedValue
+ ) {
$this->responseModel->setXAmount($amount);
$this->responseModel->setXTransId($transactionId);
- $this->responseModel->setData('x_MD5_Hash', $hash);
- $this->assertEquals($expectedValue, $this->responseModel->isValidHash($merchantMd5, $merchantApiLogin));
+ $this->responseModel->setData($hashKey, $hash);
+ $result = $this->responseModel->isValidHash($storedHash, $merchantApiLogin);
+
+ $this->assertEquals($expectedValue, $result);
}
/**
@@ -94,9 +67,14 @@ public function testIsValidHash($merchantMd5, $merchantApiLogin, $amount, $trans
*/
public function isValidHashDataProvider()
{
+ $signatureKey = '3EAFCE5697C1B4B9748385C1FCD29D86F3B9B41C7EED85A3A01DFF6570C8C' .
+ '29373C2A153355C3313CDF4AF723C0036DBF244A0821713A910024EE85547CEF37F';
+ $expectedSha2Hash = '368D48E0CD1274BF41C059138DA69985594021A4AD5B4C5526AE88C8F' .
+ '7C5769B13C5E1E4358900F3E51076FB69D14B0A797904C22E8A11A52AA49CDE5FBB703C';
return [
[
'merchantMd5' => 'FCD7F001E9274FDEFB14BFF91C799306',
+ 'hashKey' => 'x_MD5_Hash',
'merchantApiLogin' => 'Magento',
'amount' => null,
'transactionId' => '1',
@@ -105,11 +83,21 @@ public function isValidHashDataProvider()
],
[
'merchantMd5' => '8AEF4E508261A287C3E2F544720FCA3A',
+ 'hashKey' => 'x_MD5_Hash',
'merchantApiLogin' => 'Magento2',
'amount' => 100.50,
'transactionId' => '2',
'hash' => '1F24A4EC9A169B2B2A072A5F168E16DC',
'expectedValue' => false
+ ],
+ [
+ 'signatureKey' => $signatureKey,
+ 'hashKey' => 'x_SHA2_Hash',
+ 'merchantApiLogin' => 'Magento2',
+ 'amount' => 100.50,
+ 'transactionId' => '2',
+ 'hash' => $expectedSha2Hash,
+ 'expectedValue' => true
]
];
}
diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/system.xml b/app/code/Magento/Authorizenet/etc/adminhtml/system.xml
index 28bf6945c8b81..fc86c0d2dc68d 100644
--- a/app/code/Magento/Authorizenet/etc/adminhtml/system.xml
+++ b/app/code/Magento/Authorizenet/etc/adminhtml/system.xml
@@ -29,6 +29,10 @@
Transaction Key
Magento\Config\Model\Config\Backend\Encrypted
+
+ Signature Key
+ Magento\Config\Model\Config\Backend\Encrypted
+
Merchant MD5
Magento\Config\Model\Config\Backend\Encrypted
diff --git a/app/code/Magento/Authorizenet/etc/config.xml b/app/code/Magento/Authorizenet/etc/config.xml
index 02dca74023e22..60356460f553f 100644
--- a/app/code/Magento/Authorizenet/etc/config.xml
+++ b/app/code/Magento/Authorizenet/etc/config.xml
@@ -22,6 +22,7 @@
Credit Card Direct Post (Authorize.Net)
+
0
USD
1
diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml
index a52033b8d2501..98b8e702b1c53 100644
--- a/app/code/Magento/Backend/etc/adminhtml/system.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/system.xml
@@ -169,15 +169,15 @@
JavaScript Settings
-
+
Merge JavaScript Files
Magento\Config\Model\Config\Source\Yesno
-
+
Enable JavaScript Bundling
Magento\Config\Model\Config\Source\Yesno
-
+
Minify JavaScript Files
Magento\Config\Model\Config\Source\Yesno
Minification is not applied in developer mode.
@@ -185,11 +185,11 @@
CSS Settings
-
+
Merge CSS Files
Magento\Config\Model\Config\Source\Yesno
-
+
Minify CSS Files
Magento\Config\Model\Config\Source\Yesno
Minification is not applied in developer mode.
diff --git a/app/code/Magento/Backup/Test/Mftf/ActionGroup/DeleteBackupActionGroup.xml b/app/code/Magento/Backup/Test/Mftf/ActionGroup/DeleteBackupActionGroup.xml
index b3a6e5d795cea..ebc4ac1fb056a 100644
--- a/app/code/Magento/Backup/Test/Mftf/ActionGroup/DeleteBackupActionGroup.xml
+++ b/app/code/Magento/Backup/Test/Mftf/ActionGroup/DeleteBackupActionGroup.xml
@@ -19,8 +19,8 @@
+
-
diff --git a/app/code/Magento/Braintree/Controller/Paypal/Review.php b/app/code/Magento/Braintree/Controller/Paypal/Review.php
index 14ec829d98024..eb2de7c7b6e39 100644
--- a/app/code/Magento/Braintree/Controller/Paypal/Review.php
+++ b/app/code/Magento/Braintree/Controller/Paypal/Review.php
@@ -13,11 +13,12 @@
use Magento\Braintree\Model\Paypal\Helper\QuoteUpdater;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\App\Action\HttpPostActionInterface;
+use Magento\Framework\App\Action\HttpGetActionInterface;
/**
* Class Review
*/
-class Review extends AbstractAction implements HttpPostActionInterface
+class Review extends AbstractAction implements HttpPostActionInterface, HttpGetActionInterface
{
/**
* @var QuoteUpdater
diff --git a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
index e56cc6f32d804..f8d2f8bc11116 100644
--- a/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
+++ b/app/code/Magento/Bundle/view/base/web/js/price-bundle.js
@@ -374,8 +374,17 @@ define([
function applyTierPrice(oneItemPrice, qty, optionConfig) {
var tiers = optionConfig.tierPrice,
magicKey = _.keys(oneItemPrice)[0],
+ tiersFirstKey = _.keys(optionConfig)[0],
lowest = false;
+ if (!tiers) {//tiers is undefined when options has only one option
+ tiers = optionConfig[tiersFirstKey].tierPrice;
+ }
+
+ tiers.sort(function (a, b) {//sorting based on "price_qty"
+ return a['price_qty'] - b['price_qty'];
+ });
+
_.each(tiers, function (tier, index) {
if (tier['price_qty'] > qty) {
return;
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php
index dd09e40ac5b35..1b6756968662f 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit/Tab/Advanced.php
@@ -4,11 +4,6 @@
* See COPYING.txt for license details.
*/
-/**
- * Product attribute add/edit form main tab
- *
- * @author Magento Core Team
- */
namespace Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab;
use Magento\Backend\Block\Widget\Form\Generic;
@@ -18,6 +13,8 @@
use Magento\Framework\App\ObjectManager;
/**
+ * Product attribute add/edit form main tab
+ *
* @api
* @since 100.0.2
*/
@@ -73,6 +70,7 @@ public function __construct(
* Adding product form elements for editing attribute
*
* @return $this
+ * @throws \Magento\Framework\Exception\LocalizedException
* @SuppressWarnings(PHPMD)
*/
protected function _prepareForm()
@@ -255,7 +253,7 @@ protected function _prepareForm()
}
/**
- * Initialize form fileds values
+ * Initialize form fields values
*
* @return $this
*/
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml
index d786795bc3090..90d732c9654e1 100644
--- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminCategoryActionGroup.xml
@@ -302,4 +302,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml
index 20ea93cd272f1..da570f9ed99b0 100644
--- a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AdminProductActionGroup.xml
@@ -20,7 +20,7 @@
-
+
@@ -34,6 +34,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -77,6 +96,11 @@
+
+
+
+
+
@@ -389,6 +413,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductInfoOnEditPageActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductInfoOnEditPageActionGroup.xml
new file mode 100644
index 0000000000000..7917fe68aaebc
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductInfoOnEditPageActionGroup.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnAdminGridActionGroup.xml b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnAdminGridActionGroup.xml
new file mode 100644
index 0000000000000..963c9d9f1c911
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/ActionGroup/AssertProductOnAdminGridActionGroup.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogSpecialPriceData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogSpecialPriceData.xml
index 4c6b0749a0f9e..31783526932b6 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Data/CatalogSpecialPriceData.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Data/CatalogSpecialPriceData.xml
@@ -12,4 +12,9 @@
0
+
+ 55.55
+ 0
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml
index 0b3a31194ea36..bdbefbd234868 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml
@@ -60,6 +60,48 @@
EavStockItem
CustomAttributeCategoryIds
+
+ SimpleProductForTest1
+ simple
+ 4
+ SimpleProductAfterImport1
+ 250.00
+ 4
+ 1
+ 100
+ simple-product-for-test-1
+ 1
+ EavStockItem
+ CustomAttributeCategoryIds
+
+
+ SimpleProductForTest2
+ simple
+ 4
+ SimpleProductAfterImport2
+ 300.00
+ 4
+ 1
+ 100
+ simple-product-for-test-2
+ 1
+ EavStockItem
+ CustomAttributeCategoryIds
+
+
+ SimpleProductForTest3
+ simple
+ 4
+ SimpleProductAfterImport3
+ 350.00
+ 4
+ 1
+ 100
+ simple-product-for-test-3
+ 1
+ EavStockItem
+ CustomAttributeCategoryIds
+
SimpleProduct
simple
@@ -906,4 +948,20 @@
EavStockItem
CustomAttributeCategoryIds
+
+ sku_simple_product_
+ simple
+ 4
+ 4
+ SimpleProduct
+ 560
+ simple-product-
+ 1
+ 25
+ 1
+ 1
+ 1
+ 2
+ EavStockItem
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryMessagesSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryMessagesSection.xml
index fee86ca1caa29..ea4f4bf53eb71 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryMessagesSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCategoryMessagesSection.xml
@@ -10,5 +10,6 @@
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateNewProductAttributeSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateNewProductAttributeSection.xml
index e218f5ae74fc0..2de7bf19fd378 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateNewProductAttributeSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/AdminCreateNewProductAttributeSection.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMessagesSection.xml b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMessagesSection.xml
index 4dcda8dcd41ae..c58479a7b73e5 100644
--- a/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMessagesSection.xml
+++ b/app/code/Magento/Catalog/Test/Mftf/Section/StorefrontMessagesSection.xml
@@ -11,6 +11,6 @@
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateCategoryTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateCategoryTest.xml
new file mode 100644
index 0000000000000..37ec4e0d32528
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateCategoryTest.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateProductTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateProductTest.xml
new file mode 100644
index 0000000000000..575bb56912b25
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminCreateDuplicateProductTest.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml
new file mode 100644
index 0000000000000..234a7c69913c9
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Mftf/Test/AdminSortingByWebsitesTest.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
index 5af0d71dc246c..494b77724e5b7 100644
--- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns/Websites.php
@@ -3,13 +3,19 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
+declare(strict_types=1);
+
namespace Magento\Catalog\Ui\Component\Listing\Columns;
-use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\DB\Helper;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
+use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Store\Model\StoreManagerInterface;
/**
+ * Websites listing column component.
+ *
* @api
* @since 100.0.2
*/
@@ -20,6 +26,11 @@ class Websites extends \Magento\Ui\Component\Listing\Columns\Column
*/
const NAME = 'websites';
+ /**
+ * Data for concatenated website names value.
+ */
+ private $websiteNames = 'website_names';
+
/**
* Store manager
*
@@ -27,26 +38,36 @@ class Websites extends \Magento\Ui\Component\Listing\Columns\Column
*/
protected $storeManager;
+ /**
+ * @var \Magento\Framework\DB\Helper
+ */
+ private $resourceHelper;
+
/**
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param StoreManagerInterface $storeManager
* @param array $components
* @param array $data
+ * @param Helper $resourceHelper
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
StoreManagerInterface $storeManager,
array $components = [],
- array $data = []
+ array $data = [],
+ Helper $resourceHelper = null
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
+ $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->storeManager = $storeManager;
+ $this->resourceHelper = $resourceHelper ?: $objectManager->get(Helper::class);
}
/**
- * {@inheritdoc}
+ * @inheritdoc
+ *
* @deprecated 101.0.0
*/
public function prepareDataSource(array $dataSource)
@@ -71,9 +92,10 @@ public function prepareDataSource(array $dataSource)
return $dataSource;
}
-
+
/**
- * Prepare component configuration
+ * Prepare component configuration.
+ *
* @return void
*/
public function prepare()
@@ -83,4 +105,46 @@ public function prepare()
$this->_data['config']['componentDisabled'] = true;
}
}
+
+ /**
+ * Apply sorting.
+ *
+ * @return void
+ */
+ protected function applySorting()
+ {
+ $sorting = $this->getContext()->getRequestParam('sorting');
+ $isSortable = $this->getData('config/sortable');
+ if ($isSortable !== false
+ && !empty($sorting['field'])
+ && !empty($sorting['direction'])
+ && $sorting['field'] === $this->getName()
+ ) {
+ $collection = $this->getContext()->getDataProvider()->getCollection();
+ $collection
+ ->joinField(
+ 'websites_ids',
+ 'catalog_product_website',
+ 'website_id',
+ 'product_id=entity_id',
+ null,
+ 'left'
+ )
+ ->joinTable(
+ 'store_website',
+ 'website_id = websites_ids',
+ ['name'],
+ null,
+ 'left'
+ )
+ ->groupByAttribute('entity_id');
+ $this->resourceHelper->addGroupConcatColumn(
+ $collection->getSelect(),
+ $this->websiteNames,
+ 'name'
+ );
+
+ $collection->getSelect()->order($this->websiteNames . ' ' . $sorting['direction']);
+ }
+ }
}
diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml
index c930d2195a01b..1c4a37fedebe3 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/attributes.phtml
@@ -23,8 +23,8 @@
- = $block->escapeHtml(__($_data['label'])) ?>
- = /* @escapeNotVerified */ $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?>
+ = $block->escapeHtml($_data['label']) ?>
+ = /* @escapeNotVerified */ $_helper->productAttribute($_product, $_data['value'], $_data['code']) ?>
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/ActionGroup/AdminExportActionGroup.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/ActionGroup/AdminExportActionGroup.xml
new file mode 100644
index 0000000000000..63248dd53fc1b
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/ActionGroup/AdminExportActionGroup.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportBundleProductTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportBundleProductTest.xml
new file mode 100644
index 0000000000000..3a4010f417104
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportBundleProductTest.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportGroupedProductWithSpecialPriceTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportGroupedProductWithSpecialPriceTest.xml
new file mode 100644
index 0000000000000..09d9469cb093d
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportGroupedProductWithSpecialPriceTest.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleAndConfigurableProductsWithCustomOptionsTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleAndConfigurableProductsWithCustomOptionsTest.xml
new file mode 100644
index 0000000000000..aaeb0cd38cd99
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleAndConfigurableProductsWithCustomOptionsTest.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAndConfigurableProductsWithAssignedImagesTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAndConfigurableProductsWithAssignedImagesTest.xml
new file mode 100644
index 0000000000000..597ee2336b21f
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAndConfigurableProductsWithAssignedImagesTest.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAssignedToMainWebsiteAndConfigurableProductAssignedToCustomWebsiteTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAssignedToMainWebsiteAndConfigurableProductAssignedToCustomWebsiteTest.xml
new file mode 100644
index 0000000000000..b1e723e5ee1ff
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductAssignedToMainWebsiteAndConfigurableProductAssignedToCustomWebsiteTest.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductWithCustomAttributeTest.xml b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductWithCustomAttributeTest.xml
new file mode 100644
index 0000000000000..e3c5cd78397f6
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Test/Mftf/Test/AdminExportSimpleProductWithCustomAttributeTest.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogInventory/Model/Spi/StockRegistryProviderInterface.php b/app/code/Magento/CatalogInventory/Model/Spi/StockRegistryProviderInterface.php
index f711268bc7930..0fa4b919c40fa 100644
--- a/app/code/Magento/CatalogInventory/Model/Spi/StockRegistryProviderInterface.php
+++ b/app/code/Magento/CatalogInventory/Model/Spi/StockRegistryProviderInterface.php
@@ -7,16 +7,24 @@
/**
* Interface StockRegistryProviderInterface
+ *
+ * @deprecated 2.3.0 Replaced with Multi Source Inventory
+ * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html
+ * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html
*/
interface StockRegistryProviderInterface
{
/**
+ * Get stock.
+ *
* @param int $scopeId
* @return \Magento\CatalogInventory\Api\Data\StockInterface
*/
public function getStock($scopeId);
/**
+ * Get stock item.
+ *
* @param int $productId
* @param int $scopeId
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface
@@ -24,6 +32,8 @@ public function getStock($scopeId);
public function getStockItem($productId, $scopeId);
/**
+ * Get stock status.
+ *
* @param int $productId
* @param int $scopeId
* @return \Magento\CatalogInventory\Api\Data\StockStatusInterface
diff --git a/app/code/Magento/CatalogInventory/Model/Spi/StockStateProviderInterface.php b/app/code/Magento/CatalogInventory/Model/Spi/StockStateProviderInterface.php
index 89fb54e7e496b..30f703b5b928f 100644
--- a/app/code/Magento/CatalogInventory/Model/Spi/StockStateProviderInterface.php
+++ b/app/code/Magento/CatalogInventory/Model/Spi/StockStateProviderInterface.php
@@ -9,22 +9,32 @@
/**
* Interface StockStateProviderInterface
+ *
+ * @deprecated 2.3.0 Replaced with Multi Source Inventory
+ * @link https://devdocs.magento.com/guides/v2.3/inventory/index.html
+ * @link https://devdocs.magento.com/guides/v2.3/inventory/catalog-inventory-replacements.html
*/
interface StockStateProviderInterface
{
/**
+ * Verify stock.
+ *
* @param StockItemInterface $stockItem
* @return bool
*/
public function verifyStock(StockItemInterface $stockItem);
/**
+ * Verify notification.
+ *
* @param StockItemInterface $stockItem
* @return bool
*/
public function verifyNotification(StockItemInterface $stockItem);
/**
+ * Validate quote qty.
+ *
* @param StockItemInterface $stockItem
* @param int|float $itemQty
* @param int|float $qtyToCheck
@@ -44,8 +54,9 @@ public function checkQuoteItemQty(StockItemInterface $stockItem, $itemQty, $qtyT
public function checkQty(StockItemInterface $stockItem, $qty);
/**
- * Returns suggested qty that satisfies qty increments and minQty/maxQty/minSaleQty/maxSaleQty conditions
- * or original qty if such value does not exist
+ * Returns suggested qty or original qty if such value does not exist.
+ *
+ * Suggested qty satisfies qty increments and minQty/maxQty/minSaleQty/maxSaleQty conditions.
*
* @param StockItemInterface $stockItem
* @param int|float $qty
@@ -54,6 +65,8 @@ public function checkQty(StockItemInterface $stockItem, $qty);
public function suggestQty(StockItemInterface $stockItem, $qty);
/**
+ * Check qty increments.
+ *
* @param StockItemInterface $stockItem
* @param int|float $qty
* @return \Magento\Framework\DataObject
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index 8d57fab843f4c..51a5b46b59d22 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -44,7 +44,7 @@
- Magento\CatalogInventory\Model\ResourceModel\Stock\Proxy
+ Magento\CatalogInventory\Model\ResourceModel\Stock\Item\Proxy
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminCatalogSearchTermActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminCatalogSearchTermActionGroup.xml
new file mode 100644
index 0000000000000..33ffa4fe1b296
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/AdminCatalogSearchTermActionGroup.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml
index 6b913e5b458e6..4b52b2c669edf 100644
--- a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchActionGroup.xml
@@ -11,9 +11,9 @@
-
+
-
+
@@ -116,4 +116,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchTermActionGroup.xml b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchTermActionGroup.xml
new file mode 100644
index 0000000000000..83e4ac50a74e6
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/ActionGroup/StorefrontCatalogSearchTermActionGroup.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Data/SearchTermData.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Data/SearchTermData.xml
new file mode 100644
index 0000000000000..995b860d107ca
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Data/SearchTermData.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ Query text
+ Default Store View
+ http://example.com/
+ No
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermIndexPage.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermIndexPage.xml
new file mode 100644
index 0000000000000..bbafff8ad7739
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermIndexPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermNewPage.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermNewPage.xml
new file mode 100644
index 0000000000000..de7491471741c
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Page/AdminCatalogSearchTermNewPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermIndexSection.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermIndexSection.xml
new file mode 100644
index 0000000000000..ac316d060f6e9
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermIndexSection.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermMessagesSection.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermMessagesSection.xml
new file mode 100644
index 0000000000000..5d19198a1b94c
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermMessagesSection.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermNewSection.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermNewSection.xml
new file mode 100644
index 0000000000000..a7d577a7508c0
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Section/AdminCatalogSearchTermNewSection.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminCreateSearchTermEntityTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminCreateSearchTermEntityTest.xml
new file mode 100644
index 0000000000000..2b425f34f8a5b
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminCreateSearchTermEntityTest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml
new file mode 100644
index 0000000000000..c72ed424ef307
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Mftf/Test/AdminDeleteSearchTermTest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniShoppingCartSubTotalActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniShoppingCartSubTotalActionGroup.xml
new file mode 100644
index 0000000000000..8c5c6f41fffa7
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/AssertMiniShoppingCartSubTotalActionGroup.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+ $grabMiniCartTotal
+ {{dataQuote.subtotal}}
+
+
+ $grabMiniCartTotal
+ {{dataQuote.currency}}
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontUpdateProductQtyMiniShoppingCartActionGroup.xml b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontUpdateProductQtyMiniShoppingCartActionGroup.xml
new file mode 100644
index 0000000000000..ee8b761a452d4
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/ActionGroup/StorefrontUpdateProductQtyMiniShoppingCartActionGroup.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Data/QuoteData.xml b/app/code/Magento/Checkout/Test/Mftf/Data/QuoteData.xml
index 530157851191f..a14ed147aae22 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Data/QuoteData.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Data/QuoteData.xml
@@ -15,4 +15,13 @@
495.00
Flat Rate - Fixed
+
+ 560.00
+ 2
+ 1,120.00
+ 10.00
+ 1,130.00
+ Flat Rate - Fixed
+ $
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
index bdb02835c6276..38c88bf4f80bb 100644
--- a/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
+++ b/app/code/Magento/Checkout/Test/Mftf/Section/StorefrontMiniCartSection.xml
@@ -25,6 +25,8 @@
+
+
diff --git a/app/code/Magento/Checkout/Test/Mftf/Test/UpdateProductFromMiniShoppingCartEntityTest.xml b/app/code/Magento/Checkout/Test/Mftf/Test/UpdateProductFromMiniShoppingCartEntityTest.xml
new file mode 100644
index 0000000000000..7318f865a0dc1
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Mftf/Test/UpdateProductFromMiniShoppingCartEntityTest.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml
index 71dfd12bb4779..4ebd594a28562 100644
--- a/app/code/Magento/Checkout/etc/di.xml
+++ b/app/code/Magento/Checkout/etc/di.xml
@@ -49,7 +49,4 @@
-
-
-
diff --git a/app/code/Magento/Checkout/etc/frontend/di.xml b/app/code/Magento/Checkout/etc/frontend/di.xml
index 00bcd2a27005a..8f35fe9f37abf 100644
--- a/app/code/Magento/Checkout/etc/frontend/di.xml
+++ b/app/code/Magento/Checkout/etc/frontend/di.xml
@@ -96,4 +96,7 @@
+
+
+
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
index a448537d64e83..4b1a68624e547 100644
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/checkout-agreements.html
@@ -5,17 +5,17 @@
*/
-->
-
+
-
+
-
+
-
diff --git a/app/code/Magento/Cms/Test/Mftf/Test/CheckStaticBlocksTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/CheckStaticBlocksTest.xml
index b4bcdaadf9a09..e6ab1c130606b 100644
--- a/app/code/Magento/Cms/Test/Mftf/Test/CheckStaticBlocksTest.xml
+++ b/app/code/Magento/Cms/Test/Mftf/Test/CheckStaticBlocksTest.xml
@@ -17,7 +17,6 @@
-
diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php
index 9caa2988c5a94..4f129f05aa82c 100644
--- a/app/code/Magento/Customer/Model/Visitor.php
+++ b/app/code/Magento/Customer/Model/Visitor.php
@@ -14,6 +14,7 @@
*
* @package Magento\Customer\Model
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
*/
class Visitor extends \Magento\Framework\Model\AbstractModel
{
@@ -168,10 +169,6 @@ public function initByRequest($observer)
$this->setLastVisitAt((new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT));
- // prevent saving Visitor for safe methods, e.g. GET request
- if ($this->requestSafety->isSafeMethod()) {
- return $this;
- }
if (!$this->getId()) {
$this->setSessionId($this->session->getSessionId());
$this->save();
diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml
index 54644819e852b..06c23a2864984 100644
--- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerData.xml
@@ -46,6 +46,19 @@
0
US_Address_TX
+
+ 1
+ true
+ true
+ John.Doe@example.com
+ LoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsumLoremIpsum
+ Doe
+ John Doe
+ pwdTest123!
+ 0
+ 0
+ US_Address_TX
+
1
John.Doe@example.com
@@ -190,4 +203,4 @@
0
0
-
\ No newline at end of file
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerGroupData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerGroupData.xml
index 9b6155e982013..28305d37cf77b 100644
--- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerGroupData.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerGroupData.xml
@@ -8,6 +8,12 @@
+
+ 0
+ NOT LOGGED IN
+ 3
+ Retail Customer
+
General
3
diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGroupMainSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGroupMainSection.xml
index 1fdb15f189ace..4cb7f5e3f628e 100644
--- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGroupMainSection.xml
+++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerGroupMainSection.xml
@@ -15,5 +15,6 @@
+
diff --git a/app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml b/app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml
new file mode 100644
index 0000000000000..648c30b1ca0bb
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Mftf/Test/VerifyDisabledCustomerGroupFieldTest.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIndia.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIndia.php
index 69d500960d3f0..47f4fb0a6c7f3 100644
--- a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIndia.php
+++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForIndia.php
@@ -13,8 +13,7 @@
use Magento\Framework\Setup\Patch\PatchVersionInterface;
/**
- * Class AddDataForIndia
- * @package Magento\Directory\Setup\Patch\Data
+ * Add Regions for India.
*/
class AddDataForIndia implements DataPatchInterface, PatchVersionInterface
{
@@ -29,7 +28,7 @@ class AddDataForIndia implements DataPatchInterface, PatchVersionInterface
private $dataInstallerFactory;
/**
- * AddDataForCroatia constructor.
+ * AddDataForIndia constructor.
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param \Magento\Directory\Setup\DataInstallerFactory $dataInstallerFactory
@@ -43,7 +42,7 @@ public function __construct(
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function apply()
{
@@ -103,7 +102,7 @@ private function getDataForIndia()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public static function getDependencies()
{
@@ -113,7 +112,7 @@ public static function getDependencies()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public static function getVersion()
{
@@ -121,7 +120,7 @@ public static function getVersion()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getAliases()
{
diff --git a/app/code/Magento/Directory/Setup/Patch/Data/AddDataForMexico.php b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForMexico.php
new file mode 100644
index 0000000000000..32bdf90800d6b
--- /dev/null
+++ b/app/code/Magento/Directory/Setup/Patch/Data/AddDataForMexico.php
@@ -0,0 +1,127 @@
+moduleDataSetup = $moduleDataSetup;
+ $this->dataInstallerFactory = $dataInstallerFactory;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function apply()
+ {
+ /** @var DataInstaller $dataInstaller */
+ $dataInstaller = $this->dataInstallerFactory->create();
+ $dataInstaller->addCountryRegions(
+ $this->moduleDataSetup->getConnection(),
+ $this->getDataForMexico()
+ );
+ }
+
+ /**
+ * Mexican states data.
+ *
+ * @return array
+ */
+ private function getDataForMexico()
+ {
+ return [
+ ['MX', 'AGU', 'Aguascalientes'],
+ ['MX', 'BCN', 'Baja California'],
+ ['MX', 'BCS', 'Baja California Sur'],
+ ['MX', 'CAM', 'Campeche'],
+ ['MX', 'CHP', 'Chiapas'],
+ ['MX', 'CHH', 'Chihuahua'],
+ ['MX', 'CMX', 'Ciudad de México'],
+ ['MX', 'COA', 'Coahuila'],
+ ['MX', 'COL', 'Colima'],
+ ['MX', 'DUR', 'Durango'],
+ ['MX', 'MEX', 'Estado de México'],
+ ['MX', 'GUA', 'Guanajuato'],
+ ['MX', 'GRO', 'Guerrero'],
+ ['MX', 'HID', 'Hidalgo'],
+ ['MX', 'JAL', 'Jalisco'],
+ ['MX', 'MIC', 'Michoacán'],
+ ['MX', 'MOR', 'Morelos'],
+ ['MX', 'NAY', 'Nayarit'],
+ ['MX', 'NLE', 'Nuevo León'],
+ ['MX', 'OAX', 'Oaxaca'],
+ ['MX', 'PUE', 'Puebla'],
+ ['MX', 'QUE', 'Querétaro'],
+ ['MX', 'ROO', 'Quintana Roo'],
+ ['MX', 'SLP', 'San Luis Potosí'],
+ ['MX', 'SIN', 'Sinaloa'],
+ ['MX', 'SON', 'Sonora'],
+ ['MX', 'TAB', 'Tabasco'],
+ ['MX', 'TAM', 'Tamaulipas'],
+ ['MX', 'TLA', 'Tlaxcala'],
+ ['MX', 'VER', 'Veracruz'],
+ ['MX', 'YUC', 'Yucatán'],
+ ['MX', 'ZAC', 'Zacatecas']
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public static function getDependencies()
+ {
+ return [
+ InitializeDirectoryData::class,
+ AddDataForAustralia::class,
+ AddDataForCroatia::class,
+ AddDataForIndia::class,
+ ];
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public static function getVersion()
+ {
+ return '2.0.4';
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function getAliases()
+ {
+ return [];
+ }
+}
diff --git a/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php b/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
index c5a18a3de99c6..be9d2700664c7 100644
--- a/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
+++ b/app/code/Magento/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractMain.php
@@ -4,15 +4,13 @@
* See COPYING.txt for license details.
*/
-/**
- * Product attribute add/edit form main tab
- *
- * @author Magento Core Team
- */
namespace Magento\Eav\Block\Adminhtml\Attribute\Edit\Main;
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+/**
+ * Product attribute add/edit form main tab
+ */
abstract class AbstractMain extends \Magento\Backend\Block\Widget\Form\Generic
{
/**
@@ -110,7 +108,6 @@ protected function _prepareForm()
/** @var \Magento\Framework\Data\Form $form */
$form = $this->_formFactory->create(
-
['data' => ['id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post']]
);
@@ -280,10 +277,11 @@ protected function _initFormValues()
}
/**
- * Processing block html after rendering
+ * Processing block html after rendering.
+ *
* Adding js block to the end of this block
*
- * @param string $html
+ * @param string $html
* @return string
*/
protected function _afterToHtml($html)
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php
index 56188ab997b76..36ad026029056 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php
@@ -73,7 +73,7 @@ public function getOptionText($value)
}
}
// End
- if (isset($options[$value])) {
+ if (is_scalar($value) && isset($options[$value])) {
return $options[$value];
}
return false;
diff --git a/app/code/Magento/Eav/Setup/EavSetup.php b/app/code/Magento/Eav/Setup/EavSetup.php
index 6e81ddc36e9c9..29f9163a6e91d 100644
--- a/app/code/Magento/Eav/Setup/EavSetup.php
+++ b/app/code/Magento/Eav/Setup/EavSetup.php
@@ -10,12 +10,12 @@
use Magento\Eav\Model\Entity\Setup\PropertyMapperInterface;
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Group\CollectionFactory;
use Magento\Framework\App\CacheInterface;
-use Magento\Framework\App\ObjectManager;
-use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Setup\ModuleDataSetupInterface;
/**
+ * Base eav setup class.
+ *
* @api
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -101,7 +101,8 @@ public function __construct(
}
/**
- * Gets setup model
+ * Gets setup model.
+ *
* @deprecated
* @return ModuleDataSetupInterface
*/
@@ -568,6 +569,8 @@ public function addAttributeGroup($entityTypeId, $setId, $name, $sortOrder = nul
}
/**
+ * Convert group name to attribute group code.
+ *
* @param string $groupName
* @return string
* @since 100.1.0
@@ -1063,7 +1066,7 @@ private function _updateAttributeAdditionalData($entityTypeId, $id, $field, $val
return $this;
}
}
-
+
$attributeId = $this->getAttributeId($entityTypeId, $id);
if (false === $attributeId) {
throw new LocalizedException(__('Attribute with ID: "%1" does not exist', $id));
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/BooleanTest.php b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/BooleanTest.php
index ee972c27aa8a2..8cf5df877a6eb 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/BooleanTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Entity/Attribute/Source/BooleanTest.php
@@ -101,13 +101,13 @@ public function addValueSortToCollectionDataProvider()
'expectedJoinCondition' => [
0 => [
'requisites' => ['code_t1' => "table"],
- 'condition' =>
- "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123' AND code_t1.store_id='0'",
+ 'condition' => "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123'"
+ . " AND code_t1.store_id='0'",
],
1 => [
'requisites' => ['code_t2' => "table"],
- 'condition' =>
- "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123' AND code_t2.store_id='12'",
+ 'condition' => "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123'"
+ . " AND code_t2.store_id='12'",
],
],
'expectedOrder' => 'IF(code_t2.value_id > 0, code_t2.value, code_t1.value) ASC',
@@ -118,13 +118,13 @@ public function addValueSortToCollectionDataProvider()
'expectedJoinCondition' => [
0 => [
'requisites' => ['code_t1' => "table"],
- 'condition' =>
- "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123' AND code_t1.store_id='0'",
+ 'condition' => "e.entity_id=code_t1.entity_id AND code_t1.attribute_id='123'"
+ . " AND code_t1.store_id='0'",
],
1 => [
'requisites' => ['code_t2' => "table"],
- 'condition' =>
- "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123' AND code_t2.store_id='12'",
+ 'condition' => "e.entity_id=code_t2.entity_id AND code_t2.attribute_id='123'"
+ . " AND code_t2.store_id='12'",
],
],
'expectedOrder' => 'IF(code_t2.value_id > 0, code_t2.value, code_t1.value) DESC',
@@ -135,8 +135,8 @@ public function addValueSortToCollectionDataProvider()
'expectedJoinCondition' => [
0 => [
'requisites' => ['code_t' => "table"],
- 'condition' =>
- "e.entity_id=code_t.entity_id AND code_t.attribute_id='123' AND code_t.store_id='0'",
+ 'condition' => "e.entity_id=code_t.entity_id AND code_t.attribute_id='123'"
+ . " AND code_t.store_id='0'",
],
],
'expectedOrder' => 'code_t.value DESC',
@@ -147,8 +147,8 @@ public function addValueSortToCollectionDataProvider()
'expectedJoinCondition' => [
0 => [
'requisites' => ['code_t' => "table"],
- 'condition' =>
- "e.entity_id=code_t.entity_id AND code_t.attribute_id='123' AND code_t.store_id='0'",
+ 'condition' => "e.entity_id=code_t.entity_id AND code_t.attribute_id='123'"
+ . " AND code_t.store_id='0'",
],
],
'expectedOrder' => 'code_t.value ASC',
diff --git a/app/code/Magento/ImportExport/Test/Mftf/ActionGroup/AdminImportProductsActionGroup.xml b/app/code/Magento/ImportExport/Test/Mftf/ActionGroup/AdminImportProductsActionGroup.xml
new file mode 100644
index 0000000000000..a9100b4730b8c
--- /dev/null
+++ b/app/code/Magento/ImportExport/Test/Mftf/ActionGroup/AdminImportProductsActionGroup.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ImportExport/Test/Mftf/Section/AdminExportAttributeSection.xml b/app/code/Magento/ImportExport/Test/Mftf/Section/AdminExportAttributeSection.xml
index ad9e7672ce11a..528ad23aaf2bf 100644
--- a/app/code/Magento/ImportExport/Test/Mftf/Section/AdminExportAttributeSection.xml
+++ b/app/code/Magento/ImportExport/Test/Mftf/Section/AdminExportAttributeSection.xml
@@ -11,5 +11,11 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithAddUpdateBehaviorTest.xml b/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithAddUpdateBehaviorTest.xml
new file mode 100644
index 0000000000000..ceb4e93e4e9aa
--- /dev/null
+++ b/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithAddUpdateBehaviorTest.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SimpleProductForTest1
+ SimpleProductForTest1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithReplaceBehaviorTest.xml b/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithReplaceBehaviorTest.xml
new file mode 100644
index 0000000000000..d63a5546716b1
--- /dev/null
+++ b/app/code/Magento/ImportExport/Test/Mftf/Test/AdminImportProductsWithReplaceBehaviorTest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SimpleProductForTest2
+ SimpleProductForTest2
+
+
+
+
+
+ SimpleProductForTest3
+ SimpleProductForTest3
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Indexer/Model/Indexer.php b/app/code/Magento/Indexer/Model/Indexer.php
index 87a7cce58e1a5..2821a46f29416 100644
--- a/app/code/Magento/Indexer/Model/Indexer.php
+++ b/app/code/Magento/Indexer/Model/Indexer.php
@@ -3,6 +3,7 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Indexer\Model;
use Magento\Framework\Indexer\ActionFactory;
@@ -14,6 +15,8 @@
use Magento\Framework\Indexer\StructureFactory;
/**
+ * Indexer model.
+ *
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Indexer extends \Magento\Framework\DataObject implements IndexerInterface
@@ -361,7 +364,7 @@ public function getLatestUpdated()
return $this->getView()->getUpdated();
}
}
- return $this->getState()->getUpdated();
+ return $this->getState()->getUpdated() ?: '';
}
/**
diff --git a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php
index 6b7cc12218990..ca2da9585f934 100644
--- a/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php
+++ b/app/code/Magento/Indexer/Test/Unit/Model/IndexerTest.php
@@ -164,7 +164,12 @@ public function testGetLatestUpdated($getViewIsEnabled, $getViewGetUpdated, $get
}
}
} else {
- $this->assertEquals($getStateGetUpdated, $this->model->getLatestUpdated());
+ $getLatestUpdated = $this->model->getLatestUpdated();
+ $this->assertEquals($getStateGetUpdated, $getLatestUpdated);
+
+ if ($getStateGetUpdated === null) {
+ $this->assertNotNull($getLatestUpdated);
+ }
}
}
@@ -182,7 +187,8 @@ public function getLatestUpdatedDataProvider()
[true, '', '06-Jan-1944'],
[true, '06-Jan-1944', ''],
[true, '', ''],
- [true, '06-Jan-1944', '05-Jan-1944']
+ [true, '06-Jan-1944', '05-Jan-1944'],
+ [false, null, null],
];
}
diff --git a/app/code/Magento/PageCache/Test/Mftf/Section/AdminCacheManagementSection.xml b/app/code/Magento/PageCache/Test/Mftf/Section/AdminCacheManagementSection.xml
index 34a77095d524d..ee0c32633569a 100644
--- a/app/code/Magento/PageCache/Test/Mftf/Section/AdminCacheManagementSection.xml
+++ b/app/code/Magento/PageCache/Test/Mftf/Section/AdminCacheManagementSection.xml
@@ -30,5 +30,6 @@
+
diff --git a/app/code/Magento/PageCache/Test/Mftf/Test/FlushStaticFilesCacheButtonVisibilityTest.xml b/app/code/Magento/PageCache/Test/Mftf/Test/FlushStaticFilesCacheButtonVisibilityTest.xml
new file mode 100644
index 0000000000000..bd6f7ba362bf4
--- /dev/null
+++ b/app/code/Magento/PageCache/Test/Mftf/Test/FlushStaticFilesCacheButtonVisibilityTest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php
index d15c218a60b47..6b87c1fe39d8b 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractForm.php
@@ -6,6 +6,7 @@
namespace Magento\Sales\Block\Adminhtml\Order\Create\Form;
use Magento\Framework\Pricing\PriceCurrencyInterface;
+use Magento\Customer\Api\Data\AttributeMetadataInterface;
/**
* Sales Order Create Form Abstract Block
@@ -57,8 +58,7 @@ public function __construct(
}
/**
- * Prepare global layout
- * Add renderers to \Magento\Framework\Data\Form
+ * Prepare global layout. Add renderers to \Magento\Framework\Data\Form
*
* @return $this
*/
@@ -152,7 +152,7 @@ protected function _addAdditionalFormElementData(\Magento\Framework\Data\Form\El
/**
* Add rendering EAV attributes to Form element
*
- * @param \Magento\Customer\Api\Data\AttributeMetadataInterface[] $attributes
+ * @param AttributeMetadataInterface[] $attributes
* @param \Magento\Framework\Data\Form\AbstractForm $form
* @return $this
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -176,8 +176,8 @@ protected function _addAttributesToForm($attributes, \Magento\Framework\Data\For
[
'name' => $attribute->getAttributeCode(),
'label' => __($attribute->getStoreLabel()),
- 'class' => $attribute->getFrontendClass(),
- 'required' => $attribute->isRequired()
+ 'class' => $this->getValidationClasses($attribute),
+ 'required' => $attribute->isRequired(),
]
);
if ($inputType == 'multiline') {
@@ -227,4 +227,58 @@ public function getFormValues()
{
return [];
}
+
+ /**
+ * Retrieve frontend classes according validation rules
+ *
+ * @param AttributeMetadataInterface $attribute
+ *
+ * @return string
+ */
+ private function getValidationClasses(AttributeMetadataInterface $attribute) : string
+ {
+ $out = [];
+ $out[] = $attribute->getFrontendClass();
+
+ $textClasses = $this->getTextLengthValidateClasses($attribute);
+ if (!empty($textClasses)) {
+ $out = array_merge($out, $textClasses);
+ }
+
+ $out = !empty($out) ? implode(' ', array_unique(array_filter($out))) : '';
+ return $out;
+ }
+
+ /**
+ * Retrieve validation classes by min_text_length and max_text_length rules
+ *
+ * @param AttributeMetadataInterface $attribute
+ *
+ * @return array
+ */
+ private function getTextLengthValidateClasses(AttributeMetadataInterface $attribute) : array
+ {
+ $classes = [];
+
+ $validateRules = $attribute->getValidationRules();
+ if (!empty($validateRules)) {
+ foreach ($validateRules as $rule) {
+ switch ($rule->getName()) {
+ case 'min_text_length':
+ $classes[] = 'minimum-length-' . $rule->getValue();
+ break;
+
+ case 'max_text_length':
+ $classes[] = 'maximum-length-' . $rule->getValue();
+ break;
+ }
+ }
+
+ if (!empty($classes)) {
+ $classes[] = 'validate-length';
+ }
+ }
+
+ return $classes;
+ }
}
diff --git a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php
index 2716e860243bf..a75690536e760 100644
--- a/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php
+++ b/app/code/Magento/Sales/Setup/Patch/Data/FillQuoteAddressIdInSalesOrderAddress.php
@@ -8,15 +8,15 @@
use Magento\Eav\Model\Config;
use Magento\Framework\App\State;
-use Magento\Quote\Model\QuoteFactory;
-use Magento\Sales\Model\OrderFactory;
-use Magento\Sales\Model\ResourceModel\Order\Address\CollectionFactory as AddressCollectionFactory;
-use Magento\Framework\App\ResourceConnection;
-use Magento\Sales\Setup\SalesSetupFactory;
+use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
-use Magento\Framework\Setup\ModuleDataSetupInterface;
+use Magento\Sales\Model\Order\Address;
+use Magento\Sales\Setup\SalesSetupFactory;
+/**
+ * Fills quote_address_id in table sales_order_address if it is empty.
+ */
class FillQuoteAddressIdInSalesOrderAddress implements DataPatchInterface, PatchVersionInterface
{
/**
@@ -24,11 +24,6 @@ class FillQuoteAddressIdInSalesOrderAddress implements DataPatchInterface, Patch
*/
private $moduleDataSetup;
- /**
- * @var SalesSetupFactory
- */
- private $salesSetupFactory;
-
/**
* @var State
*/
@@ -40,44 +35,22 @@ class FillQuoteAddressIdInSalesOrderAddress implements DataPatchInterface, Patch
private $eavConfig;
/**
- * @var AddressCollectionFactory
- */
- private $addressCollectionFactory;
-
- /**
- * @var OrderFactory
- */
- private $orderFactory;
-
- /**
- * @var QuoteFactory
- */
- private $quoteFactory;
-
- /**
- * PatchInitial constructor.
* @param ModuleDataSetupInterface $moduleDataSetup
+ * @param State $state
+ * @param Config $eavConfig
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
- SalesSetupFactory $salesSetupFactory,
State $state,
- Config $eavConfig,
- AddressCollectionFactory $addressCollectionFactory,
- OrderFactory $orderFactory,
- QuoteFactory $quoteFactory
+ Config $eavConfig
) {
$this->moduleDataSetup = $moduleDataSetup;
- $this->salesSetupFactory = $salesSetupFactory;
$this->state = $state;
$this->eavConfig = $eavConfig;
- $this->addressCollectionFactory = $addressCollectionFactory;
- $this->orderFactory = $orderFactory;
- $this->quoteFactory = $quoteFactory;
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function apply()
{
@@ -96,32 +69,12 @@ public function apply()
*/
public function fillQuoteAddressIdInSalesOrderAddress(ModuleDataSetupInterface $setup)
{
- $addressTable = $setup->getTable('sales_order_address');
- $updateOrderAddress = $setup->getConnection()
- ->select()
- ->joinInner(
- ['sales_order' => $setup->getTable('sales_order')],
- $addressTable . '.parent_id = sales_order.entity_id',
- ['quote_address_id' => 'quote_address.address_id']
- )
- ->joinInner(
- ['quote_address' => $setup->getTable('quote_address')],
- 'sales_order.quote_id = quote_address.quote_id
- AND ' . $addressTable . '.address_type = quote_address.address_type',
- []
- )
- ->where(
- $addressTable . '.quote_address_id IS NULL'
- );
- $updateOrderAddress = $setup->getConnection()->updateFromSelect(
- $updateOrderAddress,
- $addressTable
- );
- $setup->getConnection()->query($updateOrderAddress);
+ $this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_SHIPPING);
+ $this->fillQuoteAddressIdInSalesOrderAddressByType($setup, Address::TYPE_BILLING);
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public static function getDependencies()
{
@@ -131,7 +84,7 @@ public static function getDependencies()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public static function getVersion()
{
@@ -139,10 +92,99 @@ public static function getVersion()
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function getAliases()
{
return [];
}
+
+ /**
+ * Fill quote_address_id in sales_order_address by type.
+ *
+ * @param ModuleDataSetupInterface $setup
+ * @param string $addressType
+ * @throws \Zend_Db_Statement_Exception
+ */
+ private function fillQuoteAddressIdInSalesOrderAddressByType(ModuleDataSetupInterface $setup, $addressType)
+ {
+ $salesConnection = $setup->getConnection('sales');
+
+ $orderTable = $setup->getTable('sales_order', 'sales');
+ $orderAddressTable = $setup->getTable('sales_order_address', 'sales');
+
+ $query = $salesConnection
+ ->select()
+ ->from(
+ ['sales_order_address' => $orderAddressTable],
+ ['entity_id', 'address_type']
+ )
+ ->joinInner(
+ ['sales_order' => $orderTable],
+ 'sales_order_address.parent_id = sales_order.entity_id',
+ ['quote_id' => 'sales_order.quote_id']
+ )
+ ->where('sales_order_address.quote_address_id IS NULL')
+ ->where('sales_order_address.address_type = ?', $addressType)
+ ->order('sales_order_address.entity_id');
+
+ $batchSize = 5000;
+ $result = $salesConnection->query($query);
+ $count = $result->rowCount();
+ $batches = ceil($count / $batchSize);
+
+ for ($batch = $batches; $batch > 0; $batch--) {
+ $query->limitPage($batch, $batchSize);
+ $result = $salesConnection->fetchAssoc($query);
+
+ $this->fillQuoteAddressIdInSalesOrderAddressProcessBatch($setup, $result, $addressType);
+ }
+ }
+
+ /**
+ * Process filling quote_address_id in sales_order_address in batch.
+ *
+ * @param ModuleDataSetupInterface $setup
+ * @param array $orderAddresses
+ * @param string $addressType
+ */
+ private function fillQuoteAddressIdInSalesOrderAddressProcessBatch(
+ ModuleDataSetupInterface $setup,
+ array $orderAddresses,
+ $addressType
+ ) {
+ $salesConnection = $setup->getConnection('sales');
+ $quoteConnection = $setup->getConnection('checkout');
+
+ $quoteAddressTable = $setup->getTable('quote_address', 'checkout');
+ $quoteTable = $setup->getTable('quote', 'checkout');
+ $salesOrderAddressTable = $setup->getTable('sales_order_address', 'sales');
+
+ $query = $quoteConnection
+ ->select()
+ ->from(
+ ['quote_address' => $quoteAddressTable],
+ ['quote_id', 'address_id']
+ )
+ ->joinInner(
+ ['quote' => $quoteTable],
+ 'quote_address.quote_id = quote.entity_id',
+ []
+ )
+ ->where('quote.entity_id in (?)', array_column($orderAddresses, 'quote_id'))
+ ->where('address_type = ?', $addressType);
+
+ $quoteAddresses = $quoteConnection->fetchAssoc($query);
+
+ foreach ($orderAddresses as $orderAddress) {
+ $bind = [
+ 'quote_address_id' => $quoteAddresses[$orderAddress['quote_id']]['address_id'] ?? null,
+ ];
+ $where = [
+ 'entity_id = ?' => $orderAddress['entity_id']
+ ];
+
+ $salesConnection->update($salesOrderAddressTable, $bind, $where);
+ }
+ }
}
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderStatusFormFillAndSaveActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderStatusFormFillAndSaveActionGroup.xml
new file mode 100644
index 0000000000000..8108577145421
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderStatusFormFillAndSaveActionGroup.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusExistsInGridActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusExistsInGridActionGroup.xml
new file mode 100644
index 0000000000000..5f69f52987688
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusExistsInGridActionGroup.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveDuplicateErrorActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveDuplicateErrorActionGroup.xml
new file mode 100644
index 0000000000000..5b4c3115744c9
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveDuplicateErrorActionGroup.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveSuccessActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveSuccessActionGroup.xml
new file mode 100644
index 0000000000000..d82f4b9dd25e8
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AssertOrderStatusFormSaveSuccessActionGroup.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Data/OrderStatusData.xml b/app/code/Magento/Sales/Test/Mftf/Data/OrderStatusData.xml
new file mode 100644
index 0000000000000..aecd7fcf1b703
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Data/OrderStatusData.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+ order_status
+ orderLabel
+
+
+ pending
+ orderLabel
+
+
+ order_status
+ Suspected Fraud
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderStatusPage.xml b/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderStatusPage.xml
new file mode 100644
index 0000000000000..b158e4923074a
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Page/AdminOrderStatusPage.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusFormSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusFormSection.xml
new file mode 100644
index 0000000000000..1058b2d6f2177
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusFormSection.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusGridSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusGridSection.xml
new file mode 100644
index 0000000000000..b624639281187
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminOrderStatusGridSection.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingCodeTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingCodeTest.xml
new file mode 100644
index 0000000000000..40a731410a899
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingCodeTest.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingLabelTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingLabelTest.xml
new file mode 100644
index 0000000000000..d1381bbb1efb0
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusDuplicatingLabelTest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusTest.xml
new file mode 100644
index 0000000000000..c2daaac84dd42
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminCreateOrderStatusTest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml
new file mode 100644
index 0000000000000..d418751c736e1
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Mftf/Test/AdminSubmitsOrderWithAndWithoutFieldsValidationTest.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
index 89ec2b84572fc..cf6301cb31a9c 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
@@ -61,6 +61,7 @@ public function __construct(
public function loadAttributeOptions()
{
$attributes = [
+ 'base_subtotal_with_discount' => __('Subtotal (Excl. Tax)'),
'base_subtotal' => __('Subtotal'),
'total_qty' => __('Total Items Quantity'),
'weight' => __('Total Weight'),
diff --git a/app/code/Magento/Search/Test/Mftf/ActionGroup/AdminSearchTermActionGroup.xml b/app/code/Magento/Search/Test/Mftf/ActionGroup/AdminSearchTermActionGroup.xml
new file mode 100644
index 0000000000000..e0b3d4b850bbb
--- /dev/null
+++ b/app/code/Magento/Search/Test/Mftf/ActionGroup/AdminSearchTermActionGroup.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Search/Test/Mftf/Data/SearchTermData.xml b/app/code/Magento/Search/Test/Mftf/Data/SearchTermData.xml
new file mode 100644
index 0000000000000..1518adad01347
--- /dev/null
+++ b/app/code/Magento/Search/Test/Mftf/Data/SearchTermData.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ Query text
+ 1
+ http://example.com/
+ 0
+
+
diff --git a/app/code/Magento/Search/Test/Mftf/Metadata/search_term-meta.xml b/app/code/Magento/Search/Test/Mftf/Metadata/search_term-meta.xml
new file mode 100644
index 0000000000000..0bd2dc9be4855
--- /dev/null
+++ b/app/code/Magento/Search/Test/Mftf/Metadata/search_term-meta.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ string
+ integer
+ string
+ integer
+
+
diff --git a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchResultsSection.xml b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchResultsSection.xml
index 9e5bde9a2be49..81b025c9554e2 100644
--- a/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchResultsSection.xml
+++ b/app/code/Magento/Search/Test/Mftf/Section/StorefrontQuickSearchResultsSection.xml
@@ -15,5 +15,6 @@
+
diff --git a/app/code/Magento/Search/Test/Mftf/Test/AdminMassDeleteSearchTermEntityTest.xml b/app/code/Magento/Search/Test/Mftf/Test/AdminMassDeleteSearchTermEntityTest.xml
new file mode 100644
index 0000000000000..67ccb51bf401e
--- /dev/null
+++ b/app/code/Magento/Search/Test/Mftf/Test/AdminMassDeleteSearchTermEntityTest.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml
index ef8d77c8824ff..ca614ec24138c 100644
--- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminCreateWebsiteActionGroup.xml
@@ -36,4 +36,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
index 58e1781d69eab..cf2cabdcc2399 100644
--- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteStoreViewActionGroup.xml
@@ -26,4 +26,35 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml
index 58fd0a3f0bc2b..1721e3185402e 100644
--- a/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/AdminDeleteWebsiteActionGroup.xml
@@ -19,6 +19,7 @@
+
diff --git a/app/code/Magento/Store/Test/Mftf/ActionGroup/StoreFrontProductValidationActionGroup.xml b/app/code/Magento/Store/Test/Mftf/ActionGroup/StoreFrontProductValidationActionGroup.xml
new file mode 100644
index 0000000000000..f11394c643ad7
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/ActionGroup/StoreFrontProductValidationActionGroup.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Data/WebsiteData.xml b/app/code/Magento/Store/Test/Mftf/Data/WebsiteData.xml
index f636336524f01..ae605256a2819 100644
--- a/app/code/Magento/Store/Test/Mftf/Data/WebsiteData.xml
+++ b/app/code/Magento/Store/Test/Mftf/Data/WebsiteData.xml
@@ -23,4 +23,8 @@
Custom Website
custom_website
-
+
+ website_upd
+ code_upd
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
index 592af42f2de30..d7006fd01b2ff 100644
--- a/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
+++ b/app/code/Magento/Store/Test/Mftf/Section/AdminStoresGridSection.xml
@@ -23,5 +23,6 @@
+
-
+
\ No newline at end of file
diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminCreateWebsiteTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateWebsiteTest.xml
new file mode 100644
index 0000000000000..1608d0b7b5a25
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Test/AdminCreateWebsiteTest.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml
new file mode 100644
index 0000000000000..fc1dcb5ee1a24
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Test/AdminDeleteStoreViewTest.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml
new file mode 100644
index 0000000000000..6b666126569ae
--- /dev/null
+++ b/app/code/Magento/Store/Test/Mftf/Test/AdminUpdateWebsiteTest.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
index b983e56b8aee2..b06c655939b1c 100644
--- a/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/Index/Render.php
@@ -86,6 +86,18 @@ public function execute()
$contentType = $this->contentTypeResolver->resolve($component->getContext());
$this->getResponse()->setHeader('Content-Type', $contentType, true);
+ } else {
+ /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+ $resultJson = $this->resultJsonFactory->create();
+ $resultJson->setStatusHeader(
+ \Zend\Http\Response::STATUS_CODE_403,
+ \Zend\Http\AbstractMessage::VERSION_11,
+ 'Forbidden'
+ );
+ return $resultJson->setData([
+ 'error' => $this->escaper->escapeHtml('Forbidden'),
+ 'errorcode' => 403
+ ]);
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->logger->critical($e);
diff --git a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
index 05b35fb017b4b..2bba8686490b6 100644
--- a/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Controller/Adminhtml/Index/RenderTest.php
@@ -3,12 +3,17 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
+
namespace Magento\Ui\Test\Unit\Controller\Adminhtml\Index;
+use Magento\Framework\Controller\Result\Json;
+use Magento\Framework\Escaper;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Ui\Controller\Adminhtml\Index\Render;
use Magento\Ui\Model\UiComponentTypeResolver;
-use Magento\Framework\View\Element\UiComponent\ContextInterface;
-use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Zend\Http\AbstractMessage;
+use Zend\Http\Response;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -97,6 +102,11 @@ class RenderTest extends \PHPUnit\Framework\TestCase
*/
private $loggerMock;
+ /**
+ * @var Escaper|\PHPUnit_Framework_MockObject_MockObject
+ */
+ private $escaperMock;
+
protected function setUp()
{
$this->requestMock = $this->getMockBuilder(\Magento\Framework\App\Request\Http::class)
@@ -170,6 +180,10 @@ protected function setUp()
$this->uiComponentTypeResolverMock = $this->getMockBuilder(UiComponentTypeResolver::class)
->disableOriginalConstructor()
->getMock();
+ $this->escaperMock = $this->createMock(Escaper::class);
+ $this->escaperMock->expects($this->any())
+ ->method('escapeHtml')
+ ->willReturnArgument(0);
$this->objectManagerHelper = new ObjectManagerHelper($this);
@@ -181,6 +195,7 @@ protected function setUp()
'contentTypeResolver' => $this->uiComponentTypeResolverMock,
'resultJsonFactory' => $this->resultJsonFactoryMock,
'logger' => $this->loggerMock,
+ 'escaper' => $this->escaperMock,
]
);
}
@@ -201,7 +216,7 @@ public function testExecuteAjaxRequestException()
->method('appendBody')
->willThrowException(new \Exception('exception'));
- $jsonResultMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
+ $jsonResultMock = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->setMethods(['setData'])
->getMock();
@@ -290,6 +305,34 @@ public function testExecuteAjaxRequestWithoutPermissions(array $dataProviderConf
$name = 'test-name';
$renderedData = 'data';
+ if (false === $isAllowed) {
+ $jsonResultMock = $this->getMockBuilder(Json::class)
+ ->disableOriginalConstructor()
+ ->setMethods(['setStatusHeader', 'setData'])
+ ->getMock();
+
+ $jsonResultMock->expects($this->at(0))
+ ->method('setStatusHeader')
+ ->with(
+ Response::STATUS_CODE_403,
+ AbstractMessage::VERSION_11,
+ 'Forbidden'
+ )
+ ->willReturnSelf();
+
+ $jsonResultMock->expects($this->at(1))
+ ->method('setData')
+ ->with([
+ 'error' => 'Forbidden',
+ 'errorcode' => 403
+ ])
+ ->willReturnSelf();
+
+ $this->resultJsonFactoryMock->expects($this->any())
+ ->method('create')
+ ->willReturn($jsonResultMock);
+ }
+
$this->requestMock->expects($this->any())
->method('getParam')
->with('namespace')
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
index 1b6dd9f1c57ec..0eaacdc32567b 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
@@ -20,6 +20,26 @@ define([
}
},
+ /**
+ * Initializes observable properties of instance
+ *
+ * @returns {Abstract} Chainable.
+ */
+ initObservable: function () {
+ this._super();
+
+ /**
+ * equalityComparer function
+ *
+ * @returns boolean.
+ */
+ this.value.equalityComparer = function (oldValue, newValue) {
+ return !oldValue && !newValue || oldValue === newValue;
+ };
+
+ return this;
+ },
+
/**
* @param {String} value
*/
diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUrlRewriteActionGroup.xml b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUrlRewriteActionGroup.xml
index e9651a3f26e94..50b83641e19a9 100644
--- a/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUrlRewriteActionGroup.xml
+++ b/app/code/Magento/UrlRewrite/Test/Mftf/ActionGroup/AdminUrlRewriteActionGroup.xml
@@ -83,10 +83,10 @@
-
+
-
+
diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml
index 77cf80ca95ac5..3692e82072afc 100644
--- a/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml
+++ b/app/code/Magento/UrlRewrite/Test/Mftf/Data/UrlRewriteData.xml
@@ -24,6 +24,7 @@
Temporary (302)
1
Default Store View
+ Update Url Rewrite
wishlist
diff --git a/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml
new file mode 100644
index 0000000000000..ea370d8419583
--- /dev/null
+++ b/app/code/Magento/UrlRewrite/Test/Mftf/Test/AdminUpdateProductUrlRewriteAndAddTemporaryRedirectTest.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_headings-group.less b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_headings-group.less
index 832c66b7988e0..bf7ee7850f9d0 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_headings-group.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/web/css/source/module/header/_headings-group.less
@@ -42,4 +42,5 @@
color: @page-title__color;
font-size: @page-title__font-size;
margin-bottom: 0;
+ word-break: break-all;
}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less
index 6e03e1d0cebaa..e37e08f3b667d 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Ui/web/css/source/module/data-grid/data-grid-header/_data-grid-filters.less
@@ -99,7 +99,7 @@
}
.action-menu {
- max-height: 3.85rem * @data-grid-search-control-action-menu-item__quantity; // ToDo UI: change static item height
+ max-height: 3.85rem * @data-grid-search-control-action-menu-item__quantity; // @todo: change static item height
overflow-y: auto;
z-index: @data-grid-search-menu__z-index;
}
@@ -354,6 +354,7 @@
.admin__current-filters-list-wrap {
width: 100%;
+ word-break: break-all;
}
.admin__current-filters-list {
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less
index 4479c070a4e17..8dec680b58726 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less
@@ -55,31 +55,3 @@
}
}
}
-
-//
-// Desktop
-// _____________________________________________
-
-.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
- // ToDo UI: remove with global blank theme .field.required update
- .opc-wrapper {
- .fieldset {
- > .field {
- &.required,
- &._required {
- position: relative;
-
- > label {
- padding-right: 25px;
-
- &:after {
- margin-left: @indent__s;
- position: absolute;
- top: 9px;
- }
- }
- }
- }
- }
- }
-}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
index 5f8134193c67f..35445b0989e86 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -209,6 +209,13 @@
.fieldset {
> .field {
margin: 0 0 @indent__base;
+
+ &.choice {
+ &:before {
+ padding: 0;
+ width: 0;
+ }
+ }
&.type {
.control {
diff --git a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
index d477c08fc9553..e5915969c91b9 100644
--- a/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
+++ b/app/design/frontend/Magento/luma/Magento_Catalog/web/css/source/module/_listings.less
@@ -397,7 +397,7 @@
.page-products.page-layout-3columns {
.products-grid {
.product-item {
- margin-left: 2%;
+ margin-left: 0;
width: calc(~'(100% - 4%) / 3');
&:nth-child(3n + 1) {
diff --git a/dev/tests/acceptance/tests/_data/catalog_import_products.csv b/dev/tests/acceptance/tests/_data/catalog_import_products.csv
new file mode 100644
index 0000000000000..7732f15d4ce3a
--- /dev/null
+++ b/dev/tests/acceptance/tests/_data/catalog_import_products.csv
@@ -0,0 +1,4 @@
+sku,store_view_code,attribute_set_code,product_type,categories,product_websites,name,description,short_description,weight,product_online,tax_class_name,visibility,price,special_price,special_price_from_date,special_price_to_date,url_key,meta_title,meta_keywords,meta_description,base_image,base_image_label,small_image,small_image_label,thumbnail_image,thumbnail_image_label,swatch_image,swatch_image_label,created_at,updated_at,new_from_date,new_to_date,display_product_options_in,map_price,msrp_price,map_enabled,gift_message_available,custom_design,custom_design_from,custom_design_to,custom_layout_update,page_layout,product_options_container,msrp_display_actual_price_type,country_of_manufacture,additional_attributes,qty,out_of_stock_qty,use_config_min_qty,is_qty_decimal,allow_backorders,use_config_backorders,min_cart_qty,use_config_min_sale_qty,max_cart_qty,use_config_max_sale_qty,is_in_stock,notify_on_stock_below,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,website_id,related_skus,related_position,crosssell_skus,crosssell_position,upsell_skus,upsell_position,additional_images,additional_image_labels,hide_from_product_page,custom_options,bundle_price_type,bundle_sku_type,bundle_price_view,bundle_weight_type,bundle_values,bundle_shipment_type,configurable_variations,configurable_variation_labels,associated_skus
+SimpleProductForTest1,,Default,simple,"Default","base,second_website",SimpleProductAfterImport1,,,1.0000,1,"Taxable Goods","Catalog, Search",250.0000,,,,simple-product-for-test-1,,,,,,,,,,,,"3/4/19, 5:53 AM","3/4/19, 4:47 PM",,,"Block after Info Column",,,,,,,,,,,"Use config",,,100.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,0,1,1,0.0000,1,0,0,0,,,,,,,,,,,,,,,,,,,
+SimpleProductForTest2,,Default,simple,"Default",base,SimpleProductAfterImport2,,,1.0000,1,"Taxable Goods","Catalog, Search",300.0000,,,,simple-product-for-test-2,,,,,,,,,,,,"3/4/19, 5:53 AM","3/4/19, 4:47 PM",,,"Block after Info Column",,,,,,,,,,,"Use config",,,100.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,0,1,1,0.0000,1,0,0,0,,,,,,,,,,,,,,,,,,,
+SimpleProductForTest3,,Default,simple,"Default","base,second_website",SimpleProductAfterImport3,,,1.0000,1,"Taxable Goods","Catalog, Search",350.0000,,,,simple-product-for-test-3,,,,,,,,,,,,"3/4/19, 5:53 AM","3/4/19, 4:47 PM",,,"Block after Info Column",,,,,,,,,,,"Use config",,,100.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,0,1,1,0.0000,1,0,0,0,,,,,,,,,,,,,,,,,,,
\ No newline at end of file
diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
index 6dbf2b1aa6a12..03492f7ae1a9e 100644
--- a/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
+++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/ConditionsElement.php
@@ -195,6 +195,13 @@ class ConditionsElement extends SimpleElement
*/
protected $exception;
+ /**
+ * Condition option text selector.
+ *
+ * @var string
+ */
+ private $conditionOptionTextSelector = '//option[normalize-space(text())="%s"]';
+
/**
* @inheritdoc
*/
@@ -265,7 +272,7 @@ protected function addSingleCondition($condition, ElementInterface $context)
$this->addCondition($condition['type'], $context);
$createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
$this->waitForCondition($createdCondition);
- $this->fillCondition($condition['rules'], $createdCondition);
+ $this->fillCondition($condition['rules'], $createdCondition, $condition['type']);
}
/**
@@ -282,10 +289,16 @@ protected function addCondition($type, ElementInterface $context)
$count = 0;
do {
- $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
-
try {
- $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($type);
+ $specificType = $newCondition->find(
+ sprintf($this->conditionOptionTextSelector, $type),
+ Locator::SELECTOR_XPATH
+ )->isPresent();
+ $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
+ $condition = $specificType
+ ? $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'selectcondition')
+ : $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select');
+ $condition->setValue($type);
$isSetType = true;
} catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
$isSetType = false;
@@ -306,13 +319,14 @@ protected function addCondition($type, ElementInterface $context)
*
* @param array $rules
* @param ElementInterface $element
+ * @param string|null $type
* @return void
* @throws \Exception
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
- protected function fillCondition(array $rules, ElementInterface $element)
+ protected function fillCondition(array $rules, ElementInterface $element, $type = null)
{
$this->resetKeyParam();
foreach ($rules as $rule) {
@@ -333,7 +347,7 @@ protected function fillCondition(array $rules, ElementInterface $element)
if ($this->fillGrid($rule, $param)) {
$isSet = true;
- } elseif ($this->fillSelect($rule, $param)) {
+ } elseif ($this->fillSelect($rule, $param, $type)) {
$isSet = true;
} elseif ($this->fillText($rule, $param)) {
$isSet = true;
@@ -390,11 +404,15 @@ protected function fillGrid($rule, ElementInterface $param)
*
* @param string $rule
* @param ElementInterface $param
+ * @param string|null $type
* @return bool
*/
- protected function fillSelect($rule, ElementInterface $param)
+ protected function fillSelect($rule, ElementInterface $param, $type = null)
{
- $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select');
+ //Avoid confusion between regions like: "Baja California" and "California".
+ $value = strpos($type, 'State/Province') === false
+ ? $param->find('select', Locator::SELECTOR_TAG_NAME, 'select')
+ : $param->find('select', Locator::SELECTOR_TAG_NAME, 'selectstate');
if ($value->isVisible()) {
$value->setValue($rule);
$this->click();
diff --git a/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php
new file mode 100644
index 0000000000000..15a799eac5188
--- /dev/null
+++ b/dev/tests/functional/lib/Magento/Mtf/Client/Element/SelectconditionElement.php
@@ -0,0 +1,20 @@
+
+
diff --git a/dev/tests/functional/tests/app/Magento/BundleImportExport/Test/TestCase/ExportProductsTest.xml b/dev/tests/functional/tests/app/Magento/BundleImportExport/Test/TestCase/ExportProductsTest.xml
index 3ad8cff31eaf8..bfbe233b9dc1b 100644
--- a/dev/tests/functional/tests/app/Magento/BundleImportExport/Test/TestCase/ExportProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/BundleImportExport/Test/TestCase/ExportProductsTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
default
- bundleProduct
diff --git a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ExportProductsTest.xml b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ExportProductsTest.xml
index b94f21371496a..8fe25614d1d42 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ExportProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ExportProductsTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
default
- catalogProductSimple
@@ -27,6 +28,7 @@
+ mftf_migrated:yes
default
- catalogProductSimple
@@ -43,6 +45,7 @@
+ mftf_migrated:yes
default
- catalogProductSimple
@@ -58,6 +61,7 @@
+ mftf_migrated:yes
>MC-13864 Consumer always read config from memory
default
diff --git a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ImportProductsTest.xml b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ImportProductsTest.xml
index edb0aad954fbb..77e5e2b91d93f 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ImportProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/TestCase/ImportProductsTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
- Products
- Add/Update
@@ -38,6 +39,7 @@
+ mftf_migrated:yes
Products
Replace
Stop on Error
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml
index 0437e0a5e999b..8c465544a3283 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/CreateSearchTermEntityTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
catalogProductSimple::sku
Main Website/Main Website Store/Default Store View
http://example.com/
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml
index a9cc0dfd34f9f..8fdd7ef715521 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/DeleteSearchTermEntityTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
default
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml
index 3bf4e521c4a04..3ef2b65c0224b 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/MassDeleteSearchTermEntityTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
catalogSearchQuery::default,catalogSearchQuery::default,catalogSearchQuery::default
diff --git a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlCategoryEntityTest.xml
index 398054f1f0ed3..8b15da5ecd2ef 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlCategoryEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlCategoryEntityTest.xml
@@ -14,7 +14,7 @@
Yes
Subcategory%isolation%
subcategory-%isolation%
- test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1
+ test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1, mftf_migrated:yes
diff --git a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml
index 1116821f756a9..8110ed1ed00b1 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml
@@ -8,7 +8,7 @@
- test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1
+ test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1, mftf_migrated:yes
simple-product-%isolation%
Simple Product %isolation%
simple_sku_%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
index 8b2460718097c..b4c97a11b9145 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/UpdateProductFromMiniShoppingCartEntityTest.xml
@@ -9,7 +9,7 @@
https://github.com/magento-engcom/msi/issues/1624
- test_type:extended_acceptance_test, severity:S0
+ test_type:extended_acceptance_test, severity:S0, mftf_migrated:yes
catalogProductSimple::default
simple_order_qty_2
true
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableImportExport/Test/TestCase/ExportProductsTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableImportExport/Test/TestCase/ExportProductsTest.xml
index 93240586ec92c..15dcfd0a9e7e7 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableImportExport/Test/TestCase/ExportProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableImportExport/Test/TestCase/ExportProductsTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
default
- configurableProduct
@@ -30,6 +31,7 @@
+ mftf_migrated:yes
default
- configurableProduct
@@ -45,6 +47,7 @@
+ mftf_migrated:yes
>MC-13864 Consumer always read config from memory
default
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.xml
index 70a912a3b5ffe..e88e5161e474e 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/VerifyDisabledCustomerGroupFieldTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
NOT_LOGGED_IN
- customer_group_code
diff --git a/dev/tests/functional/tests/app/Magento/GroupedImportExport/Test/TestCase/ExportProductsTest.xml b/dev/tests/functional/tests/app/Magento/GroupedImportExport/Test/TestCase/ExportProductsTest.xml
index cffcdbf45a6dc..a110dc6a89f8c 100644
--- a/dev/tests/functional/tests/app/Magento/GroupedImportExport/Test/TestCase/ExportProductsTest.xml
+++ b/dev/tests/functional/tests/app/Magento/GroupedImportExport/Test/TestCase/ExportProductsTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
default
- groupedProduct
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
index cbdce59057195..bc529729f1217 100644
--- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
@@ -8,7 +8,7 @@
- severity:S3
+ severity:S3, mftf_migrated:yes
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.xml
index 38ce04fa56d81..e05d0fea6b129 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCustomOrderStatusEntityTest.xml
@@ -8,17 +8,20 @@
+ mftf_migrated:yes
order_status%isolation%
orderLabel%isolation%
+ mftf_migrated:yes
pending
orderLabel%isolation%
+ mftf_migrated:yes
order_status%isolation%
Suspected Fraud
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.xml
index 5a547f69280e1..e35ef853d1b68 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/CreateWebsiteEntityTest.xml
@@ -8,7 +8,7 @@
- severity:S1
+ severity:S1, mftf_migrated:yes
website_%isolation%
code_%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
index 306a9fd2024a4..cd37c555fdb1d 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/DeleteStoreEntityTest.xml
@@ -8,7 +8,7 @@
- severity:S2
+ severity:S2, mftf_migrated:yes
custom
Yes
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.xml
index ac857ad035f44..5db0e7f8baad4 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/UpdateWebsiteEntityTest.xml
@@ -8,7 +8,7 @@
- severity:S2
+ severity:S2, mftf_migrated:yes
custom_website
website_upd%isolation%
code_upd%isolation%
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.xml
index 60de554d594d2..8f12930aa417b 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/UpdateProductUrlRewriteEntityTest.xml
@@ -8,6 +8,7 @@
+ mftf_migrated:yes
product/%catalogProductSimple::product_100_dollar%
Main Website/Main Website Store/Default Store View
test_%isolation%.html
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccess.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccess.php
index f7c56ae1b9653..ecfbc8d353888 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccess.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccess.php
@@ -10,6 +10,7 @@
use Magento\Mtf\Client\BrowserInterface;
use Magento\Mtf\Constraint\AbstractConstraint;
use Magento\User\Test\Fixture\User;
+use Magento\User\Test\TestStep\LoginUserOnBackendWithErrorStep;
/**
* Asserts that user has only related permissions.
@@ -18,6 +19,8 @@ class AssertUserRoleRestrictedAccess extends AbstractConstraint
{
const DENIED_ACCESS = 'Sorry, you need permissions to view this content.';
+ protected $loginStep = 'Magento\User\Test\TestStep\LoginUserOnBackendStep';
+
/**
* Asserts that user has only related permissions.
*
@@ -36,7 +39,7 @@ public function processAssert(
$denyUrl
) {
$this->objectManager->create(
- \Magento\User\Test\TestStep\LoginUserOnBackendStep::class,
+ $this->loginStep,
['user' => $user]
)->run();
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccessWithError.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccessWithError.php
new file mode 100644
index 0000000000000..b001893abb4c4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleRestrictedAccessWithError.php
@@ -0,0 +1,17 @@
+objectManager->create(
- \Magento\User\Test\TestStep\LoginUserOnBackendStep::class,
+ $this->loginStep,
['user' => $user]
)->run();
\PHPUnit\Framework\Assert::assertTrue(
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLoginWithError.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLoginWithError.php
new file mode 100644
index 0000000000000..9fed1f4df8573
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLoginWithError.php
@@ -0,0 +1,20 @@
+
-
+
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php
index cc1d0fc980fbf..58450abc71633 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php
@@ -121,6 +121,11 @@ public function testUpdateAdminUserRolesEntity(
*/
public function tearDown()
{
+ sleep(3);
+ $modalMessage = $this->dashboard->getModalMessage();
+ if ($modalMessage->isVisible()) {
+ $modalMessage->acceptAlert();
+ }
$this->dashboard->getAdminPanelHeader()->logOut();
}
}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml
index 224ccbce10f96..db6a13d0f3551 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.xml
@@ -29,8 +29,8 @@
-
-
+
+
custom_admin_with_default_role
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/CloseErrorAlertStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/CloseErrorAlertStep.php
new file mode 100644
index 0000000000000..51d48058c8ae5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/CloseErrorAlertStep.php
@@ -0,0 +1,57 @@
+dashboard = $dashboard;
+ $this->browser = $browser;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function run()
+ {
+ $modalMessage = $this->dashboard->getModalMessage();
+ try {
+ $this->browser->waitUntil(
+ function () use ($modalMessage) {
+ return $modalMessage->isVisible() ? true : null;
+ }
+ );
+ $modalMessage->acceptAlert();
+ } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
+ //There is no modal to accept.
+ }
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
index 4f7e6deed7a85..c244e27d42899 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
@@ -50,7 +50,7 @@ class LoginUserOnBackendStep implements TestStepInterface
*
* @var BrowserInterface
*/
- private $browser;
+ protected $browser;
/**
* Array of error messages on admin login form.
@@ -108,8 +108,6 @@ public function run()
}
}
}
-
- $this->dashboard->getSystemMessageDialog()->closePopup();
}
/**
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendWithErrorStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendWithErrorStep.php
new file mode 100644
index 0000000000000..094f90d0a5d70
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendWithErrorStep.php
@@ -0,0 +1,53 @@
+closeErrorAlertStep = $closeErrorAlertStep;
+ }
+
+ /**
+ * Run step flow.
+ *
+ * @return void
+ */
+ public function run()
+ {
+ parent::run();
+ $this->closeErrorAlertStep->run();
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
index 70a4080a0b4d5..7f366312bba24 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
@@ -48,7 +48,6 @@ public function __construct(AdminAuthLogin $adminAuth, Dashboard $dashboard)
public function run()
{
$this->adminAuth->open();
- $this->dashboard->getSystemMessageDialog()->closePopup();
$this->dashboard->getAdminPanelHeader()->logOut();
}
}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendWithErrorStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendWithErrorStep.php
new file mode 100644
index 0000000000000..ce49e86afc065
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendWithErrorStep.php
@@ -0,0 +1,40 @@
+closeErrorAlertStep = $closeErrorAlertStep;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function run()
+ {
+ $this->adminAuth->open();
+ $this->closeErrorAlertStep->run();
+ $this->dashboard->getAdminPanelHeader()->logOut();
+ }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/di.xml
new file mode 100644
index 0000000000000..1298bd56a8fb0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/di.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ \Magento\User\Test\TestStep\LogoutUserOnBackendWithErrorStep
+
+
+
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php
index 07af21505f180..89f1e5e5d53d6 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php
@@ -21,6 +21,8 @@ public function testAjaxBlockAction()
public function testTunnelAction()
{
+ $this->markTestSkipped('MAGETWO-98800: TunnelAction fails when Google Chart API is not available');
+
$testUrl = \Magento\Backend\Block\Dashboard\Graph::API_URL . '?cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World';
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $testUrl);
diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Controller/Paypal/ReviewTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Paypal/ReviewTest.php
new file mode 100644
index 0000000000000..fc79048f15f45
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Braintree/Controller/Paypal/ReviewTest.php
@@ -0,0 +1,43 @@
+controller = $this->_objectManager->create(Review::class);
+ }
+
+ /**
+ * Test controller implements correct interfaces
+ *
+ */
+ public function testInterfaceImplementation()
+ {
+ $this->assertInstanceOf(HttpGetActionInterface::class, $this->controller);
+ $this->assertInstanceOf(HttpPostActionInterface::class, $this->controller);
+ }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundlePriceCalculatorWithDimensionTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundlePriceCalculatorWithDimensionTest.php
index b97bd9f822666..e9cb2f2d6c9d4 100644
--- a/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundlePriceCalculatorWithDimensionTest.php
+++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Product/FixedBundlePriceCalculatorWithDimensionTest.php
@@ -13,7 +13,6 @@
* @magentoDbIsolation disabled
* @magentoIndexerDimensionMode catalog_product_price website_and_customer_group
* @group indexer_dimension
- * @magentoAppArea frontend
*/
class FixedBundlePriceCalculatorWithDimensionTest extends BundlePriceAbstract
{
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php
index 994076badddae..60ccdb88676aa 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Plugin/Model/Quote/ResetQuoteAddressesTest.php
@@ -22,6 +22,7 @@ class ResetQuoteAddressesTest extends \PHPUnit\Framework\TestCase
/**
* @magentoDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
*
+ * @magentoAppArea frontend
* @return void
*/
public function testAfterRemoveItem(): void
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
index ea7a7710acbc3..10b632c002475 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
@@ -751,6 +751,21 @@ public function loginPostRedirectDataProvider()
];
}
+ /**
+ * @magentoDataFixture Magento/Customer/_files/customer.php
+ * @magentoDataFixture Magento/Customer/_files/customer_address.php
+ * @magentoAppArea frontend
+ */
+ public function testCheckVisitorModel()
+ {
+ /** @var \Magento\Customer\Model\Visitor $visitor */
+ $visitor = $this->_objectManager->get(\Magento\Customer\Model\Visitor::class);
+ $this->login(1);
+ $this->assertNull($visitor->getId());
+ $this->dispatch('customer/account/index');
+ $this->assertNotNull($visitor->getId());
+ }
+
/**
* @param string $email
* @return void
diff --git a/lib/internal/Magento/Framework/App/FrontControllerInterface.php b/lib/internal/Magento/Framework/App/FrontControllerInterface.php
index a552d88e68f50..afd3091097d19 100644
--- a/lib/internal/Magento/Framework/App/FrontControllerInterface.php
+++ b/lib/internal/Magento/Framework/App/FrontControllerInterface.php
@@ -8,7 +8,7 @@
/**
* Application front controller responsible for dispatching application requests.
* Front controller contains logic common for all actions.
- * Evary application area has own front controller
+ * Every application area has own front controller.
*
* @api
*/
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
index f4d83ece134cf..e1b423d738a20 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/Adapter.php
@@ -7,6 +7,7 @@
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Ddl\Table;
+use Magento\Framework\DB\Select;
use Magento\Framework\Search\Adapter\Mysql\Aggregation\Builder as AggregationBuilder;
use Magento\Framework\Search\AdapterInterface;
use Magento\Framework\Search\RequestInterface;
@@ -49,6 +50,16 @@ class Adapter implements AdapterInterface
*/
private $temporaryStorageFactory;
+ /**
+ * Query Select Parts to be skipped when prepare query for count
+ *
+ * @var array
+ */
+ private $countSqlSkipParts = [
+ \Magento\Framework\DB\Select::LIMIT_COUNT => true,
+ \Magento\Framework\DB\Select::LIMIT_OFFSET => true,
+ ];
+
/**
* @param Mapper $mapper
* @param ResponseFactory $responseFactory
@@ -86,7 +97,7 @@ public function query(RequestInterface $request)
$response = [
'documents' => $documents,
'aggregations' => $aggregations,
- 'total' => count($documents)
+ 'total' => $this->getSize($query)
];
return $this->responseFactory->create($response);
}
@@ -115,4 +126,39 @@ private function getConnection()
{
return $this->resource->getConnection();
}
+
+ /**
+ * Get rows size
+ *
+ * @param Select $query
+ * @return int
+ */
+ private function getSize(Select $query): int
+ {
+ $sql = $this->getSelectCountSql($query);
+ $parentSelect = $this->getConnection()->select();
+ $parentSelect->from(['core_select' => $sql]);
+ $parentSelect->reset(\Magento\Framework\DB\Select::COLUMNS);
+ $parentSelect->columns('COUNT(*)');
+ $totalRecords = $this->getConnection()->fetchOne($parentSelect);
+
+ return intval($totalRecords);
+ }
+
+ /**
+ * Reset limit and offset
+ *
+ * @param Select $query
+ * @return Select
+ */
+ private function getSelectCountSql(Select $query): Select
+ {
+ foreach ($this->countSqlSkipParts as $part => $toSkip) {
+ if ($toSkip) {
+ $query->reset($part);
+ }
+ }
+
+ return $query;
+ }
}
diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php
index a35e1fd8b6151..fbb56361bfe71 100644
--- a/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php
+++ b/lib/internal/Magento/Framework/Search/Test/Unit/Adapter/Mysql/AdapterTest.php
@@ -161,10 +161,16 @@ public function testQuery()
$select = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
->disableOriginalConstructor()
->getMock();
- $this->connectionAdapter->expects($this->once())
+
+ $this->connectionAdapter->expects($this->exactly(2))
->method('select')
->willReturn($select);
+ $this->connectionAdapter->expects($this->once())
+ ->method('fetchOne')
+ ->with($select)
+ ->willReturn($selectResult['total']);
+
$table = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class)
->disableOriginalConstructor()
->getMock();