Files
magento2/app/code/Magento/Multishipping/Test/Unit/Plugin/MultishippingQuoteRepositoryTest.php

324 lines
12 KiB
PHP

<?php
/************************************************************************
*
* Copyright 2023 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
declare(strict_types=1);
namespace Magento\Multishipping\Test\Unit\Plugin;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Type;
use Magento\Catalog\Model\Product\Type\Simple;
use Magento\Multishipping\Plugin\MultishippingQuoteRepository;
use Magento\Payment\Model\Method\AbstractMethod;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Api\Data\CartExtensionInterface;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\Address\Item;
use Magento\Quote\Model\Quote\Item as QuoteItem;
use Magento\Quote\Model\Quote\Address\Rate;
use Magento\Quote\Model\Quote\Payment;
use Magento\Quote\Model\Quote\ShippingAssignment\ShippingProcessor;
use Magento\Quote\Model\ShippingAssignmentFactory;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* Unit Test case for MultishippingQuoteRepository plugin
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class MultishippingQuoteRepositoryTest extends TestCase
{
/**
* @var CartRepositoryInterface|MockObject
*/
private $cartMock;
/**
* @var CartInterface|MockObject
*/
private $quoteMock;
/**
* @var QuoteItem|MockObject
*/
private $quoteItemMock;
/**
* @var ShippingAssignmentFactory|MockObject
*/
private $shippingAssignmentFactoryMock;
/**
* @var ShippingProcessor|MockObject
*/
private $shippingProcessorMock;
/**
* @var MultishippingQuoteRepository
*/
private $multishippingQuoteRepository;
/**
* @inheritdoc
*/
protected function setUp(): void
{
$this->cartMock = $this->createMock(CartRepositoryInterface::class);
$this->quoteMock = $this->getMockBuilder(CartInterface::class)
->addMethods(
[
'hasVirtualItems',
'getAllShippingAddresses',
'getPayment',
'getIsMultiShipping',
'reserveOrderId'
]
)
->onlyMethods(['setItems', 'getItems'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->quoteItemMock = $this->getMockBuilder(QuoteItem::class)
->disableOriginalConstructor()
->onlyMethods(['getProductType', 'getProduct', 'getQuote', 'getQty', 'getPrice', 'setQuote'])
->getMock();
$this->shippingAssignmentFactoryMock = $this->getMockBuilder(ShippingAssignmentFactory::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->shippingProcessorMock = $this->getMockBuilder(ShippingProcessor::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->multishippingQuoteRepository = new MultishippingQuoteRepository(
$this->shippingAssignmentFactoryMock,
$this->shippingProcessorMock
);
}
/**
* Test afterGet plugin and check the quote has items or null
*
* @param bool $isMultiShippingMode
* @param array $productData
* @return void
* @dataProvider pluginForAfterGetMultiShippingModeDataProvider
*/
public function testPluginAfterGetWithMultiShippingMode(bool $isMultiShippingMode, array $productData): void
{
$simpleProductTypeMock = $this->getMockBuilder(Simple::class)
->disableOriginalConstructor()
->onlyMethods(['getOrderOptions'])
->getMock();
$productMock = $this->getProductMock($simpleProductTypeMock);
$this->getQuoteItemMock($productData['productType'], $productMock);
$quoteAddressItemMock = $this->getQuoteAddressItemMock(
$productData['productType'],
$productData['productOptions']
);
list($shippingAddressMock, $billingAddressMock) =
$this->getQuoteAddressesMock($quoteAddressItemMock);
$this->setQuoteMockData($productData['paymentProviderCode'], $shippingAddressMock, $billingAddressMock);
$this->quoteItemMock->method('setQuote')->with($this->quoteMock)->willReturnSelf();
$this->quoteItemMock->method('getQuote')->willReturn($this->quoteMock);
$extensionAttributesMock = $this->getMockBuilder(CartExtensionInterface::class)
->disableOriginalConstructor()
->addMethods(['getShippingAssignments'])
->getMockForAbstractClass();
$this->quoteMock->expects($this->any())
->method('getIsMultiShipping')
->willReturn($isMultiShippingMode);
$this->quoteMock->expects($this->any())
->method('getExtensionAttributes')
->willReturn($extensionAttributesMock);
$extensionAttributesMock->expects($this->any())
->method('getShippingAssignments')
->willReturn($this->shippingAssignmentFactoryMock);
$quote = $this->multishippingQuoteRepository->afterGet($this->cartMock, $this->quoteMock);
$this->assertNotEmpty($quote);
$this->assertEquals(1, count($quote->getItems()));
$this->assertNotEmpty(current($quote->getItems()));
}
/**
* Return Product Mock.
*
* @param Simple|MockObject $simpleProductTypeMock
* @return MockObject
*/
private function getProductMock($simpleProductTypeMock): MockObject
{
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getTypeInstance'])
->getMock();
$productMock->method('getTypeInstance')->willReturn($simpleProductTypeMock);
return $productMock;
}
/**
* Return Quote Item Mock.
*
* @param string $productType
* @param Product|MockObject $productMock
* @return void
*/
private function getQuoteItemMock(string $productType, Product|MockObject $productMock): void
{
$this->quoteItemMock->method('getProductType')->willReturn($productType);
$this->quoteItemMock->method('getProduct')->willReturn($productMock);
$this->quoteItemMock->method('getQty')->willReturn(1);
$this->quoteItemMock->method('getPrice')->willReturn(10);
$this->quoteItemMock->method('getQuote')->willReturn($this->quoteMock);
}
/**
* Return Quote Address Item Mock
*
* @param string $productType
* @param array $productOptions
* @return MockObject
*/
private function getQuoteAddressItemMock(string $productType, array $productOptions): MockObject
{
$quoteAddressItemMock = $this->getMockBuilder(Item::class)
->disableOriginalConstructor()
->addMethods(['getQuoteItem','setProductType', 'setProductOptions'])
->onlyMethods(['getParentItem'])
->getMock();
$quoteAddressItemMock->method('getQuoteItem')->willReturn($this->quoteItemMock);
$quoteAddressItemMock->method('setProductType')->with($productType)->willReturnSelf();
$quoteAddressItemMock->method('setProductOptions')->willReturn($productOptions);
$quoteAddressItemMock->method('getParentItem')->willReturn(false);
return $quoteAddressItemMock;
}
/**
* Return Quote Addresses Mock
* @param Item|MockObject $quoteAddressItemMock
* @return array
*/
private function getQuoteAddressesMock(Item|MockObject $quoteAddressItemMock): array
{
$shippingAddressMock = $this->getMockBuilder(Address::class)
->disableOriginalConstructor()
->addMethods(['getAddressType', 'getGrandTotal'])
->onlyMethods(
[
'validate',
'getShippingMethod',
'getShippingRateByCode',
'getCountryId',
'getAllItems',
]
)->getMock();
$shippingAddressMock->method('validate')->willReturn(true);
$shippingAddressMock->method('getAllItems')->willReturn([$quoteAddressItemMock]);
$shippingAddressMock->method('getAddressType')->willReturn('shipping');
$shippingRateMock = $this->getMockBuilder(Rate::class)
->disableOriginalConstructor()
->addMethods([ 'getPrice' ])
->getMock();
$shippingAddressMock->method('getShippingRateByCode')->willReturn($shippingRateMock);
$billingAddressMock = $this->getMockBuilder(Address::class)
->disableOriginalConstructor()
->onlyMethods(['validate'])
->getMock();
$billingAddressMock->method('validate')->willReturn(true);
return [$shippingAddressMock, $billingAddressMock];
}
/**
* Set data for Quote Mock.
*
* @param string $paymentProviderCode
* @param Address|MockObject $shippingAddressMock
* @param Address|MockObject $billingAddressMock
* @return void
*/
private function setQuoteMockData(
string $paymentProviderCode,
Address|MockObject $shippingAddressMock,
Address|MockObject $billingAddressMock
): void {
$paymentMock = $this->getPaymentMock($paymentProviderCode);
$this->quoteMock->method('getPayment')
->willReturn($paymentMock);
$this->quoteMock->method('getAllShippingAddresses')
->willReturn([$shippingAddressMock]);
$this->quoteMock->method('getBillingAddress')
->willReturn($billingAddressMock);
$this->quoteMock->method('hasVirtualItems')
->willReturn(false);
$this->quoteMock->expects($this->any())->method('reserveOrderId')->willReturnSelf();
$this->quoteMock->method('setIsActive')->with(false)->willReturnSelf();
$this->quoteMock->method('setItems')->with([$this->quoteItemMock])->willReturnSelf();
$this->quoteMock->method('getItems')->willReturn([$this->quoteItemMock]);
}
/**
* Return Payment Mock.
*
* @param string $paymentProviderCode
* @return MockObject
*/
private function getPaymentMock(string $paymentProviderCode): MockObject
{
$abstractMethod = $this->getMockBuilder(AbstractMethod::class)
->disableOriginalConstructor()
->onlyMethods(['isAvailable'])
->getMockForAbstractClass();
$abstractMethod->method('isAvailable')->willReturn(true);
$paymentMock = $this->getMockBuilder(Payment::class)
->disableOriginalConstructor()
->onlyMethods(['getMethodInstance', 'getMethod'])
->getMock();
$paymentMock->method('getMethodInstance')->willReturn($abstractMethod);
$paymentMock->method('getMethod')->willReturn($paymentProviderCode);
return $paymentMock;
}
/**
* DataProvider for pluginForAfterGetMultiShippingModeDataProvider().
*
* @return array
*/
public function pluginForAfterGetMultiShippingModeDataProvider(): array
{
$productData = [
'productType' => Type::TYPE_SIMPLE,
'paymentProviderCode' => 'checkmo',
'productOptions' => [
'info_buyRequest' => [
'product' => '1',
'qty' => 1,
],
]
];
return [
'test case for multi shipping quote' => [true, $productData],
'test case for single shipping quote' => [false, $productData]
];
}
}