| Current Path : /home/rtorresani/www/vendor/magento/module-checkout/Test/Unit/Block/Cart/ |
| Current File : //home/rtorresani/www/vendor/magento/module-checkout/Test/Unit/Block/Cart/CrosssellTest.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Checkout\Test\Unit\Block\Cart;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Link;
use Magento\Catalog\Model\Product\LinkFactory;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection;
use Magento\Checkout\Block\Cart\Crosssell;
use Magento\Checkout\Model\Session;
use Magento\Framework\DataObject;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\EntityMetadataInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Model\StoreManagerInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CrosssellTest extends TestCase
{
/**
* @var Session|MockObject
*/
private $checkoutSession;
/**
* @var Crosssell
*/
private $model;
/**
* @var ProductRepositoryInterface|MockObject
*/
private $productRepository;
/**
* @var LinkFactory|MockObject
*/
private $productLinkFactory;
/**
* @var array
*/
private $productLinks = [];
/**
* @var Context
*/
private $context;
/**
* @var StoreManagerInterface|MockObject
*/
private $storeManager;
/**
* @var MockObject
*/
private $productCollectionFactory;
/**
* @inheritDoc
*/
protected function setUp(): void
{
$objectManager = new ObjectManager($this);
$this->storeManager = $this->createMock(
StoreManagerInterface::class
);
$this->context = $objectManager->getObject(
Context::class,
[
'storeManager' => $this->storeManager
]
);
$this->checkoutSession = $this->getMockBuilder(Session::class)
->addMethods(['getLastAddedProductId'])
->onlyMethods(['getQuote'])
->disableOriginalConstructor()
->getMock();
$this->productRepository = $this->createMock(
ProductRepositoryInterface::class
);
$this->productLinkFactory = $this->createMock(
LinkFactory::class
);
$this->productLinkFactory = $this->createMock(
LinkFactory::class
);
$this->productCollectionFactory = $this->createMock(
CollectionFactory::class
);
$this->model = $objectManager->getObject(
Crosssell::class,
[
'context' => $this->context,
'checkoutSession' => $this->checkoutSession,
'productRepository' => $this->productRepository,
'productLinkFactory' => $this->productLinkFactory,
'productCollectionFactory' => $this->productCollectionFactory,
]
);
}
/**
* @dataProvider getItemsDataProvider
* @param array $productLinks
* @param array $cartProductIds
* @param int|null $lastAddedProductId
* @param array $expected
*/
public function testGetItems(
array $productLinks,
array $cartProductIds,
?int $lastAddedProductId,
array $expected
) {
$this->productLinks = $productLinks;
$cartProducts = array_map(
function ($id) {
return $this->getProduct(['entity_id' => $id]);
},
$cartProductIds
);
$cartItems = array_map(
function ($product) {
return new DataObject(['product' => $product]);
},
$cartProducts
);
$quote = new DataObject(['all_items' => $cartItems]);
$this->checkoutSession->method('getQuote')
->willReturn($quote);
$this->checkoutSession->method('getLastAddedProductId')
->willReturn($lastAddedProductId);
$this->productRepository->method('getById')
->willReturnCallback(
function ($id) {
return $this->getProduct(['entity_id' => $id]);
}
);
$link = $this->createMock(Link::class);
$this->productLinkFactory->method('create')
->willReturn($link);
$link->method('useCrossSellLinks')
->willReturnSelf();
$link->method('getProductCollection')
->willReturnCallback(
function () {
return $this->createLinkCollection();
}
);
$this->productCollectionFactory->method('create')
->willReturnCallback(
function () {
return $this->createProductCollection();
}
);
$store = $this->createMock(StoreInterface::class);
$this->storeManager->method('getStore')
->willReturn($store);
$actual = array_map(
function ($product) {
return $product->getId();
},
$this->model->getItems()
);
$this->assertEquals($expected, $actual);
}
/**
* @return array
*/
public function getItemsDataProvider(): array
{
$links = [
1001 => [
1003,
1005
],
1006 => [
1002,
]
];
return [
[
'productLinks' => $links,
'cartProducts' => [
1001,
1006,
],
'lastAddedProduct' => 1006,
'cross-sells' => [
1002,
1003,
1005
]
],
[
'productLinks' => $links,
'cartProducts' => [
1001,
1006,
],
'lastAddedProduct' => null,
'cross-sells' => [
1003,
1005,
1002,
]
],
[
'productLinks' => $links,
'cartProducts' => [
1001,
1005,
],
'lastAddedProduct' => null,
'cross-sells' => [
1003
]
],
[
'productLinks' => $links,
'cartProducts' => [
1002,
1003,
],
'lastAddedProduct' => null,
'cross-sells' => [
]
]
];
}
/**
* @param array $data
* @return MockObject
*/
private function getProduct(array $data): MockObject
{
$product = $this->createPartialMock(Product::class, []);
$product->setData($data);
return $product;
}
/**
* @return MockObject
*/
private function createLinkCollection(): MockObject
{
$returnSelfMethods = [
'setStoreId',
'setPageSize',
'setGroupBy',
'setVisibility',
'addMinimalPrice',
'addFinalPrice',
'addTaxPercents',
'addAttributeToSelect',
'addStoreFilter',
'setPositionOrder',
'addUrlRewrite',
'load',
];
$linkCollection = $this->createPartialMock(
Collection::class,
array_merge(
$returnSelfMethods,
[
'addProductFilter',
'addExcludeProductFilter',
'getSelect',
'getIterator',
]
)
);
foreach ($returnSelfMethods as $method) {
$linkCollection->method($method)
->willReturnSelf();
}
$linkCollection->method('addProductFilter')
->willReturnCallback(
function ($products) use ($linkCollection) {
if (!is_array($products)) {
$products = [$products];
}
$linkCollection->setFlag('test_product_ids', $products);
return $linkCollection;
}
);
$linkCollection->method('addExcludeProductFilter')
->willReturnCallback(
function ($products) use ($linkCollection) {
if (!is_array($products)) {
$products = [$products];
}
$linkCollection->setFlag('test_exclude_product_ids', $products);
return $linkCollection;
}
);
$linkCollection->method('getSelect')->willReturn(
$this->createMock(Select::class)
);
$linkCollection->method('getIterator')
->willReturnCallback(
function () use ($linkCollection) {
$productIds = $linkCollection->getFlag('test_product_ids') ?? [];
$excludeProductIds = $linkCollection->getFlag('test_exclude_product_ids') ?? [];
$links = [];
foreach ($productIds as $id) {
if (isset($this->productLinks[$id])) {
array_push($links, ...$this->productLinks[$id]);
}
}
$links = array_values(array_unique(array_diff($links, $excludeProductIds)));
$links = array_combine($links, $links);
$products = array_map(
function ($id) {
return $this->getProduct(['entity_id' => $id]);
},
$links
);
return new \ArrayIterator($products);
}
);
return $linkCollection;
}
/**
* @return MockObject
*/
private function createProductCollection(): MockObject
{
$productCollection = $this->createMock(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
$entityMetadataInterface =$this->createMock(EntityMetadataInterface::class);
$entityMetadataInterface->method('getLinkField')
->willReturn('entity_id');
$productCollection->method('getProductEntityMetadata')
->willReturn($entityMetadataInterface);
return $productCollection;
}
}