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;
}
}
