RefundInvoiceTest.php 17 KB

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