Skip to content

Commit

Permalink
ENGCOM-7793: Fixing bug with non-existent customer group breaking quote
Browse files Browse the repository at this point in the history
#28902

 - Merge Pull Request #28902 from kodubovik/magento2:bug/non-existent-customer-group-breaks-quote
 - Merged commits:
   1. c9fef1b
   2. fd77b60
   3. f674258
   4. e80d7e4
   5. 6bbf4d7
   6. bdf203e
   7. 460ca11
   8. 42486a6
  • Loading branch information
magento-engcom-team committed Aug 5, 2020
2 parents 00f8a8c + 42486a6 commit 820f557
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?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="OnePageCheckoutAsCustomerUsingNonExistentCustomerGroupTest">
<annotations>
<features value="OnePageCheckout"/>
<stories value="OnePageCheckout within Offline Payment Methods"/>
<title value="OnePageCheckout as a customer with non-existent customer group assigned to the quote"/>
<description value="Checkout as a customer with non-existent customer group assigned to the quote"/>
<severity value="AVERAGE"/>
<testCaseId value="MC-36385"/>
<group value="checkout"/>
</annotations>
<before>
<!-- Create Simple Product -->
<createData entity="SimpleProduct2" stepKey="createSimpleProduct">
<field key="price">560</field>
</createData>

<!-- Create customer group -->
<createData entity="CustomCustomerGroup" stepKey="createCustomerGroup"/>

<!-- Create customer and assign it to the customer group created on the previous step -->
<createData entity="Simple_US_Customer_Multiple_Addresses" stepKey="createCustomer">
<field key="group_id">$$createCustomerGroup.id$$</field>
</createData>
</before>
<after>
<!-- Admin log out -->
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>

<!-- Customer log out -->
<actionGroup ref="StorefrontCustomerLogoutActionGroup" stepKey="customerLogout"/>

<!-- Delete created product -->
<deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct"/>

<!-- Delete customer -->
<deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/>
</after>

<!-- Login as customer -->
<actionGroup ref="LoginToStorefrontActionGroup" stepKey="customerLogin">
<argument name="Customer" value="$$createCustomer$$"/>
</actionGroup>

<!-- Add Simple Product to cart -->
<amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.custom_attributes[url_key]$$)}}" stepKey="navigateToSimpleProductPage"/>
<waitForPageLoad stepKey="waitForSimpleProductPageLoad"/>
<actionGroup ref="AddToCartFromStorefrontProductPageActionGroup" stepKey="addToCartFromStorefrontProductPage">
<argument name="productName" value="$$createSimpleProduct.name$$"/>
</actionGroup>

<!-- Delete customer group -->
<deleteData createDataKey="createCustomerGroup" stepKey="deleteCustomerGroup"/>

<!-- Go to shopping cart -->
<actionGroup ref="ClickViewAndEditCartFromMiniCartActionGroup" stepKey="goToShoppingCartFromMinicart"/>
<actionGroup ref="FillShippingZipForm" stepKey="fillShippingZipForm">
<argument name="address" value="US_Address_CA"/>
</actionGroup>
<click selector="{{CheckoutCartSummarySection.proceedToCheckout}}" stepKey="clickProceedToCheckout"/>
<waitForPageLoad stepKey="waitForProceedToCheckout"/>

<!-- Check that error does not appear and shipping methods are available to select -->
<dontSee selector="{{CheckoutCartMessageSection.errorMessage}}" userInput="No such entity with id = $$createCustomerGroup.id$$" stepKey="assertErrorMessage"/>
<dontSee selector="{{CheckoutShippingMethodsSection.noQuotesMsg}}" userInput="Sorry, no quotes are available for this order at this time" stepKey="assertNoQuotesMessage"/>

<!-- Fill customer address data -->
<waitForElementVisible selector="{{CheckoutShippingSection.shipHereButton(UK_Not_Default_Address.street[0])}}" stepKey="waitForShipHereVisible"/>
<!-- Change address -->
<click selector="{{CheckoutShippingSection.shipHereButton(UK_Not_Default_Address.street[0])}}" stepKey="clickShipHere"/>

<!-- Click next button to open payment section -->
<click selector="{{CheckoutShippingGuestInfoSection.next}}" stepKey="clickNext"/>
<waitForPageLoad stepKey="waitForShipmentPageLoad"/>

<!-- Select payment solution -->
<checkOption selector="{{CheckoutPaymentSection.billingAddressNotSameCheckbox}}" stepKey="selectPaymentSolution" />

<!-- Check order summary in checkout -->
<waitForElement selector="{{CheckoutPaymentSection.paymentSectionTitle}}" stepKey="waitForPaymentSectionLoaded"/>
<click selector="{{CheckoutPaymentSection.placeOrder}}" stepKey="clickPlaceOrderButton"/>
<seeElement selector="{{CheckoutSuccessMainSection.success}}" stepKey="orderIsSuccessfullyPlaced"/>
<grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/>

<!-- Login as admin -->
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>

<!-- Open created order in backend -->
<amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToOrders"/>
<waitForPageLoad stepKey="waitForOrdersPageLoad"/>
<actionGroup ref="OpenOrderByIdActionGroup" stepKey="filterOrderGridById">
<argument name="orderId" value="$grabOrderNumber"/>
</actionGroup>

<!-- Assert order total -->
<scrollTo selector="{{AdminOrderTotalSection.grandTotal}}" stepKey="scrollToOrderTotalSection"/>
<see selector="{{AdminOrderTotalSection.grandTotal}}" userInput="$565.00" stepKey="checkOrderTotalInBackend"/>

<!-- Assert order addresses -->
<see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{UK_Not_Default_Address.street[0]}}" stepKey="seeBillingAddressStreet"/>
<see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{UK_Not_Default_Address.city}}" stepKey="seeBillingAddressCity"/>
<see selector="{{AdminShipmentAddressInformationSection.billingAddress}}" userInput="{{UK_Not_Default_Address.postcode}}" stepKey="seeBillingAddressPostcode"/>
<see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{UK_Not_Default_Address.street[0]}}" stepKey="seeShippingAddressStreet"/>
<see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{UK_Not_Default_Address.city}}" stepKey="seeShippingAddressCity"/>
<see selector="{{AdminShipmentAddressInformationSection.shippingAddress}}" userInput="{{UK_Not_Default_Address.postcode}}" stepKey="seeShippingAddressPostcode"/>
</test>
</tests>
18 changes: 17 additions & 1 deletion app/code/Magento/Quote/Model/Quote.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Directory\Model\AllowedCountries;
use Magento\Framework\Api\AttributeValueFactory;
use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Model\AbstractExtensibleModel;
use Magento\Quote\Api\Data\PaymentInterface;
use Magento\Quote\Model\Quote\Address;
Expand Down Expand Up @@ -1104,7 +1105,22 @@ public function getCustomerTaxClassId()
//if (!$this->getData('customer_group_id') && !$this->getData('customer_tax_class_id')) {
$groupId = $this->getCustomerGroupId();
if ($groupId !== null) {
$taxClassId = $this->groupRepository->getById($this->getCustomerGroupId())->getTaxClassId();
$taxClassId = null;
try {
$taxClassId = $this->groupRepository->getById($this->getCustomerGroupId())->getTaxClassId();
} catch (NoSuchEntityException $e) {
/**
* A customer MAY create a quote and AFTER that customer group MAY be deleted.
* That breaks a quote because it still refers no a non-existent customer group.
* In such a case we should load a new customer group id from the current customer
* object and use it to retrieve tax class and update quote.
*/
$groupId = $this->getCustomer()->getGroupId();
$this->setCustomerGroupId($groupId);
if ($groupId !== null) {
$taxClassId = $this->groupRepository->getById($groupId)->getTaxClassId();
}
}
$this->setCustomerTaxClassId($taxClassId);
}

Expand Down
44 changes: 44 additions & 0 deletions app/code/Magento/Quote/Test/Unit/Model/QuoteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
use Magento\Framework\DataObject\Copy;
use Magento\Framework\DataObject\Factory;
use Magento\Framework\Event\Manager;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Model\Context;
use Magento\Framework\Phrase;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Model\Quote;
Expand Down Expand Up @@ -640,6 +642,48 @@ public function testGetCustomerTaxClassId()
$this->assertEquals($taxClassId, $result);
}

/**
* Test case when non-existent customer group is stored into the quote.
* In such a case we should get a NoSuchEntityException exception and try
* to get a valid customer group from the current customer object.
*/
public function testGetCustomerTaxClassIdForNonExistentCustomerGroup()
{
$customerId = 1;
$nonExistentGroupId = 100;
$groupId = 1;
$taxClassId = 1;
$groupMock = $this->getMockForAbstractClass(GroupInterface::class, [], '', false);
$this->groupRepositoryMock->expects($this->at(0))
->method('getById')
->with($nonExistentGroupId)
->willThrowException(new NoSuchEntityException(new Phrase('Entity Id does not exist')));
$customerMock = $this->getMockForAbstractClass(
CustomerInterface::class,
[],
'',
false
);
$customerMock->expects($this->once())
->method('getGroupId')
->willReturn($groupId);
$this->customerRepositoryMock->expects($this->once())
->method('getById')
->with($customerId)
->willReturn($customerMock);
$this->groupRepositoryMock->expects($this->at(1))
->method('getById')
->with($groupId)
->willReturn($groupMock);
$groupMock->expects($this->once())
->method('getTaxClassId')
->willReturn($taxClassId);
$this->quote->setData('customer_id', $customerId);
$this->quote->setData('customer_group_id', $nonExistentGroupId);
$result = $this->quote->getCustomerTaxClassId();
$this->assertEquals($taxClassId, $result);
}

public function testGetAllAddresses()
{
$id = 1;
Expand Down

0 comments on commit 820f557

Please sign in to comment.