RefundOrderTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sales\Test\Unit\Model;
  7. use Magento\Framework\App\ResourceConnection;
  8. use Magento\Framework\DB\Adapter\AdapterInterface;
  9. use Magento\Sales\Api\CreditmemoRepositoryInterface;
  10. use Magento\Sales\Api\Data\CreditmemoCommentCreationInterface;
  11. use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
  12. use Magento\Sales\Api\Data\CreditmemoInterface;
  13. use Magento\Sales\Api\Data\CreditmemoItemCreationInterface;
  14. use Magento\Sales\Api\Data\OrderInterface;
  15. use Magento\Sales\Api\OrderRepositoryInterface;
  16. use Magento\Sales\Model\Order;
  17. use Magento\Sales\Model\Order\Config as OrderConfig;
  18. use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
  19. use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
  20. use Magento\Sales\Model\Order\OrderStateResolverInterface;
  21. use Magento\Sales\Model\Order\RefundAdapterInterface;
  22. use Magento\Sales\Model\Order\Validation\RefundOrderInterface;
  23. use Magento\Sales\Model\RefundOrder;
  24. use Magento\Sales\Model\ValidatorResultInterface;
  25. use Psr\Log\LoggerInterface;
  26. /**
  27. * Class RefundOrderTest
  28. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  29. * @SuppressWarnings(PHPMD.TooManyFields)
  30. */
  31. class RefundOrderTest extends \PHPUnit\Framework\TestCase
  32. {
  33. /**
  34. * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
  35. */
  36. private $resourceConnectionMock;
  37. /**
  38. * @var OrderRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
  39. */
  40. private $orderRepositoryMock;
  41. /**
  42. * @var CreditmemoDocumentFactory|\PHPUnit_Framework_MockObject_MockObject
  43. */
  44. private $creditmemoDocumentFactoryMock;
  45. /**
  46. * @var RefundAdapterInterface|\PHPUnit_Framework_MockObject_MockObject
  47. */
  48. private $refundAdapterMock;
  49. /**
  50. * @var OrderStateResolverInterface|\PHPUnit_Framework_MockObject_MockObject
  51. */
  52. private $orderStateResolverMock;
  53. /**
  54. * @var OrderConfig|\PHPUnit_Framework_MockObject_MockObject
  55. */
  56. private $configMock;
  57. /**
  58. * @var Order\CreditmemoRepository|\PHPUnit_Framework_MockObject_MockObject
  59. */
  60. private $creditmemoRepositoryMock;
  61. /**
  62. * @var NotifierInterface|\PHPUnit_Framework_MockObject_MockObject
  63. */
  64. private $notifierMock;
  65. /**
  66. * @var RefundOrder|\PHPUnit_Framework_MockObject_MockObject
  67. */
  68. private $refundOrder;
  69. /**
  70. * @var CreditmemoCreationArgumentsInterface|\PHPUnit_Framework_MockObject_MockObject
  71. */
  72. private $creditmemoCommentCreationMock;
  73. /**
  74. * @var CreditmemoCommentCreationInterface|\PHPUnit_Framework_MockObject_MockObject
  75. */
  76. private $creditmemoCreationArgumentsMock;
  77. /**
  78. * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject
  79. */
  80. private $orderMock;
  81. /**
  82. * @var CreditmemoInterface|\PHPUnit_Framework_MockObject_MockObject
  83. */
  84. private $creditmemoMock;
  85. /**
  86. * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
  87. */
  88. private $adapterInterface;
  89. /**
  90. * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
  91. */
  92. private $loggerMock;
  93. /**
  94. * @var RefundOrderInterface|\PHPUnit_Framework_MockObject_MockObject
  95. */
  96. private $refundOrderValidatorMock;
  97. /**
  98. * @var CreditmemoItemCreationInterface|\PHPUnit_Framework_MockObject_MockObject
  99. */
  100. private $creditmemoItemCreationMock;
  101. /**
  102. * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
  103. */
  104. private $validationMessagesMock;
  105. protected function setUp()
  106. {
  107. $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
  108. ->disableOriginalConstructor()
  109. ->getMock();
  110. $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
  111. ->disableOriginalConstructor()
  112. ->getMock();
  113. $this->creditmemoDocumentFactoryMock = $this->getMockBuilder(CreditmemoDocumentFactory::class)
  114. ->disableOriginalConstructor()
  115. ->getMock();
  116. $this->refundOrderValidatorMock = $this->getMockBuilder(RefundOrderInterface::class)
  117. ->disableOriginalConstructor()
  118. ->getMock();
  119. $this->refundAdapterMock = $this->getMockBuilder(RefundAdapterInterface::class)
  120. ->disableOriginalConstructor()
  121. ->getMock();
  122. $this->orderStateResolverMock = $this->getMockBuilder(OrderStateResolverInterface::class)
  123. ->disableOriginalConstructor()
  124. ->getMockForAbstractClass();
  125. $this->configMock = $this->getMockBuilder(OrderConfig::class)
  126. ->disableOriginalConstructor()
  127. ->getMock();
  128. $this->creditmemoRepositoryMock = $this->getMockBuilder(CreditmemoRepositoryInterface::class)
  129. ->disableOriginalConstructor()
  130. ->getMockForAbstractClass();
  131. $this->notifierMock = $this->getMockBuilder(NotifierInterface::class)
  132. ->disableOriginalConstructor()
  133. ->getMockForAbstractClass();
  134. $this->loggerMock = $this->getMockBuilder(LoggerInterface::class)
  135. ->disableOriginalConstructor()
  136. ->getMockForAbstractClass();
  137. $this->creditmemoCommentCreationMock = $this->getMockBuilder(CreditmemoCommentCreationInterface::class)
  138. ->disableOriginalConstructor()
  139. ->getMockForAbstractClass();
  140. $this->creditmemoCreationArgumentsMock = $this->getMockBuilder(CreditmemoCreationArgumentsInterface::class)
  141. ->disableOriginalConstructor()
  142. ->getMockForAbstractClass();
  143. $this->orderMock = $this->getMockBuilder(OrderInterface::class)
  144. ->disableOriginalConstructor()
  145. ->getMockForAbstractClass();
  146. $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
  147. ->disableOriginalConstructor()
  148. ->getMockForAbstractClass();
  149. $this->adapterInterface = $this->getMockBuilder(AdapterInterface::class)
  150. ->disableOriginalConstructor()
  151. ->getMockForAbstractClass();
  152. $this->creditmemoItemCreationMock = $this->getMockBuilder(CreditmemoItemCreationInterface::class)
  153. ->disableOriginalConstructor()
  154. ->getMockForAbstractClass();
  155. $this->validationMessagesMock = $this->getMockBuilder(ValidatorResultInterface::class)
  156. ->disableOriginalConstructor()
  157. ->setMethods(['hasMessages', 'getMessages', 'addMessage'])
  158. ->getMock();
  159. $this->refundOrder = new RefundOrder(
  160. $this->resourceConnectionMock,
  161. $this->orderStateResolverMock,
  162. $this->orderRepositoryMock,
  163. $this->creditmemoRepositoryMock,
  164. $this->refundAdapterMock,
  165. $this->creditmemoDocumentFactoryMock,
  166. $this->refundOrderValidatorMock,
  167. $this->notifierMock,
  168. $this->configMock,
  169. $this->loggerMock
  170. );
  171. }
  172. /**
  173. * @param int $orderId
  174. * @param bool $notify
  175. * @param bool $appendComment
  176. * @throws \Magento\Sales\Exception\CouldNotRefundException
  177. * @throws \Magento\Sales\Exception\DocumentValidationException
  178. * @dataProvider dataProvider
  179. */
  180. public function testOrderCreditmemo($orderId, $notify, $appendComment)
  181. {
  182. $items = [$this->creditmemoItemCreationMock];
  183. $this->resourceConnectionMock->expects($this->once())
  184. ->method('getConnection')
  185. ->with('sales')
  186. ->willReturn($this->adapterInterface);
  187. $this->orderRepositoryMock->expects($this->once())
  188. ->method('get')
  189. ->willReturn($this->orderMock);
  190. $this->creditmemoDocumentFactoryMock->expects($this->once())
  191. ->method('createFromOrder')
  192. ->with(
  193. $this->orderMock,
  194. $items,
  195. $this->creditmemoCommentCreationMock,
  196. ($appendComment && $notify),
  197. $this->creditmemoCreationArgumentsMock
  198. )->willReturn($this->creditmemoMock);
  199. $this->refundOrderValidatorMock->expects($this->once())
  200. ->method('validate')
  201. ->with(
  202. $this->orderMock,
  203. $this->creditmemoMock,
  204. $items,
  205. $notify,
  206. $appendComment,
  207. $this->creditmemoCommentCreationMock,
  208. $this->creditmemoCreationArgumentsMock
  209. )
  210. ->willReturn($this->validationMessagesMock);
  211. $hasMessages = false;
  212. $this->validationMessagesMock->expects($this->once())
  213. ->method('hasMessages')->willReturn($hasMessages);
  214. $this->refundAdapterMock->expects($this->once())
  215. ->method('refund')
  216. ->with($this->creditmemoMock, $this->orderMock)
  217. ->willReturn($this->orderMock);
  218. $this->orderStateResolverMock->expects($this->once())
  219. ->method('getStateForOrder')
  220. ->with($this->orderMock, [])
  221. ->willReturn(Order::STATE_CLOSED);
  222. $this->orderMock->expects($this->once())
  223. ->method('setState')
  224. ->with(Order::STATE_CLOSED)
  225. ->willReturnSelf();
  226. $this->orderMock->expects($this->once())
  227. ->method('getState')
  228. ->willReturn(Order::STATE_CLOSED);
  229. $this->configMock->expects($this->once())
  230. ->method('getStateDefaultStatus')
  231. ->with(Order::STATE_CLOSED)
  232. ->willReturn('Closed');
  233. $this->orderMock->expects($this->once())
  234. ->method('setStatus')
  235. ->with('Closed')
  236. ->willReturnSelf();
  237. $this->creditmemoMock->expects($this->once())
  238. ->method('setState')
  239. ->with(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED)
  240. ->willReturnSelf();
  241. $this->creditmemoRepositoryMock->expects($this->once())
  242. ->method('save')
  243. ->with($this->creditmemoMock)
  244. ->willReturn($this->creditmemoMock);
  245. $this->orderRepositoryMock->expects($this->once())
  246. ->method('save')
  247. ->with($this->orderMock)
  248. ->willReturn($this->orderMock);
  249. if ($notify) {
  250. $this->notifierMock->expects($this->once())
  251. ->method('notify')
  252. ->with($this->orderMock, $this->creditmemoMock, $this->creditmemoCommentCreationMock);
  253. }
  254. $this->creditmemoMock->expects($this->once())
  255. ->method('getEntityId')
  256. ->willReturn(2);
  257. $this->assertEquals(
  258. 2,
  259. $this->refundOrder->execute(
  260. $orderId,
  261. $items,
  262. $notify,
  263. $appendComment,
  264. $this->creditmemoCommentCreationMock,
  265. $this->creditmemoCreationArgumentsMock
  266. )
  267. );
  268. }
  269. /**
  270. * @expectedException \Magento\Sales\Api\Exception\DocumentValidationExceptionInterface
  271. */
  272. public function testDocumentValidationException()
  273. {
  274. $orderId = 1;
  275. $items = [$this->creditmemoItemCreationMock];
  276. $notify = true;
  277. $appendComment = true;
  278. $errorMessages = ['error1', 'error2'];
  279. $this->orderRepositoryMock->expects($this->once())
  280. ->method('get')
  281. ->willReturn($this->orderMock);
  282. $this->creditmemoDocumentFactoryMock->expects($this->once())
  283. ->method('createFromOrder')
  284. ->with(
  285. $this->orderMock,
  286. $items,
  287. $this->creditmemoCommentCreationMock,
  288. ($appendComment && $notify),
  289. $this->creditmemoCreationArgumentsMock
  290. )->willReturn($this->creditmemoMock);
  291. $this->refundOrderValidatorMock->expects($this->once())
  292. ->method('validate')
  293. ->with(
  294. $this->orderMock,
  295. $this->creditmemoMock,
  296. $items,
  297. $notify,
  298. $appendComment,
  299. $this->creditmemoCommentCreationMock,
  300. $this->creditmemoCreationArgumentsMock
  301. )
  302. ->willReturn($this->validationMessagesMock);
  303. $hasMessages = true;
  304. $this->validationMessagesMock->expects($this->once())
  305. ->method('hasMessages')->willReturn($hasMessages);
  306. $this->validationMessagesMock->expects($this->once())
  307. ->method('getMessages')->willReturn($errorMessages);
  308. $this->assertEquals(
  309. $errorMessages,
  310. $this->refundOrder->execute(
  311. $orderId,
  312. $items,
  313. $notify,
  314. $appendComment,
  315. $this->creditmemoCommentCreationMock,
  316. $this->creditmemoCreationArgumentsMock
  317. )
  318. );
  319. }
  320. /**
  321. * @expectedException \Magento\Sales\Api\Exception\CouldNotRefundExceptionInterface
  322. */
  323. public function testCouldNotCreditmemoException()
  324. {
  325. $orderId = 1;
  326. $items = [$this->creditmemoItemCreationMock];
  327. $notify = true;
  328. $appendComment = true;
  329. $this->resourceConnectionMock->expects($this->once())
  330. ->method('getConnection')
  331. ->with('sales')
  332. ->willReturn($this->adapterInterface);
  333. $this->orderRepositoryMock->expects($this->once())
  334. ->method('get')
  335. ->willReturn($this->orderMock);
  336. $this->creditmemoDocumentFactoryMock->expects($this->once())
  337. ->method('createFromOrder')
  338. ->with(
  339. $this->orderMock,
  340. $items,
  341. $this->creditmemoCommentCreationMock,
  342. ($appendComment && $notify),
  343. $this->creditmemoCreationArgumentsMock
  344. )->willReturn($this->creditmemoMock);
  345. $this->refundOrderValidatorMock->expects($this->once())
  346. ->method('validate')
  347. ->with(
  348. $this->orderMock,
  349. $this->creditmemoMock,
  350. $items,
  351. $notify,
  352. $appendComment,
  353. $this->creditmemoCommentCreationMock,
  354. $this->creditmemoCreationArgumentsMock
  355. )
  356. ->willReturn($this->validationMessagesMock);
  357. $hasMessages = false;
  358. $this->validationMessagesMock->expects($this->once())
  359. ->method('hasMessages')->willReturn($hasMessages);
  360. $e = new \Exception();
  361. $this->refundAdapterMock->expects($this->once())
  362. ->method('refund')
  363. ->with($this->creditmemoMock, $this->orderMock)
  364. ->willThrowException($e);
  365. $this->loggerMock->expects($this->once())
  366. ->method('critical')
  367. ->with($e);
  368. $this->adapterInterface->expects($this->once())
  369. ->method('rollBack');
  370. $this->refundOrder->execute(
  371. $orderId,
  372. $items,
  373. $notify,
  374. $appendComment,
  375. $this->creditmemoCommentCreationMock,
  376. $this->creditmemoCreationArgumentsMock
  377. );
  378. }
  379. /**
  380. * @return array
  381. */
  382. public function dataProvider()
  383. {
  384. return [
  385. 'TestWithNotifyTrue' => [1, true, true],
  386. 'TestWithNotifyFalse' => [1, false, true],
  387. ];
  388. }
  389. }