PlaceOrderTest.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Signifyd\Test\Unit\Observer;
  7. use Magento\Framework\Event;
  8. use Magento\Framework\Event\Observer;
  9. use Magento\Framework\Exception\AlreadyExistsException;
  10. use Magento\Payment\Model\MethodInterface;
  11. use Magento\Sales\Api\Data\OrderInterface;
  12. use Magento\Sales\Model\Order;
  13. use Magento\Sales\Model\Order\Payment;
  14. use Magento\Signifyd\Api\CaseCreationServiceInterface;
  15. use Magento\Signifyd\Model\Config;
  16. use Magento\Signifyd\Observer\PlaceOrder;
  17. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  18. use Psr\Log\LoggerInterface;
  19. class PlaceOrderTest extends \PHPUnit\Framework\TestCase
  20. {
  21. /**
  22. * @var Config|MockObject
  23. */
  24. private $config;
  25. /**
  26. * @var CaseCreationServiceInterface|MockObject
  27. */
  28. private $creationService;
  29. /**
  30. * @var LoggerInterface|MockObject
  31. */
  32. private $logger;
  33. /**
  34. * @var Observer|MockObject
  35. */
  36. private $observer;
  37. /**
  38. * @var Event|MockObject
  39. */
  40. private $event;
  41. /**
  42. * @var OrderInterface|MockObject
  43. */
  44. private $orderEntity;
  45. /**
  46. * @var PlaceOrder
  47. */
  48. private $placeOrder;
  49. /**
  50. * @inheritdoc
  51. */
  52. protected function setUp()
  53. {
  54. $this->config = $this->getMockBuilder(Config::class)
  55. ->disableOriginalConstructor()
  56. ->setMethods(['isActive'])
  57. ->getMock();
  58. $this->logger = $this->getMockBuilder(LoggerInterface::class)
  59. ->disableOriginalConstructor()
  60. ->getMock();
  61. $this->creationService = $this->getMockBuilder(CaseCreationServiceInterface::class)
  62. ->disableOriginalConstructor()
  63. ->setMethods(['createForOrder'])
  64. ->getMock();
  65. $this->observer = $this->getMockBuilder(Observer::class)
  66. ->disableOriginalConstructor()
  67. ->setMethods(['getEvent'])
  68. ->getMock();
  69. $this->event = $this->getMockBuilder(Event::class)
  70. ->disableOriginalConstructor()
  71. ->setMethods(['getData'])
  72. ->getMock();
  73. $this->placeOrder = new PlaceOrder(
  74. $this->config,
  75. $this->creationService,
  76. $this->logger
  77. );
  78. }
  79. /**
  80. * Checks a test case when Signifyd module is disabled.
  81. *
  82. * @covers \Magento\Signifyd\Observer\PlaceOrder::execute
  83. */
  84. public function testExecuteWithDisabledModule()
  85. {
  86. $orderId = 1;
  87. $storeId = 2;
  88. $this->withActiveSignifydIntegration(false, $storeId);
  89. $this->withOrderEntity($orderId, $storeId);
  90. $this->creationService->expects(self::never())
  91. ->method('createForOrder');
  92. $this->placeOrder->execute($this->observer);
  93. }
  94. /**
  95. * Checks a test case when the observer event returns empty an order entity.
  96. *
  97. * @covers \Magento\Signifyd\Observer\PlaceOrder::execute
  98. */
  99. public function testExecuteWithoutOrder()
  100. {
  101. $this->withActiveSignifydIntegration(true);
  102. $this->withOrderEntity(null, null);
  103. $this->creationService->expects(self::never())
  104. ->method('createForOrder');
  105. $this->placeOrder->execute($this->observer);
  106. }
  107. /**
  108. * Checks a test case when the order placed with offline payment method.
  109. *
  110. * @covers \Magento\Signifyd\Observer\PlaceOrder::execute
  111. */
  112. public function testExecuteWithOfflinePayment()
  113. {
  114. $orderId = 1;
  115. $storeId = 2;
  116. $this->withActiveSignifydIntegration(true, $storeId);
  117. $this->withOrderEntity($orderId, $storeId);
  118. $this->withAvailablePaymentMethod(false);
  119. $this->creationService->expects(self::never())
  120. ->method('createForOrder');
  121. $this->placeOrder->execute($this->observer);
  122. }
  123. /**
  124. * Checks a test case when case creation service fails.
  125. *
  126. * @covers \Magento\Signifyd\Observer\PlaceOrder::execute
  127. */
  128. public function testExecuteWithFailedCaseCreation()
  129. {
  130. $orderId = 1;
  131. $storeId = 2;
  132. $exceptionMessage = __('Case with the same order id already exists.');
  133. $this->withActiveSignifydIntegration(true, $storeId);
  134. $this->withOrderEntity($orderId, $storeId);
  135. $this->withAvailablePaymentMethod(true);
  136. $this->creationService->method('createForOrder')
  137. ->with(self::equalTo($orderId))
  138. ->willThrowException(new AlreadyExistsException($exceptionMessage));
  139. $this->logger->method('error')
  140. ->with(self::equalTo($exceptionMessage));
  141. $result = $this->placeOrder->execute($this->observer);
  142. $this->assertNull($result);
  143. }
  144. /**
  145. * Checks a test case when observer successfully calls case creation service.
  146. *
  147. * @covers \Magento\Signifyd\Observer\PlaceOrder::execute
  148. */
  149. public function testExecute()
  150. {
  151. $orderId = 1;
  152. $storeId = 2;
  153. $this->withActiveSignifydIntegration(true, $storeId);
  154. $this->withOrderEntity($orderId, $storeId);
  155. $this->withAvailablePaymentMethod(true);
  156. $this->creationService
  157. ->method('createForOrder')
  158. ->with(self::equalTo($orderId));
  159. $this->logger->expects(self::never())
  160. ->method('error');
  161. $this->placeOrder->execute($this->observer);
  162. }
  163. public function testExecuteWithOrderPendingPayment()
  164. {
  165. $orderId = 1;
  166. $storeId = 2;
  167. $this->withActiveSignifydIntegration(true, $storeId);
  168. $this->withOrderEntity($orderId, $storeId);
  169. $this->orderEntity->method('getState')
  170. ->willReturn(Order::STATE_PENDING_PAYMENT);
  171. $this->withAvailablePaymentMethod(true);
  172. $this->creationService->expects(self::never())
  173. ->method('createForOrder');
  174. $this->placeOrder->execute($this->observer);
  175. }
  176. /**
  177. * Specifies order entity mock execution.
  178. *
  179. * @param int|null $orderId
  180. * @param int|null $storeId
  181. * @return void
  182. */
  183. private function withOrderEntity($orderId, $storeId): void
  184. {
  185. $this->orderEntity = $this->getMockBuilder(OrderInterface::class)
  186. ->disableOriginalConstructor()
  187. ->getMock();
  188. $this->orderEntity->method('getEntityId')
  189. ->willReturn($orderId);
  190. $this->orderEntity->method('getStoreId')
  191. ->willReturn($storeId);
  192. $this->observer->method('getEvent')
  193. ->willReturn($this->event);
  194. $this->event->method('getData')
  195. ->with('order')
  196. ->willReturn($this->orderEntity);
  197. }
  198. /**
  199. * Specifies config mock execution.
  200. *
  201. * @param bool $isActive
  202. * @param int|null $storeId
  203. * @return void
  204. */
  205. private function withActiveSignifydIntegration(bool $isActive, $storeId = null): void
  206. {
  207. $this->config->method('isActive')
  208. ->with($storeId)
  209. ->willReturn($isActive);
  210. }
  211. /**
  212. * Specifies payment method mock execution.
  213. *
  214. * @param bool $isAvailable
  215. * @return void
  216. */
  217. private function withAvailablePaymentMethod($isAvailable)
  218. {
  219. /** @var MethodInterface|MockObject $paymentMethod */
  220. $paymentMethod = $this->getMockBuilder(MethodInterface::class)
  221. ->disableOriginalConstructor()
  222. ->getMock();
  223. /**
  224. * The code depends on implementation but not interface
  225. * because order payment implements two interfaces
  226. */
  227. /** @var Payment|MockObject $orderPayment */
  228. $orderPayment = $this->getMockBuilder(Payment::class)
  229. ->disableOriginalConstructor()
  230. ->getMock();
  231. $this->orderEntity->method('getPayment')
  232. ->willReturn($orderPayment);
  233. $orderPayment->method('getMethodInstance')
  234. ->willReturn($paymentMethod);
  235. $paymentMethod->method('isOffline')
  236. ->willReturn(!$isAvailable);
  237. }
  238. }