From bebc0e91c5c5c62d7c4f0e8841e1295e8a47bca4 Mon Sep 17 00:00:00 2001 From: Ievgen Shakhsuvarov Date: Fri, 26 May 2017 16:01:29 +0300 Subject: [PATCH] MAGETWO-69375: Can't delete last item in cart if Minimum Order is Enable #6151 #9714 --- .../Magento/Quote/Model/QuoteManagement.php | 16 +--- .../Magento/Quote/Model/QuoteValidator.php | 19 +++- .../Test/Unit/Model/QuoteManagementTest.php | 94 +------------------ .../Test/Unit/Model/QuoteValidatorTest.php | 41 +++++++- 4 files changed, 61 insertions(+), 109 deletions(-) diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php index 9afccbb957ab5..89b8b7a17b697 100644 --- a/app/code/Magento/Quote/Model/QuoteManagement.php +++ b/app/code/Magento/Quote/Model/QuoteManagement.php @@ -10,7 +10,6 @@ use Magento\Framework\App\ObjectManager; use Magento\Framework\Event\ManagerInterface as EventManager; use Magento\Framework\Exception\CouldNotSaveException; -use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\StateException; use Magento\Quote\Api\Data\PaymentInterface; @@ -137,11 +136,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface */ private $quoteIdMaskFactory; - /** - * @var \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage - */ - private $minimumAmountMessage; - /** * @param EventManager $eventManager * @param QuoteValidator $quoteValidator @@ -163,7 +157,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface * @param \Magento\Customer\Model\Session $customerSession * @param \Magento\Customer\Api\AccountManagementInterface $accountManagement * @param QuoteFactory $quoteFactory - * @param Quote\Validator\MinimumOrderAmount\ValidationMessage $minimumAmountMessage * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -186,8 +179,7 @@ public function __construct( \Magento\Checkout\Model\Session $checkoutSession, \Magento\Customer\Model\Session $customerSession, \Magento\Customer\Api\AccountManagementInterface $accountManagement, - \Magento\Quote\Model\QuoteFactory $quoteFactory, - \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage $minimumAmountMessage = null + \Magento\Quote\Model\QuoteFactory $quoteFactory ) { $this->eventManager = $eventManager; $this->quoteValidator = $quoteValidator; @@ -209,8 +201,6 @@ public function __construct( $this->accountManagement = $accountManagement; $this->customerSession = $customerSession; $this->quoteFactory = $quoteFactory; - $this->minimumAmountMessage = $minimumAmountMessage ?: \Magento\Framework\App\ObjectManager::getInstance() - ->get(\Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage::class); } /** @@ -330,10 +320,6 @@ protected function createCustomerCart($customerId, $storeId) public function placeOrder($cartId, PaymentInterface $paymentMethod = null) { $quote = $this->quoteRepository->getActive($cartId); - if (!$quote->validateMinimumAmount($quote->getIsMultiShipping())) { - throw new InputException($this->minimumAmountMessage->getMessage()); - } - if ($paymentMethod) { $paymentMethod->setChecks([ \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT, diff --git a/app/code/Magento/Quote/Model/QuoteValidator.php b/app/code/Magento/Quote/Model/QuoteValidator.php index 0c84ac1883a85..93bf3e958dfbb 100644 --- a/app/code/Magento/Quote/Model/QuoteValidator.php +++ b/app/code/Magento/Quote/Model/QuoteValidator.php @@ -6,9 +6,11 @@ namespace Magento\Quote\Model; +use Magento\Framework\Exception\LocalizedException; use Magento\Quote\Model\Quote as QuoteEntity; use Magento\Directory\Model\AllowedCountries; use Magento\Framework\App\ObjectManager; +use Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage as OrderAmountValidationMessage; /** * @api @@ -25,15 +27,25 @@ class QuoteValidator */ private $allowedCountryReader; + /** + * @var OrderAmountValidationMessage + */ + private $minimumAmountMessage; + /** * QuoteValidator constructor. * * @param AllowedCountries|null $allowedCountryReader + * @param OrderAmountValidationMessage|null $minimumAmountMessage */ - public function __construct(AllowedCountries $allowedCountryReader = null) - { + public function __construct( + AllowedCountries $allowedCountryReader = null, + OrderAmountValidationMessage $minimumAmountMessage = null + ) { $this->allowedCountryReader = $allowedCountryReader ?: ObjectManager::getInstance() ->get(AllowedCountries::class); + $this->minimumAmountMessage = $minimumAmountMessage ?: ObjectManager::getInstance() + ->get(OrderAmountValidationMessage::class); } /** @@ -98,6 +110,9 @@ public function validateBeforeSubmit(QuoteEntity $quote) if (!$quote->getPayment()->getMethod()) { throw new \Magento\Framework\Exception\LocalizedException(__('Please select a valid payment method.')); } + if (!$quote->validateMinimumAmount($quote->getIsMultiShipping())) { + throw new LocalizedException($this->minimumAmountMessage->getMessage()); + } return $this; } diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php index fbc2065845cb9..43571f4f86a7a 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php @@ -121,11 +121,6 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase */ protected $quoteMock; - /** - * @var \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage - */ - private $minimumAmountMessage; - /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -223,8 +218,6 @@ protected function setUp() 'setCustomerGroupId', 'assignCustomer', 'getPayment', - 'getIsMultiShipping', - 'validateMinimumAmount' ], [], '', @@ -256,14 +249,6 @@ protected function setUp() false ); - $this->minimumAmountMessage = $this->getMock( - \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage::class, - ['getMessage'], - [], - '', - false - ); - $this->quoteFactoryMock = $this->getMock(\Magento\Quote\Model\QuoteFactory::class, ['create'], [], '', false); $this->model = $objectManager->getObject( \Magento\Quote\Model\QuoteManagement::class, @@ -287,8 +272,7 @@ protected function setUp() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock, - 'minimumAmountMessage' => $this->minimumAmountMessage + 'quoteFactory' => $this->quoteFactoryMock ] ); @@ -721,10 +705,6 @@ public function testPlaceOrderIfCustomerIsGuest() ->willReturn(\Magento\Checkout\Model\Type\Onepage::METHOD_GUEST); $this->quoteMock->expects($this->once())->method('setCustomerId')->with(null)->willReturnSelf(); $this->quoteMock->expects($this->once())->method('setCustomerEmail')->with($email)->willReturnSelf(); - $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false); - $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(true); - - $this->minimumAmountMessage->expects($this->never())->method('getMessage'); $addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, ['getEmail'], [], '', false); $addressMock->expects($this->once())->method('getEmail')->willReturn($email); @@ -759,8 +739,7 @@ public function testPlaceOrderIfCustomerIsGuest() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock, - 'minimumAmountMessage' => $this->minimumAmountMessage + 'quoteFactory' => $this->quoteFactoryMock ] ); $orderMock = $this->getMock( @@ -818,8 +797,7 @@ public function testPlaceOrder() 'checkoutSession' => $this->checkoutSessionMock, 'customerSession' => $this->customerSessionMock, 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock, - 'minimumAmountMessage' => $this->minimumAmountMessage + 'quoteFactory' => $this->quoteFactoryMock ] ); $orderMock = $this->getMock( @@ -851,11 +829,6 @@ public function testPlaceOrder() ->method('setCustomerIsGuest') ->with(true); - $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false); - $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(true); - - $this->minimumAmountMessage->expects($this->never())->method('getMessage'); - $service->expects($this->once())->method('submit')->willReturn($orderMock); $this->quoteMock->expects($this->atLeastOnce())->method('getId')->willReturn($cartId); @@ -883,67 +856,6 @@ public function testPlaceOrder() $this->assertEquals($orderId, $service->placeOrder($cartId, $paymentMethod)); } - /** - * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage Incorrect amount - */ - public function testPlaceOrderWithViolationOfMinimumAmount() - { - $cartId = 323; - - $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false); - $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(false); - - $this->minimumAmountMessage->expects($this->once()) - ->method('getMessage') - ->willReturn(__('Incorrect amount')); - - $this->quoteRepositoryMock->expects($this->once()) - ->method('getActive') - ->with($cartId) - ->willReturn($this->quoteMock); - - /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\QuoteManagement $service */ - $service = $this->getMock( - \Magento\Quote\Model\QuoteManagement::class, - ['submit'], - [ - 'eventManager' => $this->eventManager, - 'quoteValidator' => $this->quoteValidator, - 'orderFactory' => $this->orderFactory, - 'orderManagement' => $this->orderManagement, - 'customerManagement' => $this->customerManagement, - 'quoteAddressToOrder' => $this->quoteAddressToOrder, - 'quoteAddressToOrderAddress' => $this->quoteAddressToOrderAddress, - 'quoteItemToOrderItem' => $this->quoteItemToOrderItem, - 'quotePaymentToOrderPayment' => $this->quotePaymentToOrderPayment, - 'userContext' => $this->userContextMock, - 'quoteRepository' => $this->quoteRepositoryMock, - 'customerRepository' => $this->customerRepositoryMock, - 'customerModelFactory' => $this->customerFactoryMock, - 'quoteAddressFactory' => $this->quoteAddressFactory, - 'dataObjectHelper' => $this->dataObjectHelperMock, - 'storeManager' => $this->storeManagerMock, - 'checkoutSession' => $this->checkoutSessionMock, - 'customerSession' => $this->customerSessionMock, - 'accountManagement' => $this->accountManagementMock, - 'quoteFactory' => $this->quoteFactoryMock, - 'minimumAmountMessage' => $this->minimumAmountMessage - ] - ); - - $service->expects($this->never())->method('submit'); - - $paymentMethod = $this->getMock( - \Magento\Quote\Model\Quote\Payment::class, - [], - [], - '', - false - ); - $service->placeOrder($cartId, $paymentMethod); - } - /** * @param $isGuest * @param $isVirtual diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteValidatorTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteValidatorTest.php index 317ab6dad5680..fee2efa7f26a1 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/QuoteValidatorTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteValidatorTest.php @@ -9,6 +9,7 @@ use Magento\Quote\Model\Quote\Address; use Magento\Quote\Model\Quote\Payment; use Magento\Quote\Model\QuoteValidator; +use Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage as OrderAmountValidationMessage; /** * Class QuoteValidatorTest @@ -30,6 +31,11 @@ class QuoteValidatorTest extends \PHPUnit_Framework_TestCase */ private $allowedCountryReader; + /** + * @var OrderAmountValidationMessage|\PHPUnit_Framework_MockObject_MockObject + */ + private $orderAmountValidationMessage; + /** * @return void */ @@ -38,8 +44,14 @@ protected function setUp() $this->allowedCountryReader = $this->getMockBuilder(AllowedCountries::class) ->disableOriginalConstructor() ->getMock(); + $this->orderAmountValidationMessage = $this->getMockBuilder(OrderAmountValidationMessage::class) + ->disableOriginalConstructor() + ->getMock(); - $this->quoteValidator = new \Magento\Quote\Model\QuoteValidator($this->allowedCountryReader); + $this->quoteValidator = new \Magento\Quote\Model\QuoteValidator( + $this->allowedCountryReader, + $this->orderAmountValidationMessage + ); $this->quoteMock = $this->getMock( \Magento\Quote\Model\Quote::class, @@ -51,6 +63,8 @@ protected function setUp() 'setHasError', 'addMessage', 'isVirtual', + 'validateMinimumAmount', + 'getIsMultiShipping', '__wakeup' ], [], @@ -185,6 +199,31 @@ public function testValidateBeforeSubmitThrowsExceptionIfPaymentMethodIsNotSelec $this->quoteValidator->validateBeforeSubmit($this->quoteMock); } + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage Minimum Order Amount Exceeded. + */ + public function testValidateBeforeSubmitThrowsExceptionIfMinimumOrderAmount() + { + $paymentMock = $this->getMock(\Magento\Quote\Model\Quote\Payment::class, [], [], '', false); + $paymentMock->expects($this->once())->method('getMethod')->willReturn('checkmo'); + + $billingAddressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false); + $billingAddressMock->expects($this->any())->method('validate')->willReturn(true); + + $this->quoteMock->expects($this->any())->method('getBillingAddress')->willReturn($billingAddressMock); + $this->quoteMock->expects($this->any())->method('getPayment')->willReturn($paymentMock); + $this->quoteMock->expects($this->any())->method('isVirtual')->willReturn(true); + + $this->quoteMock->expects($this->any())->method('getIsMultiShipping')->willReturn(false); + $this->quoteMock->expects($this->any())->method('validateMinimumAmount')->willReturn(false); + + $this->orderAmountValidationMessage->expects($this->once())->method('getMessage') + ->willReturn(__("Minimum Order Amount Exceeded.")); + + $this->quoteValidator->validateBeforeSubmit($this->quoteMock); + } + /** * Test case when country id not present in allowed countries list. *