RulesApplierTest.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\SalesRule\Test\Unit\Model;
  7. /**
  8. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  9. */
  10. class RulesApplierTest extends \PHPUnit\Framework\TestCase
  11. {
  12. /**
  13. * @var \Magento\SalesRule\Model\RulesApplier
  14. */
  15. protected $rulesApplier;
  16. /**
  17. * @var \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory|\PHPUnit_Framework_MockObject_MockObject
  18. */
  19. protected $calculatorFactory;
  20. /**
  21. * @var \Magento\Framework\Event\Manager|\PHPUnit_Framework_MockObject_MockObject
  22. */
  23. protected $eventManager;
  24. /**
  25. * @var \Magento\SalesRule\Model\Utility|\PHPUnit_Framework_MockObject_MockObject
  26. */
  27. protected $validatorUtility;
  28. /**
  29. * @var \Magento\SalesRule\Model\Quote\ChildrenValidationLocator|\PHPUnit_Framework_MockObject_MockObject
  30. */
  31. protected $childrenValidationLocator;
  32. protected function setUp()
  33. {
  34. $this->calculatorFactory = $this->createMock(
  35. \Magento\SalesRule\Model\Rule\Action\Discount\CalculatorFactory::class
  36. );
  37. $this->eventManager = $this->createPartialMock(\Magento\Framework\Event\Manager::class, ['dispatch']);
  38. $this->validatorUtility = $this->createPartialMock(
  39. \Magento\SalesRule\Model\Utility::class,
  40. ['canProcessRule', 'minFix', 'deltaRoundingFix', 'getItemQty']
  41. );
  42. $this->childrenValidationLocator = $this->createPartialMock(
  43. \Magento\SalesRule\Model\Quote\ChildrenValidationLocator::class,
  44. ['isChildrenValidationRequired']
  45. );
  46. $this->rulesApplier = new \Magento\SalesRule\Model\RulesApplier(
  47. $this->calculatorFactory,
  48. $this->eventManager,
  49. $this->validatorUtility,
  50. $this->childrenValidationLocator
  51. );
  52. }
  53. /**
  54. * @param bool $isChildren
  55. * @param bool $isContinue
  56. *
  57. * @dataProvider dataProviderChildren
  58. */
  59. public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed($isChildren, $isContinue)
  60. {
  61. $positivePrice = 1;
  62. $skipValidation = false;
  63. $item = $this->getPreparedItem();
  64. $couponCode = 111;
  65. $ruleId = 1;
  66. $appliedRuleIds = [$ruleId => $ruleId];
  67. /**
  68. * @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleWithStopFurtherProcessing
  69. */
  70. $ruleWithStopFurtherProcessing = $this->createPartialMock(
  71. \Magento\SalesRule\Model\Rule::class,
  72. ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup', 'getActions']
  73. );
  74. /** @var \Magento\SalesRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject $ruleThatShouldNotBeRun */
  75. $ruleThatShouldNotBeRun = $this->createPartialMock(
  76. \Magento\SalesRule\Model\Rule::class,
  77. ['getStopRulesProcessing', '__wakeup']
  78. );
  79. $actionMock = $this->createPartialMock(\Magento\Rule\Model\Action\Collection::class, ['validate']);
  80. $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing');
  81. $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun');
  82. $rules = [$ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun];
  83. $item->setDiscountCalculationPrice($positivePrice);
  84. $item->setData('calculation_price', $positivePrice);
  85. $this->childrenValidationLocator->expects($this->any())
  86. ->method('isChildrenValidationRequired')
  87. ->willReturn(true);
  88. $this->validatorUtility->expects($this->atLeastOnce())
  89. ->method('canProcessRule')
  90. ->will($this->returnValue(true));
  91. $ruleWithStopFurtherProcessing->expects($this->atLeastOnce())
  92. ->method('getActions')
  93. ->willReturn($actionMock);
  94. $actionMock->expects($this->at(0))
  95. ->method('validate')
  96. ->with($item)
  97. ->willReturn(!$isChildren);
  98. // if there are child elements, check them
  99. if ($isChildren) {
  100. $item->expects($this->atLeastOnce())
  101. ->method('getChildren')
  102. ->willReturn([$item]);
  103. $actionMock->expects($this->at(1))
  104. ->method('validate')
  105. ->with($item)
  106. ->willReturn(!$isContinue);
  107. }
  108. //
  109. if (!$isContinue || !$isChildren) {
  110. $ruleWithStopFurtherProcessing->expects($this->any())
  111. ->method('getRuleId')
  112. ->will($this->returnValue($ruleId));
  113. $this->applyRule($item, $ruleWithStopFurtherProcessing);
  114. $ruleWithStopFurtherProcessing->setStopRulesProcessing(true);
  115. $ruleThatShouldNotBeRun->expects($this->never())
  116. ->method('getStopRulesProcessing');
  117. }
  118. $result = $this->rulesApplier->applyRules($item, $rules, $skipValidation, $couponCode);
  119. $this->assertEquals($appliedRuleIds, $result);
  120. }
  121. /**
  122. * @return array
  123. */
  124. public function dataProviderChildren()
  125. {
  126. return [
  127. ['isChildren' => true, 'isContinue' => false],
  128. ['isChildren' => false, 'isContinue' => true],
  129. ];
  130. }
  131. /**
  132. * @return \Magento\Quote\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject
  133. */
  134. protected function getPreparedItem()
  135. {
  136. /** @var \Magento\Quote\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject $address */
  137. $address = $this->createPartialMock(\Magento\Quote\Model\Quote\Address::class, [
  138. 'getQuote',
  139. 'setCouponCode',
  140. 'setAppliedRuleIds',
  141. '__wakeup'
  142. ]);
  143. /** @var \Magento\Quote\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */
  144. $item = $this->createPartialMock(\Magento\Quote\Model\Quote\Item::class, [
  145. 'setDiscountAmount',
  146. 'setBaseDiscountAmount',
  147. 'setDiscountPercent',
  148. 'getAddress',
  149. 'setAppliedRuleIds',
  150. '__wakeup',
  151. 'getChildren'
  152. ]);
  153. $quote = $this->createPartialMock(\Magento\Quote\Model\Quote::class, ['getStore', '__wakeUp']);
  154. $item->expects($this->any())->method('getAddress')->will($this->returnValue($address));
  155. $address->expects($this->any())
  156. ->method('getQuote')
  157. ->will($this->returnValue($quote));
  158. return $item;
  159. }
  160. /**
  161. * @param $item
  162. * @param $rule
  163. */
  164. protected function applyRule($item, $rule)
  165. {
  166. $qty = 2;
  167. $discountCalc = $this->createPartialMock(
  168. \Magento\SalesRule\Model\Rule\Action\Discount\DiscountInterface::class,
  169. ['fixQuantity', 'calculate']
  170. );
  171. $discountData = $this->getMockBuilder(\Magento\SalesRule\Model\Rule\Action\Discount\Data::class)
  172. ->setConstructorArgs(
  173. [
  174. 'amount' => 30,
  175. 'baseAmount' => 30,
  176. 'originalAmount' => 30,
  177. 'baseOriginalAmount' => 30
  178. ]
  179. )
  180. ->getMock();
  181. $this->validatorUtility->expects($this->any())
  182. ->method('getItemQty')
  183. ->with($this->anything(), $this->anything())
  184. ->will($this->returnValue($qty));
  185. $discountCalc->expects($this->any())
  186. ->method('fixQuantity')
  187. ->with($this->equalTo($qty), $this->equalTo($rule))
  188. ->will($this->returnValue($qty));
  189. $discountCalc->expects($this->any())
  190. ->method('calculate')
  191. ->with($this->equalTo($rule), $this->equalTo($item), $this->equalTo($qty))
  192. ->will($this->returnValue($discountData));
  193. $this->calculatorFactory->expects($this->any())
  194. ->method('create')
  195. ->with($this->anything())
  196. ->will($this->returnValue($discountCalc));
  197. }
  198. }