Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 8d417ac

Browse files
committed
#14020-Cart-Sales-Rule-with-negated-condition-over-special-price-does-not-work-for-configurable-products.
Unit tests coverage: case when child should be used
1 parent 5a7e78a commit 8d417ac

File tree

1 file changed

+198
-0
lines changed
  • app/code/Magento/ConfigurableProduct/Test/Unit/Plugin/SalesRule/Model/Rule/Condition

1 file changed

+198
-0
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\ConfigurableProduct\Plugin\SalesRule\Model\Rule\Condition;
8+
9+
use Magento\Backend\Helper\Data;
10+
use Magento\Catalog\Api\ProductRepositoryInterface;
11+
use Magento\Catalog\Model\Product\Type;
12+
use Magento\Catalog\Model\ProductFactory;
13+
use Magento\Catalog\Model\ResourceModel\Product;
14+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
15+
use Magento\ConfigurableProduct\Plugin\SalesRule\Model\Rule\Condition\Product as ValidatorPlugin;
16+
use Magento\Directory\Model\CurrencyFactory;
17+
use Magento\Eav\Model\Config;
18+
use Magento\Eav\Model\Entity\AbstractEntity;
19+
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection;
20+
use Magento\Framework\App\ScopeResolverInterface;
21+
use Magento\Framework\Locale\Format;
22+
use Magento\Framework\Locale\FormatInterface;
23+
use Magento\Framework\Locale\ResolverInterface;
24+
use Magento\Quote\Model\Quote\Item\AbstractItem;
25+
use Magento\Rule\Model\Condition\Context;
26+
use Magento\SalesRule\Model\Rule\Condition\Product as SalesRuleProduct;
27+
28+
/**
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
31+
class ProductTest extends \PHPUnit\Framework\TestCase
32+
{
33+
/**
34+
* @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
35+
*/
36+
private $objectManager;
37+
38+
/**
39+
* @var SalesRuleProduct
40+
*/
41+
private $validator;
42+
43+
/**
44+
* @var \Magento\ConfigurableProduct\Plugin\SalesRule\Model\Rule\Condition\Product
45+
*/
46+
private $validatorPlugin;
47+
48+
public function setUp()
49+
{
50+
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
51+
$this->validator = $this->createValidator();
52+
$this->validatorPlugin = $this->objectManager->getObject(ValidatorPlugin::class);
53+
}
54+
55+
/**
56+
* @return \Magento\SalesRule\Model\Rule\Condition\Product
57+
*/
58+
private function createValidator(): SalesRuleProduct
59+
{
60+
/** @var Context|\PHPUnit_Framework_MockObject_MockObject $contextMock */
61+
$contextMock = $this->getMockBuilder(Context::class)
62+
->disableOriginalConstructor()
63+
->getMock();
64+
/** @var Data|\PHPUnit_Framework_MockObject_MockObject $backendHelperMock */
65+
$backendHelperMock = $this->getMockBuilder(Data::class)
66+
->disableOriginalConstructor()
67+
->getMock();
68+
/** @var Config|\PHPUnit_Framework_MockObject_MockObject $configMock */
69+
$configMock = $this->getMockBuilder(Config::class)
70+
->disableOriginalConstructor()
71+
->getMock();
72+
/** @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject $productFactoryMock */
73+
$productFactoryMock = $this->getMockBuilder(ProductFactory::class)
74+
->disableOriginalConstructor()
75+
->getMock();
76+
/** @var ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $productRepositoryMock */
77+
$productRepositoryMock = $this->getMockBuilder(ProductRepositoryInterface::class)
78+
->getMockForAbstractClass();
79+
$attributeLoaderInterfaceMock = $this->getMockBuilder(AbstractEntity::class)
80+
->disableOriginalConstructor()
81+
->setMethods(['getAttributesByCode'])
82+
->getMock();
83+
$attributeLoaderInterfaceMock
84+
->expects($this->any())
85+
->method('getAttributesByCode')
86+
->willReturn([]);
87+
/** @var Product|\PHPUnit_Framework_MockObject_MockObject $productMock */
88+
$productMock = $this->getMockBuilder(Product::class)
89+
->disableOriginalConstructor()
90+
->setMethods(['loadAllAttributes', 'getConnection', 'getTable'])
91+
->getMock();
92+
$productMock->expects($this->any())
93+
->method('loadAllAttributes')
94+
->willReturn($attributeLoaderInterfaceMock);
95+
/** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collectionMock */
96+
$collectionMock = $this->getMockBuilder(Collection::class)
97+
->disableOriginalConstructor()
98+
->getMock();
99+
/** @var FormatInterface|\PHPUnit_Framework_MockObject_MockObject $formatMock */
100+
$formatMock = new Format(
101+
$this->getMockBuilder(ScopeResolverInterface::class)->disableOriginalConstructor()->getMock(),
102+
$this->getMockBuilder(ResolverInterface::class)->disableOriginalConstructor()->getMock(),
103+
$this->getMockBuilder(CurrencyFactory::class)->disableOriginalConstructor()->getMock()
104+
);
105+
106+
return new SalesRuleProduct(
107+
$contextMock,
108+
$backendHelperMock,
109+
$configMock,
110+
$productFactoryMock,
111+
$productRepositoryMock,
112+
$productMock,
113+
$collectionMock,
114+
$formatMock
115+
);
116+
}
117+
118+
public function testChildIsUsedForValidation()
119+
{
120+
$configurableProductMock = $this->createProductMock();
121+
$configurableProductMock
122+
->expects($this->any())
123+
->method('getTypeId')
124+
->willReturn(Configurable::TYPE_CODE);
125+
$configurableProductMock
126+
->expects($this->any())
127+
->method('hasData')
128+
->with($this->equalTo('special_price'))
129+
->willReturn(false);
130+
131+
/* @var AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */
132+
$item = $this->getMockBuilder(AbstractItem::class)
133+
->disableOriginalConstructor()
134+
->setMethods(['setProduct', 'getProduct', 'getChildren'])
135+
->getMockForAbstractClass();
136+
$item->expects($this->any())
137+
->method('getProduct')
138+
->willReturn($configurableProductMock);
139+
140+
$simpleProductMock = $this->createProductMock();
141+
$simpleProductMock
142+
->expects($this->any())
143+
->method('getTypeId')
144+
->willReturn(Type::TYPE_SIMPLE);
145+
$simpleProductMock
146+
->expects($this->any())
147+
->method('hasData')
148+
->with($this->equalTo('special_price'))
149+
->willReturn(true);
150+
151+
$childItem = $this->getMockBuilder(AbstractItem::class)
152+
->disableOriginalConstructor()
153+
->setMethods(['getProduct'])
154+
->getMockForAbstractClass();
155+
$childItem->expects($this->any())
156+
->method('getProduct')
157+
->willReturn($simpleProductMock);
158+
159+
$item->expects($this->any())
160+
->method('getChildren')
161+
->willReturn([$childItem]);
162+
$item->expects($this->once())
163+
->method('setProduct')
164+
->with($simpleProductMock);
165+
166+
$this->validator->setAttribute('special_price');
167+
168+
$this->validatorPlugin->beforeValidate($this->validator, $item);
169+
}
170+
171+
/**
172+
* @return Product|\PHPUnit_Framework_MockObject_MockObject
173+
*/
174+
private function createProductMock(): \PHPUnit_Framework_MockObject_MockObject
175+
{
176+
$productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
177+
->disableOriginalConstructor()
178+
->setMethods([
179+
'getAttribute',
180+
'getId',
181+
'setQuoteItemQty',
182+
'setQuoteItemPrice',
183+
'getTypeId',
184+
'hasData',
185+
])
186+
->getMock();
187+
$productMock
188+
->expects($this->any())
189+
->method('setQuoteItemQty')
190+
->willReturnSelf();
191+
$productMock
192+
->expects($this->any())
193+
->method('setQuoteItemPrice')
194+
->willReturnSelf();
195+
196+
return $productMock;
197+
}
198+
}

0 commit comments

Comments
 (0)