| Current Path : /var/www/www.indacotrentino.com/www/vendor/magento/module-quote/Test/Unit/Model/Quote/ |
| Current File : /var/www/www.indacotrentino.com/www/vendor/magento/module-quote/Test/Unit/Model/Quote/ItemTest.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Quote\Test\Unit\Model\Quote;
use Magento\Catalog\Api\Data\ProductExtensionInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Type\AbstractType;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\Locale\FormatInterface;
use Magento\Framework\Model\Context;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\Item\Compare;
use Magento\Quote\Model\Quote\Item\Option;
use Magento\Quote\Model\Quote\Item\Option\Comparator;
use Magento\Quote\Model\Quote\Item\OptionFactory;
use Magento\Sales\Model\Status\ListFactory;
use Magento\Sales\Model\Status\ListStatus;
use Magento\Store\Model\Store;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ItemTest extends TestCase
{
/**
* @var Item
*/
private $model;
/**
* @var FormatInterface
*/
private $localeFormat;
/**
* @var Context
*/
private $modelContext;
/**
* @var ManagerInterface
*/
private $eventDispatcher;
/**
* @var ListStatus
*/
private $errorInfos;
/**
* @var OptionFactory
*/
private $itemOptionFactory;
/**
* @var ObjectManager
*/
private $objectManagerHelper;
/**
* @var Compare|MockObject
*/
protected $compareHelper;
/**
* @var MockObject
*/
protected $stockItemMock;
/**
* @var Json
*/
private $serializer;
const PRODUCT_ID = 1;
const PRODUCT_TYPE = 'simple';
const PRODUCT_SKU = '12345';
const PRODUCT_NAME = 'test_product';
const PRODUCT_WEIGHT = '1lb';
const PRODUCT_TAX_CLASS_ID = 3;
const PRODUCT_COST = 9.00;
/**
* @inheirtDoc
*/
protected function setUp(): void
{
$this->objectManagerHelper = new ObjectManager($this);
$this->localeFormat = $this->getMockBuilder(FormatInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->modelContext = $this->getMockBuilder(Context::class)
->disableOriginalConstructor()
->onlyMethods(['getEventDispatcher'])
->getMock();
$this->eventDispatcher = $this->getMockBuilder(ManagerInterface::class)
->disableOriginalConstructor()
->onlyMethods(['dispatch'])
->getMockForAbstractClass();
$this->modelContext->expects($this->any())
->method('getEventDispatcher')
->willReturn($this->eventDispatcher);
$this->errorInfos = $this->getMockBuilder(ListStatus::class)
->disableOriginalConstructor()
->onlyMethods(['clear', 'addItem', 'getItems', 'removeItemsByParams'])
->getMock();
$statusListFactory = $this->getMockBuilder(ListFactory::class)
->disableOriginalConstructor()
->onlyMethods(['create'])
->getMock();
$statusListFactory->expects($this->any())
->method('create')
->willReturn($this->errorInfos);
$this->itemOptionFactory = $this->getMockBuilder(OptionFactory::class)
->disableOriginalConstructor()
->onlyMethods(['create'])
->getMock();
$this->compareHelper = $this->createMock(Compare::class);
$this->stockItemMock = $this->createPartialMock(
\Magento\CatalogInventory\Model\Stock\Item::class,
['getIsQtyDecimal', '__wakeup']
);
$this->serializer = $this->getMockBuilder(Json::class)
->onlyMethods(['unserialize'])
->getMockForAbstractClass();
$this->model = $this->objectManagerHelper->getObject(
Item::class,
[
'localeFormat' => $this->localeFormat,
'context' => $this->modelContext,
'statusListFactory' => $statusListFactory,
'itemOptionFactory' => $this->itemOptionFactory,
'quoteItemCompare' => $this->compareHelper,
'serializer' => $this->serializer,
'itemOptionComparator' => new Comparator()
]
);
}
/**
* @return void
*/
public function testGetAddress(): void
{
$quote = $this->getMockBuilder(Quote::class)
->onlyMethods(['getShippingAddress', 'getBillingAddress', 'getStoreId', '__wakeup', 'isVirtual'])
->disableOriginalConstructor()
->getMock();
$quote->expects($this->once())
->method('getShippingAddress')
->willReturn('shipping');
$quote->expects($this->once())
->method('getBillingAddress')
->willReturn('billing');
$quote->expects($this->any())
->method('getStoreId')
->willReturn(1);
$quote->expects($this->exactly(2))
->method('isVirtual')
->willReturnOnConsecutiveCalls(false, true);
$this->model->setQuote($quote);
$this->assertEquals('shipping', $this->model->getAddress(), 'Wrong shipping address');
$this->assertEquals('billing', $this->model->getAddress(), 'Wrong billing address');
}
/**
* @return void
*/
public function testSetAndQuote(): void
{
$idValue = "id_value";
$quote = $this->getMockBuilder(Quote::class)
->onlyMethods(['getId', 'getStoreId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$quote->expects($this->once())
->method('getId')
->willReturn($idValue);
$quote->expects($this->any())
->method('getStoreId')
->willReturn(1);
$this->model->setQuote($quote);
$this->assertSame($quote, $this->model->getQuote());
$this->assertEquals($idValue, $this->model->getQuoteId());
}
/**
* Tests that adding a quantity to an item without a parent item or an id will add additional quantity.
*
* @return void
*/
public function testAddQtyNormal(): void
{
$existingQuantity = 2;
$quantityToAdd = 3;
$preparedQuantityToAdd = 4;
$this->model->setData('qty', $existingQuantity);
$this->localeFormat
->method('getNumber')
->withConsecutive([$quantityToAdd], [$preparedQuantityToAdd + $existingQuantity])
->willReturnOnConsecutiveCalls($preparedQuantityToAdd, $preparedQuantityToAdd + $existingQuantity);
$this->model->addQty($quantityToAdd);
$this->assertEquals($preparedQuantityToAdd, $this->model->getQtyToAdd());
$this->assertEquals($preparedQuantityToAdd + $existingQuantity, $this->model->getQty());
}
/**
* Tests that adding a quantity to an item with a parent item and an id will not change the quantity.
*
* @return void
*/
public function testAddQtyExistingParentItemAndId(): void
{
$existingQuantity = 2;
$quantityToAdd = 3;
$parentItemMock = $this->getMockBuilder(Item::class)
->onlyMethods(['addChild', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->model->setParentItem($parentItemMock);
$this->model->setId(1);
$this->model->setData('qty', $existingQuantity);
$this->model->addQty($quantityToAdd);
$this->assertEquals($existingQuantity, $this->model->getQty());
$this->assertNull($this->model->getQtyToAdd());
}
/**
* @return void
*/
public function testSetQty(): void
{
$existingQuantity = 2;
$quantityToAdd = 3;
$preparedQuantityToAdd = 4;
$this->localeFormat->expects($this->once())
->method('getNumber')
->with($quantityToAdd)
->willReturn($preparedQuantityToAdd);
$this->model->setData('qty', $existingQuantity);
$this->eventDispatcher->expects($this->once())
->method('dispatch')
->with('sales_quote_item_qty_set_after', ['item' => $this->model]);
$this->model->setQty($quantityToAdd);
$this->assertEquals($preparedQuantityToAdd, $this->model->getQty());
}
/**
* @return void
*/
public function testSetQtyQuoteIgnoreOldQuantity(): void
{
$existingQuantity = 2;
$quantityToAdd = 3;
$preparedQuantityToAdd = 4;
$this->localeFormat->expects($this->once())
->method('getNumber')
->with($quantityToAdd)
->willReturn($preparedQuantityToAdd);
$quoteMock = $this->getMockBuilder(Quote::class)
->disableOriginalConstructor()
->onlyMethods(['getStoreId', '__wakeup'])
->addMethods(['getIgnoreOldQty'])
->getMock();
$quoteMock->expects($this->once())
->method('getIgnoreOldQty')
->willReturn(true);
$quoteMock->expects($this->any())
->method('getStoreId')
->willReturn(1);
$this->model->setQuote($quoteMock);
$this->model->setData('qty', $existingQuantity);
$this->eventDispatcher->expects($this->once())
->method('dispatch')
->with('sales_quote_item_qty_set_after', ['item' => $this->model]);
$this->model->setQty($quantityToAdd);
$this->assertEquals($preparedQuantityToAdd, $this->model->getQty());
}
/**
* @return void
*/
public function testSetQtyUseOldQuantity(): void
{
$existingQuantity = 2;
$quantityToAdd = 3;
$preparedQuantityToAdd = 4;
$this->localeFormat->expects($this->once())
->method('getNumber')
->with($quantityToAdd)
->willReturn($preparedQuantityToAdd);
$this->model->setData('qty', $existingQuantity);
$this->model->setUseOldQty(true);
$this->eventDispatcher->expects($this->once())
->method('dispatch')
->with('sales_quote_item_qty_set_after', ['item' => $this->model]);
$this->model->setQty($quantityToAdd);
$this->assertEquals($existingQuantity, $this->model->getQty());
}
/**
* @return void
*/
public function testSetQtyOptions(): void
{
$value = ['a' => 'b'];
$this->model->setQtyOptions($value);
$this->assertEquals($value, $this->model->getQtyOptions());
}
/**
* @return void
*/
public function testSetProduct(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->eventDispatcher->expects($this->once())
->method('dispatch')
->with('sales_quote_item_set_product', ['product' => $productMock, 'quote_item' => $this->model]);
$this->model->setProduct($productMock);
$this->assertEquals($productMock, $this->model->getProduct());
$this->assertEquals(self::PRODUCT_ID, $this->model->getProductId());
$this->assertEquals(self::PRODUCT_TYPE, $this->model->getData('product_type'));
$this->assertEquals(self::PRODUCT_SKU, $this->model->getSku());
$this->assertEquals(self::PRODUCT_NAME, $this->model->getName());
$this->assertEquals(self::PRODUCT_WEIGHT, $this->model->getWeight());
$this->assertEquals(self::PRODUCT_TAX_CLASS_ID, $this->model->getTaxClassId());
$this->assertEquals(self::PRODUCT_COST, $this->model->getBaseCost());
$this->assertNull($this->model->getIsQtyDecimal());
}
/**
* @return void
*/
public function testSetProductWithQuoteAndStockItem(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->eventDispatcher->expects($this->once())
->method('dispatch')
->with('sales_quote_item_set_product', ['product' => $productMock, 'quote_item' => $this->model]);
$isQtyDecimal = true;
$this->stockItemMock->expects($this->once())
->method('getIsQtyDecimal')
->willReturn($isQtyDecimal);
$storeId = 15;
$customerGroupId = 11;
$quoteMock = $this->getMockBuilder(Quote::class)
->disableOriginalConstructor()
->onlyMethods(['getStoreId', 'getCustomerGroupId', '__wakeup'])
->getMock();
$quoteMock->expects($this->any())
->method('getStoreId')
->willReturn($storeId);
$quoteMock->expects($this->once())
->method('getCustomerGroupId')
->willReturn($customerGroupId);
$this->model->setQuote($quoteMock);
$productMock->expects($this->once())
->method('setStoreId')
->with($storeId);
$productMock->expects($this->once())
->method('setCustomerGroupId')
->with($customerGroupId);
$this->model->setProduct($productMock);
$this->assertEquals($productMock, $this->model->getProduct());
$this->assertEquals(self::PRODUCT_ID, $this->model->getProductId());
$this->assertEquals(self::PRODUCT_TYPE, $this->model->getRealProductType());
$this->assertEquals(self::PRODUCT_SKU, $this->model->getSku());
$this->assertEquals(self::PRODUCT_NAME, $this->model->getName());
$this->assertEquals(self::PRODUCT_WEIGHT, $this->model->getWeight());
$this->assertEquals(self::PRODUCT_TAX_CLASS_ID, $this->model->getTaxClassId());
$this->assertEquals(self::PRODUCT_COST, $this->model->getBaseCost());
$this->assertEquals($isQtyDecimal, $this->model->getIsQtyDecimal());
}
/**
* Generate product mock.
*
* @param int $productId
* @param string $productType
* @param string $productSku
* @param string $productName
* @param string $productWeight
* @param int $productTaxClassId
* @param float $productCost
*
* @return MockObject
*/
private function generateProductMock(
int $productId,
string $productType,
string $productSku,
string $productName,
string $productWeight,
int $productTaxClassId,
float $productCost
): MockObject {
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(
[
'getId',
'getTypeId',
'getSku',
'getName',
'getWeight',
'setStoreId',
'getTypeInstance',
'getCustomOptions',
'getExtensionAttributes',
'toArray',
'__wakeup',
'getStore'
]
)
->addMethods(
[
'getTaxClassId',
'getCost',
'setCustomerGroupId',
'getStickWithinParent'
]
)
->getMock();
$productMock->expects($this->any())
->method('getId')
->willReturn($productId);
$productMock->expects($this->any())
->method('getTypeId')
->willReturn($productType);
$productMock->expects($this->any())
->method('getSku')
->willReturn($productSku);
$productMock->expects($this->any())
->method('getName')
->willReturn($productName);
$productMock->expects($this->any())
->method('getWeight')
->willReturn($productWeight);
$productMock->expects($this->any())
->method('getTaxClassId')
->willReturn($productTaxClassId);
$productMock->expects($this->any())
->method('getCost')
->willReturn($productCost);
$store = $this->createPartialMock(Store::class, ['getWebsiteId']);
$store->expects($this->any())
->method('getWebsiteId')
->willReturn(10);
$productMock->expects($this->any())
->method('getStore')
->willReturn($store);
$extensionAttribute = $this->getMockBuilder(ProductExtensionInterface::class)
->addMethods(['getStockItem'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$extensionAttribute->expects($this->atLeastOnce())
->method('getStockItem')
->willReturn($this->stockItemMock);
$productMock->expects($this->atLeastOnce())->method('getExtensionAttributes')->willReturn($extensionAttribute);
return $productMock;
}
/**
* @return void
*/
public function testRepresentProductNoProduct(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->model->setProduct($productMock);
$this->assertFalse($this->model->representProduct(null));
}
/**
* @return void
*/
public function testRepresentProductStickWithinParentNotSameAsParentItem(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$parentItemMock = $this->getMockBuilder(Item::class)
->onlyMethods(['addChild', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->model->setProduct($productMock);
$this->model->setParentItem($parentItemMock);
$productMock->expects($this->once())
->method('getStickWithinParent')
->willReturn(true);
$this->assertFalse($this->model->representProduct($productMock));
}
/**
* @return void
*/
public function testRepresentProductItemOptionsNotInProductOptions(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$parentItemMock = $this->getMockBuilder(Item::class)
->onlyMethods(['addChild', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->model->setProduct($productMock);
$this->model->setParentItem($parentItemMock);
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 7890;
$optionMock2 = $this->createOptionMock($optionCode2);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(7890);
$this->model->setOptions([$optionMock1, $optionMock2]);
$productMock->expects($this->once())
->method('getStickWithinParent')
->willReturn($parentItemMock);
$productMock->expects($this->once())
->method('getCustomOptions')
->willReturn([$optionCode1 => $optionMock1]);
$this->assertFalse($this->model->representProduct($productMock));
}
/**
* @return void
*/
public function testRepresentProductProductOptionsNotInItemOptions(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$parentItemMock = $this->getMockBuilder(Item::class)
->onlyMethods(['addChild', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->model->setProduct($productMock);
$this->model->setParentItem($parentItemMock);
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 7890;
$optionMock2 = $this->createOptionMock($optionCode2);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(7890);
$this->model->setOptions([$optionMock1]);
$productMock->expects($this->once())
->method('getStickWithinParent')
->willReturn($parentItemMock);
$productMock->expects($this->once())
->method('getCustomOptions')
->willReturn([$optionCode1 => $optionMock1, $optionCode2 => $optionMock2]);
$this->assertFalse($this->model->representProduct($productMock));
}
/**
* @return void
*/
public function testRepresentProductTrue(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$parentItemMock = $this->getMockBuilder(Item::class)
->onlyMethods(['addChild', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->model->setProduct($productMock);
$this->model->setParentItem($parentItemMock);
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 7890;
$optionMock2 = $this->createOptionMock($optionCode2);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(7890);
$this->model->setOptions([$optionMock1, $optionMock2]);
$productMock->expects($this->once())
->method('getStickWithinParent')
->willReturn($parentItemMock);
$productMock->expects($this->once())
->method('getCustomOptions')
->willReturn([$optionCode1 => $optionMock1, $optionCode2 => $optionMock2]);
$this->assertTrue($this->model->representProduct($productMock));
}
/**
* test compare
*
* @return void
*/
public function testCompare(): void
{
$itemMock = $this->createMock(Item::class);
$this->compareHelper->expects($this->once())
->method('compare')
->with($this->model, $itemMock)
->willReturn(true);
$this->assertTrue($this->model->compare($itemMock));
}
/**
* @return void
*/
public function testCompareOptionsEqual(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$this->assertTrue(
$this->model->compareOptions([$optionCode1 => $optionMock1], [$optionCode1 => $optionMock1])
);
}
/**
* @return void
*/
public function testCompareOptionsDifferentValues(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 1234;
$optionMock2 = $this->createOptionMock($optionCode1);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(7890);
$this->assertFalse(
$this->model->compareOptions([$optionCode1 => $optionMock1], [$optionCode2 => $optionMock2])
);
}
/**
* @return void
*/
public function testCompareOptionsNullValues(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 1234;
$optionMock2 = $this->createOptionMock($optionCode1);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(null);
$this->assertFalse(
$this->model->compareOptions([$optionCode1 => $optionMock1], [$optionCode2 => $optionMock2])
);
}
/**
* @return void
*/
public function testCompareOptionsMultipleEquals(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionMock1->expects($this->any())
->method('getValue')
->willReturn(1234);
$optionCode2 = 7890;
$optionMock2 = $this->createOptionMock($optionCode1);
$optionMock2->expects($this->any())
->method('getValue')
->willReturn(7890);
$this->assertFalse(
$this->model->compareOptions(
[$optionCode1 => $optionMock1, $optionCode2 => $optionMock2],
[$optionCode1 => $optionMock1, $optionCode2 => $optionMock2]
)
);
}
/**
* @return void
*/
public function testGetQtyOptions(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$optionMock1->expects($this->any())
->method('getProduct')
->willReturn($productMock);
$optionCode2 = 'product_qty_' . self::PRODUCT_ID;
$optionMock2 = $this->createOptionMock($optionCode2);
$productMock2 = $this->generateProductMock(
self::PRODUCT_ID + 1,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->model->setProduct($productMock);
$this->model->setProduct($productMock2);
$this->model->setOptions([$optionCode1 => $optionMock1, $optionCode2 => $optionMock2]);
$this->assertEquals([self::PRODUCT_ID => $optionMock2], $this->model->getQtyOptions());
}
/**
* @return void
*/
public function testToArray(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->model->setProduct($productMock);
$toArrayValue = ['a' => 'b'];
$productMock->expects($this->once())
->method('toArray')
->willReturn($toArrayValue);
$data = $this->model->toArray();
$this->assertEquals($toArrayValue, $data['product']);
}
/**
* @return void
*/
public function testGetProductTypeOption(): void
{
$optionProductType = 'product_type';
$optionProductTypeValue = 'abcd';
$optionMock = $this->createOptionMock($optionProductType);
$optionMock->expects($this->once())
->method('getValue')
->willReturn($optionProductTypeValue);
$this->model->addOption($optionMock);
$this->assertEquals($optionProductTypeValue, $this->model->getProductType());
}
/**
* @return void
*/
public function testGetProductTypeWithProduct(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$this->model->setProduct($productMock);
$this->assertEquals(self::PRODUCT_TYPE, $this->model->getProductType());
}
/**
* @return void
*/
public function testSetOptions(): void
{
$optionCode1 = 1234;
$optionMock1 = $this->createOptionMock($optionCode1);
$optionCode2 = 7890;
$optionMock2 = $this->createOptionMock($optionCode2);
$this->assertSame($this->model, $this->model->setOptions([$optionMock1, $optionMock2]));
$this->assertEquals([$optionMock1, $optionMock2], $this->model->getOptions());
$this->assertEquals($optionMock1, $this->model->getOptionByCode($optionCode1));
$this->assertEquals($optionMock2, $this->model->getOptionByCode($optionCode2));
}
/**
* @return void
*/
public function testSetOptionsWithNull(): void
{
$this->assertEquals($this->model, $this->model->setOptions(null));
}
/**
* @param mixed $optionCode
* @param array $optionData
*
* @return MockObject
*/
private function createOptionMock($optionCode, array $optionData = []): MockObject
{
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(
[
'setData',
'setItem',
'getItem',
'__wakeup',
'isDeleted',
'delete',
'getValue',
'getProduct',
'save'
]
)
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->any())
->method('setData')
->with($optionData)
->willReturn($optionMock);
$optionMock->expects($this->any())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->any())
->method('getCode')
->willReturn($optionCode);
return $optionMock;
}
/**
* @return void
*/
public function testAddOptionArray(): void
{
$optionCode = 1234;
$optionData = ['product' => 'test', 'code' => $optionCode];
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(['setData', 'setItem', '__wakeup', 'isDeleted'])
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->once())
->method('setData')
->with($optionData)
->willReturn($optionMock);
$optionMock->expects($this->once())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->exactly(3))
->method('getCode')
->willReturn($optionCode);
$this->itemOptionFactory
->method('create')
->willReturn($optionMock);
$this->model->addOption($optionData);
$this->assertEquals([$optionMock], $this->model->getOptions());
$this->assertEquals([$optionCode => $optionMock], $this->model->getOptionsByCode());
$this->assertEquals($optionMock, $this->model->getOptionByCode($optionCode));
}
/**
* @return void
*/
public function testUpdateQtyOption(): void
{
$productMock = $this->generateProductMock(
self::PRODUCT_ID,
self::PRODUCT_TYPE,
self::PRODUCT_SKU,
self::PRODUCT_NAME,
self::PRODUCT_WEIGHT,
self::PRODUCT_TAX_CLASS_ID,
self::PRODUCT_COST
);
$typeInstanceMock = $this->getMockForAbstractClass(
AbstractType::class,
[],
'',
false,
false,
true,
['updateQtyOption']
);
$productMock->expects($this->once())
->method('getTypeInstance')
->willReturn($typeInstanceMock);
$optionMock = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->addMethods(['getProduct'])
->getMock();
$optionMock->expects($this->once())
->method('getProduct')
->willReturn($productMock);
$quantityValue = 12;
$this->model->setProduct($productMock);
$typeInstanceMock->expects($this->once())
->method('updateQtyOption')
->with($this->model->getOptions(), $optionMock, $quantityValue, $productMock);
$this->assertEquals($this->model, $this->model->updateQtyOption($optionMock, $quantityValue));
}
/**
* @return void
*/
public function testRemoveOption(): void
{
$optionCode = 1234;
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(['setItem', '__wakeup', 'isDeleted'])
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->once())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->exactly(3))
->method('getCode')
->willReturn($optionCode);
$optionMock->method('isDeleted')
->willReturnOnConsecutiveCalls(false, true);
$this->model->addOption($optionMock);
$this->assertEquals($this->model, $this->model->removeOption($optionCode));
}
/**
* @return void
*/
public function testRemoveOptionNoOptionCodeExists(): void
{
$this->assertEquals($this->model, $this->model->removeOption('random'));
}
/**
* @return void
*/
public function testGetOptionByCodeNonExistent(): void
{
$this->assertNull($this->model->getOptionByCode('random'));
}
/**
* @return void
*/
public function testGetOptionByCodeDeletedCode(): void
{
$optionCode = 1234;
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(['setItem', '__wakeup', 'isDeleted'])
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->once())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->exactly(3))
->method('getCode')
->willReturn($optionCode);
$optionMock->expects($this->once())
->method('isDeleted')
->willReturn(true);
$this->model->addOption($optionMock);
$this->assertNull($this->model->getOptionByCode($optionCode));
}
/**
* @return void
*/
public function testGetOptionByCodeNotDeletedCode(): void
{
$optionCode = 1234;
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(['setItem', '__wakeup', 'isDeleted'])
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->once())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->exactly(3))
->method('getCode')
->willReturn($optionCode);
$optionMock->expects($this->once())
->method('isDeleted')
->willReturn(false);
$this->model->addOption($optionMock);
$this->assertSame($optionMock, $this->model->getOptionByCode($optionCode));
}
/**
* @return void
*/
public function testGetBuyRequestNoOptionByCode(): void
{
$quantity = 12;
$this->localeFormat
->method('getNumber')
->with($quantity)
->willReturn($quantity);
$this->model->setQty($quantity);
$this->assertEquals($quantity, $this->model->getQty());
$buyRequest = $this->model->getBuyRequest();
$this->assertEquals(0, $buyRequest->getOriginalQty());
$this->assertEquals($quantity, $buyRequest->getQty());
}
/**
* @return void
*/
public function testGetBuyRequestOptionByCode(): void
{
$optionCode = 'info_buyRequest';
$buyRequestQuantity = 23;
$optionMock = $this->getMockBuilder(Option::class)
->onlyMethods(['setItem', '__wakeup', 'getValue'])
->addMethods(['getCode'])
->disableOriginalConstructor()
->getMock();
$optionMock->expects($this->once())
->method('setItem')
->with($this->model)
->willReturn($optionMock);
$optionMock->expects($this->exactly(3))
->method('getCode')
->willReturn($optionCode);
$optionMock->expects($this->any())
->method('getValue')
->willReturn('{"qty":23}');
$this->model->addOption($optionMock);
$quantity = 12;
$this->localeFormat
->method('getNumber')
->with($quantity)
->willReturn($quantity);
$this->model->setQty($quantity);
$this->assertEquals($quantity, $this->model->getQty());
$this->serializer->expects($this->any())
->method('unserialize')
->willReturn(json_decode($optionMock->getValue(), true));
$buyRequest = $this->model->getBuyRequest();
$this->assertEquals($buyRequestQuantity, $buyRequest->getOriginalQty());
$this->assertEquals($quantity, $buyRequest->getQty());
}
/**
* @return void
*/
public function testSetHasErrorFalse(): void
{
$this->errorInfos->expects($this->once())
->method('clear');
$this->assertEquals($this->model, $this->model->setHasError(false));
$this->assertFalse($this->model->getHasError());
}
/**
* @return void
*/
public function testSetHasErrorTrue(): void
{
$this->errorInfos->expects($this->once())
->method('addItem')
->with(null, null, null, null);
$this->assertEquals($this->model, $this->model->setHasError(true));
$this->assertTrue($this->model->getHasError());
$this->assertEquals('', $this->model->getMessage());
}
/**
* @return void
*/
public function testAddErrorInfo(): void
{
$origin = 'origin';
$code = 1;
$message = 'message';
$additionalData = new DataObject();
$additionalData->setTemp(true);
$this->errorInfos->expects($this->once())
->method('addItem')
->with($origin, $code, $message, $additionalData);
$this->assertEquals($this->model, $this->model->addErrorInfo($origin, $code, $message, $additionalData));
$this->assertTrue($this->model->getHasError());
$this->assertEquals($message, $this->model->getMessage());
}
/**
* @return void
*/
public function testGetErrorInfos(): void
{
$retValue = 'return value';
$this->errorInfos->expects($this->once())
->method('getItems')
->willReturn($retValue);
$this->assertEquals($retValue, $this->model->getErrorInfos());
}
/**
* @return void
*/
public function testRemoveErrorInfosByParams(): void
{
$message = 'message';
$message2 = 'message2';
$this->errorInfos->method('addItem')
->withConsecutive(
[null, null, $message],
[null, null, $message2]
);
$this->assertEquals($this->model, $this->model->addErrorInfo(null, null, $message));
$this->assertEquals($this->model, $this->model->addErrorInfo(null, null, $message2));
$this->assertEquals($message . "\n" . $message2, $this->model->getMessage());
$params = [];
$removedItems = [['message' => $message]];
$this->errorInfos->expects($this->once())
->method('removeItemsByParams')
->with($params)
->willReturn($removedItems);
$this->errorInfos->expects($this->once())
->method('getItems')
->willReturn(true);
$this->assertEquals($this->model, $this->model->removeErrorInfosByParams($params));
$this->assertEquals($message2, $this->model->getMessage());
}
/**
* @return void
*/
public function testRemoveErrorInfosByParamsAllErrorsRemoved(): void
{
$message = 'message';
$message2 = 'message2';
$this->errorInfos->method('addItem')
->withConsecutive(
[null, null, $message],
[null, null, $message2]
);
$this->assertEquals($this->model, $this->model->addErrorInfo(null, null, $message));
$this->assertEquals($this->model, $this->model->addErrorInfo(null, null, $message2));
$this->assertEquals($message . "\n" . $message2, $this->model->getMessage());
$params = [];
$removedItems = [['message' => $message], ['message' => $message2]];
$this->errorInfos->expects($this->once())
->method('removeItemsByParams')
->with($params)
->willReturn($removedItems);
$this->errorInfos->expects($this->once())
->method('getItems')
->willReturn([]);
$this->assertEquals($this->model, $this->model->removeErrorInfosByParams($params));
$this->assertFalse($this->model->getHasError());
$this->assertEquals('', $this->model->getMessage());
}
/**
* Test method \Magento\Quote\Model\Quote\Item::saveItemOptions
*
* @return void
*/
public function testSaveItemOptions(): void
{
$optionMockDeleted = $this->createOptionMock(100);
$optionMockDeleted->expects(self::once())->method('isDeleted')->willReturn(true);
$optionMockDeleted->expects(self::once())->method('delete');
$optionMock1 = $this->createOptionMock(200);
$optionMock1->expects(self::once())->method('isDeleted')->willReturn(false);
$quoteItemMock1 = $this->createPartialMock(Item::class, ['getId']);
$quoteItemMock1->expects(self::once())->method('getId')->willReturn(null);
$optionMock1->expects(self::exactly(2))->method('getItem')->willReturn($quoteItemMock1);
$optionMock1->expects(self::exactly(2))->method('setItem')->with($this->model);
$optionMock1->expects(self::once())->method('save');
$optionMock2 = $this->createOptionMock(300);
$optionMock2->expects(self::once())->method('isDeleted')->willReturn(false);
$quoteItemMock2 = $this->createPartialMock(Item::class, ['getId']);
$quoteItemMock2->expects(self::once())->method('getId')->willReturn(11);
$optionMock2->expects(self::exactly(2))->method('getItem')->willReturn($quoteItemMock2);
$optionMock2->expects(self::once())->method('setItem')->with($this->model);
$optionMock2->expects(self::once())->method('save');
$this->model->setOptions([$optionMockDeleted, $optionMock1, $optionMock2]);
$this->model->saveItemOptions();
}
}