![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/cartforge.co/vendor/magento/module-quote/Test/Unit/Model/Quote/ |
<?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(); } }