Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ValidatorTest.php
Go to the documentation of this file.
1 <?php
7 
12 class ValidatorTest extends \PHPUnit\Framework\TestCase
13 {
17  protected $helper;
18 
22  protected $model;
23 
27  protected $item;
28 
32  protected $addressMock;
33 
37  protected $rulesApplier;
38 
42  protected $validators;
43 
47  protected $utility;
48 
52  protected $ruleCollection;
53 
57  protected $catalogData;
58 
62  protected $messageManager;
63 
64  protected function setUp()
65  {
66  $this->helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
67  $this->rulesApplier = $this->createPartialMock(
68  \Magento\SalesRule\Model\RulesApplier::class,
69  ['setAppliedRuleIds', 'applyRules', 'addDiscountDescription', '__wakeup']
70  );
71 
72  $this->addressMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address::class)
73  ->disableOriginalConstructor()
74  ->setMethods(
75  [
76  'getShippingAmountForDiscount',
77  'getQuote',
78  'getCustomAttributesCodes',
79  'setCartFixedRules'
80  ]
81  )
82  ->getMock();
83 
85  $this->item = $this->createPartialMock(
86  \Magento\Quote\Model\Quote\Item::class,
87  ['__wakeup', 'getAddress', 'getParentItemId']
88  );
89  $this->item->expects($this->any())
90  ->method('getAddress')
91  ->willReturn($this->addressMock);
92 
93  $context = $this->createMock(\Magento\Framework\Model\Context::class);
94  $registry = $this->createMock(\Magento\Framework\Registry::class);
95  $this->catalogData = $this->createMock(\Magento\Catalog\Helper\Data::class);
96  $this->utility = $this->createMock(\Magento\SalesRule\Model\Utility::class);
97  $this->validators = $this->createPartialMock(\Magento\SalesRule\Model\Validator\Pool::class, ['getValidators']);
98  $this->messageManager = $this->createMock(\Magento\Framework\Message\Manager::class);
99  $this->ruleCollection = $this->getMockBuilder(\Magento\SalesRule\Model\ResourceModel\Rule\Collection::class)
100  ->disableOriginalConstructor()
101  ->getMock();
102  $ruleCollectionFactoryMock = $this->prepareRuleCollectionMock($this->ruleCollection);
103 
105  $this->model = $this->helper->getObject(
106  \Magento\SalesRule\Model\Validator::class,
107  [
108  'context' => $context,
109  'registry' => $registry,
110  'collectionFactory' => $ruleCollectionFactoryMock,
111  'catalogData' => $this->catalogData,
112  'utility' => $this->utility,
113  'rulesApplier' => $this->rulesApplier,
114  'validators' => $this->validators,
115  'messageManager' => $this->messageManager
116  ]
117  );
118  $this->model->setWebsiteId(1);
119  $this->model->setCustomerGroupId(2);
120  $this->model->setCouponCode('code');
121  $this->ruleCollection->expects($this->any())
122  ->method('setValidationFilter')
123  ->with(
124  $this->model->getWebsiteId(),
125  $this->model->getCustomerGroupId(),
126  $this->model->getCouponCode(),
127  null,
129  )
130  ->willReturnSelf();
131  }
132 
136  protected function getQuoteItemMock()
137  {
138  $fixturePath = __DIR__ . '/_files/';
139  $itemDownloadable = $this->createPartialMock(
140  \Magento\Quote\Model\Quote\Item::class,
141  ['getAddress', '__wakeup']
142  );
143  $itemDownloadable->expects($this->any())->method('getAddress')->will($this->returnValue($this->addressMock));
144 
145  $itemSimple = $this->createPartialMock(\Magento\Quote\Model\Quote\Item::class, ['getAddress', '__wakeup']);
146  $itemSimple->expects($this->any())->method('getAddress')->will($this->returnValue($this->addressMock));
147 
149  $quote = $this->createPartialMock(\Magento\Quote\Model\Quote::class, ['getStoreId', '__wakeup']);
150  $quote->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
151 
152  $itemData = include $fixturePath . 'quote_item_downloadable.php';
153  $itemDownloadable->addData($itemData);
154  $quote->addItem($itemDownloadable);
155 
156  $itemData = include $fixturePath . 'quote_item_simple.php';
157  $itemSimple->addData($itemData);
158  $quote->addItem($itemSimple);
159 
160  return $itemDownloadable;
161  }
162 
163  public function testCanApplyRules()
164  {
165  $this->model->init(
166  $this->model->getWebsiteId(),
167  $this->model->getCustomerGroupId(),
168  $this->model->getCouponCode()
169  );
170  $item = $this->getQuoteItemMock();
171  $rule = $this->createMock(\Magento\SalesRule\Model\Rule::class);
172  $actionsCollection = $this->createPartialMock(\Magento\Rule\Model\Action\Collection::class, ['validate']);
173  $actionsCollection->expects($this->any())
174  ->method('validate')
175  ->with($item)
176  ->willReturn(true);
177  $rule->expects($this->any())
178  ->method('getActions')
179  ->willReturn($actionsCollection);
180  $iterator = new \ArrayIterator([$rule]);
181  $this->ruleCollection->expects($this->any())
182  ->method('getIterator')
183  ->willReturn($iterator);
184 
185  $this->utility->expects($this->any())
186  ->method('canProcessRule')
187  ->with($rule, $this->anything())
188  ->willReturn(true);
189 
190  $quote = $item->getQuote();
191  $quote->setItemsQty(2);
192  $quote->setVirtualItemsQty(1);
193 
194  $this->assertTrue($this->model->canApplyRules($item));
195 
196  $quote->setItemsQty(2);
197  $quote->setVirtualItemsQty(2);
198 
199  $this->assertTrue($this->model->canApplyRules($item));
200  }
201 
202  public function testProcess()
203  {
204  $negativePrice = -1;
205 
206  $this->item->setDiscountCalculationPrice($negativePrice);
207  $this->item->setData('calculation_price', $negativePrice);
208 
209  $this->rulesApplier->expects($this->never())->method('applyRules');
210 
211  $this->model->init(
212  $this->model->getWebsiteId(),
213  $this->model->getCustomerGroupId(),
214  $this->model->getCouponCode()
215  );
216  $this->model->process($this->item);
217  }
218 
220  {
221  $negativePrice = -1;
222  $nonZeroDiscount = 123;
223  $this->model->init(
224  $this->model->getWebsiteId(),
225  $this->model->getCustomerGroupId(),
226  $this->model->getCouponCode()
227  );
228 
229  $this->item->setDiscountCalculationPrice($negativePrice);
230  $this->item->setData('calculation_price', $negativePrice);
231 
232  $this->item->setDiscountAmount($nonZeroDiscount);
233  $this->item->setBaseDiscountAmount($nonZeroDiscount);
234  $this->item->setDiscountPercent($nonZeroDiscount);
235 
236  $this->model->process($this->item);
237 
238  $this->assertEquals(0, $this->item->getDiscountAmount());
239  $this->assertEquals(0, $this->item->getBaseDiscountAmount());
240  $this->assertEquals(0, $this->item->getDiscountPercent());
241  }
242 
244  {
245  $positivePrice = 1;
246  $ruleId1 = 123;
247  $ruleId2 = 234;
248  $expectedRuleIds = [$ruleId1 => $ruleId1, $ruleId2 => $ruleId2];
249  $this->model->init(
250  $this->model->getWebsiteId(),
251  $this->model->getCustomerGroupId(),
252  $this->model->getCouponCode()
253  );
254 
255  $this->item->setDiscountCalculationPrice($positivePrice);
256  $this->item->setData('calculation_price', $positivePrice);
257  $this->model->setSkipActionsValidation(true);
258 
259  $this->rulesApplier->expects($this->once())
260  ->method('applyRules')
261  ->with(
262  $this->equalTo($this->item),
263  $this->equalTo($this->ruleCollection),
264  $this->anything(),
265  $this->anything()
266  )
267  ->will($this->returnValue($expectedRuleIds));
268  $this->rulesApplier->expects($this->once())
269  ->method('setAppliedRuleIds')
270  ->with(
271  $this->anything(),
272  $expectedRuleIds
273  );
274 
275  $this->model->process($this->item);
276  }
277 
278  public function testInit()
279  {
280  $this->assertInstanceOf(
281  \Magento\SalesRule\Model\Validator::class,
282  $this->model->init(
283  $this->model->getWebsiteId(),
284  $this->model->getCustomerGroupId(),
285  $this->model->getCouponCode()
286  )
287  );
288  }
289 
290  public function testCanApplyDiscount()
291  {
292  $validator = $this->getMockBuilder(\Magento\Framework\Validator\AbstractValidator::class)
293  ->setMethods(['isValid'])
294  ->disableOriginalConstructor()
295  ->getMockForAbstractClass();
296 
297  $this->validators->expects($this->any())
298  ->method('getValidators')
299  ->with('discount')
300  ->willReturn([$validator]);
301  $validator->expects($this->any())
302  ->method('isValid')
303  ->with($this->item)
304  ->willReturn(false);
305 
306  $this->model->init(
307  $this->model->getWebsiteId(),
308  $this->model->getCustomerGroupId(),
309  $this->model->getCouponCode()
310  );
311  $this->assertFalse($this->model->canApplyDiscount($this->item));
312  }
313 
315  {
316  $rule = $this->createPartialMock(
317  \Magento\SalesRule\Model\Rule::class,
318  ['getSimpleAction', 'getActions', 'getId']
319  );
320  $item1 = $this->getMockForAbstractClass(
321  \Magento\Quote\Model\Quote\Item\AbstractItem::class,
322  [],
323  '',
324  false,
325  true,
326  true,
327  [
328  '__clone',
329  'getDiscountCalculationPrice',
330  'getBaseDiscountCalculationPrice',
331  'getCalculationPrice',
332  'getParentItemId'
333  ]
334  );
335  $item2 = clone $item1;
336  $items = [$item1, $item2];
337 
338  $rule->expects($this->any())
339  ->method('getSimpleAction')
340  ->willReturn(\Magento\SalesRule\Model\Rule::CART_FIXED_ACTION);
341  $iterator = new \ArrayIterator([$rule]);
342  $this->ruleCollection->expects($this->once())->method('getIterator')->willReturn($iterator);
343  $validator = $this->getMockBuilder(\Magento\Framework\Validator\AbstractValidator::class)
344  ->setMethods(['isValid'])
345  ->disableOriginalConstructor()
346  ->getMockForAbstractClass();
347 
348  $this->validators->expects($this->atLeastOnce())->method('getValidators')->with('discount')
349  ->willReturn([$validator]);
350  $validator->expects($this->at(0))->method('isValid')->with($item1)->willReturn(false);
351  $validator->expects($this->at(1))->method('isValid')->with($item2)->willReturn(true);
352 
353  $item1->expects($this->any())->method('getParentItemId')->willReturn(false);
354  $item1->expects($this->never())->method('getDiscountCalculationPrice');
355  $item1->expects($this->never())->method('getBaseDiscountCalculationPrice');
356  $item2->expects($this->any())->method('getParentItemId')->willReturn(false);
357  $item2->expects($this->any())->method('getDiscountCalculationPrice')->willReturn(50);
358  $item2->expects($this->once())->method('getBaseDiscountCalculationPrice')->willReturn(50);
359  $this->utility->expects($this->once())->method('getItemQty')->willReturn(1);
360  $this->utility->expects($this->any())->method('canProcessRule')->willReturn(true);
361 
362  $actionsCollection = $this->createPartialMock(\Magento\Rule\Model\Action\Collection::class, ['validate']);
363  $actionsCollection->expects($this->at(0))->method('validate')->with($item1)->willReturn(true);
364  $actionsCollection->expects($this->at(1))->method('validate')->with($item2)->willReturn(true);
365  $rule->expects($this->any())->method('getActions')->willReturn($actionsCollection);
366  $rule->expects($this->any())->method('getId')->willReturn(1);
367 
368  $this->model->init(
369  $this->model->getWebsiteId(),
370  $this->model->getCustomerGroupId(),
371  $this->model->getCouponCode()
372  );
373  $this->model->initTotals($items, $this->addressMock);
374  $this->assertArrayHasKey('items_price', $this->model->getRuleItemTotalsInfo($rule->getId()));
375  $this->assertArrayHasKey('base_items_price', $this->model->getRuleItemTotalsInfo($rule->getId()));
376  $this->assertArrayHasKey('items_count', $this->model->getRuleItemTotalsInfo($rule->getId()));
377  $this->assertEquals(1, $this->model->getRuleItemTotalsInfo($rule->getId())['items_count']);
378  }
379 
380  public function testInitTotalsNoItems()
381  {
382  $address = $this->createMock(\Magento\Quote\Model\Quote\Address::class);
383  $this->item->expects($this->never())
384  ->method('getParentItemId');
385  $this->model->init(
386  $this->model->getWebsiteId(),
387  $this->model->getCustomerGroupId(),
388  $this->model->getCouponCode()
389  );
390  $this->model->initTotals([], $address);
391  }
392 
398  {
399  $this->ruleCollection->expects($this->any())
400  ->method('addFieldToFilter')
401  ->with('is_active', 1)
402  ->will($this->returnSelf());
403  $this->ruleCollection->expects($this->any())
404  ->method('load')
405  ->will($this->returnSelf());
406 
407  $ruleCollectionFactoryMock =
408  $this->getMockBuilder(\Magento\SalesRule\Model\ResourceModel\Rule\CollectionFactory::class)
409  ->disableOriginalConstructor()
410  ->setMethods(['create'])
411  ->getMock();
412  $ruleCollectionFactoryMock->expects($this->any())
413  ->method('create')
414  ->will($this->returnValue($ruleCollection));
415  return $ruleCollectionFactoryMock;
416  }
417 
419  {
420  $iterator = new \ArrayIterator([]);
421  $this->ruleCollection->expects($this->any())
422  ->method('getIterator')
423  ->willReturn($iterator);
424  $this->model->init(
425  $this->model->getWebsiteId(),
426  $this->model->getCustomerGroupId(),
427  $this->model->getCouponCode()
428  );
429  $this->assertInstanceOf(
430  \Magento\SalesRule\Model\Validator::class,
431  $this->model->processShippingAmount($this->setupAddressMock())
432  );
433  }
434 
436  {
437  $ruleMock = $this->getMockBuilder(\Magento\SalesRule\Model\Rule::class)
438  ->disableOriginalConstructor()
439  ->setMethods([])
440  ->getMock();
441  $iterator = new \ArrayIterator([$ruleMock]);
442  $this->ruleCollection->expects($this->any())
443  ->method('getIterator')
444  ->willReturn($iterator);
445  $this->model->init(
446  $this->model->getWebsiteId(),
447  $this->model->getCustomerGroupId(),
448  $this->model->getCouponCode()
449  );
450  $this->assertInstanceOf(
451  \Magento\SalesRule\Model\Validator::class,
452  $this->model->processShippingAmount($this->setupAddressMock())
453  );
454  }
455 
460  public function testProcessShippingAmountActions($action)
461  {
462  $discountAmount = 50;
463 
464  $ruleMock = $this->getMockBuilder(\Magento\SalesRule\Model\Rule::class)
465  ->disableOriginalConstructor()
466  ->setMethods(['getApplyToShipping', 'getSimpleAction', 'getDiscountAmount'])
467  ->getMock();
468  $ruleMock->expects($this->any())
469  ->method('getApplyToShipping')
470  ->willReturn(true);
471  $ruleMock->expects($this->any())
472  ->method('getDiscountAmount')
473  ->willReturn($discountAmount);
474  $ruleMock->expects($this->any())
475  ->method('getSimpleAction')
476  ->willReturn($action);
477 
478  $iterator = new \ArrayIterator([$ruleMock]);
479  $this->ruleCollection->expects($this->any())
480  ->method('getIterator')
481  ->willReturn($iterator);
482 
483  $this->utility->expects($this->any())
484  ->method('canProcessRule')
485  ->willReturn(true);
486 
487  $this->model->init(
488  $this->model->getWebsiteId(),
489  $this->model->getCustomerGroupId(),
490  $this->model->getCouponCode()
491  );
492  $this->assertInstanceOf(
493  \Magento\SalesRule\Model\Validator::class,
494  $this->model->processShippingAmount($this->setupAddressMock(5))
495  );
496  }
497 
501  public static function dataProviderActions()
502  {
503  return [
509  ];
510  }
511 
516  protected function setupAddressMock($shippingAmount = null)
517  {
518  $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
519  ->disableOriginalConstructor()
520  ->setMethods([])
521  ->getMock();
522  $quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class)
523  ->disableOriginalConstructor()
524  ->setMethods(['setAppliedRuleIds', 'getStore'])
525  ->getMock();
526  $quoteMock->expects($this->any())
527  ->method('getStore')
528  ->willReturn($storeMock);
529  $quoteMock->expects($this->any())
530  ->method('setAppliedRuleIds')
531  ->willReturnSelf();
532 
533  $this->addressMock->expects($this->any())
534  ->method('getShippingAmountForDiscount')
535  ->willReturn($shippingAmount);
536  $this->addressMock->expects($this->any())
537  ->method('getQuote')
538  ->willReturn($quoteMock);
539  $this->addressMock->expects($this->any())
540  ->method('getCustomAttributesCodes')
541  ->willReturn([]);
542  return $this->addressMock;
543  }
544 
545  public function testReset()
546  {
547  $this->utility->expects($this->once())
548  ->method('resetRoundingDeltas');
549  $quoteMock = $this->getMockBuilder(\Magento\Quote\Model\Quote::class)
550  ->disableOriginalConstructor()
551  ->getMock();
552  $addressMock = $this->getMockBuilder(\Magento\Quote\Model\Quote\Address::class)
553  ->disableOriginalConstructor()
554  ->getMock();
555  $addressMock->expects($this->once())
556  ->method('getQuote')
557  ->willReturn($quoteMock);
558  $this->model->init(
559  $this->model->getWebsiteId(),
560  $this->model->getCustomerGroupId(),
561  $this->model->getCouponCode()
562  );
563  $this->assertInstanceOf(\Magento\SalesRule\Model\Validator::class, $this->model->reset($addressMock));
564  }
565 }
defined('TESTS_BP')||define('TESTS_BP' __DIR__
Definition: _bootstrap.php:60
$quote
$address
Definition: customer.php:38
$items