HandlerTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Signifyd\Test\Unit\Controller\Webhooks;
  7. use Magento\Framework\App\Action\Context;
  8. use Magento\Framework\App\Response\Http as ResponseHttp;
  9. use Magento\Framework\App\Response\RedirectInterface;
  10. use Magento\Framework\Exception\LocalizedException;
  11. use Magento\Signifyd\Api\CaseRepositoryInterface;
  12. use Magento\Signifyd\Api\Data\CaseInterface;
  13. use Magento\Signifyd\Controller\Webhooks\Handler;
  14. use Magento\Signifyd\Model\CaseServices\UpdatingService;
  15. use Magento\Signifyd\Model\CaseServices\UpdatingServiceFactory;
  16. use Magento\Signifyd\Model\Config;
  17. use Magento\Signifyd\Model\SignifydGateway\Response\WebhookMessage;
  18. use Magento\Signifyd\Model\SignifydGateway\Response\WebhookMessageReader;
  19. use Magento\Signifyd\Model\SignifydGateway\Response\WebhookRequest;
  20. use Magento\Signifyd\Model\SignifydGateway\Response\WebhookRequestValidator;
  21. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  22. use Psr\Log\LoggerInterface;
  23. /**
  24. * Class IndexTest
  25. *
  26. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  27. */
  28. class HandlerTest extends \PHPUnit\Framework\TestCase
  29. {
  30. /**
  31. * @var Handler
  32. */
  33. private $controller;
  34. /**
  35. * @var LoggerInterface|MockObject
  36. */
  37. private $logger;
  38. /**
  39. * @var RedirectInterface|MockObject
  40. */
  41. private $redirect;
  42. /**
  43. * @var ResponseHttp|MockObject
  44. */
  45. private $response;
  46. /**
  47. * @var Context|MockObject
  48. */
  49. private $context;
  50. /**
  51. * @var WebhookRequest|MockObject
  52. */
  53. private $webhookRequest;
  54. /**
  55. * @var WebhookMessageReader|MockObject
  56. */
  57. private $webhookMessageReader;
  58. /**
  59. * @var WebhookRequestValidator|MockObject
  60. */
  61. private $webhookRequestValidator;
  62. /**
  63. * @var UpdatingServiceFactory|MockObject
  64. */
  65. private $caseUpdatingServiceFactory;
  66. /**
  67. * @var CaseRepositoryInterface|MockObject
  68. */
  69. private $caseRepository;
  70. /**
  71. * @inheritdoc
  72. */
  73. protected function setUp()
  74. {
  75. $this->context = $this->getMockBuilder(Context::class)
  76. ->disableOriginalConstructor()
  77. ->getMock();
  78. $this->webhookRequest = $this->getMockBuilder(WebhookRequest::class)
  79. ->disableOriginalConstructor()
  80. ->getMock();
  81. $this->webhookMessageReader = $this->getMockBuilder(WebhookMessageReader::class)
  82. ->disableOriginalConstructor()
  83. ->getMock();
  84. $this->webhookRequestValidator = $this->getMockBuilder(WebhookRequestValidator::class)
  85. ->disableOriginalConstructor()
  86. ->getMock();
  87. $this->caseUpdatingServiceFactory = $this->getMockBuilder(UpdatingServiceFactory::class)
  88. ->disableOriginalConstructor()
  89. ->getMock();
  90. $this->logger = $this->getMockBuilder(LoggerInterface::class)
  91. ->getMockForAbstractClass();
  92. $this->response = $this->getMockBuilder(ResponseHttp::class)
  93. ->disableOriginalConstructor()
  94. ->getMock();
  95. $this->context->expects($this->once())
  96. ->method('getResponse')
  97. ->willReturn($this->response);
  98. $this->redirect = $this->getMockBuilder(RedirectInterface::class)
  99. ->getMockForAbstractClass();
  100. $this->context->expects($this->once())
  101. ->method('getRedirect')
  102. ->willReturn($this->redirect);
  103. $this->caseRepository = $this->getMockBuilder(CaseRepositoryInterface::class)
  104. ->disableOriginalConstructor()
  105. ->setMethods(['getByCaseId'])
  106. ->getMockForAbstractClass();
  107. $config = $this->getMockBuilder(Config::class)
  108. ->disableOriginalConstructor()
  109. ->setMethods(['isDebugModeEnabled', 'getByCaseId'])
  110. ->getMock();
  111. $config->expects(self::any())
  112. ->method('getByCaseId')
  113. ->willReturn(false);
  114. $this->controller = new Handler(
  115. $this->context,
  116. $this->webhookRequest,
  117. $this->logger,
  118. $this->webhookMessageReader,
  119. $this->caseUpdatingServiceFactory,
  120. $this->webhookRequestValidator,
  121. $this->caseRepository,
  122. $config
  123. );
  124. }
  125. /**
  126. * Successful case
  127. */
  128. public function testExecuteSuccessfully()
  129. {
  130. $eventTopic = 'cases/creation';
  131. $caseId = 1;
  132. $data = ['score' => 200, 'caseId' => $caseId];
  133. $this->webhookRequestValidator->expects($this->once())
  134. ->method('validate')
  135. ->willReturn(true);
  136. $webhookMessage = $this->getMockBuilder(WebhookMessage::class)
  137. ->disableOriginalConstructor()
  138. ->getMock();
  139. $webhookMessage->expects($this->exactly(2))
  140. ->method('getEventTopic')
  141. ->willReturn($eventTopic);
  142. $webhookMessage->expects($this->once())
  143. ->method('getData')
  144. ->willReturn($data);
  145. $this->webhookMessageReader->expects($this->once())
  146. ->method('read')
  147. ->with($this->webhookRequest)
  148. ->willReturn($webhookMessage);
  149. $caseEntity = $this->getMockBuilder(CaseInterface::class)
  150. ->disableOriginalConstructor()
  151. ->getMock();
  152. $this->caseRepository->expects(self::once())
  153. ->method('getByCaseId')
  154. ->with(self::equalTo($caseId))
  155. ->willReturn($caseEntity);
  156. $caseUpdatingService = $this->getMockBuilder(UpdatingService::class)
  157. ->disableOriginalConstructor()
  158. ->getMock();
  159. $caseUpdatingService->expects($this->once())
  160. ->method('update')
  161. ->with($caseEntity, $data);
  162. $this->caseUpdatingServiceFactory->expects($this->once())
  163. ->method('create')
  164. ->with($eventTopic)
  165. ->willReturn($caseUpdatingService);
  166. $this->controller->execute();
  167. }
  168. /**
  169. * Case when there is exception while updating case
  170. */
  171. public function testExecuteCaseUpdatingServiceException()
  172. {
  173. $eventTopic = 'cases/creation';
  174. $caseId = 1;
  175. $data = ['score' => 200, 'caseId' => $caseId];
  176. $this->webhookRequestValidator->expects($this->once())
  177. ->method('validate')
  178. ->willReturn(true);
  179. $webhookMessage = $this->getMockBuilder(WebhookMessage::class)
  180. ->disableOriginalConstructor()
  181. ->getMock();
  182. $webhookMessage->expects($this->exactly(2))
  183. ->method('getEventTopic')
  184. ->willReturn($eventTopic);
  185. $webhookMessage->expects($this->once())
  186. ->method('getData')
  187. ->willReturn($data);
  188. $this->webhookMessageReader->expects($this->once())
  189. ->method('read')
  190. ->with($this->webhookRequest)
  191. ->willReturn($webhookMessage);
  192. $caseEntity = $this->getMockBuilder(CaseInterface::class)
  193. ->disableOriginalConstructor()
  194. ->getMock();
  195. $this->caseRepository->expects(self::once())
  196. ->method('getByCaseId')
  197. ->with(self::equalTo($caseId))
  198. ->willReturn($caseEntity);
  199. $caseUpdatingService = $this->getMockBuilder(UpdatingService::class)
  200. ->disableOriginalConstructor()
  201. ->getMock();
  202. $caseUpdatingService->expects($this->once())
  203. ->method('update')
  204. ->with($caseEntity, $data)
  205. ->willThrowException(new LocalizedException(__('Error')));
  206. $this->caseUpdatingServiceFactory->expects($this->once())
  207. ->method('create')
  208. ->with($eventTopic)
  209. ->willReturn($caseUpdatingService);
  210. $this->response->expects($this->once())
  211. ->method('setHttpResponseCode')
  212. ->with(400);
  213. $this->logger->expects($this->once())
  214. ->method('critical');
  215. $this->controller->execute();
  216. }
  217. /**
  218. * Case when webhook request validation fails
  219. */
  220. public function testExecuteRequestValidationFails()
  221. {
  222. $this->webhookRequestValidator->expects($this->once())
  223. ->method('validate')
  224. ->willReturn(false);
  225. $this->redirect->expects($this->once())
  226. ->method('redirect')
  227. ->with($this->response, 'noroute', []);
  228. $this->webhookMessageReader->expects($this->never())
  229. ->method('read');
  230. $this->caseUpdatingServiceFactory->expects($this->never())
  231. ->method('create');
  232. $this->controller->execute();
  233. }
  234. /**
  235. * Case when webhook request has test event topic.
  236. */
  237. public function testExecuteWithTestEventTopic()
  238. {
  239. $this->webhookRequestValidator->expects($this->once())
  240. ->method('validate')
  241. ->willReturn(true);
  242. $this->redirect->expects($this->never())
  243. ->method('redirect');
  244. $webhookMessage = $this->getMockBuilder(WebhookMessage::class)
  245. ->disableOriginalConstructor()
  246. ->getMock();
  247. $webhookMessage->expects($this->once())
  248. ->method('getEventTopic')
  249. ->willReturn('cases/test');
  250. $webhookMessage->expects($this->never())
  251. ->method('getData');
  252. $this->webhookMessageReader->expects($this->once())
  253. ->method('read')
  254. ->with($this->webhookRequest)
  255. ->willReturn($webhookMessage);
  256. $this->caseUpdatingServiceFactory->expects($this->never())
  257. ->method('create');
  258. $this->controller->execute();
  259. }
  260. /**
  261. * Checks a test case when received input data does not contain Signifyd case id.
  262. *
  263. * @covers \Magento\Signifyd\Controller\Webhooks\Handler::execute
  264. */
  265. public function testExecuteWithMissedCaseId()
  266. {
  267. $this->webhookRequestValidator->expects(self::once())
  268. ->method('validate')
  269. ->willReturn(true);
  270. $webhookMessage = $this->getMockBuilder(WebhookMessage::class)
  271. ->disableOriginalConstructor()
  272. ->getMock();
  273. $webhookMessage->expects($this->once())
  274. ->method('getEventTopic')
  275. ->willReturn('cases/creation');
  276. $webhookMessage->expects(self::once())
  277. ->method('getData')
  278. ->willReturn([
  279. 'orderId' => '1000101'
  280. ]);
  281. $this->webhookMessageReader->expects(self::once())
  282. ->method('read')
  283. ->with($this->webhookRequest)
  284. ->willReturn($webhookMessage);
  285. $this->redirect->expects(self::once())
  286. ->method('redirect')
  287. ->with($this->response, 'noroute', []);
  288. $this->controller->execute();
  289. }
  290. /**
  291. * Checks a case when Signifyd case entity not found.
  292. *
  293. * @covers \Magento\Signifyd\Controller\Webhooks\Handler::execute
  294. */
  295. public function testExecuteWithNotFoundCaseEntity()
  296. {
  297. $caseId = 123;
  298. $this->webhookRequestValidator->expects(self::once())
  299. ->method('validate')
  300. ->willReturn(true);
  301. $webhookMessage = $this->getMockBuilder(WebhookMessage::class)
  302. ->disableOriginalConstructor()
  303. ->setMethods(['getData'])
  304. ->getMock();
  305. $webhookMessage->expects(self::once())
  306. ->method('getData')
  307. ->willReturn([
  308. 'orderId' => '1000101',
  309. 'caseId' => $caseId
  310. ]);
  311. $this->webhookMessageReader->expects(self::once())
  312. ->method('read')
  313. ->with($this->webhookRequest)
  314. ->willReturn($webhookMessage);
  315. $this->caseRepository->expects(self::once())
  316. ->method('getByCaseId')
  317. ->with(self::equalTo($caseId))
  318. ->willReturn(null);
  319. $this->redirect->expects(self::once())
  320. ->method('redirect')
  321. ->with($this->response, 'noroute', []);
  322. $this->controller->execute();
  323. }
  324. }