commerce_signifyd-1.0.x-dev/tests/src/Kernel/Signifyd/WebhookTest.php
tests/src/Kernel/Signifyd/WebhookTest.php
<?php namespace Drupal\Tests\commerce_signifyd\Kernel\Signifyd; use Drupal\commerce_order\Entity\OrderInterface; use Drupal\commerce_signifyd\Signifyd\WebhookInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** * Tests the webhook calls. * * @coversDefaultClass \Drupal\commerce_signifyd\Signifyd\Webhook * * @group commerce_signifyd */ class WebhookTest extends AbstractSignifydKernelBase { /** * @covers ::events * @covers \Drupal\commerce_signifyd\Controller\WebhookController::build */ public function testNoHeaders() { $http_kernel = $this->container->get('http_kernel'); $request = Request::create('/webhook/signifyd/test'); $request->setMethod('POST'); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_BAD_REQUEST, $response->getStatusCode()); } /** * @covers ::events * @covers \Drupal\commerce_signifyd\SignifydCaseStorage::loadByOrder */ public function testEventsGuaranteeApproved() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); // Run signifyd case creation. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":988.8908180639474,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","adjustedScore":988.8908180639474,"guaranteeDisposition":"APPROVED"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_CREATION); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $cases = $this->getSignifydCase($this->order); $this->assertNotEmpty($cases); $this->assertEquals(1, count($cases)); $this->assertEquals('fulfillment', $this->order->getState()->getId()); $case = end($cases); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(988, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals(NULL, $case->getDecision()); // Run decision made with different score. $payload = '{"caseId":100111,"score":982.9171616667305,"customerCaseId":"1","checkpointAction":"ACCEPT"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_DESCISION_MADE); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(982, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals('ACCEPT', $case->getDecision()); $this->assertEquals('fulfillment', $this->order->getState()->getId()); } /** * @covers ::events * @covers \Drupal\commerce_signifyd\SignifydCaseStorage::loadByOrder */ public function testEventsGuaranteeDeclined() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); // Run signifyd case creation. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":420.5666,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","adjustedScore":420.5666,"guaranteeDisposition":"DECLINED"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_CREATION); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $cases = $this->getSignifydCase($this->order); $this->assertNotEmpty($cases); $this->assertEquals(1, count($cases)); $this->assertEquals('flagged_fraud', $this->order->getState()->getId()); $case = end($cases); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(420, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals(NULL, $case->getDecision()); } /** * @covers ::events * @covers \Drupal\commerce_signifyd\SignifydCaseStorage::loadByOrder */ public function testEventsGuaranteeNeutral() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); // Run signifyd case creation. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":420.5666,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","guaranteeDisposition":"PENDING"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_CREATION); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $cases = $this->getSignifydCase($this->order); $this->assertNotEmpty($cases); $this->assertEquals(1, count($cases)); $this->assertEquals('validation', $this->order->getState()->getId()); $case = end($cases); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(420, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals(NULL, $case->getDecision()); } /** * @covers ::events * @covers \Drupal\commerce_signifyd\SignifydCaseStorage::loadByOrder */ public function testEventsDecisionApproved() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); $this->config('commerce_signifyd.settings')->set('decision_type', 'decision')->save(); // Run signifyd case review with approved. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":765.5666,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","guaranteeDisposition":"PENDING"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_REVIEW); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $cases = $this->getSignifydCase($this->order); $this->assertNotEmpty($cases); $this->assertEquals(1, count($cases)); $this->assertEquals('validation', $this->order->getState()->getId()); $case = end($cases); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(765, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals(NULL, $case->getDecision()); $this->assertEquals('PENDING', $case->getGuarantee()); // Run decision made with different score. $payload = '{"caseId":100111,"score":765,"customerCaseId":"1","checkpointAction":"ACCEPT"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_DESCISION_MADE); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(765, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals('ACCEPT', $case->getDecision()); $this->assertEquals('APPROVED', $case->getGuarantee()); $this->assertEquals('fulfillment', $this->order->getState()->getId()); } /** * @covers ::events * @covers \Drupal\commerce_signifyd\SignifydCaseStorage::loadByOrder */ public function testEventsScoreDeclined() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); $this->config('commerce_signifyd.settings')->set('decision_type', 'score')->save(); $this->assertEquals(700, $this->config('commerce_signifyd.settings')->get('score')); // Run signifyd case review with approved but score below // our threshold. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":699.87775565665,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","guaranteeDisposition":"APPROVED"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_CREATION); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $cases = $this->getSignifydCase($this->order); $this->assertNotEmpty($cases); $this->assertEquals(1, count($cases)); $this->assertEquals('flagged_fraud', $this->order->getState()->getId()); $case = end($cases); $this->assertEquals(100111, $case->id()); $this->assertEquals(100111, $case->getInvestigationId()); $this->assertEquals(699, $case->getScore()); $this->assertEquals(1, $case->getOrderId()); $this->assertEquals(NULL, $case->getDecision()); } /** * @covers ::events */ public function testEventsScoreApproved() { $this->assertEquals('validation', $this->order->getState()->getId()); $this->assertEmpty($this->getSignifydCase($this->order)); $this->config('commerce_signifyd.settings')->set('decision_type', 'score')->save(); $this->assertEquals(700, $this->config('commerce_signifyd.settings')->get('score')); // Run review of the case with bigger score. // Run signifyd case review with approved. $http_kernel = $this->container->get('http_kernel'); $payload = '{"score":702.87775565665,"caseId":100111,"investigationId":100111,"status":"OPEN","orderId":"1","guaranteeDisposition":"APPROVED"}'; $request = $this->getMockedRequest($payload, WebhookInterface::SIGNIFYD_CASE_RESCORE); $response = $http_kernel->handle($request); $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); $this->assertEquals('fulfillment', $this->order->getState()->getId()); } /** * Fetch signifyd cases by order. * * @param \Drupal\commerce_order\Entity\OrderInterface $order * The order. * * @return \Drupal\commerce_signifyd\Entity\SignifydCaseInterface[] * List of associated cases. */ protected function getSignifydCase(OrderInterface $order) { return $this->entityTypeManager->getStorage('signifyd_case')->loadByOrder($order); } /** * Creates a request object. * * @param string $request_body * The document. * @param string $topic * The Signifyd topic. * * @return \Symfony\Component\HttpFoundation\Request * The request. * * @throws \Exception */ protected function getMockedRequest(string $request_body, $topic): Request { $request = Request::create('/webhook/signifyd/test', 'POST', [], [], [], [], $request_body); $request->headers->set('X-SIGNIFYD-TOPIC', $topic); $hash = base64_encode( hash_hmac('sha256', $request_body, $this->signifydTeam->getApiKey(), TRUE) ); $request->headers->set('X-SIGNIFYD-SEC-HMAC-SHA256', $hash); return $request; } }