Skip to content

Commit

Permalink
[ECP-8947] Add unit tests for /Helper/Webhook.php (#2555)
Browse files Browse the repository at this point in the history
* add unit tests for webhook helper

* remove redundant comments
  • Loading branch information
RokPopov authored Mar 21, 2024
1 parent 5ccceec commit b7af268
Showing 1 changed file with 277 additions and 15 deletions.
292 changes: 277 additions & 15 deletions Test/Unit/Helper/WebhookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Adyen\Payment\Helper\Webhook\WebhookHandlerFactory;
use Adyen\Payment\Logger\AdyenLogger;
use ReflectionMethod;
use Adyen\Payment\Exception\AdyenWebhookException;


class WebhookTest extends AbstractAdyenTestCase
{
Expand All @@ -40,7 +42,7 @@ public function testProcessNotificationWithInvalidMerchantReference()

public function testProcessNotificationWithOrderNotFound()
{
$merchantReference = 'TestMerchant'; // Replace with a merchant reference that does not exist
$merchantReference = 'TestMerchant';
$notification = $this->createMock(Notification::class);
$notification->method('getMerchantReference')->willReturn($merchantReference);

Expand All @@ -53,7 +55,6 @@ public function testProcessNotificationWithOrderNotFound()

$result = $webhookHandler->processNotification($notification);

// Assertions for the unsuccessful processing
$this->assertFalse($result);
}

Expand All @@ -74,7 +75,6 @@ public function testProcessNotificationForInvalidDataException()
$notification->method('getPspreference')->willReturn('ABCD1234GHJK5678');
$notification->method('getPaymentMethod')->willReturn('ADYEN_CC');

// Mocking Order and other dependencies
$payment = $this->createMock(Payment::class);
$order = $this->createMock(Order::class);
$order->method('getState')->willReturn(Order::STATE_NEW);
Expand All @@ -93,10 +93,8 @@ public function testProcessNotificationForInvalidDataException()
$logger = $this->createMock(AdyenLogger::class);
$logger->method('getOrderContext')->with($order);

// Mock the WebhookHandlerFactory and WebhookHandler
$webhookHandlerFactory = $this->createMock(WebhookHandlerFactory::class);

// Partially mock the Webhook class
$webhookHandler = $this->getMockBuilder(Webhook::class)
->setConstructorArgs([
$this->createMock(Data::class),
Expand Down Expand Up @@ -126,7 +124,6 @@ public function testProcessNotificationForInvalidDataException()

public function testAddNotificationDetailsHistoryComment()
{
// Mock necessary dependencies
$orderMock = $this->getMockBuilder(Order::class)
->disableOriginalConstructor()
->getMock();
Expand All @@ -144,19 +141,15 @@ public function testAddNotificationDetailsHistoryComment()

public function testGetTransitionState()
{
// Mock necessary dependencies
$notificationMock = $this->getMockBuilder(Notification::class)
->disableOriginalConstructor()
->getMock();

// Create an instance of your class
$webhook = $this->createWebhook(null, null, null, null, null, null, null, null, null);

// Use reflection to make the private method accessible
$method = new ReflectionMethod(Webhook::class, 'getTransitionState');
$method->setAccessible(true);

// Set up expectations for the mocked objects
$notificationMock->expects($this->once())
->method('getEventCode')
->willReturn('AUTHORISATION');
Expand All @@ -167,10 +160,8 @@ public function testGetTransitionState()

$orderState = Order::STATE_NEW;

// Call the private method
$result = $method->invokeArgs($webhook, [$notificationMock, $orderState]);

// Assertions based on your logic
$this->assertNotEquals(
'STATE_NEW',
$result,
Expand Down Expand Up @@ -205,7 +196,6 @@ public function testUpdateAdyenAttributes()
$orderRepositoryMock = $this->createMock(OrderRepository::class);
$orderRepositoryMock->method('get')->willReturn($orderMock);

// Create an instance of your class
$webhook = $this->createWebhook(
null,
$serializerMock,
Expand All @@ -218,7 +208,6 @@ public function testUpdateAdyenAttributes()
$orderRepositoryMock
);

// Set up expectations for the mocked objects
$notificationMock->expects($this->once())
->method('getEventCode')
->willReturn(Notification::AUTHORISATION);
Expand Down Expand Up @@ -264,7 +253,6 @@ public function testProcessNotificationWithSuccess()
$orderHelper = $this->createMock(OrderHelper::class);
$orderHelper->method('getOrderByIncrementId')->willReturn($order);

// Create a mock for the payment
$payment = $this->createMock(Payment::class);
$mockWebhookHandlerFactory = $this->createMock(WebhookHandlerFactory::class);
$webhookHandlerInterface = $this->createMock(WebhookHandlerInterface::class);
Expand All @@ -291,6 +279,280 @@ public function testProcessNotificationWithSuccess()
$this->assertTrue($result);
}

public function testProcessNotificationWithAdyenWebhookException()
{
$notification = $this->createMock(Notification::class);
$notification->method('getMerchantReference')->willReturn('TestMerchant');
$notification->method('getEventCode')->willReturn('AUTHORISATION : FALSE');
$notification->method('getEntityId')->willReturn('1234');
$notification->method('getPspreference')->willReturn('ABCD1234GHJK5678');
$notification->method('getPaymentMethod')->willReturn('ADYEN_CC');

$payment = $this->createMock(Payment::class);
$order = $this->createMock(Order::class);
$order->method('getState')->willReturn(Order::STATE_NEW);
$order->method('getIncrementId')->willReturn(123);
$order->method('getId')->willReturn(123);
$order->method('getStatus')->willReturn('processing');
$order->method('getPayment')->willReturn($payment);

$orderHelper = $this->createMock(OrderHelper::class);
$orderHelper->method('getOrderByIncrementId')->willReturn($order);

$payment->expects($this->once())
->method('setAdditionalInformation')
->with('payment_method', $notification->getPaymentMethod());

$webhookHandlerInterfaceMock = $this->createMock(WebhookHandlerInterface::class);
$webhookHandlerInterfaceMock->method('handleWebhook')->willThrowException(new AdyenWebhookException(
new \Magento\Framework\Phrase("Test Adyen webhook exception"
)));

$webhookHandlerFactory = $this->createMock(WebhookHandlerFactory::class);
$webhookHandlerFactory->method('create')
->willReturn($webhookHandlerInterfaceMock);

$logger = $this->createMock(AdyenLogger::class);
$logger->method('getOrderContext')->with($order);

$webhookHandler = $this->getMockBuilder(Webhook::class)
->setConstructorArgs([
$this->createMock(Data::class),
$this->createMock(SerializerInterface::class),
$this->createMock(TimezoneInterface::class),
$this->createMock(ConfigHelper::class),
$this->createMock(ChargedCurrency::class),
$logger,
$webhookHandlerFactory,
$orderHelper,
$this->createMock(OrderRepository::class)
])
->onlyMethods([
'updateNotification',
'addNotificationDetailsHistoryComment',
'updateAdyenAttributes',
'getCurrentState',
'getTransitionState',
'handleNotificationError'
])
->getMock();

$result = $webhookHandler->processNotification($notification);

$this->assertFalse($result);
}

public function testProcessNotificationWithGeneralException()
{
$notification = $this->createMock(Notification::class);
$notification->method('getMerchantReference')->willReturn('TestMerchant');
$notification->method('getEventCode')->willReturn('AUTHORISATION : FALSE');
$notification->method('getEntityId')->willReturn('1234');
$notification->method('getPspreference')->willReturn('ABCD1234GHJK5678');
$notification->method('getPaymentMethod')->willReturn('ADYEN_CC');

$payment = $this->createMock(Payment::class);
$order = $this->createMock(Order::class);
$order->method('getState')->willReturn(Order::STATE_NEW);
$order->method('getIncrementId')->willReturn(123);
$order->method('getId')->willReturn(123);
$order->method('getStatus')->willReturn('processing');
$order->method('getPayment')->willReturn($payment);

$orderHelper = $this->createMock(OrderHelper::class);
$orderHelper->method('getOrderByIncrementId')->willReturn($order);

$payment->expects($this->once())
->method('setAdditionalInformation')
->with('payment_method', $notification->getPaymentMethod());

$webhookHandlerInterfaceMock = $this->createMock(WebhookHandlerInterface::class);
$webhookHandlerInterfaceMock->method('handleWebhook')->willThrowException(new \Exception(
new \Magento\Framework\Phrase("Test generic exception"
)));

$webhookHandlerFactory = $this->createMock(WebhookHandlerFactory::class);
$webhookHandlerFactory->method('create')
->willReturn($webhookHandlerInterfaceMock);

$logger = $this->createMock(AdyenLogger::class);
$logger->method('getOrderContext')->with($order);

$webhookHandler = $this->getMockBuilder(Webhook::class)
->setConstructorArgs([
$this->createMock(Data::class),
$this->createMock(SerializerInterface::class),
$this->createMock(TimezoneInterface::class),
$this->createMock(ConfigHelper::class),
$this->createMock(ChargedCurrency::class),
$logger,
$webhookHandlerFactory,
$orderHelper,
$this->createMock(OrderRepository::class)
])
->onlyMethods([
'updateNotification',
'addNotificationDetailsHistoryComment',
'updateAdyenAttributes',
'getCurrentState',
'getTransitionState',
'handleNotificationError'
])
->getMock();

$result = $webhookHandler->processNotification($notification);

$this->assertFalse($result);
}

public function testAddNotificationDetailsHistoryCommentWithFullRefund()
{
$orderMock = $this->getMockBuilder(Order::class)
->disableOriginalConstructor()
->getMock();
$notificationMock = $this->getMockBuilder(Notification::class)
->disableOriginalConstructor()
->getMock();

$orderAmountCurrencyObject = new class {
public function getAmount() {
return 100;
}
public function getCurrencyCode() {
return 'EUR';
}
};

$chargedCurrencyMock = $this->createMock(ChargedCurrency::class);
$chargedCurrencyMock->method('getOrderAmountCurrency')
->willReturn($orderAmountCurrencyObject);

$adyenHelperMock = $this->createMock(Data::class);
$adyenHelperMock->method('formatAmount')
->willReturn(100);

$webhook = $this->createWebhook(
$adyenHelperMock,
null,
null,
null,
$chargedCurrencyMock,
null,
null,
null,
null
);

$notificationMock->method('getEventCode')
->willReturn(Notification::REFUND);
$notificationMock->method('getAmountValue')
->willReturn(100);
$notificationMock->method('isSuccessful')
->willReturn(true);

$orderMock->expects($this->once())
->method('setData')
->with(
'adyen_notification_event_code',
$this->stringContains('REFUND : TRUE')
);

$reflection = new \ReflectionClass(get_class($webhook));
$method = $reflection->getMethod('addNotificationDetailsHistoryComment');
$method->setAccessible(true);

$result = $method->invokeArgs($webhook, [$orderMock, $notificationMock]);

$this->assertInstanceOf(Order::class, $result);
}

public function testAddNotificationDetailsHistoryCommentWithPendingEventCode()
{
$orderMock = $this->getMockBuilder(Order::class)
->disableOriginalConstructor()
->getMock();
$notificationMock = $this->getMockBuilder(Notification::class)
->disableOriginalConstructor()
->getMock();
$configHelperMock = $this->createMock(ConfigHelper::class);
$adyenHelperMock = $this->createMock(Data::class);
$chargedCurrencyMock = $this->createMock(ChargedCurrency::class);

$webhook = $this->createWebhook(
$adyenHelperMock,
null,
null,
$configHelperMock,
$chargedCurrencyMock,
null,
null,
null,
null
);

$notificationMock->method('getEventCode')
->willReturn(Notification::PENDING);
$notificationMock->method('getPspreference')
->willReturn('some_psp_reference');
$orderMock->method('getStoreId')
->willReturn(1);

$configHelperMock->method('getConfigData')
->with('pending_status', 'adyen_abstract', 1)
->willReturn('pending_status_value');

$reflection = new \ReflectionClass(get_class($webhook));
$method = $reflection->getMethod('addNotificationDetailsHistoryComment');
$method->setAccessible(true);

$orderMock->expects($this->once())
->method('addStatusHistoryComment')
->with(
$this->anything(),
'pending_status_value'
);

$result = $method->invokeArgs($webhook, [$orderMock, $notificationMock]);

$this->assertInstanceOf(Order::class, $result);
}

public function testUpdateOrderPaymentWithAdyenAttributes()
{
$paymentMock = $this->getMockBuilder(Order\Payment::class)
->disableOriginalConstructor()
->getMock();
$notificationMock = $this->getMockBuilder(Notification::class)
->disableOriginalConstructor()
->getMock();

$webhook = $this->createWebhook(null,null,null,null,null,null,null,null,null);

$additionalData = [
'avsResult' => 'avs_result_value',
'cvcResult' => 'cvc_result_value',
];

$notificationMock->method('getPspreference')->willReturn('pspReference');
$notificationMock->method('getReason')->willReturn('card summary reason');

$reflection = new \ReflectionClass(get_class($webhook));
$method = $reflection->getMethod('updateOrderPaymentWithAdyenAttributes');
$method->setAccessible(true);

$paymentMock->expects($this->exactly(4))
->method('setAdditionalInformation')
->withConsecutive(
['adyen_avs_result', 'avs_result_value'],
['adyen_cvc_result', 'cvc_result_value'],
['pspReference', 'pspReference'],
['adyen_ratepay_descriptor', $this->anything()]
);

$method->invokeArgs($webhook, [$paymentMock, $notificationMock, $additionalData]);
}


protected function createWebhook(
$mockAdyenHelper = null,
$mockSerializer = null,
Expand Down

0 comments on commit b7af268

Please sign in to comment.