BundleSelectionPriceTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Bundle\Test\Unit\Pricing\Price;
  7. use Magento\Bundle\Pricing\Price\FinalPrice;
  8. use Magento\Catalog\Pricing\Price\RegularPrice;
  9. /**
  10. * Class BundleSelectionPriceTest
  11. *
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. */
  14. class BundleSelectionPriceTest extends \PHPUnit\Framework\TestCase
  15. {
  16. /**
  17. * @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice
  18. */
  19. protected $selectionPrice;
  20. /**
  21. * @var \Magento\Framework\Pricing\Adjustment\CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
  22. */
  23. protected $calculatorMock;
  24. /**
  25. * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
  26. */
  27. protected $productMock;
  28. /**
  29. * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
  30. */
  31. protected $bundleMock;
  32. /**
  33. * @var \Magento\Framework\Event\Manager|\PHPUnit_Framework_MockObject_MockObject
  34. */
  35. protected $eventManagerMock;
  36. /**
  37. * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
  38. */
  39. protected $priceInfoMock;
  40. /**
  41. * @var \Magento\Catalog\Pricing\Price\FinalPrice|\PHPUnit_Framework_MockObject_MockObject
  42. */
  43. protected $finalPriceMock;
  44. /**
  45. * @var \Magento\Catalog\Pricing\Price\RegularPrice|\PHPUnit_Framework_MockObject_MockObject
  46. */
  47. protected $regularPriceMock;
  48. /**
  49. * @var \Magento\Bundle\Pricing\Price\DiscountCalculator|\PHPUnit_Framework_MockObject_MockObject
  50. */
  51. protected $discountCalculatorMock;
  52. /**
  53. * @var \Magento\Framework\Pricing\PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
  54. */
  55. protected $priceCurrencyMock;
  56. /**
  57. * @var float
  58. */
  59. protected $quantity;
  60. /**
  61. * Test setUp
  62. */
  63. protected function setUp()
  64. {
  65. $this->productMock = $this->createPartialMock(
  66. \Magento\Catalog\Model\Product::class,
  67. ['__wakeup', 'getPriceInfo', 'getSelectionPriceType', 'getSelectionPriceValue']
  68. );
  69. $this->bundleMock = $this->createPartialMock(
  70. \Magento\Catalog\Model\Product::class,
  71. ['__wakeup', 'getPriceType', 'getPriceInfo', 'setFinalPrice', 'getData']
  72. );
  73. $this->calculatorMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\CalculatorInterface::class)
  74. ->getMockForAbstractClass();
  75. $this->eventManagerMock = $this->createPartialMock(\Magento\Framework\Event\Manager::class, ['dispatch']);
  76. $this->priceInfoMock = $this->createPartialMock(\Magento\Framework\Pricing\PriceInfo\Base::class, ['getPrice']);
  77. $this->discountCalculatorMock = $this->createMock(\Magento\Bundle\Pricing\Price\DiscountCalculator::class);
  78. $this->finalPriceMock = $this->createMock(\Magento\Catalog\Pricing\Price\FinalPrice::class);
  79. $this->regularPriceMock = $this->createMock(\Magento\Catalog\Pricing\Price\RegularPrice::class);
  80. $this->productMock->expects($this->atLeastOnce())
  81. ->method('getPriceInfo')
  82. ->will($this->returnValue($this->priceInfoMock));
  83. $this->priceCurrencyMock = $this->createMock(\Magento\Framework\Pricing\PriceCurrencyInterface::class);
  84. $this->quantity = 1;
  85. $this->setupSelectionPrice();
  86. }
  87. /**
  88. * @param bool $useRegularPrice
  89. */
  90. protected function setupSelectionPrice($useRegularPrice = false)
  91. {
  92. $this->selectionPrice = new \Magento\Bundle\Pricing\Price\BundleSelectionPrice(
  93. $this->productMock,
  94. $this->quantity,
  95. $this->calculatorMock,
  96. $this->priceCurrencyMock,
  97. $this->bundleMock,
  98. $this->eventManagerMock,
  99. $this->discountCalculatorMock,
  100. $useRegularPrice
  101. );
  102. }
  103. /**
  104. * Test for method getValue with dynamic productType
  105. *
  106. * @param bool $useRegularPrice
  107. * @dataProvider useRegularPriceDataProvider
  108. * @SuppressWarnings(PHPMD.NPathComplexity)
  109. */
  110. public function testGetValueTypeDynamic($useRegularPrice)
  111. {
  112. $this->setupSelectionPrice($useRegularPrice);
  113. $priceCode = $useRegularPrice ? RegularPrice::PRICE_CODE : FinalPrice::PRICE_CODE;
  114. $regularPrice = 100.125;
  115. $discountedPrice = 70.453;
  116. $actualPrice = $useRegularPrice ? $regularPrice : $discountedPrice;
  117. $expectedPrice = $useRegularPrice ? round($regularPrice, 2) : round($discountedPrice, 2);
  118. $this->bundleMock->expects($this->once())
  119. ->method('getPriceType')
  120. ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC));
  121. $this->priceInfoMock->expects($this->once())
  122. ->method('getPrice')
  123. ->with($this->equalTo($priceCode))
  124. ->will($this->returnValue($this->finalPriceMock));
  125. $this->finalPriceMock->expects($this->once())
  126. ->method('getValue')
  127. ->will($this->returnValue($actualPrice));
  128. if (!$useRegularPrice) {
  129. $this->discountCalculatorMock->expects($this->once())
  130. ->method('calculateDiscount')
  131. ->with(
  132. $this->equalTo($this->bundleMock),
  133. $this->equalTo($actualPrice)
  134. )
  135. ->will($this->returnValue($discountedPrice));
  136. }
  137. $this->priceCurrencyMock->expects($this->once())
  138. ->method('round')
  139. ->with($actualPrice)
  140. ->will($this->returnValue($expectedPrice));
  141. $this->assertEquals($expectedPrice, $this->selectionPrice->getValue());
  142. }
  143. /**
  144. * Test for method getValue with type Fixed and selectionPriceType not null.
  145. *
  146. * @param bool $useRegularPrice
  147. * @dataProvider useRegularPriceDataProvider
  148. *
  149. * @return void
  150. */
  151. public function testGetValueTypeFixedWithSelectionPriceType(bool $useRegularPrice)
  152. {
  153. $this->setupSelectionPrice($useRegularPrice);
  154. $regularPrice = 100.125;
  155. $discountedPrice = 70.453;
  156. $actualPrice = $useRegularPrice ? $regularPrice : $discountedPrice;
  157. $expectedPrice = $useRegularPrice ? round($regularPrice, 2) : round($discountedPrice, 2);
  158. $this->bundleMock->expects($this->once())
  159. ->method('getPriceType')
  160. ->willReturn(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED);
  161. $this->bundleMock->expects($this->atLeastOnce())
  162. ->method('getPriceInfo')
  163. ->willReturn($this->priceInfoMock);
  164. $this->priceInfoMock->expects($this->once())
  165. ->method('getPrice')
  166. ->with(RegularPrice::PRICE_CODE)
  167. ->willReturn($this->regularPriceMock);
  168. $this->regularPriceMock->expects($this->once())
  169. ->method('getValue')
  170. ->willReturn($actualPrice);
  171. $this->bundleMock->expects($this->once())
  172. ->method('setFinalPrice')
  173. ->willReturnSelf();
  174. $this->eventManagerMock->expects($this->once())
  175. ->method('dispatch');
  176. $this->bundleMock->expects($this->exactly(2))
  177. ->method('getData')
  178. ->willReturnMap(
  179. [
  180. ['qty', null, 1],
  181. ['final_price', null, 100],
  182. ['price', null, 100],
  183. ]
  184. );
  185. $this->productMock->expects($this->once())
  186. ->method('getSelectionPriceType')
  187. ->willReturn(true);
  188. $this->productMock->expects($this->any())
  189. ->method('getSelectionPriceValue')
  190. ->willReturn($actualPrice);
  191. if (!$useRegularPrice) {
  192. $this->discountCalculatorMock->expects($this->once())
  193. ->method('calculateDiscount')
  194. ->with($this->bundleMock, $actualPrice)
  195. ->willReturn($discountedPrice);
  196. }
  197. $this->priceCurrencyMock->expects($this->once())
  198. ->method('round')
  199. ->with($actualPrice)
  200. ->willReturn($expectedPrice);
  201. $this->assertEquals($expectedPrice, $this->selectionPrice->getValue());
  202. }
  203. /**
  204. * test for method getValue with type Fixed and selectionPriceType is empty or zero
  205. *
  206. * @param bool $useRegularPrice
  207. * @dataProvider useRegularPriceDataProvider
  208. */
  209. public function testGetValueTypeFixedWithoutSelectionPriceType($useRegularPrice)
  210. {
  211. $this->setupSelectionPrice($useRegularPrice);
  212. $regularPrice = 100.125;
  213. $discountedPrice = 70.453;
  214. $convertedValue = 100.247;
  215. $actualPrice = $useRegularPrice ? $convertedValue : $discountedPrice;
  216. $expectedPrice = $useRegularPrice ? round($convertedValue, 2) : round($discountedPrice, 2);
  217. $this->bundleMock->expects($this->once())
  218. ->method('getPriceType')
  219. ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
  220. $this->productMock->expects($this->once())
  221. ->method('getSelectionPriceType')
  222. ->will($this->returnValue(false));
  223. $this->productMock->expects($this->any())
  224. ->method('getSelectionPriceValue')
  225. ->will($this->returnValue($regularPrice));
  226. $this->priceCurrencyMock->expects($this->once())
  227. ->method('convert')
  228. ->with($regularPrice)
  229. ->will($this->returnValue($convertedValue));
  230. if (!$useRegularPrice) {
  231. $this->discountCalculatorMock->expects($this->once())
  232. ->method('calculateDiscount')
  233. ->with(
  234. $this->equalTo($this->bundleMock),
  235. $this->equalTo($convertedValue)
  236. )
  237. ->will($this->returnValue($discountedPrice));
  238. }
  239. $this->priceCurrencyMock->expects($this->once())
  240. ->method('round')
  241. ->with($actualPrice)
  242. ->will($this->returnValue($expectedPrice));
  243. $this->assertEquals($expectedPrice, $this->selectionPrice->getValue());
  244. }
  245. /**
  246. * test for method getValue with type Fixed and selectionPriceType is empty or zero
  247. *
  248. * @param bool $useRegularPrice
  249. * @dataProvider useRegularPriceDataProvider
  250. */
  251. public function testFixedPriceWithMultipleQty($useRegularPrice)
  252. {
  253. $qty = 2;
  254. $selectionPrice = new \Magento\Bundle\Pricing\Price\BundleSelectionPrice(
  255. $this->productMock,
  256. $qty,
  257. $this->calculatorMock,
  258. $this->priceCurrencyMock,
  259. $this->bundleMock,
  260. $this->eventManagerMock,
  261. $this->discountCalculatorMock,
  262. $useRegularPrice
  263. );
  264. $this->setupSelectionPrice($useRegularPrice);
  265. $regularPrice = 100.125;
  266. $discountedPrice = 70.453;
  267. $convertedValue = 100.247;
  268. $actualPrice = $useRegularPrice ? $convertedValue : $discountedPrice;
  269. $expectedPrice = $useRegularPrice ? round($convertedValue, 2) : round($discountedPrice, 2);
  270. $this->bundleMock->expects($this->once())
  271. ->method('getPriceType')
  272. ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
  273. $this->productMock->expects($this->once())
  274. ->method('getSelectionPriceType')
  275. ->will($this->returnValue(false));
  276. $this->productMock->expects($this->any())
  277. ->method('getSelectionPriceValue')
  278. ->will($this->returnValue($regularPrice));
  279. $this->priceCurrencyMock->expects($this->once())
  280. ->method('convert')
  281. ->with($regularPrice)
  282. ->will($this->returnValue($convertedValue));
  283. if (!$useRegularPrice) {
  284. $this->discountCalculatorMock->expects($this->once())
  285. ->method('calculateDiscount')
  286. ->with(
  287. $this->equalTo($this->bundleMock),
  288. $this->equalTo($convertedValue)
  289. )
  290. ->will($this->returnValue($discountedPrice));
  291. }
  292. $this->priceCurrencyMock->expects($this->once())
  293. ->method('round')
  294. ->with($actualPrice)
  295. ->will($this->returnValue($expectedPrice));
  296. $this->assertEquals($expectedPrice, $selectionPrice->getValue());
  297. }
  298. /**
  299. * @return array
  300. */
  301. public function useRegularPriceDataProvider()
  302. {
  303. return [
  304. 'useRegularPrice' => [
  305. true,
  306. ],
  307. 'notUseRegularPrice' => [
  308. false,
  309. ],
  310. ];
  311. }
  312. public function testGetProductFixedBundle()
  313. {
  314. $this->bundleMock->expects($this->any())
  315. ->method('getPriceType')
  316. ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
  317. $product = $this->selectionPrice->getProduct();
  318. $this->assertEquals($this->bundleMock, $product);
  319. }
  320. public function testGetProductDynamicBundle()
  321. {
  322. $this->bundleMock->expects($this->any())
  323. ->method('getPriceType')
  324. ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC));
  325. $product = $this->selectionPrice->getProduct();
  326. $this->assertEquals($this->productMock, $product);
  327. }
  328. public function testGetAmount()
  329. {
  330. $this->setupSelectionPrice();
  331. $price = 10.;
  332. $amount = 20.;
  333. $this->priceInfoMock->expects($this->once())
  334. ->method('getPrice')
  335. ->with(\Magento\Bundle\Pricing\Price\FinalPrice::PRICE_CODE)
  336. ->willReturn($this->finalPriceMock);
  337. $this->finalPriceMock->expects($this->once())
  338. ->method('getValue')
  339. ->willReturn($price);
  340. $this->discountCalculatorMock->expects($this->once())
  341. ->method('calculateDiscount')
  342. ->with($this->bundleMock, $price)
  343. ->willReturn($price);
  344. $this->priceCurrencyMock->expects($this->once())
  345. ->method('round')
  346. ->with($price)
  347. ->willReturn($price);
  348. $this->bundleMock->expects($this->any())
  349. ->method('getPriceType')
  350. ->willReturn(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC);
  351. $this->calculatorMock->expects($this->once())
  352. ->method('getAmount')
  353. ->with($price, $this->productMock, null)
  354. ->willReturn($amount);
  355. $this->assertEquals($amount, $this->selectionPrice->getAmount());
  356. }
  357. }