Skip to content

Commit

Permalink
Merge pull request #7826 from magento-gl/2_4_6_Quality_Backlog_v1
Browse files Browse the repository at this point in the history
[Hammer][2.4.6] Quality Backlog
  • Loading branch information
andimov committed Aug 26, 2022
2 parents 82ecd9d + 8d68e2b commit e235082
Show file tree
Hide file tree
Showing 15 changed files with 418 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ private function updateItemQuantity(Item $item, float $qty)
{
if ($qty > 0) {
$item->clearMessage();
$item->setHasError(false);
$item->setQty($qty);

if ($item->getHasError()) {
Expand Down
6 changes: 6 additions & 0 deletions app/code/Magento/Checkout/Model/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ public function updateItems($data)

$qty = isset($itemInfo['qty']) ? (double)$itemInfo['qty'] : false;
if ($qty > 0) {
$item->clearMessage();
$item->setHasError(false);
$item->setQty($qty);

if ($item->getHasError()) {
Expand Down Expand Up @@ -707,6 +709,9 @@ public function getItemsQty()
*/
public function updateItem($itemId, $requestInfo = null, $updatingParams = null)
{
$product = null;
$productId = null;

try {
$item = $this->getQuote()->getItemById($itemId);
if (!$item) {
Expand Down Expand Up @@ -757,6 +762,7 @@ public function updateItem($itemId, $requestInfo = null, $updatingParams = null)
* Getter for RequestInfoFilter
*
* @deprecated 100.1.2
* @see MAGETWO-60073
* @return \Magento\Checkout\Model\Cart\RequestInfoFilterInterface
*/
private function getRequestInfoFilter()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StorefrontProductQuantityAcceptLowerThanStockQuantityAfterChangingStockInBackendTest">
<annotations>
<stories value="Cart"/>
<title value="Verify if lower than stock product quantity is accepted after changing stock qty in backend"/>
<description value="Verify if lower than stock product quantity is accepted after changing stock qty in backend"/>
<severity value="CRITICAL"/>
<testCaseId value="AC-5987"/>
<group value="mtf_migrated"/>
</annotations>

<before>
<actionGroup ref="AdminLoginActionGroup" stepKey="loginToAdminPanel"/>
<createData entity="defaultSimpleProduct" stepKey="simpleProduct">
<field key="price">10.00</field>
<field key="quantity">20</field>
</createData>
</before>
<after>
<deleteData createDataKey="simpleProduct" stepKey="deleteProduct"/>
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
</after>

<!--Open Product page in StoreFront and assert product and price range -->
<actionGroup ref="AssertProductNameAndSkuInStorefrontProductPageByCustomAttributeUrlKeyActionGroup" stepKey="openProductPage">
<argument name="product" value="$$simpleProduct$$"/>
</actionGroup>

<!--Add product to the cart -->
<actionGroup ref="StorefrontAddProductToCartWithQtyActionGroup" stepKey="addProductToTheCart">
<argument name="productQty" value="12"/>
</actionGroup>

<!--Open View and edit -->
<actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="clickMiniCart"/>

<waitForPageLoad stepKey="waitForOrderPageToLoad"/>

<!--Edit product qty via admin panel-->
<openNewTab stepKey="openNewTab"/>
<actionGroup ref="AdminProductPageOpenByIdActionGroup" stepKey="goToProductEditPage">
<argument name="productId" value="$$simpleProduct.id$$"/>
</actionGroup>
<fillField userInput="10" selector="{{AdminProductFormSection.productQuantity}}" stepKey="setNewQty"/>
<actionGroup ref="SaveProductFormActionGroup" stepKey="saveProduct"/>
<closeTab stepKey="closeTab"/>

<!--Check quantity-->
<actionGroup ref="ReloadPageActionGroup" stepKey="reloadPage"/>
<comment userInput="Replacing reload action and preserve Backward Compatibility" stepKey="waitForCheckoutPageReload"/>

<waitForPageLoad stepKey="waitForPageLoad1"/>
<waitForAjaxLoad stepKey="waitForAjaxLoad1"/>

<!--Assert "The requested qty is not available"-->
<see selector="{{CheckoutCartMessageSection.errorMessage}}" userInput="The requested qty is not available" stepKey="seeTheErrorMessageDisplayed"/>

<fillField selector="{{CheckoutCartProductSection.qty($$simpleProduct.sku$$)}}" userInput="8" stepKey="updateProductQty"/>
<click selector="{{CheckoutCartProductSection.updateShoppingCartButton}}" stepKey="clickUpdateShoppingCart"/>
<waitForAjaxLoad stepKey="waitForAjaxLoad2"/>
<waitForAjaxLoad stepKey="waitForPageLoad2"/>

<dontSee userInput="The requested qty is not available" stepKey="dontSeeTheErrorMessageDisplayed"/>

</test>
</tests>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ define(
'use strict';

return function (serviceUrl, payload, messageContainer) {
var headers = {};
var headers = {}, redirectURL = '';

fullScreenLoader.startLoader();
_.each(hooks.requestModifiers, function (modifier) {
Expand All @@ -30,6 +30,13 @@ define(
).fail(
function (response) {
errorProcessor.process(response, messageContainer);
redirectURL = response.getResponseHeader('errorRedirectAction');

if (redirectURL) {
setTimeout(function () {
errorProcessor.redirectTo(redirectURL);
}, 3000);
}
}
).done(
function (response) {
Expand Down
63 changes: 63 additions & 0 deletions app/code/Magento/Payment/Plugin/PaymentMethodProcess.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Payment\Plugin;

use Magento\Framework\App\ObjectManager;
use Magento\Payment\Block\Form\Container;
use Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider;

/**
* @SuppressWarnings(PHPMD)
*/
class PaymentMethodProcess
{
/**
* @var string
*/
private string $braintreeCCVault;

/**
* @var TokensConfigProvider
*/
private TokensConfigProvider $tokensConfigProvider;

/**
* @param string $braintreeCCVault
* @param TokensConfigProvider|null $tokensConfigProvider
*/
public function __construct(
string $braintreeCCVault = '',
TokensConfigProvider $tokensConfigProvider = null
) {
$this->braintreeCCVault = $braintreeCCVault;
$this->tokensConfigProvider = $tokensConfigProvider ??
ObjectManager::getInstance()->get(TokensConfigProvider::class);
}

/**
* Retrieve available payment methods
*
* @param Container $container
* @param array $results
* @return array
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGetMethods(Container $container, array $results): array
{
$methods = [];
foreach ($results as $result) {
if ($result->getCode() === $this->braintreeCCVault
&& empty($this->tokensConfigProvider->getTokensComponents($result->getCode()))) {

continue;
}
$methods[] = $result;
}
return $methods;
}
}
142 changes: 142 additions & 0 deletions app/code/Magento/Payment/Test/Unit/Plugin/PaymentMethodProcessTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Payment\Test\Unit\Plugin;

use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Payment\Api\Data\PaymentMethodInterface;
use Magento\Payment\Block\Form\Container;
use Magento\Payment\Plugin\PaymentMethodProcess;
use Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider;
use Magento\Vault\Model\Ui\TokenUiComponentInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class PaymentMethodProcessTest extends TestCase
{
/**
* @const string
*/
public const PAYMENT_METHOD_CHECKMO = 'checkmo';

/**
* @const string
*/
public const PAYMENT_METHOD_BRAINTREE = 'braintree';

/**
* @const string
*/
public const PAYMENT_METHOD_BRAINTREE_CC_VAULT = 'braintree_cc_vault';

/**
* @var TokensConfigProvider|MockObject
*/
private TokensConfigProvider $tokensConfigProviderMock;

/**
* @var Container|MockObject
*/
private $containerMock;

/**
* @var PaymentMethodProcess
*/
private $plugin;

/**
* Set up
*/
protected function setUp(): void
{
$this->tokensConfigProviderMock = $this->getMockBuilder(TokensConfigProvider::class)
->disableOriginalConstructor()
->getMock();
$objectManagerHelper = new ObjectManager($this);
$this->containerMock = $objectManagerHelper->getObject(Container::class);

$this->plugin = $objectManagerHelper->getObject(
PaymentMethodProcess::class,
[
'braintreeCCVault' => self::PAYMENT_METHOD_BRAINTREE_CC_VAULT,
'tokensConfigProvider' => $this->tokensConfigProviderMock
]
);
}

/**
* @param array $methods
* @param array $expectedResult
* @param array $tokenComponents
* @dataProvider afterGetMethodsDataProvider
*/
public function testAfterGetMethods(array $methods, array $expectedResult, array $tokenComponents)
{

$this->tokensConfigProviderMock->method('getTokensComponents')
->with(self::PAYMENT_METHOD_BRAINTREE_CC_VAULT)
->willReturn($tokenComponents);

$result = $this->plugin->afterGetMethods($this->containerMock, $methods);
$this->assertEquals($result, $expectedResult);
}

/**
* Data provider for AfterGetMethods.
*
* @return array
*/
public function afterGetMethodsDataProvider(): array
{
$tokenUiComponentInterface = $this->getMockBuilder(TokenUiComponentInterface::class)
->disableOriginalConstructor()
->getMock();

$checkmoPaymentMethod = $this
->getMockBuilder(PaymentMethodInterface::class)
->disableOriginalConstructor()
->setMethods(['getCode'])
->getMockForAbstractClass();
$brainTreePaymentMethod = $this
->getMockBuilder(PaymentMethodInterface::class)
->disableOriginalConstructor()
->setMethods(['getCode'])
->getMockForAbstractClass();
$brainTreeCCVaultTPaymentMethod = $this
->getMockBuilder(PaymentMethodInterface::class)
->disableOriginalConstructor()
->setMethods(['getCode'])
->getMockForAbstractClass();

$checkmoPaymentMethod->expects($this->any())->method('getCode')
->willReturn(self::PAYMENT_METHOD_CHECKMO);
$brainTreePaymentMethod->expects($this->any())->method('getCode')
->willReturn(self::PAYMENT_METHOD_BRAINTREE);
$brainTreeCCVaultTPaymentMethod->expects($this->any())->method('getCode')
->willReturn(self::PAYMENT_METHOD_BRAINTREE_CC_VAULT);

$paymentMethods = [
$checkmoPaymentMethod,
$brainTreePaymentMethod,
$brainTreeCCVaultTPaymentMethod,
];
$expectedResult1 = [
$checkmoPaymentMethod,
$brainTreePaymentMethod,
$brainTreeCCVaultTPaymentMethod
];
$expectedResult2 = [
$checkmoPaymentMethod,
$brainTreePaymentMethod,
];

return [
[$paymentMethods, $expectedResult1, [$tokenUiComponentInterface]],
[$paymentMethods, $expectedResult2, []],
];
}
}
3 changes: 2 additions & 1 deletion app/code/Magento/Payment/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"magento/module-quote": "*",
"magento/module-sales": "*",
"magento/module-store": "*",
"magento/module-ui": "*"
"magento/module-ui": "*",
"magento/module-vault": "*"
},
"type": "magento2-module",
"license": [
Expand Down
8 changes: 8 additions & 0 deletions app/code/Magento/Payment/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,12 @@
<argument name="logger" xsi:type="object">Magento\Payment\Model\Method\VirtualLogger</argument>
</arguments>
</type>
<type name="Magento\Payment\Block\Form\Container">
<plugin name="PaymentMethodProcess" type="Magento\Payment\Plugin\PaymentMethodProcess"/>
</type>
<type name="Magento\Payment\Plugin\PaymentMethodProcess">
<arguments>
<argument name="braintreeCCVault" xsi:type="string">braintree_cc_vault</argument>
</arguments>
</type>
</config>

0 comments on commit e235082

Please sign in to comment.