Find this useful? Enter your email to receive occasional updates for securing PHP code.
Signing you up...
Thank you for signing up!
PHP Decode
<?php /** * Copyright Magento, Inc. All rights reserved. * See COPYING.txt for license ..
Decoded Output download
<?php
/**
* Copyright Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Bundle\Test\Unit\Model\Product;
use Magento\Bundle\Model\OptionFactory;
use Magento\Bundle\Model\Product\Type;
use Magento\Bundle\Model\ResourceModel\BundleFactory;
use Magento\Bundle\Model\ResourceModel\Option\Collection;
use Magento\Bundle\Model\ResourceModel\Selection\Collection as SelectionCollection;
use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory;
use Magento\Bundle\Model\Selection;
use Magento\Bundle\Model\SelectionFactory;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Helper\Data;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Option;
use Magento\Catalog\Model\Product\Option\Type\DefaultType;
use Magento\Catalog\Model\Product\Type\Price;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Api\StockStateInterface;
use Magento\CatalogInventory\Model\StockRegistry;
use Magento\CatalogInventory\Model\StockState;
use Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor;
use Magento\Framework\DataObject;
use Magento\Framework\EntityManager\EntityMetadataInterface;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Stdlib\ArrayUtils;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* Test for bundle product type
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TypeTest extends TestCase
{
/**
* @var BundleFactory|MockObject
*/
private $bundleFactory;
/**
* @var SelectionFactory|MockObject
*/
private $bundleModelSelection;
/**
* @var Type
*/
protected $model;
/**
* @var CollectionFactory|MockObject
*/
protected $bundleCollectionFactory;
/**
* @var \Magento\Catalog\Helper\Data|MockObject
*/
protected $catalogData;
/**
* @var StoreManagerInterface|MockObject
*/
protected $storeManager;
/**
* @var OptionFactory|MockObject
*/
protected $bundleOptionFactory;
/**
* @var StockRegistryInterface|MockObject
*/
protected $stockRegistry;
/**
* @var StockStateInterface|MockObject
*/
protected $stockState;
/**
* @var \Magento\Catalog\Helper\Product|MockObject
*/
private $catalogProduct;
/**
* @var PriceCurrencyInterface|MockObject
*/
private $priceCurrency;
/**
* @var MetadataPool|MockObject
*/
private $metadataPool;
/**
* @var Json
*/
private $serializer;
/**
* @var ArrayUtils|MockObject
*/
private $arrayUtility;
/**
* @var CollectionProcessor|MockObject
*/
private $catalogRuleProcessor;
/**
* @inheritDoc
*/
protected function setUp(): void
{
$this->bundleCollectionFactory =
$this->getMockBuilder(CollectionFactory::class)
->onlyMethods(['create'])
->addMethods(
[
'addFilterByRequiredOptions',
'addAttributeToSelect',
'getItemById',
'setOptionIdsFilter',
'setFlag',
'setPositionOrder',
'addStoreFilter',
'setStoreId'
]
)
->disableOriginalConstructor()
->getMock();
$this->catalogData = $this->getMockBuilder(Data::class)
->disableOriginalConstructor()
->getMock();
$this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->bundleOptionFactory = $this->getMockBuilder(OptionFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->stockRegistry = $this->getMockBuilder(StockRegistry::class)
->onlyMethods(['getStockItem'])
->disableOriginalConstructor()
->getMock();
$this->stockState = $this->getMockBuilder(StockState::class)
->onlyMethods(['getStockQty'])
->disableOriginalConstructor()
->getMock();
$this->catalogProduct = $this->getMockBuilder(\Magento\Catalog\Helper\Product::class)
->onlyMethods(['getSkipSaleableCheck'])
->disableOriginalConstructor()
->getMock();
$this->priceCurrency = $this->getMockBuilder(PriceCurrencyInterface::class)
->onlyMethods(['convert'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->bundleModelSelection = $this->getMockBuilder(SelectionFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->bundleFactory = $this->getMockBuilder(BundleFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->serializer = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->onlyMethods([])
->getMock();
$this->metadataPool = $this->getMockBuilder(MetadataPool::class)
->disableOriginalConstructor()
->getMock();
$this->arrayUtility = $this->getMockBuilder(ArrayUtils::class)
->onlyMethods(['flatten'])
->disableOriginalConstructor()
->getMock();
$this->catalogRuleProcessor = $this->getMockBuilder(CollectionProcessor::class)
->disableOriginalConstructor()
->getMock();
$objectHelper = new ObjectManager($this);
$this->model = $objectHelper->getObject(
Type::class,
[
'bundleModelSelection' => $this->bundleModelSelection,
'bundleFactory' => $this->bundleFactory,
'bundleCollection' => $this->bundleCollectionFactory,
'bundleOption' => $this->bundleOptionFactory,
'catalogData' => $this->catalogData,
'storeManager' => $this->storeManager,
'stockRegistry' => $this->stockRegistry,
'stockState' => $this->stockState,
'catalogProduct' => $this->catalogProduct,
'priceCurrency' => $this->priceCurrency,
'serializer' => $this->serializer,
'metadataPool' => $this->metadataPool,
'arrayUtility' => $this->arrayUtility
]
);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithoutOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'getOptionsCollection', 'getOptionsIds', 'getSelectionsCollection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->any())
->method('getTypeInstance')
->willReturn($productType);
$optionCollection->expects($this->any())
->method('appendSelections')
->with($selectionCollection, true, true)
->willReturn([$option]);
$productType->expects($this->once())
->method('setStoreFilter');
$productType->expects($this->once())
->method('getOptionsCollection')
->willReturn($optionCollection);
$productType->expects($this->once())
->method('getOptionsIds')
->willReturn([1, 2, 3]);
$productType->expects($this->once())
->method('getSelectionsCollection')
->willReturn($selectionCollection);
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn('options');
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithShoppingCart(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->addMethods(['setParentProductId', 'addCustomOption', 'setCartQty', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$bundleOptions = [3 => 5];
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn([$productType]);
$productType->expects($this->once())
->method('setParentProductId')
->willReturnSelf();
$productType->expects($this->any())
->method('addCustomOption')
->willReturnSelf();
$productType->expects($this->once())
->method('setCartQty')
->willReturnSelf();
$productType->expects($this->once())
->method('getSelectionId')
->willReturn(314);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals([$product, $productType], $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedEmptyShoppingCart(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$bundleOptions = [3 => 5];
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn([]);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('We can\'t add this item to your shopping cart right now.', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedStringInResult(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn('string');
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('string', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithoutSelections(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
}
return $resultValue;
}
);
$product->expects($this->once())
->method('getId')
->willReturn(333);
$productType->expects($this->once())
->method('setStoreFilter');
$option
->method('getId')
->willReturnOnConsecutiveCalls(333);
$bundleOptions = [];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product, 'single');
$this->assertEquals([$product], $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedSelectionsSelectionIdsExists(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(['__wakeup', 'isSalable', 'getOptionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection
->method('getItems')
->willReturnOnConsecutiveCalls([$selection], []);
$selectionCollection
->method('getSize')
->willReturnOnConsecutiveCalls(1, 0);
$option->expects($this->any())
->method('getId')
->willReturn(3);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedSelectRequiredOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(['__wakeup', 'isSalable', 'getOptionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [0 => 5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('The required options you selected are not available.', $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedParentClassReturnString(): void
{
$exceptedResult = 'String message';
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->addMethods(['getItems', '__wakeup'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(['getOptions'])
->addMethods(['getHasOptions'])
->disableOriginalConstructor()
->getMock();
$product->expects($this->any())
->method('getOptions')
->willThrowException(new LocalizedException(__($exceptedResult)));
$product->expects($this->once())
->method('getHasOptions')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals($exceptedResult, $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedAllRequiredOption(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(false);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [0 => 5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('getItems')
->willReturn([$option]);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn([3 => 5]);
$option->method('getId')
->willReturnOnConsecutiveCalls(3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please select all required options.', $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedSpecifyProductOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(['getOptions', 'prepareCustomOptions', 'addCustomOption', 'setQty'])
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
$buyRequest->method('getOptions')
->willReturn([333 => ['type' => 'image/jpeg']]);
$option->method('getId')
->willReturn(333);
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn([0, '', 'str']);
$group->expects($this->once())
->method('validateUserValue');
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
*/
public function testHasWeightTrue(): void
{
$this->assertTrue($this->model->hasWeight(), 'This product has no weight, but it should');
}
/**
* @return void
*/
public function testGetIdentities(): void
{
$identities = ['id1', 'id2'];
$productMock = $this->createMock(Product::class);
$optionMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)->addMethods(['getSelections'])
->onlyMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$optionCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class);
$cacheKey = '_cache_instance_options_collection';
$productMock->expects($this->once())
->method('getIdentities')
->willReturn($identities);
$productMock->expects($this->once())
->method('hasData')
->with($cacheKey)
->willReturn(true);
$productMock->expects($this->once())
->method('getData')
->with($cacheKey)
->willReturn($optionCollectionMock);
$optionCollectionMock
->expects($this->once())
->method('getItems')
->willReturn([$optionMock]);
$optionMock
->expects($this->exactly(2))
->method('getSelections')
->willReturn([$productMock]);
$this->assertEquals($identities, $this->model->getIdentities($productMock));
}
/**
* @return void
*/
public function testGetSkuWithType(): void
{
$sku = 'sku';
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['sku'] => $sku,
['sku_type'] => 'some_data'
});
$this->assertEquals($sku, $this->model->getSku($productMock));
}
/**
* @return void
*/
public function testGetSkuWithoutType(): void
{
$sku = 'sku';
$itemSku = 'item';
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSku', 'getEntityId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$productMock
->method('getCustomOption')
->willReturnCallback(fn($param) => match ([$param]) {
['option_ids'] => false,
['bundle_selection_ids'] => $customOptionMock
});
$customOptionMock->expects($this->any())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['sku'] => $sku,
['sku_type'] => null,
['_cache_instance_used_selections'] => $selectionMock,
['_cache_instance_used_selections_ids'] => $selectionIds
});
$selectionMock->expects(($this->any()))
->method('getItemByColumnValue')
->willReturn($selectionItemMock);
$selectionItemMock
->method('getEntityId')
->willReturnOnConsecutiveCalls(1);
$selectionItemMock->expects($this->once())
->method('getSku')
->willReturn($itemSku);
$this->assertEquals($sku . '-' . $itemSku, $this->model->getSku($productMock));
}
/**
* @return void
*/
public function testGetWeightWithoutCustomOption(): void
{
$weight = 5;
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData'])
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['weight_type'] => true,
['weight'] => $weight
});
$this->assertEquals($weight, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testGetWeightWithCustomOption(): void
{
$weight = 5;
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSelectionId', 'getWeight', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['weight_type'] => false,
['_cache_instance_used_selections'] => $selectionMock,
['_cache_instance_used_selections_ids'] => $selectionIds
});
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->any())
->method('getSelectionId')
->willReturn('id');
$productMock
->method('getCustomOption')
->willReturnCallback(fn($param) => match ([$param]) {
['bundle_selection_ids'] => $customOptionMock,
['selection_qty_' . 'id'] => null
});
$selectionItemMock->expects($this->once())
->method('getWeight')
->willReturn($weight);
$this->assertEquals($weight, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testGetWeightWithSeveralCustomOption(): void
{
$weight = 5;
$qtyOption = 5;
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$qtyOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSelectionId', 'getWeight', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($selectionMock, $selectionIds) {
if ($arg === 'weight_type') {
return false;
} elseif ($arg === '_cache_instance_used_selections') {
return $selectionMock;
} elseif ($arg === '_cache_instance_used_selections_ids') {
return $selectionIds;
}
}
);
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->any())
->method('getSelectionId')
->willReturn('id');
$productMock
->method('getCustomOption')
->willReturnCallback(
function ($arg) use ($customOptionMock, $qtyOptionMock) {
if ($arg === 'bundle_selection_ids') {
return $customOptionMock;
} elseif ($arg === 'selection_qty_id') {
return $qtyOptionMock;
}
}
);
$qtyOptionMock->expects($this->once())
->method('getValue')
->willReturn($qtyOption);
$selectionItemMock->expects($this->once())
->method('getWeight')
->willReturn($weight);
$this->assertEquals($weight * $qtyOption, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testIsVirtualWithoutCustomOption(): void
{
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(false);
$this->assertFalse($this->model->isVirtual($productMock));
}
/**
* @return void
*/
public function testIsVirtual(): void
{
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['isVirtual', 'getItems', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$productMock->expects($this->once())
->method('getCustomOption')
->with('bundle_selection_ids')
->willReturn($customOptionMock);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($selectionMock, $selectionIds) {
if ($arg === '_cache_instance_used_selections') {
return $selectionMock;
} elseif ($arg === '_cache_instance_used_selections_ids') {
return $selectionIds;
}
}
);
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->once())
->method('isVirtual')
->willReturn(true);
$selectionItemMock->expects($this->once())
->method('isVirtual')
->willReturn(true);
$selectionMock->expects($this->once())
->method('count')
->willReturn(1);
$isVirtual = (bool)$this->model->isVirtual($productMock);
$this->assertTrue($isVirtual);
}
/**
* @param int $expected
* @param int $firstId
* @param int $secondId
*
* @return void
* @dataProvider shakeSelectionsDataProvider
*/
public function testShakeSelections($expected, $firstId, $secondId): void
{
$firstItemMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup'])
->addMethods(['getOption', 'getOptionId', 'getPosition', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
$secondItemMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup'])
->addMethods(['getOption', 'getOptionId', 'getPosition', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
$optionFirstMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->onlyMethods(['getPosition', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$optionSecondMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->onlyMethods(['getPosition', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$firstItemMock->expects($this->once())
->method('getOption')
->willReturn($optionFirstMock);
$optionFirstMock->expects($this->once())
->method('getPosition')
->willReturn('option_position');
$firstItemMock->expects($this->once())
->method('getOptionId')
->willReturn('option_id');
$firstItemMock->expects($this->once())
->method('getPosition')
->willReturn('position');
$firstItemMock->expects($this->once())
->method('getSelectionId')
->willReturn($firstId);
$secondItemMock->expects($this->once())
->method('getOption')
->willReturn($optionSecondMock);
$optionSecondMock->expects($this->any())
->method('getPosition')
->willReturn('option_position');
$secondItemMock->expects($this->once())
->method('getOptionId')
->willReturn('option_id');
$secondItemMock->expects($this->once())
->method('getPosition')
->willReturn('position');
$secondItemMock->expects($this->once())
->method('getSelectionId')
->willReturn($secondId);
$this->assertEquals($expected, $this->model->shakeSelections($firstItemMock, $secondItemMock));
}
/**
* @return array
*/
public static function shakeSelectionsDataProvider(): array
{
return [
[0, 0, 0],
[1, 1, 0],
[-1, 0, 1]
];
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testGetSelectionsByIds(): void
{
$selectionIds = [1, 2, 3];
$usedSelectionsIds = [4, 5, 6];
$storeId = 2;
$websiteId = 1;
$storeFilter = 'store_filter';
$this->expectProductEntityMetadata();
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$usedSelectionsMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(
[
'addAttributeToSelect',
'setFlag',
'addStoreFilter',
'setStoreId',
'setPositionOrder',
'addFilterByRequiredOptions',
'setSelectionIdsFilter',
'joinPrices'
]
)
->disableOriginalConstructor()
->getMock();
$productGetMap = [
['_cache_instance_used_selections', null, null],
['_cache_instance_used_selections_ids', null, $usedSelectionsIds],
['_cache_instance_store_filter', null, $storeFilter],
];
$productMock->expects($this->any())
->method('getData')
->willReturnMap($productGetMap);
$productSetMap = [
['_cache_instance_used_selections', $usedSelectionsMock, $productMock],
['_cache_instance_used_selections_ids', $selectionIds, $productMock],
];
$productMock->expects($this->any())
->method('setData')
->willReturnMap($productSetMap);
$productMock->expects($this->once())
->method('getStoreId')
->willReturn($storeId);
$storeMock = $this->getMockBuilder(Store::class)
->onlyMethods(['getWebsiteId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->storeManager->expects($this->once())
->method('getStore')
->with($storeId)
->willReturn($storeMock);
$storeMock->expects($this->once())
->method('getWebsiteId')
->willReturn($websiteId);
$this->bundleCollectionFactory->expects($this->once())
->method('create')
->willReturn($usedSelectionsMock);
$usedSelectionsMock->expects($this->once())
->method('addAttributeToSelect')
->with('*')
->willReturnSelf();
$flagMap = [
['product_children', true, $usedSelectionsMock],
];
$usedSelectionsMock->expects($this->any())
->method('setFlag')
->willReturnMap($flagMap);
$usedSelectionsMock->expects($this->once())
->method('addStoreFilter')
->with($storeFilter)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setStoreId')
->with($storeId)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setPositionOrder')
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('addFilterByRequiredOptions')
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setSelectionIdsFilter')
->with($selectionIds)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('joinPrices')
->with($websiteId)
->willReturnSelf();
$this->catalogData->expects($this->once())
->method('isPriceGlobal')
->willReturn(false);
$this->model->getSelectionsByIds($selectionIds, $productMock);
}
/**
* @return void
*/
public function testGetOptionsByIds(): void
{
$optionsIds = [1, 2, 3];
$usedOptionsIds = [4, 5, 6];
$productId = 3;
$storeId = 2;
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$usedOptionsMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->addMethods(['getResourceCollection'])
->disableOriginalConstructor()
->getMock();
$resourceClassName = AbstractCollection::class;
$dbResourceMock = $this->getMockBuilder($resourceClassName)
->addMethods(['setProductIdFilter', 'setPositionOrder', 'joinValues', 'setIdFilter'])
->disableOriginalConstructor()
->getMock();
$storeMock = $this->getMockBuilder(Store::class)
->onlyMethods(['getId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('getId')
->willReturn($productId);
$this->bundleOptionFactory->expects($this->once())
->method('create')
->willReturn($usedOptionsMock);
$usedOptionsMock->expects($this->once())
->method('getResourceCollection')
->willReturn($dbResourceMock);
$dbResourceMock->expects($this->once())
->method('setProductIdFilter')
->with($productId)
->willReturnSelf();
$dbResourceMock->expects($this->once())
->method('setPositionOrder')
->willReturnSelf();
$this->storeManager->expects($this->once())
->method('getStore')
->willReturn($storeMock);
$storeMock->expects($this->once())
->method('getId')
->willReturn($storeId);
$dbResourceMock->expects($this->once())
->method('joinValues')
->willReturnSelf();
$dbResourceMock->expects($this->once())
->method('setIdFilter')
->with($optionsIds)
->willReturnSelf();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($usedOptionsIds) {
if ($arg === '_cache_instance_used_options') {
return null;
} elseif ($arg === '_cache_instance_used_options_ids') {
return $usedOptionsIds;
}
}
);
$productMock
->method('setData')
->willReturnCallback(
function ($arg1, $arg2) use ($dbResourceMock, $optionsIds, $productMock) {
if ($arg1 === '_cache_instance_used_options' && $arg2 === $dbResourceMock) {
return $productMock;
} elseif ($arg1 === '_cache_instance_used_options_ids' && $arg2 === $optionsIds) {
return $productMock;
}
}
);
$this->model->getOptionsByIds($optionsIds, $productMock);
}
/**
* @return void
*/
public function testIsSalableFalse(): void
{
$product = new DataObject(
[
'is_salable' => false,
'status' => Status::STATUS_ENABLED
]
);
$this->assertFalse($this->model->isSalable($product));
}
/**
* @return void
*/
public function testIsSalableCache(): void
{
$product = new DataObject(
[
'is_salable' => true,
'status' => Status::STATUS_ENABLED,
'all_items_salable' => true
]
);
$this->assertTrue($this->model->isSalable($product));
}
/**
* @param array $selectedOptions
*
* @return MockObject
*/
private function getSelectionCollectionMock(array $selectedOptions): MockObject
{
$selectionCollectionMock = $this->getMockBuilder(
\Magento\Bundle\Model\ResourceModel\Selection\Collection::class
)->disableOriginalConstructor()
->getMock();
$selectionCollectionMock
->expects($this->any())
->method('getIterator')
->willReturn(new \ArrayIterator($selectedOptions));
return $selectionCollectionMock;
}
/**
* @param bool $isManageStock
*
* @return StockItemInterface|MockObject
*/
protected function getStockItem(bool $isManageStock): MockObject
{
$result = $this->getMockBuilder(StockItemInterface::class)
->getMock();
$result->method('getManageStock')
->willReturn($isManageStock);
return $result;
}
/**
* @param MockObject|DefaultType $group
* @param MockObject|Option $option
* @param MockObject|DataObject $buyRequest
* @param MockObject|Product $product
*
* @return void
*/
protected function parentClass($group, $option, $buyRequest, $product): void
{
$group->expects($this->once())
->method('setOption')
->willReturnSelf();
$group->expects($this->once())
->method('setProduct')
->willReturnSelf();
$group->expects($this->once())
->method('setRequest')
->willReturnSelf();
$group->expects($this->once())
->method('setProcessMode')
->willReturnSelf();
$group->expects($this->once())
->method('prepareForCart')
->willReturn('someString');
$option->expects($this->once())
->method('getType');
$option->expects($this->once())
->method('groupFactory')
->willReturn($group);
$buyRequest->expects($this->once())
->method('getData');
$buyRequest->expects($this->once())
->method('getOptions');
$buyRequest->expects($this->once())
->method('getSuperProductConfig')
->willReturn([]);
$buyRequest->expects($this->any())
->method('unsetData')
->willReturnSelf();
$buyRequest->expects($this->any())
->method('getQty');
$product->expects($this->once())
->method('getOptions')
->willReturn([$option]);
$product->expects($this->once())
->method('getHasOptions')
->willReturn(true);
$product->expects($this->once())
->method('prepareCustomOptions');
$product->expects($this->any())
->method('addCustomOption')
->willReturnSelf();
$product->expects($this->any())
->method('setCartQty')
->willReturnSelf();
$product->expects($this->once())
->method('setQty');
$this->catalogProduct->expects($this->once())
->method('getSkipSaleableCheck')
->willReturn(false);
}
/**
* @return void
*/
public function testGetSelectionsCollection(): void
{
$optionIds = [1, 2, 3];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getStoreId', 'getData', 'hasData', 'setData', 'getId'])
->addMethods(['_wakeup'])
->getMock();
$this->expectProductEntityMetadata();
$store = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->onlyMethods(['getWebsiteId'])
->getMock();
$product->expects($this->once())->method('getStoreId')->willReturn('store_id');
$selectionCollection = $this->getSelectionCollection();
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$this->storeManager->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn('website_id');
$selectionCollection->expects($this->any())->method('joinPrices')->with('website_id')->willReturnSelf();
$this->assertEquals($selectionCollection, $this->model->getSelectionsCollection($optionIds, $product));
}
/**
* @return MockObject
*/
private function getSelectionCollection(): MockObject
{
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$selectionCollection->expects($this->any())->method('addAttributeToSelect')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setFlag')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setPositionOrder')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addStoreFilter')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setStoreId')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addFilterByRequiredOptions')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setOptionIdsFilter')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addPriceData')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addTierPriceData')->willReturnSelf();
return $selectionCollection;
}
/**
* @return void
*/
public function testProcessBuyRequest(): void
{
$result = ['bundle_option' => [], 'bundle_option_qty' => []];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$buyRequest = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->addMethods(['getBundleOption', 'getBundleOptionQty'])
->getMock();
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn('bundleOption');
$buyRequest->expects($this->once())->method('getBundleOptionQty')->willReturn('optionId');
$this->assertEquals($result, $this->model->processBuyRequest($product, $buyRequest));
}
/**
* @return void
*/
public function testGetProductsToPurchaseByReqGroups(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$this->expectProductEntityMetadata();
$resourceClassName = AbstractCollection::class;
$dbResourceMock = $this->getMockBuilder($resourceClassName)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
$item = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->addMethods(['getId', 'getRequired'])
->getMock();
$selectionCollection = $this->getSelectionCollection();
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$selectionItem = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->getMock();
$product->expects($this->any())->method('hasData')->willReturn(true);
$product
->method('getData')
->willReturnCallback(
function ($arg) use ($dbResourceMock) {
if ($arg === '_cache_instance_options_collection') {
return $dbResourceMock;
}
}
);
$dbResourceMock->expects($this->once())->method('getItems')->willReturn([$item]);
$item->expects($this->once())->method('getId')->willReturn('itemId');
$item->expects($this->once())->method('getRequired')->willReturn(true);
$selectionCollection
->expects($this->any())
->method('getIterator')
->willReturn(new \ArrayIterator([$selectionItem]));
$this->assertEquals([[$selectionItem]], $this->model->getProductsToPurchaseByReqGroups($product));
}
/**
* @return void
*/
public function testGetSearchableData(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getId', 'getStoreId'])
->addMethods(['_wakeup', 'getHasOptions'])
->getMock();
$option = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->disableOriginalConstructor()
->onlyMethods(['getSearchableData'])
->getMock();
$product->expects($this->once())->method('getHasOptions')->willReturn(false);
$product->expects($this->once())->method('getId')->willReturn('productId');
$product->expects($this->once())->method('getStoreId')->willReturn('storeId');
$this->bundleOptionFactory->expects($this->once())->method('create')->willReturn($option);
$option->expects($this->once())->method('getSearchableData')->willReturn(['optionSearchdata']);
$this->assertEquals(['optionSearchdata'], $this->model->getSearchableData($product));
}
/**
* @return void
*/
public function testHasOptions(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['hasData', 'getData', 'setData', 'getId', 'getStoreId'])
->addMethods(['_wakeup'])
->getMock();
$this->expectProductEntityMetadata();
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->disableOriginalConstructor()
->onlyMethods(['getAllIds'])
->getMock();
$selectionCollection = $this->getSelectionCollection();
$selectionCollection
->expects($this->any())
->method('getSize')
->willReturn(1);
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$product->expects($this->any())->method('getStoreId')->willReturn(0);
$product->expects($this->once())
->method('setData')
->with('_cache_instance_store_filter', 0)
->willReturnSelf();
$product->expects($this->any())->method('hasData')->willReturn(true);
$product
->method('getData')
->willReturnCallback(
function ($arg) use ($optionCollection) {
if ($arg === '_cache_instance_options_collection') {
return $optionCollection;
}
}
);
$optionCollection->expects($this->once())->method('getAllIds')->willReturn(['ids']);
$this->assertTrue($this->model->hasOptions($product));
}
/**
* Bundle product without options should not be possible to buy.
*
* @return void
*/
public function testCheckProductBuyStateEmptyOptionsException(): void
{
$this->expectException(LocalizedException::class);
$this->expectExceptionMessage('Please specify product option');
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => '[]'])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => ''])])]
]);
$product->setCustomOption(json_encode([]));
$this->model->checkProductBuyState($product);
}
/**
* Previously selected options are not more available for buying.
*
* @param object $element
* @param string $expectedMessage
* @param bool $check
*
* @return void
* @throws LocalizedException
* @dataProvider notAvailableOptionProvider
*/
public function testCheckProductBuyStateMissedOptionException($element, $expectedMessage, $check): void
{
$this->expectException(LocalizedException::class);
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => json_encode([1])])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => [1]])])],
]);
$product->setCustomOption(json_encode([]));
$this->bundleCollectionFactory->method('getItemById')->willReturn($element);
$this->catalogProduct->setSkipSaleableCheck($check);
try {
$this->model->checkProductBuyState($product);
} catch (LocalizedException $e) {
$this->assertStringContainsString(
$expectedMessage,
$e->getMessage()
);
throw $e;
}
}
/**
* In case of missed selection for required options, bundle product should be not able to buy.
*
* @return void
*/
public function testCheckProductBuyStateRequiredOptionException(): void
{
$this->expectException(LocalizedException::class);
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => json_encode([])])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => [1]])])],
]);
$product->setCustomOption(json_encode([]));
$falseSelection = $this->getMockBuilder(Selection::class)->disableOriginalConstructor()
->addMethods(['isSalable'])
->getMock();
$falseSelection->method('isSalable')->willReturn(false);
$this->bundleCollectionFactory->method('getItemById')->willReturn($falseSelection);
$this->catalogProduct->setSkipSaleableCheck(false);
try {
$this->model->checkProductBuyState($product);
} catch (LocalizedException $e) {
$this->assertStringContainsString(
'Please select all required options',
$e->getMessage()
);
throw $e;
}
}
/**
* Prepare product mock for testing.
*
* @return MockObject
*/
public function getProductMock(): MockObject
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getId', 'getStoreId', 'getCustomOption', 'getTypeInstance'])
->addMethods(['_wakeup', 'getHasOptions', 'setStoreFilter', 'setCustomOption'])
->getMock();
$product->method('getTypeInstance')->willReturn($product);
$product->method('setStoreFilter')->willReturn($product);
$optionCollectionCache = new DataObject();
$optionCollectionCache->setAllIds([]);
$optionCollectionCache->setItems([
new DataObject([
'required' => true,
'id' => 1
]),
]);
$product->setData('_cache_instance_options_collection', $optionCollectionCache);
return $product;
}
/**
* Preparation mocks for checkProductsBuyState.
*
* @return void
*/
public function mockBundleCollection(): void
{
$selectionCollectionMock = $this->getSelectionCollectionMock([]);
$this->bundleCollectionFactory->expects($this->once())
->method('create')
->willReturn($selectionCollectionMock);
$this->bundleCollectionFactory->method('create')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addAttributeToSelect')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setFlag')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setPositionOrder')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addStoreFilter')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setStoreId')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addFilterByRequiredOptions')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setOptionIdsFilter')->willReturn($selectionCollectionMock);
}
/**
* Data provider for not available option.
*
* @return array
*/
public function notAvailableOptionProvider(): array
{
$falseSelection = $this->getMockBuilder(Selection::class)->disableOriginalConstructor()
->addMethods(['isSalable'])
->getMock();
$falseSelection->method('isSalable')->willReturn(false);
return [
[
false,
'The required options you selected are not available',
false
],
[
$falseSelection,
'The required options you selected are not available',
false
]
];
}
/**
* @return void
*/
private function expectProductEntityMetadata(): void
{
$entityMetadataMock = $this->getMockBuilder(EntityMetadataInterface::class)
->onlyMethods(['getLinkField'])
->getMockForAbstractClass();
$entityMetadataMock->method('getLinkField')->willReturn('test_link_field');
$this->metadataPool->expects($this->any())->method('getMetadata')
->with(ProductInterface::class)
->willReturn($entityMetadataMock);
}
}
?>
Did this file decode correctly?
Original Code
<?php
/**
* Copyright Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Bundle\Test\Unit\Model\Product;
use Magento\Bundle\Model\OptionFactory;
use Magento\Bundle\Model\Product\Type;
use Magento\Bundle\Model\ResourceModel\BundleFactory;
use Magento\Bundle\Model\ResourceModel\Option\Collection;
use Magento\Bundle\Model\ResourceModel\Selection\Collection as SelectionCollection;
use Magento\Bundle\Model\ResourceModel\Selection\CollectionFactory;
use Magento\Bundle\Model\Selection;
use Magento\Bundle\Model\SelectionFactory;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Helper\Data;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Option;
use Magento\Catalog\Model\Product\Option\Type\DefaultType;
use Magento\Catalog\Model\Product\Type\Price;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\CatalogInventory\Api\StockStateInterface;
use Magento\CatalogInventory\Model\StockRegistry;
use Magento\CatalogInventory\Model\StockState;
use Magento\CatalogRule\Model\ResourceModel\Product\CollectionProcessor;
use Magento\Framework\DataObject;
use Magento\Framework\EntityManager\EntityMetadataInterface;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Stdlib\ArrayUtils;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* Test for bundle product type
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TypeTest extends TestCase
{
/**
* @var BundleFactory|MockObject
*/
private $bundleFactory;
/**
* @var SelectionFactory|MockObject
*/
private $bundleModelSelection;
/**
* @var Type
*/
protected $model;
/**
* @var CollectionFactory|MockObject
*/
protected $bundleCollectionFactory;
/**
* @var \Magento\Catalog\Helper\Data|MockObject
*/
protected $catalogData;
/**
* @var StoreManagerInterface|MockObject
*/
protected $storeManager;
/**
* @var OptionFactory|MockObject
*/
protected $bundleOptionFactory;
/**
* @var StockRegistryInterface|MockObject
*/
protected $stockRegistry;
/**
* @var StockStateInterface|MockObject
*/
protected $stockState;
/**
* @var \Magento\Catalog\Helper\Product|MockObject
*/
private $catalogProduct;
/**
* @var PriceCurrencyInterface|MockObject
*/
private $priceCurrency;
/**
* @var MetadataPool|MockObject
*/
private $metadataPool;
/**
* @var Json
*/
private $serializer;
/**
* @var ArrayUtils|MockObject
*/
private $arrayUtility;
/**
* @var CollectionProcessor|MockObject
*/
private $catalogRuleProcessor;
/**
* @inheritDoc
*/
protected function setUp(): void
{
$this->bundleCollectionFactory =
$this->getMockBuilder(CollectionFactory::class)
->onlyMethods(['create'])
->addMethods(
[
'addFilterByRequiredOptions',
'addAttributeToSelect',
'getItemById',
'setOptionIdsFilter',
'setFlag',
'setPositionOrder',
'addStoreFilter',
'setStoreId'
]
)
->disableOriginalConstructor()
->getMock();
$this->catalogData = $this->getMockBuilder(Data::class)
->disableOriginalConstructor()
->getMock();
$this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->bundleOptionFactory = $this->getMockBuilder(OptionFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->stockRegistry = $this->getMockBuilder(StockRegistry::class)
->onlyMethods(['getStockItem'])
->disableOriginalConstructor()
->getMock();
$this->stockState = $this->getMockBuilder(StockState::class)
->onlyMethods(['getStockQty'])
->disableOriginalConstructor()
->getMock();
$this->catalogProduct = $this->getMockBuilder(\Magento\Catalog\Helper\Product::class)
->onlyMethods(['getSkipSaleableCheck'])
->disableOriginalConstructor()
->getMock();
$this->priceCurrency = $this->getMockBuilder(PriceCurrencyInterface::class)
->onlyMethods(['convert'])
->disableOriginalConstructor()
->getMockForAbstractClass();
$this->bundleModelSelection = $this->getMockBuilder(SelectionFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->bundleFactory = $this->getMockBuilder(BundleFactory::class)
->onlyMethods(['create'])
->disableOriginalConstructor()
->getMock();
$this->serializer = $this->getMockBuilder(Json::class)
->disableOriginalConstructor()
->onlyMethods([])
->getMock();
$this->metadataPool = $this->getMockBuilder(MetadataPool::class)
->disableOriginalConstructor()
->getMock();
$this->arrayUtility = $this->getMockBuilder(ArrayUtils::class)
->onlyMethods(['flatten'])
->disableOriginalConstructor()
->getMock();
$this->catalogRuleProcessor = $this->getMockBuilder(CollectionProcessor::class)
->disableOriginalConstructor()
->getMock();
$objectHelper = new ObjectManager($this);
$this->model = $objectHelper->getObject(
Type::class,
[
'bundleModelSelection' => $this->bundleModelSelection,
'bundleFactory' => $this->bundleFactory,
'bundleCollection' => $this->bundleCollectionFactory,
'bundleOption' => $this->bundleOptionFactory,
'catalogData' => $this->catalogData,
'storeManager' => $this->storeManager,
'stockRegistry' => $this->stockRegistry,
'stockState' => $this->stockState,
'catalogProduct' => $this->catalogProduct,
'priceCurrency' => $this->priceCurrency,
'serializer' => $this->serializer,
'metadataPool' => $this->metadataPool,
'arrayUtility' => $this->arrayUtility
]
);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithoutOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'getOptionsCollection', 'getOptionsIds', 'getSelectionsCollection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->any())
->method('getTypeInstance')
->willReturn($productType);
$optionCollection->expects($this->any())
->method('appendSelections')
->with($selectionCollection, true, true)
->willReturn([$option]);
$productType->expects($this->once())
->method('setStoreFilter');
$productType->expects($this->once())
->method('getOptionsCollection')
->willReturn($optionCollection);
$productType->expects($this->once())
->method('getOptionsIds')
->willReturn([1, 2, 3]);
$productType->expects($this->once())
->method('getSelectionsCollection')
->willReturn($selectionCollection);
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn('options');
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithShoppingCart(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->addMethods(['setParentProductId', 'addCustomOption', 'setCartQty', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$bundleOptions = [3 => 5];
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn([$productType]);
$productType->expects($this->once())
->method('setParentProductId')
->willReturnSelf();
$productType->expects($this->any())
->method('addCustomOption')
->willReturnSelf();
$productType->expects($this->once())
->method('setCartQty')
->willReturnSelf();
$productType->expects($this->once())
->method('getSelectionId')
->willReturn(314);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals([$product, $productType], $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedEmptyShoppingCart(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$bundleOptions = [3 => 5];
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn([]);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('We can\'t add this item to your shopping cart right now.', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedStringInResult(): void
{
/** @var MockObject|Price $priceModel */
$priceModel = $this->getMockBuilder(Price::class)
->addMethods(['getSelectionFinalTotalPrice'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId', 'getProduct', 'getTitle'])
->addMethods(['getRequired', 'isMultiSelection', 'getValue'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(
[
'__wakeup',
'isSalable',
'getOptionId',
'getSelectionCanChangeQty',
'getSelectionId',
'addCustomOption',
'getId',
'getOption',
'getTypeInstance'
]
)
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId',
'getCustomOption',
'getPriceModel'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter', 'prepareForCart'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$product->expects($this->any())
->method('getId')
->willReturn(333);
$product->expects($this->once())
->method('getCustomOption')
->willReturn($option);
$product->expects($this->once())
->method('getPriceModel')
->willReturn($priceModel);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$selection->expects($this->any())
->method('getOptionId')
->willReturn(3);
$selection->expects($this->any())
->method('getOption')
->willReturn($option);
$selection->expects($this->once())
->method('getSelectionCanChangeQty')
->willReturn(true);
$selection->expects($this->once())
->method('getSelectionId');
$selection->expects($this->once())
->method('addCustomOption')
->willReturnSelf();
$selection->expects($this->any())
->method('getId')
->willReturn(333);
$selection->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(false);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$option->expects($this->once())
->method('getProduct')
->willReturn($product);
$option->expects($this->once())
->method('getValue')
->willReturn(4);
$option->expects($this->once())
->method('getTitle')
->willReturn('Title for option');
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$priceModel->expects($this->once())
->method('getSelectionFinalTotalPrice')
->willReturnSelf();
$productType->expects($this->once())
->method('prepareForCart')
->willReturn('string');
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('string', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedWithoutSelections(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionQty',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData',
'getId'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
}
return $resultValue;
}
);
$product->expects($this->once())
->method('getId')
->willReturn(333);
$productType->expects($this->once())
->method('setStoreFilter');
$option
->method('getId')
->willReturnOnConsecutiveCalls(333);
$bundleOptions = [];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$buyRequest->expects($this->once())
->method('getBundleOptionQty')
->willReturn([3 => 5]);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product, 'single');
$this->assertEquals([$product], $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedSelectionsSelectionIdsExists(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(['__wakeup', 'isSalable', 'getOptionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById', 'appendSelections'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('appendSelections')
->with($selectionCollection, true, true);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection
->method('getItems')
->willReturnOnConsecutiveCalls([$selection], []);
$selectionCollection
->method('getSize')
->willReturnOnConsecutiveCalls(1, 0);
$option->expects($this->any())
->method('getId')
->willReturn(3);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testPrepareForCartAdvancedSelectRequiredOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired', 'isMultiSelection'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|SelectionCollection $selectionCollection */
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(['getItems', 'getSize'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$selection = $this->getMockBuilder(DataObject::class)
->addMethods(['__wakeup', 'isSalable', 'getOptionId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems', 'getItemById'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection, $selectionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections':
$resultValue = $selectionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [0 => 5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('getItemById')
->willReturn($option);
$productType->expects($this->once())
->method('setStoreFilter');
$bundleOptions = [3 => 5];
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn($bundleOptions);
$this->arrayUtility->expects($this->once())->method('flatten')->willReturn($bundleOptions);
$selectionCollection->expects($this->any())
->method('getItems')
->willReturn([$selection]);
$selectionCollection->expects($this->any())
->method('getSize')
->willReturn(1);
$selection->expects($this->once())
->method('isSalable')
->willReturn(false);
$option
->method('getId')
->willReturnOnConsecutiveCalls(333, 3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$option->expects($this->once())
->method('isMultiSelection')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('The required options you selected are not available.', $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedParentClassReturnString(): void
{
$exceptedResult = 'String message';
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->addMethods(['getItems', '__wakeup'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(['getOptions'])
->addMethods(['getHasOptions'])
->disableOriginalConstructor()
->getMock();
$product->expects($this->any())
->method('getOptions')
->willThrowException(new LocalizedException(__($exceptedResult)));
$product->expects($this->once())
->method('getHasOptions')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals($exceptedResult, $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedAllRequiredOption(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->addMethods(['getRequired'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(
[
'getOptions',
'prepareCustomOptions',
'addCustomOption',
'setQty',
'getTypeInstance',
'getStoreId',
'hasData',
'getData'
]
)->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Type $productType */
$productType = $this->getMockBuilder(Type::class)
->onlyMethods(['setStoreFilter'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Collection $optionCollection */
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(false);
$product->expects($this->once())
->method('getTypeInstance')
->willReturn($productType);
$product->expects($this->once())
->method('hasData')
->willReturn(true);
$product->expects($this->any())
->method('getData')
->willReturnCallback(
function ($key) use ($optionCollection) {
$resultValue = null;
switch ($key) {
case '_cache_instance_options_collection':
$resultValue = $optionCollection;
break;
case '_cache_instance_used_selections_ids':
$resultValue = [0 => 5];
break;
}
return $resultValue;
}
);
$optionCollection->expects($this->once())
->method('getItems')
->willReturn([$option]);
$productType->expects($this->once())
->method('setStoreFilter');
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn([3 => 5]);
$option->method('getId')
->willReturnOnConsecutiveCalls(3);
$option->expects($this->once())
->method('getRequired')
->willReturn(true);
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please select all required options.', $result);
}
/**
* @return void
*/
public function testPrepareForCartAdvancedSpecifyProductOptions(): void
{
/** @var MockObject|DefaultType $group */
$group = $this->getMockBuilder(DefaultType::class)
->onlyMethods(['setOption', 'setProduct', 'validateUserValue', 'prepareForCart'])
->addMethods(['setRequest', 'setProcessMode'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|DataObject $buyRequest */
$buyRequest = $this->getMockBuilder(DataObject::class)
->onlyMethods(['unsetData', 'getData'])
->addMethods(
[
'__wakeup',
'getOptions',
'getSuperProductConfig',
'getQty',
'getBundleOption',
'getBundleOptionsData'
]
)
->disableOriginalConstructor()
->getMock();
/* @var \PHPUnit\Framework\MockObject\MockObject|\Magento\Catalog\Model\Product\Option $option */
$option = $this->getMockBuilder(Option::class)
->onlyMethods(['groupFactory', 'getType', 'getId'])
->disableOriginalConstructor()
->getMock();
/** @var MockObject|Product $product */
$product = $this->getMockBuilder(Product::class)
->onlyMethods(['getOptions', 'prepareCustomOptions', 'addCustomOption', 'setQty'])
->addMethods(['getHasOptions', 'setCartQty', 'getSkipCheckRequiredOption'])
->disableOriginalConstructor()
->getMock();
$buyRequest->method('getOptions')
->willReturn([333 => ['type' => 'image/jpeg']]);
$option->method('getId')
->willReturn(333);
$this->parentClass($group, $option, $buyRequest, $product);
$product->expects($this->any())
->method('getSkipCheckRequiredOption')
->willReturn(true);
$buyRequest->expects($this->once())
->method('getBundleOption')
->willReturn([0, '', 'str']);
$group->expects($this->once())
->method('validateUserValue');
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
$this->assertEquals('Please specify product option(s).', $result);
}
/**
* @return void
*/
public function testHasWeightTrue(): void
{
$this->assertTrue($this->model->hasWeight(), 'This product has no weight, but it should');
}
/**
* @return void
*/
public function testGetIdentities(): void
{
$identities = ['id1', 'id2'];
$productMock = $this->createMock(Product::class);
$optionMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)->addMethods(['getSelections'])
->onlyMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$optionCollectionMock = $this->createMock(\Magento\Bundle\Model\ResourceModel\Option\Collection::class);
$cacheKey = '_cache_instance_options_collection';
$productMock->expects($this->once())
->method('getIdentities')
->willReturn($identities);
$productMock->expects($this->once())
->method('hasData')
->with($cacheKey)
->willReturn(true);
$productMock->expects($this->once())
->method('getData')
->with($cacheKey)
->willReturn($optionCollectionMock);
$optionCollectionMock
->expects($this->once())
->method('getItems')
->willReturn([$optionMock]);
$optionMock
->expects($this->exactly(2))
->method('getSelections')
->willReturn([$productMock]);
$this->assertEquals($identities, $this->model->getIdentities($productMock));
}
/**
* @return void
*/
public function testGetSkuWithType(): void
{
$sku = 'sku';
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['sku'] => $sku,
['sku_type'] => 'some_data'
});
$this->assertEquals($sku, $this->model->getSku($productMock));
}
/**
* @return void
*/
public function testGetSkuWithoutType(): void
{
$sku = 'sku';
$itemSku = 'item';
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSku', 'getEntityId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$productMock
->method('getCustomOption')
->willReturnCallback(fn($param) => match ([$param]) {
['option_ids'] => false,
['bundle_selection_ids'] => $customOptionMock
});
$customOptionMock->expects($this->any())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['sku'] => $sku,
['sku_type'] => null,
['_cache_instance_used_selections'] => $selectionMock,
['_cache_instance_used_selections_ids'] => $selectionIds
});
$selectionMock->expects(($this->any()))
->method('getItemByColumnValue')
->willReturn($selectionItemMock);
$selectionItemMock
->method('getEntityId')
->willReturnOnConsecutiveCalls(1);
$selectionItemMock->expects($this->once())
->method('getSku')
->willReturn($itemSku);
$this->assertEquals($sku . '-' . $itemSku, $this->model->getSku($productMock));
}
/**
* @return void
*/
public function testGetWeightWithoutCustomOption(): void
{
$weight = 5;
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData'])
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['weight_type'] => true,
['weight'] => $weight
});
$this->assertEquals($weight, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testGetWeightWithCustomOption(): void
{
$weight = 5;
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSelectionId', 'getWeight', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(fn($param) => match ([$param]) {
['weight_type'] => false,
['_cache_instance_used_selections'] => $selectionMock,
['_cache_instance_used_selections_ids'] => $selectionIds
});
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->any())
->method('getSelectionId')
->willReturn('id');
$productMock
->method('getCustomOption')
->willReturnCallback(fn($param) => match ([$param]) {
['bundle_selection_ids'] => $customOptionMock,
['selection_qty_' . 'id'] => null
});
$selectionItemMock->expects($this->once())
->method('getWeight')
->willReturn($weight);
$this->assertEquals($weight, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testGetWeightWithSeveralCustomOption(): void
{
$weight = 5;
$qtyOption = 5;
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup', 'getData', 'hasCustomOptions', 'getCustomOption'])
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$qtyOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['getSelectionId', 'getWeight', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($selectionMock, $selectionIds) {
if ($arg === 'weight_type') {
return false;
} elseif ($arg === '_cache_instance_used_selections') {
return $selectionMock;
} elseif ($arg === '_cache_instance_used_selections_ids') {
return $selectionIds;
}
}
);
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->any())
->method('getSelectionId')
->willReturn('id');
$productMock
->method('getCustomOption')
->willReturnCallback(
function ($arg) use ($customOptionMock, $qtyOptionMock) {
if ($arg === 'bundle_selection_ids') {
return $customOptionMock;
} elseif ($arg === 'selection_qty_id') {
return $qtyOptionMock;
}
}
);
$qtyOptionMock->expects($this->once())
->method('getValue')
->willReturn($qtyOption);
$selectionItemMock->expects($this->once())
->method('getWeight')
->willReturn($weight);
$this->assertEquals($weight * $qtyOption, $this->model->getWeight($productMock));
}
/**
* @return void
*/
public function testIsVirtualWithoutCustomOption(): void
{
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(false);
$this->assertFalse($this->model->isVirtual($productMock));
}
/**
* @return void
*/
public function testIsVirtual(): void
{
$selectionIds = [1, 2, 3];
$serializeIds = json_encode($selectionIds);
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$customOptionMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Configuration\Item\Option::class)
->onlyMethods(['getValue'])
->addMethods(['__wakeup'])
->disableOriginalConstructor()
->getMock();
$selectionItemMock = $this->getMockBuilder(DataObject::class)
->addMethods(['isVirtual', 'getItems', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('hasCustomOptions')
->willReturn(true);
$productMock->expects($this->once())
->method('getCustomOption')
->with('bundle_selection_ids')
->willReturn($customOptionMock);
$customOptionMock->expects($this->once())
->method('getValue')
->willReturn($serializeIds);
$selectionMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($selectionMock, $selectionIds) {
if ($arg === '_cache_instance_used_selections') {
return $selectionMock;
} elseif ($arg === '_cache_instance_used_selections_ids') {
return $selectionIds;
}
}
);
$selectionMock->expects($this->once())
->method('getItems')
->willReturn([$selectionItemMock]);
$selectionItemMock->expects($this->once())
->method('isVirtual')
->willReturn(true);
$selectionItemMock->expects($this->once())
->method('isVirtual')
->willReturn(true);
$selectionMock->expects($this->once())
->method('count')
->willReturn(1);
$isVirtual = (bool)$this->model->isVirtual($productMock);
$this->assertTrue($isVirtual);
}
/**
* @param int $expected
* @param int $firstId
* @param int $secondId
*
* @return void
* @dataProvider shakeSelectionsDataProvider
*/
public function testShakeSelections($expected, $firstId, $secondId): void
{
$firstItemMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup'])
->addMethods(['getOption', 'getOptionId', 'getPosition', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
$secondItemMock = $this->getMockBuilder(Product::class)
->onlyMethods(['__wakeup'])
->addMethods(['getOption', 'getOptionId', 'getPosition', 'getSelectionId'])
->disableOriginalConstructor()
->getMock();
$optionFirstMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->onlyMethods(['getPosition', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$optionSecondMock = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->onlyMethods(['getPosition', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$firstItemMock->expects($this->once())
->method('getOption')
->willReturn($optionFirstMock);
$optionFirstMock->expects($this->once())
->method('getPosition')
->willReturn('option_position');
$firstItemMock->expects($this->once())
->method('getOptionId')
->willReturn('option_id');
$firstItemMock->expects($this->once())
->method('getPosition')
->willReturn('position');
$firstItemMock->expects($this->once())
->method('getSelectionId')
->willReturn($firstId);
$secondItemMock->expects($this->once())
->method('getOption')
->willReturn($optionSecondMock);
$optionSecondMock->expects($this->any())
->method('getPosition')
->willReturn('option_position');
$secondItemMock->expects($this->once())
->method('getOptionId')
->willReturn('option_id');
$secondItemMock->expects($this->once())
->method('getPosition')
->willReturn('position');
$secondItemMock->expects($this->once())
->method('getSelectionId')
->willReturn($secondId);
$this->assertEquals($expected, $this->model->shakeSelections($firstItemMock, $secondItemMock));
}
/**
* @return array
*/
public static function shakeSelectionsDataProvider(): array
{
return [
[0, 0, 0],
[1, 1, 0],
[-1, 0, 1]
];
}
/**
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function testGetSelectionsByIds(): void
{
$selectionIds = [1, 2, 3];
$usedSelectionsIds = [4, 5, 6];
$storeId = 2;
$websiteId = 1;
$storeFilter = 'store_filter';
$this->expectProductEntityMetadata();
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$usedSelectionsMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->onlyMethods(
[
'addAttributeToSelect',
'setFlag',
'addStoreFilter',
'setStoreId',
'setPositionOrder',
'addFilterByRequiredOptions',
'setSelectionIdsFilter',
'joinPrices'
]
)
->disableOriginalConstructor()
->getMock();
$productGetMap = [
['_cache_instance_used_selections', null, null],
['_cache_instance_used_selections_ids', null, $usedSelectionsIds],
['_cache_instance_store_filter', null, $storeFilter],
];
$productMock->expects($this->any())
->method('getData')
->willReturnMap($productGetMap);
$productSetMap = [
['_cache_instance_used_selections', $usedSelectionsMock, $productMock],
['_cache_instance_used_selections_ids', $selectionIds, $productMock],
];
$productMock->expects($this->any())
->method('setData')
->willReturnMap($productSetMap);
$productMock->expects($this->once())
->method('getStoreId')
->willReturn($storeId);
$storeMock = $this->getMockBuilder(Store::class)
->onlyMethods(['getWebsiteId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$this->storeManager->expects($this->once())
->method('getStore')
->with($storeId)
->willReturn($storeMock);
$storeMock->expects($this->once())
->method('getWebsiteId')
->willReturn($websiteId);
$this->bundleCollectionFactory->expects($this->once())
->method('create')
->willReturn($usedSelectionsMock);
$usedSelectionsMock->expects($this->once())
->method('addAttributeToSelect')
->with('*')
->willReturnSelf();
$flagMap = [
['product_children', true, $usedSelectionsMock],
];
$usedSelectionsMock->expects($this->any())
->method('setFlag')
->willReturnMap($flagMap);
$usedSelectionsMock->expects($this->once())
->method('addStoreFilter')
->with($storeFilter)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setStoreId')
->with($storeId)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setPositionOrder')
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('addFilterByRequiredOptions')
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('setSelectionIdsFilter')
->with($selectionIds)
->willReturnSelf();
$usedSelectionsMock->expects($this->once())
->method('joinPrices')
->with($websiteId)
->willReturnSelf();
$this->catalogData->expects($this->once())
->method('isPriceGlobal')
->willReturn(false);
$this->model->getSelectionsByIds($selectionIds, $productMock);
}
/**
* @return void
*/
public function testGetOptionsByIds(): void
{
$optionsIds = [1, 2, 3];
$usedOptionsIds = [4, 5, 6];
$productId = 3;
$storeId = 2;
$productMock = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$usedOptionsMock = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->addMethods(['getResourceCollection'])
->disableOriginalConstructor()
->getMock();
$resourceClassName = AbstractCollection::class;
$dbResourceMock = $this->getMockBuilder($resourceClassName)
->addMethods(['setProductIdFilter', 'setPositionOrder', 'joinValues', 'setIdFilter'])
->disableOriginalConstructor()
->getMock();
$storeMock = $this->getMockBuilder(Store::class)
->onlyMethods(['getId', '__wakeup'])
->disableOriginalConstructor()
->getMock();
$productMock->expects($this->once())
->method('getId')
->willReturn($productId);
$this->bundleOptionFactory->expects($this->once())
->method('create')
->willReturn($usedOptionsMock);
$usedOptionsMock->expects($this->once())
->method('getResourceCollection')
->willReturn($dbResourceMock);
$dbResourceMock->expects($this->once())
->method('setProductIdFilter')
->with($productId)
->willReturnSelf();
$dbResourceMock->expects($this->once())
->method('setPositionOrder')
->willReturnSelf();
$this->storeManager->expects($this->once())
->method('getStore')
->willReturn($storeMock);
$storeMock->expects($this->once())
->method('getId')
->willReturn($storeId);
$dbResourceMock->expects($this->once())
->method('joinValues')
->willReturnSelf();
$dbResourceMock->expects($this->once())
->method('setIdFilter')
->with($optionsIds)
->willReturnSelf();
$productMock
->method('getData')
->willReturnCallback(
function ($arg) use ($usedOptionsIds) {
if ($arg === '_cache_instance_used_options') {
return null;
} elseif ($arg === '_cache_instance_used_options_ids') {
return $usedOptionsIds;
}
}
);
$productMock
->method('setData')
->willReturnCallback(
function ($arg1, $arg2) use ($dbResourceMock, $optionsIds, $productMock) {
if ($arg1 === '_cache_instance_used_options' && $arg2 === $dbResourceMock) {
return $productMock;
} elseif ($arg1 === '_cache_instance_used_options_ids' && $arg2 === $optionsIds) {
return $productMock;
}
}
);
$this->model->getOptionsByIds($optionsIds, $productMock);
}
/**
* @return void
*/
public function testIsSalableFalse(): void
{
$product = new DataObject(
[
'is_salable' => false,
'status' => Status::STATUS_ENABLED
]
);
$this->assertFalse($this->model->isSalable($product));
}
/**
* @return void
*/
public function testIsSalableCache(): void
{
$product = new DataObject(
[
'is_salable' => true,
'status' => Status::STATUS_ENABLED,
'all_items_salable' => true
]
);
$this->assertTrue($this->model->isSalable($product));
}
/**
* @param array $selectedOptions
*
* @return MockObject
*/
private function getSelectionCollectionMock(array $selectedOptions): MockObject
{
$selectionCollectionMock = $this->getMockBuilder(
\Magento\Bundle\Model\ResourceModel\Selection\Collection::class
)->disableOriginalConstructor()
->getMock();
$selectionCollectionMock
->expects($this->any())
->method('getIterator')
->willReturn(new \ArrayIterator($selectedOptions));
return $selectionCollectionMock;
}
/**
* @param bool $isManageStock
*
* @return StockItemInterface|MockObject
*/
protected function getStockItem(bool $isManageStock): MockObject
{
$result = $this->getMockBuilder(StockItemInterface::class)
->getMock();
$result->method('getManageStock')
->willReturn($isManageStock);
return $result;
}
/**
* @param MockObject|DefaultType $group
* @param MockObject|Option $option
* @param MockObject|DataObject $buyRequest
* @param MockObject|Product $product
*
* @return void
*/
protected function parentClass($group, $option, $buyRequest, $product): void
{
$group->expects($this->once())
->method('setOption')
->willReturnSelf();
$group->expects($this->once())
->method('setProduct')
->willReturnSelf();
$group->expects($this->once())
->method('setRequest')
->willReturnSelf();
$group->expects($this->once())
->method('setProcessMode')
->willReturnSelf();
$group->expects($this->once())
->method('prepareForCart')
->willReturn('someString');
$option->expects($this->once())
->method('getType');
$option->expects($this->once())
->method('groupFactory')
->willReturn($group);
$buyRequest->expects($this->once())
->method('getData');
$buyRequest->expects($this->once())
->method('getOptions');
$buyRequest->expects($this->once())
->method('getSuperProductConfig')
->willReturn([]);
$buyRequest->expects($this->any())
->method('unsetData')
->willReturnSelf();
$buyRequest->expects($this->any())
->method('getQty');
$product->expects($this->once())
->method('getOptions')
->willReturn([$option]);
$product->expects($this->once())
->method('getHasOptions')
->willReturn(true);
$product->expects($this->once())
->method('prepareCustomOptions');
$product->expects($this->any())
->method('addCustomOption')
->willReturnSelf();
$product->expects($this->any())
->method('setCartQty')
->willReturnSelf();
$product->expects($this->once())
->method('setQty');
$this->catalogProduct->expects($this->once())
->method('getSkipSaleableCheck')
->willReturn(false);
}
/**
* @return void
*/
public function testGetSelectionsCollection(): void
{
$optionIds = [1, 2, 3];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getStoreId', 'getData', 'hasData', 'setData', 'getId'])
->addMethods(['_wakeup'])
->getMock();
$this->expectProductEntityMetadata();
$store = $this->getMockBuilder(Store::class)
->disableOriginalConstructor()
->onlyMethods(['getWebsiteId'])
->getMock();
$product->expects($this->once())->method('getStoreId')->willReturn('store_id');
$selectionCollection = $this->getSelectionCollection();
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$this->storeManager->expects($this->once())->method('getStore')->willReturn($store);
$store->expects($this->once())->method('getWebsiteId')->willReturn('website_id');
$selectionCollection->expects($this->any())->method('joinPrices')->with('website_id')->willReturnSelf();
$this->assertEquals($selectionCollection, $this->model->getSelectionsCollection($optionIds, $product));
}
/**
* @return MockObject
*/
private function getSelectionCollection(): MockObject
{
$selectionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Selection\Collection::class)
->disableOriginalConstructor()
->getMock();
$selectionCollection->expects($this->any())->method('addAttributeToSelect')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setFlag')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setPositionOrder')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addStoreFilter')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setStoreId')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addFilterByRequiredOptions')->willReturnSelf();
$selectionCollection->expects($this->any())->method('setOptionIdsFilter')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addPriceData')->willReturnSelf();
$selectionCollection->expects($this->any())->method('addTierPriceData')->willReturnSelf();
return $selectionCollection;
}
/**
* @return void
*/
public function testProcessBuyRequest(): void
{
$result = ['bundle_option' => [], 'bundle_option_qty' => []];
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$buyRequest = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->addMethods(['getBundleOption', 'getBundleOptionQty'])
->getMock();
$buyRequest->expects($this->once())->method('getBundleOption')->willReturn('bundleOption');
$buyRequest->expects($this->once())->method('getBundleOptionQty')->willReturn('optionId');
$this->assertEquals($result, $this->model->processBuyRequest($product, $buyRequest));
}
/**
* @return void
*/
public function testGetProductsToPurchaseByReqGroups(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$this->expectProductEntityMetadata();
$resourceClassName = AbstractCollection::class;
$dbResourceMock = $this->getMockBuilder($resourceClassName)
->onlyMethods(['getItems'])
->disableOriginalConstructor()
->getMock();
$item = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->addMethods(['getId', 'getRequired'])
->getMock();
$selectionCollection = $this->getSelectionCollection();
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$selectionItem = $this->getMockBuilder(DataObject::class)
->disableOriginalConstructor()
->getMock();
$product->expects($this->any())->method('hasData')->willReturn(true);
$product
->method('getData')
->willReturnCallback(
function ($arg) use ($dbResourceMock) {
if ($arg === '_cache_instance_options_collection') {
return $dbResourceMock;
}
}
);
$dbResourceMock->expects($this->once())->method('getItems')->willReturn([$item]);
$item->expects($this->once())->method('getId')->willReturn('itemId');
$item->expects($this->once())->method('getRequired')->willReturn(true);
$selectionCollection
->expects($this->any())
->method('getIterator')
->willReturn(new \ArrayIterator([$selectionItem]));
$this->assertEquals([[$selectionItem]], $this->model->getProductsToPurchaseByReqGroups($product));
}
/**
* @return void
*/
public function testGetSearchableData(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getId', 'getStoreId'])
->addMethods(['_wakeup', 'getHasOptions'])
->getMock();
$option = $this->getMockBuilder(\Magento\Bundle\Model\Option::class)
->disableOriginalConstructor()
->onlyMethods(['getSearchableData'])
->getMock();
$product->expects($this->once())->method('getHasOptions')->willReturn(false);
$product->expects($this->once())->method('getId')->willReturn('productId');
$product->expects($this->once())->method('getStoreId')->willReturn('storeId');
$this->bundleOptionFactory->expects($this->once())->method('create')->willReturn($option);
$option->expects($this->once())->method('getSearchableData')->willReturn(['optionSearchdata']);
$this->assertEquals(['optionSearchdata'], $this->model->getSearchableData($product));
}
/**
* @return void
*/
public function testHasOptions(): void
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['hasData', 'getData', 'setData', 'getId', 'getStoreId'])
->addMethods(['_wakeup'])
->getMock();
$this->expectProductEntityMetadata();
$optionCollection = $this->getMockBuilder(\Magento\Bundle\Model\ResourceModel\Option\Collection::class)
->disableOriginalConstructor()
->onlyMethods(['getAllIds'])
->getMock();
$selectionCollection = $this->getSelectionCollection();
$selectionCollection
->expects($this->any())
->method('getSize')
->willReturn(1);
$this->bundleCollectionFactory->expects($this->once())->method('create')->willReturn($selectionCollection);
$product->expects($this->any())->method('getStoreId')->willReturn(0);
$product->expects($this->once())
->method('setData')
->with('_cache_instance_store_filter', 0)
->willReturnSelf();
$product->expects($this->any())->method('hasData')->willReturn(true);
$product
->method('getData')
->willReturnCallback(
function ($arg) use ($optionCollection) {
if ($arg === '_cache_instance_options_collection') {
return $optionCollection;
}
}
);
$optionCollection->expects($this->once())->method('getAllIds')->willReturn(['ids']);
$this->assertTrue($this->model->hasOptions($product));
}
/**
* Bundle product without options should not be possible to buy.
*
* @return void
*/
public function testCheckProductBuyStateEmptyOptionsException(): void
{
$this->expectException(LocalizedException::class);
$this->expectExceptionMessage('Please specify product option');
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => '[]'])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => ''])])]
]);
$product->setCustomOption(json_encode([]));
$this->model->checkProductBuyState($product);
}
/**
* Previously selected options are not more available for buying.
*
* @param object $element
* @param string $expectedMessage
* @param bool $check
*
* @return void
* @throws LocalizedException
* @dataProvider notAvailableOptionProvider
*/
public function testCheckProductBuyStateMissedOptionException($element, $expectedMessage, $check): void
{
$this->expectException(LocalizedException::class);
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => json_encode([1])])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => [1]])])],
]);
$product->setCustomOption(json_encode([]));
$this->bundleCollectionFactory->method('getItemById')->willReturn($element);
$this->catalogProduct->setSkipSaleableCheck($check);
try {
$this->model->checkProductBuyState($product);
} catch (LocalizedException $e) {
$this->assertStringContainsString(
$expectedMessage,
$e->getMessage()
);
throw $e;
}
}
/**
* In case of missed selection for required options, bundle product should be not able to buy.
*
* @return void
*/
public function testCheckProductBuyStateRequiredOptionException(): void
{
$this->expectException(LocalizedException::class);
$this->mockBundleCollection();
$product = $this->getProductMock();
$this->expectProductEntityMetadata();
$product->method('getCustomOption')->willReturnMap([
['bundle_selection_ids', new DataObject(['value' => json_encode([])])],
['info_buyRequest', new DataObject(['value' => json_encode(['bundle_option' => [1]])])],
]);
$product->setCustomOption(json_encode([]));
$falseSelection = $this->getMockBuilder(Selection::class)->disableOriginalConstructor()
->addMethods(['isSalable'])
->getMock();
$falseSelection->method('isSalable')->willReturn(false);
$this->bundleCollectionFactory->method('getItemById')->willReturn($falseSelection);
$this->catalogProduct->setSkipSaleableCheck(false);
try {
$this->model->checkProductBuyState($product);
} catch (LocalizedException $e) {
$this->assertStringContainsString(
'Please select all required options',
$e->getMessage()
);
throw $e;
}
}
/**
* Prepare product mock for testing.
*
* @return MockObject
*/
public function getProductMock(): MockObject
{
$product = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->onlyMethods(['getId', 'getStoreId', 'getCustomOption', 'getTypeInstance'])
->addMethods(['_wakeup', 'getHasOptions', 'setStoreFilter', 'setCustomOption'])
->getMock();
$product->method('getTypeInstance')->willReturn($product);
$product->method('setStoreFilter')->willReturn($product);
$optionCollectionCache = new DataObject();
$optionCollectionCache->setAllIds([]);
$optionCollectionCache->setItems([
new DataObject([
'required' => true,
'id' => 1
]),
]);
$product->setData('_cache_instance_options_collection', $optionCollectionCache);
return $product;
}
/**
* Preparation mocks for checkProductsBuyState.
*
* @return void
*/
public function mockBundleCollection(): void
{
$selectionCollectionMock = $this->getSelectionCollectionMock([]);
$this->bundleCollectionFactory->expects($this->once())
->method('create')
->willReturn($selectionCollectionMock);
$this->bundleCollectionFactory->method('create')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addAttributeToSelect')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setFlag')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setPositionOrder')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addStoreFilter')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setStoreId')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('addFilterByRequiredOptions')->willReturn($selectionCollectionMock);
$selectionCollectionMock->method('setOptionIdsFilter')->willReturn($selectionCollectionMock);
}
/**
* Data provider for not available option.
*
* @return array
*/
public function notAvailableOptionProvider(): array
{
$falseSelection = $this->getMockBuilder(Selection::class)->disableOriginalConstructor()
->addMethods(['isSalable'])
->getMock();
$falseSelection->method('isSalable')->willReturn(false);
return [
[
false,
'The required options you selected are not available',
false
],
[
$falseSelection,
'The required options you selected are not available',
false
]
];
}
/**
* @return void
*/
private function expectProductEntityMetadata(): void
{
$entityMetadataMock = $this->getMockBuilder(EntityMetadataInterface::class)
->onlyMethods(['getLinkField'])
->getMockForAbstractClass();
$entityMetadataMock->method('getLinkField')->willReturn('test_link_field');
$this->metadataPool->expects($this->any())->method('getMetadata')
->with(ProductInterface::class)
->willReturn($entityMetadataMock);
}
}
Function Calls
| None |
Stats
| MD5 | b34ded989aaf36be02cc73529fb1ae02 |
| Eval Count | 0 |
| Decode Time | 101 ms |