| Current Path : /var/www/clients/client3/web2/web/vendor/magento/module-payment/Test/Unit/Model/ |
| Current File : /var/www/clients/client3/web2/web/vendor/magento/module-payment/Test/Unit/Model/CartTest.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\Payment\Test\Unit\Model;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface;
use Magento\Payment\Model\Cart;
use Magento\Payment\Model\Cart\SalesModel\Factory;
use Magento\Payment\Model\Cart\SalesModel\SalesModelInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class CartTest extends TestCase
{
/** @var \Magento\Payment\Model\Cart */
protected $_model;
/** @var MockObject */
protected $_eventManagerMock;
/** @var MockObject */
protected $_salesModelMock;
protected function setUp(): void
{
$this->_eventManagerMock = $this->getMockForAbstractClass(ManagerInterface::class);
$this->_salesModelMock = $this->getMockForAbstractClass(SalesModelInterface::class);
$factoryMock = $this->createMock(Factory::class);
$factoryMock->expects($this->once())->method('create')->willReturn($this->_salesModelMock);
$this->_model = new Cart($factoryMock, $this->_eventManagerMock, null);
}
/**
* Test sales model getter
*/
public function testGetSalesModel()
{
$this->assertSame($this->_model->getSalesModel(), $this->_salesModelMock);
}
/**
* Test addCustomItem()
*/
public function testAddCustomItem()
{
$this->_salesModelMock->expects(
$this->once()
)->method(
'getAllItems'
)->willReturn(
$this->_getSalesModelItems()
);
$this->_model->getAllItems();
$this->_model->addCustomItem('test', 10, 10.5, 'some_id');
$items = $this->_model->getAllItems();
$customItem = array_pop($items);
$this->assertTrue(
$customItem->getName() == 'test' &&
$customItem->getQty() == 10 &&
$customItem->getAmount() == 10.5 &&
$customItem->getId() == 'some_id'
);
}
/**
* @param array $transferFlags
* @param array $salesModelItems
* @param array $salesModelAmounts
* @param array $expected
* @dataProvider cartDataProvider
*/
public function testGetAmounts($transferFlags, $salesModelItems, $salesModelAmounts, $expected)
{
$amounts = $this->_collectItemsAndAmounts($transferFlags, $salesModelItems, $salesModelAmounts);
$this->assertEquals($expected, $amounts);
// check that method just return calculated result for further calls
$this->_eventManagerMock->expects($this->never())->method('dispatch');
$amounts = $this->_model->getAmounts();
$this->assertEquals($expected, $amounts);
}
/**
* @param array $transferFlags
* @param array $salesModelItems
* @param array $salesModelAmounts
* @dataProvider cartDataProvider
*/
public function testGetAllItems($transferFlags, $salesModelItems, $salesModelAmounts)
{
$this->_collectItemsAndAmounts($transferFlags, $salesModelItems, $salesModelAmounts);
$customItems = [];
if ($transferFlags['transfer_shipping']) {
$customItems[] = new DataObject(
['name' => 'Shipping', 'qty' => 1, 'amount' => $salesModelAmounts['BaseShippingAmount']]
);
}
if ($transferFlags['transfer_discount']) {
$customItems[] = new DataObject(
['name' => 'Discount', 'qty' => 1, 'amount' => -1.00 * $salesModelAmounts['BaseDiscountAmount']]
);
}
$cartItems = $this->_convertToCartItems($salesModelItems);
$expected = array_merge($cartItems, $customItems);
$areEqual = $this->_compareSalesItems($expected, $this->_model->getAllItems());
$this->assertTrue($areEqual);
}
/**
* Test all amount specific methods i.e. add...(), set...(), get...()
*/
public function testAmountSettersAndGetters()
{
foreach (['Discount', 'Shipping', 'Tax'] as $amountType) {
$setMethod = 'set' . $amountType;
$getMethod = 'get' . $amountType;
$addMethod = 'add' . $amountType;
$this->_model->{$setMethod}(10);
$this->assertEquals(10, $this->_model->{$getMethod}());
$this->_model->{$addMethod}(5);
$this->assertEquals(15, $this->_model->{$getMethod}());
$this->_model->{$addMethod}(-20);
$this->assertEquals(-5, $this->_model->{$getMethod}());
$this->_model->{$setMethod}(10);
$this->assertEquals(10, $this->_model->{$getMethod}());
}
// there is no method setSubtotal(), so test the following separately
$this->_model->addSubtotal(10);
$this->assertEquals(10, $this->_model->getSubtotal());
$this->_model->addSubtotal(2);
$this->assertEquals(12, $this->_model->getSubtotal());
$this->_model->addSubtotal(-20);
$this->assertEquals(-8, $this->_model->getSubtotal());
}
/**
* Data provider
*
* @return array
*/
public function cartDataProvider()
{
return [
// 1. All transfer flags set to true
[
['transfer_shipping' => true, 'transfer_discount' => true],
$this->_getSalesModelItems(),
[
'BaseDiscountAmount' => 15.0,
'BaseShippingAmount' => 20.0,
'BaseSubtotal' => 100.0,
'BaseTaxAmount' => 8.0
],
[
Cart::AMOUNT_DISCOUNT => 0.0,
Cart::AMOUNT_SHIPPING => 0.0,
Cart::AMOUNT_SUBTOTAL => 105.0, // = 100.5 + shipping - discount
Cart::AMOUNT_TAX => 8.0
]
],
// 2. All transfer flags set to false
[
['transfer_shipping' => false, 'transfer_discount' => false],
$this->_getSalesModelItems(),
[
'BaseDiscountAmount' => 15.0,
'BaseShippingAmount' => 20.0,
'BaseSubtotal' => 100.0,
'BaseTaxAmount' => 8.0
],
[
Cart::AMOUNT_DISCOUNT => 15.0,
Cart::AMOUNT_SHIPPING => 20.0,
Cart::AMOUNT_SUBTOTAL => 100.0,
Cart::AMOUNT_TAX => 8.0
]
],
// 3. Shipping transfer flag set to true, discount to false, sales items are empty (don't affect result)
[
['transfer_shipping' => true, 'transfer_discount' => false],
[],
[
'BaseDiscountAmount' => 15.0,
'BaseShippingAmount' => 20.0,
'BaseSubtotal' => 100.0,
'BaseTaxAmount' => 8.0
],
[
Cart::AMOUNT_DISCOUNT => 15.0,
Cart::AMOUNT_SHIPPING => 0.0,
Cart::AMOUNT_SUBTOTAL => 120.0,
Cart::AMOUNT_TAX => 8.0
]
]
];
}
/**
* Return true if arrays of cart sales items are equal, false otherwise. Elements order not considered
*
* @param array $salesItemsA
* @param array $salesItemsB
* @return bool
*/
protected function _compareSalesItems(array $salesItemsA, array $salesItemsB)
{
if (count($salesItemsA) != count($salesItemsB)) {
return false;
}
$toStringCallback = function (&$item) {
$item = $item->toString();
};
array_walk($salesItemsA, $toStringCallback);
array_walk($salesItemsB, $toStringCallback);
sort($salesItemsA);
sort($salesItemsB);
return implode('', $salesItemsA) == implode('', $salesItemsB);
}
/**
* Collect sales model items and calculate amounts of sales model
*
* @param array $transferFlags
* @param array $salesModelItems
* @param array $salesModelAmounts
* @return array Cart amounts
*/
protected function _collectItemsAndAmounts($transferFlags, $salesModelItems, $salesModelAmounts)
{
if ($transferFlags['transfer_shipping']) {
$this->_model->setTransferShippingAsItem();
}
if ($transferFlags['transfer_discount']) {
$this->_model->setTransferDiscountAsItem();
}
$this->_eventManagerMock->expects(
$this->once()
)->method(
'dispatch'
)->with(
'payment_cart_collect_items_and_amounts',
['cart' => $this->_model]
);
$this->_salesModelMock->expects(
$this->once()
)->method(
'getAllItems'
)->willReturn(
$salesModelItems
);
foreach ($salesModelAmounts as $key => $value) {
$this->_salesModelMock->expects($this->once())->method('get' . $key)->willReturn($value);
}
return $this->_model->getAmounts();
}
/**
* Return sales model items
*
* @return array
*/
protected function _getSalesModelItems()
{
$product = new DataObject(['id' => '1']);
return [
new DataObject(
['name' => 'name 1', 'qty' => 1, 'price' => 0.1, 'original_item' => $product]
),
new DataObject(
['name' => 'name 2', 'qty' => 2, 'price' => 1.2, 'original_item' => $product]
),
new DataObject(
[
'parent_item' => 'parent item 3',
'name' => 'name 3',
'qty' => 3,
'price' => 2.3,
'original_item' => $product,
]
)
];
}
/**
* Convert sales model items to cart items
*
* @param array $salesModelItems
* @return array
*/
protected function _convertToCartItems(array $salesModelItems)
{
$result = [];
foreach ($salesModelItems as $item) {
if ($item->getParentItem()) {
continue;
}
$result[] = new DataObject(
[
'name' => $item->getName(),
'qty' => $item->getQty(),
'amount' => $item->getPrice(),
'id' => $item->getOriginalItem()->getId(),
]
);
}
return $result;
}
}