From 59fcf748c1817f225c718b250c7ea7ca239b219b Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 14:21:45 +0100 Subject: [PATCH 1/9] Solving the issue of Config "Refund strategy Giftcard" is not working as expected in version 9 --- Helper/Webhook/OrderClosedWebhookHandler.php | 41 +++++++++++++++++++ Model/Order/Payment.php | 21 ++++++++++ .../Order/Payment/Collection.php | 4 +- etc/db_schema.xml | 1 + 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/Helper/Webhook/OrderClosedWebhookHandler.php b/Helper/Webhook/OrderClosedWebhookHandler.php index 091a6424cd..9019617f9a 100644 --- a/Helper/Webhook/OrderClosedWebhookHandler.php +++ b/Helper/Webhook/OrderClosedWebhookHandler.php @@ -71,7 +71,48 @@ public function handleWebhook( Notification $notification, string $transitionState ): MagentoOrder { + $additionalData = $notification->getAdditionalData(); + if (is_string($additionalData)) { + $additionalData = @unserialize($additionalData) ?: []; + } if ($notification->isSuccessful()) { + foreach ($additionalData as $key => $value) { + // Check if the key matches the pattern "order-X-pspReference" + if (preg_match('/^order-(\d+)-pspReference$/', $key, $matches)) { + $orderIndex = (int) $matches[1]; // Get the order number, e.g., 1, 2 + $pspReference = $value; + $sortValue = $orderIndex; // Set status based on order index + + // Retrieve adyen_order_payment for this pspReference + $adyenOrderPayment = $this->adyenOrderPaymentCollectionFactory->create() + ->addFieldToFilter('pspreference', $pspReference) + ->getFirstItem(); + + if ($adyenOrderPayment->getId()) { + // Update the status with the order index + $adyenOrderPayment->setSortOrder($sortValue); + $adyenOrderPayment->save(); + + $this->adyenLogger->addAdyenNotification( + sprintf("Updated adyen_order_payment with order status %d for pspReference %s", $sortValue, $pspReference), + [ + 'pspReference' => $pspReference, + 'status' => $sortValue, + 'merchantReference' => $notification->getMerchantReference() + ] + ); + } else { + // Log if no matching record was found for the given pspReference + $this->adyenLogger->addAdyenNotification( + sprintf("No adyen_order_payment record found for pspReference %s", $pspReference), + [ + 'pspReference' => $pspReference, + 'merchantReference' => $notification->getMerchantReference() + ] + ); + } + } + } $order->addCommentToStatusHistory(__('This order has been successfully completed.')); } else { /** @var OrderPaymentInterface $orderPayment */ diff --git a/Model/Order/Payment.php b/Model/Order/Payment.php index bf4c0d2877..4b5f777612 100644 --- a/Model/Order/Payment.php +++ b/Model/Order/Payment.php @@ -183,4 +183,25 @@ public function getFormattedTotalCapturedWithCurrency(): string false ); } + + /** + * Set sort order. + * + * @param int $sortOrder + * @return $this + */ + public function setSortOrder($sortOrder) + { + return $this->setData('order_sort', $sortOrder); + } + + /** + * Get sort order. + * + * @return int|null + */ + public function getSortOrder() + { + return $this->getData('order_sort'); + } } diff --git a/Model/ResourceModel/Order/Payment/Collection.php b/Model/ResourceModel/Order/Payment/Collection.php index 035999ca4f..19931856e8 100644 --- a/Model/ResourceModel/Order/Payment/Collection.php +++ b/Model/ResourceModel/Order/Payment/Collection.php @@ -72,7 +72,7 @@ public function getTotalAmount($paymentId, $captured = false) public function addPaymentFilterAscending($paymentId) { $this->addFieldToFilter('payment_id', $paymentId); - $this->getSelect()->order(['created_at ASC']); + $this->getSelect()->order(['order_sort ASC']); return $this; } @@ -83,7 +83,7 @@ public function addPaymentFilterAscending($paymentId) public function addPaymentFilterDescending($paymentId) { $this->addFieldToFilter('payment_id', $paymentId); - $this->getSelect()->order(['created_at DESC', 'entity_id DESC']); + $this->getSelect()->order(['order_sort DESC']); return $this; } } diff --git a/etc/db_schema.xml b/etc/db_schema.xml index 6f61474813..00b97e61d7 100644 --- a/etc/db_schema.xml +++ b/etc/db_schema.xml @@ -24,6 +24,7 @@ + From 52c2e9d6f10cbe633a21ec3b15a17add63eb64df Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 14:52:18 +0100 Subject: [PATCH 2/9] Adding Unit Test for OrderClosedWebhookNotification --- .../Webhook/OrderClosedWebhookHandlerTest.php | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php diff --git a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php new file mode 100644 index 0000000000..b5d1168053 --- /dev/null +++ b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php @@ -0,0 +1,112 @@ +adyenOrderPaymentHelperMock = $this->createMock(AdyenOrderPayment::class); + $this->orderHelperMock = $this->createMock(OrderHelper::class); + $this->configHelperMock = $this->createMock(Config::class); + $this->adyenLoggerMock = $this->createMock(AdyenLogger::class); + $this->adyenOrderPaymentCollectionFactoryMock = $this->createMock(OrderPaymentCollectionFactory::class); + + $this->orderClosedWebhookHandler = new OrderClosedWebhookHandler( + $this->adyenOrderPaymentHelperMock, + $this->orderHelperMock, + $this->configHelperMock, + $this->adyenOrderPaymentCollectionFactoryMock, + $this->adyenLoggerMock + ); + } + + public function testHandleWebhookSuccessfulNotificationWithMatchingAdyenOrderPayment() + { + $orderMock = $this->createMock(MagentoOrder::class); + $notificationMock = $this->createMock(Notification::class); + //$adyenOrderPaymentMock = $this->createMock(OrderPaymentInterface::class); + $adyenOrderPaymentMock = $this->createConfiguredMock(Order\Payment::class, [ + 'getId' => 123 + ]); + $adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); + + $notificationMock->expects($this->once())->method('isSuccessful')->willReturn(true); + $notificationMock->expects($this->once())->method('getAdditionalData')->willReturn(serialize(['order-1-pspReference' => 'testPspReference'])); + + $adyenOrderPaymentCollectionMock->expects($this->once())->method('addFieldToFilter')->willReturnSelf(); + $adyenOrderPaymentCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($adyenOrderPaymentMock); + + $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($adyenOrderPaymentCollectionMock); + + $this->adyenLoggerMock->expects($this->once())->method('addAdyenNotification') + ->with('Updated adyen_order_payment with order status 1 for pspReference testPspReference', [ + 'pspReference' => 'testPspReference', + 'status' => 1, + 'merchantReference' => $notificationMock->getMerchantReference() + ]); + + $orderMock->expects($this->once())->method('addCommentToStatusHistory') + ->with(__('This order has been successfully completed.')); + + $result = $this->orderClosedWebhookHandler->handleWebhook($orderMock, $notificationMock, 'completed'); + $this->assertSame($orderMock, $result); + } + + public function testHandleWebhookUnsuccessfulNotificationWithRefund() + { + $orderMock = $this->createMock(MagentoOrder::class); + $notificationMock = $this->createMock(Notification::class); + $adyenOrderPaymentMock = $this->createMock(OrderPaymentInterface::class); + $adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); + + $notificationMock->expects($this->once())->method('isSuccessful')->willReturn(false); + + $orderMock->expects($this->once())->method('getPayment')->willReturn( + $this->createConfiguredMock(MagentoOrderPaymentInterface::class, ['getEntityId' => 123]) + ); + + $adyenOrderPaymentCollectionMock->method('addFieldToFilter') + ->willReturnSelf(); + + $adyenOrderPaymentCollectionMock->expects($this->once())->method('getItems')->willReturn([$adyenOrderPaymentMock]); + + $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($adyenOrderPaymentCollectionMock); + + $this->adyenOrderPaymentHelperMock->expects($this->once())->method('refundFullyAdyenOrderPayment')->with($adyenOrderPaymentMock); + + $orderMock->expects($this->once())->method('addCommentToStatusHistory') + ->with(__('All the funds captured/settled will be refunded by Adyen.')); + + $this->adyenLoggerMock->expects($this->once())->method('addAdyenNotification') + ->with('All the funds captured/settled will be refunded by Adyen.', [ + 'pspReference' => $notificationMock->getPspreference(), + 'merchantReference' => $notificationMock->getMerchantReference() + ]); + + $this->orderHelperMock->method('holdCancelOrder')->with($orderMock, true); + + $this->configHelperMock->method('getNotificationsCanCancel')->with($orderMock->getStoreId())->willReturn(true); + + $result = $this->orderClosedWebhookHandler->handleWebhook($orderMock, $notificationMock, 'completed'); + $this->assertSame($orderMock, $result); + } +} From 27dbd8fc096d2cb1061b9c0b786492d51c468cd0 Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 15:57:33 +0100 Subject: [PATCH 3/9] Updating to serializer --- Helper/Webhook/OrderClosedWebhookHandler.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Helper/Webhook/OrderClosedWebhookHandler.php b/Helper/Webhook/OrderClosedWebhookHandler.php index 9019617f9a..bd29934713 100644 --- a/Helper/Webhook/OrderClosedWebhookHandler.php +++ b/Helper/Webhook/OrderClosedWebhookHandler.php @@ -20,6 +20,7 @@ use Adyen\Payment\Model\Notification; use Magento\Sales\Model\Order as MagentoOrder; use Adyen\Payment\Model\ResourceModel\Order\Payment\CollectionFactory as OrderPaymentCollectionFactory; +use Magento\Framework\Serialize\SerializerInterface; class OrderClosedWebhookHandler implements WebhookHandlerInterface { @@ -38,6 +39,11 @@ class OrderClosedWebhookHandler implements WebhookHandlerInterface /** @var OrderPaymentCollectionFactory */ private $adyenOrderPaymentCollectionFactory; + /** + * @var SerializerInterface + */ + private $serializer; + /** * @param AdyenOrderPayment $adyenOrderPayment * @param OrderHelper $orderHelper @@ -50,13 +56,15 @@ public function __construct( OrderHelper $orderHelper, Config $configHelper, OrderPaymentCollectionFactory $adyenOrderPaymentCollectionFactory, - AdyenLogger $adyenLogger + AdyenLogger $adyenLogger, + SerializerInterface $serializer ) { $this->adyenOrderPaymentHelper = $adyenOrderPayment; $this->orderHelper = $orderHelper; $this->configHelper = $configHelper; $this->adyenOrderPaymentCollectionFactory = $adyenOrderPaymentCollectionFactory; $this->adyenLogger = $adyenLogger; + $this->serializer = $serializer; } /** @@ -73,7 +81,7 @@ public function handleWebhook( ): MagentoOrder { $additionalData = $notification->getAdditionalData(); if (is_string($additionalData)) { - $additionalData = @unserialize($additionalData) ?: []; + $additionalData = $this->serializer->unserialize($additionalData); } if ($notification->isSuccessful()) { foreach ($additionalData as $key => $value) { From c6afd0b9f4341c1be90dcd7f243938080b5582c0 Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 16:41:17 +0100 Subject: [PATCH 4/9] Updating to serializer in unit test --- Helper/Webhook/OrderClosedWebhookHandler.php | 6 +++-- .../Webhook/OrderClosedWebhookHandlerTest.php | 26 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Helper/Webhook/OrderClosedWebhookHandler.php b/Helper/Webhook/OrderClosedWebhookHandler.php index bd29934713..ed1cbe1331 100644 --- a/Helper/Webhook/OrderClosedWebhookHandler.php +++ b/Helper/Webhook/OrderClosedWebhookHandler.php @@ -80,14 +80,15 @@ public function handleWebhook( string $transitionState ): MagentoOrder { $additionalData = $notification->getAdditionalData(); - if (is_string($additionalData)) { + if (!empty($additionalData)) { $additionalData = $this->serializer->unserialize($additionalData); } + if ($notification->isSuccessful()) { foreach ($additionalData as $key => $value) { // Check if the key matches the pattern "order-X-pspReference" if (preg_match('/^order-(\d+)-pspReference$/', $key, $matches)) { - $orderIndex = (int) $matches[1]; // Get the order number, e.g., 1, 2 + $orderIndex = (int)$matches[1]; // Get the order number, e.g., 1, 2 $pspReference = $value; $sortValue = $orderIndex; // Set status based on order index @@ -121,6 +122,7 @@ public function handleWebhook( } } } + $order->addCommentToStatusHistory(__('This order has been successfully completed.')); } else { /** @var OrderPaymentInterface $orderPayment */ diff --git a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php index b5d1168053..b9c815e269 100644 --- a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php +++ b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php @@ -1,5 +1,6 @@ configHelperMock = $this->createMock(Config::class); $this->adyenLoggerMock = $this->createMock(AdyenLogger::class); $this->adyenOrderPaymentCollectionFactoryMock = $this->createMock(OrderPaymentCollectionFactory::class); + $this->serializerMock = $this->createMock(SerializerInterface::class); $this->orderClosedWebhookHandler = new OrderClosedWebhookHandler( $this->adyenOrderPaymentHelperMock, $this->orderHelperMock, $this->configHelperMock, $this->adyenOrderPaymentCollectionFactoryMock, - $this->adyenLoggerMock + $this->adyenLoggerMock, + $this->serializerMock ); } @@ -43,21 +47,27 @@ public function testHandleWebhookSuccessfulNotificationWithMatchingAdyenOrderPay { $orderMock = $this->createMock(MagentoOrder::class); $notificationMock = $this->createMock(Notification::class); - //$adyenOrderPaymentMock = $this->createMock(OrderPaymentInterface::class); $adyenOrderPaymentMock = $this->createConfiguredMock(Order\Payment::class, [ 'getId' => 123 ]); $adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); - + $additionalDataString = 'a:1:{s:20:"order-1-pspReference";s:16:"testPspReference";}'; + $additionalData = array ( + 'order-1-pspReference' => 'testPspReference', + ); $notificationMock->expects($this->once())->method('isSuccessful')->willReturn(true); - $notificationMock->expects($this->once())->method('getAdditionalData')->willReturn(serialize(['order-1-pspReference' => 'testPspReference'])); + $notificationMock->expects($this->once())->method('getAdditionalData')->willReturn($additionalDataString); + $this->serializerMock + ->method('unserialize') + ->with($additionalDataString) + ->willReturn($additionalData); - $adyenOrderPaymentCollectionMock->expects($this->once())->method('addFieldToFilter')->willReturnSelf(); - $adyenOrderPaymentCollectionMock->expects($this->once())->method('getFirstItem')->willReturn($adyenOrderPaymentMock); + $adyenOrderPaymentCollectionMock->method('addFieldToFilter')->willReturnSelf(); + $adyenOrderPaymentCollectionMock->method('getFirstItem')->willReturn($adyenOrderPaymentMock); - $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($adyenOrderPaymentCollectionMock); + $this->adyenOrderPaymentCollectionFactoryMock->method('create')->willReturn($adyenOrderPaymentCollectionMock); - $this->adyenLoggerMock->expects($this->once())->method('addAdyenNotification') + $this->adyenLoggerMock->method('addAdyenNotification') ->with('Updated adyen_order_payment with order status 1 for pspReference testPspReference', [ 'pspReference' => 'testPspReference', 'status' => 1, From f392c00780b9c8549f83aefcc9eb23dbc4084123 Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 16:46:39 +0100 Subject: [PATCH 5/9] Updating to serializer in unit test --- Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php index b9c815e269..62bb112f8f 100644 --- a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php +++ b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php @@ -1,4 +1,5 @@ Date: Wed, 30 Oct 2024 16:58:01 +0100 Subject: [PATCH 6/9] Updating to serializer in unit test --- Helper/Webhook/OrderClosedWebhookHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Helper/Webhook/OrderClosedWebhookHandler.php b/Helper/Webhook/OrderClosedWebhookHandler.php index ed1cbe1331..385ab48083 100644 --- a/Helper/Webhook/OrderClosedWebhookHandler.php +++ b/Helper/Webhook/OrderClosedWebhookHandler.php @@ -88,9 +88,9 @@ public function handleWebhook( foreach ($additionalData as $key => $value) { // Check if the key matches the pattern "order-X-pspReference" if (preg_match('/^order-(\d+)-pspReference$/', $key, $matches)) { - $orderIndex = (int)$matches[1]; // Get the order number, e.g., 1, 2 + $orderIndex = (int)$matches[1]; $pspReference = $value; - $sortValue = $orderIndex; // Set status based on order index + $sortValue = $orderIndex; // Retrieve adyen_order_payment for this pspReference $adyenOrderPayment = $this->adyenOrderPaymentCollectionFactory->create() From 45f09795eb5cb1fa99dfab0a648018687029037d Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 30 Oct 2024 16:59:53 +0100 Subject: [PATCH 7/9] Updating to serializer in unit test --- Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php index 62bb112f8f..a0e8168b37 100644 --- a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php +++ b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php @@ -1,6 +1,7 @@ orderHelperMock = $this->createMock(OrderHelper::class); $this->configHelperMock = $this->createMock(Config::class); $this->adyenLoggerMock = $this->createMock(AdyenLogger::class); - $this->adyenOrderPaymentCollectionFactoryMock = $this->createMock(OrderPaymentCollectionFactory::class); + $this->adyenOrderPaymentCollectionFactoryMock = $this->createGeneratedMock(OrderPaymentCollectionFactory::class, ['create']); $this->serializerMock = $this->createMock(SerializerInterface::class); $this->orderClosedWebhookHandler = new OrderClosedWebhookHandler( From ec31551908cc7deb155fb739a09510383a142b0a Mon Sep 17 00:00:00 2001 From: khushboos Date: Tue, 5 Nov 2024 16:55:41 +0100 Subject: [PATCH 8/9] Writing unit test for more scenarios --- .../Webhook/OrderClosedWebhookHandlerTest.php | 112 +++++++++++----- Test/Unit/Model/Order/PaymentTest.php | 120 ++++++++++++++++++ 2 files changed, 198 insertions(+), 34 deletions(-) create mode 100644 Test/Unit/Model/Order/PaymentTest.php diff --git a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php index a0e8168b37..14e1da83c1 100644 --- a/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php +++ b/Test/Unit/Helper/Webhook/OrderClosedWebhookHandlerTest.php @@ -28,13 +28,19 @@ class OrderClosedWebhookHandlerTest extends AbstractAdyenTestCase protected function setUp(): void { + $this->orderMock = $this->createMock(MagentoOrder::class); + $this->notificationMock = $this->createMock(Notification::class); + $this->adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); $this->adyenOrderPaymentHelperMock = $this->createMock(AdyenOrderPayment::class); $this->orderHelperMock = $this->createMock(OrderHelper::class); $this->configHelperMock = $this->createMock(Config::class); $this->adyenLoggerMock = $this->createMock(AdyenLogger::class); $this->adyenOrderPaymentCollectionFactoryMock = $this->createGeneratedMock(OrderPaymentCollectionFactory::class, ['create']); + $this->adyenOrderPaymentMock = $this->createConfiguredMock(Order\Payment::class, [ + 'getId' => 123 + ]); $this->serializerMock = $this->createMock(SerializerInterface::class); - + $this->adyenOrderPaymentInterfaceMock = $this->createMock(OrderPaymentInterface::class); $this->orderClosedWebhookHandler = new OrderClosedWebhookHandler( $this->adyenOrderPaymentHelperMock, $this->orderHelperMock, @@ -47,78 +53,116 @@ protected function setUp(): void public function testHandleWebhookSuccessfulNotificationWithMatchingAdyenOrderPayment() { - $orderMock = $this->createMock(MagentoOrder::class); - $notificationMock = $this->createMock(Notification::class); - $adyenOrderPaymentMock = $this->createConfiguredMock(Order\Payment::class, [ - 'getId' => 123 - ]); - $adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); $additionalDataString = 'a:1:{s:20:"order-1-pspReference";s:16:"testPspReference";}'; $additionalData = array ( 'order-1-pspReference' => 'testPspReference', ); - $notificationMock->expects($this->once())->method('isSuccessful')->willReturn(true); - $notificationMock->expects($this->once())->method('getAdditionalData')->willReturn($additionalDataString); + $this->notificationMock->expects($this->once())->method('isSuccessful')->willReturn(true); + $this->notificationMock->expects($this->once())->method('getAdditionalData')->willReturn($additionalDataString); $this->serializerMock ->method('unserialize') ->with($additionalDataString) ->willReturn($additionalData); - $adyenOrderPaymentCollectionMock->method('addFieldToFilter')->willReturnSelf(); - $adyenOrderPaymentCollectionMock->method('getFirstItem')->willReturn($adyenOrderPaymentMock); + $this->adyenOrderPaymentCollectionMock->method('addFieldToFilter')->willReturnSelf(); + $this->adyenOrderPaymentCollectionMock->method('getFirstItem')->willReturn($this->adyenOrderPaymentMock); - $this->adyenOrderPaymentCollectionFactoryMock->method('create')->willReturn($adyenOrderPaymentCollectionMock); + $this->adyenOrderPaymentCollectionFactoryMock->method('create')->willReturn($this->adyenOrderPaymentCollectionMock); $this->adyenLoggerMock->method('addAdyenNotification') ->with('Updated adyen_order_payment with order status 1 for pspReference testPspReference', [ 'pspReference' => 'testPspReference', 'status' => 1, - 'merchantReference' => $notificationMock->getMerchantReference() + 'merchantReference' => $this->notificationMock->getMerchantReference() ]); - $orderMock->expects($this->once())->method('addCommentToStatusHistory') + $this->orderMock->expects($this->once())->method('addCommentToStatusHistory') ->with(__('This order has been successfully completed.')); - $result = $this->orderClosedWebhookHandler->handleWebhook($orderMock, $notificationMock, 'completed'); - $this->assertSame($orderMock, $result); + $result = $this->orderClosedWebhookHandler->handleWebhook($this->orderMock, $this->notificationMock, 'completed'); + $this->assertSame($this->orderMock, $result); } public function testHandleWebhookUnsuccessfulNotificationWithRefund() { - $orderMock = $this->createMock(MagentoOrder::class); - $notificationMock = $this->createMock(Notification::class); - $adyenOrderPaymentMock = $this->createMock(OrderPaymentInterface::class); - $adyenOrderPaymentCollectionMock = $this->createMock(\Magento\Framework\Data\Collection\AbstractDb::class); - - $notificationMock->expects($this->once())->method('isSuccessful')->willReturn(false); + $this->notificationMock->expects($this->once())->method('isSuccessful')->willReturn(false); - $orderMock->expects($this->once())->method('getPayment')->willReturn( + $this->orderMock->expects($this->once())->method('getPayment')->willReturn( $this->createConfiguredMock(MagentoOrderPaymentInterface::class, ['getEntityId' => 123]) ); - $adyenOrderPaymentCollectionMock->method('addFieldToFilter') + $this->adyenOrderPaymentCollectionMock->method('addFieldToFilter') ->willReturnSelf(); - $adyenOrderPaymentCollectionMock->expects($this->once())->method('getItems')->willReturn([$adyenOrderPaymentMock]); + $this->adyenOrderPaymentCollectionMock->expects($this->once())->method('getItems')->willReturn([$this->adyenOrderPaymentInterfaceMock]); - $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($adyenOrderPaymentCollectionMock); + $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($this->adyenOrderPaymentCollectionMock); - $this->adyenOrderPaymentHelperMock->expects($this->once())->method('refundFullyAdyenOrderPayment')->with($adyenOrderPaymentMock); + $this->adyenOrderPaymentHelperMock->expects($this->once())->method('refundFullyAdyenOrderPayment')->with($this->adyenOrderPaymentInterfaceMock); - $orderMock->expects($this->once())->method('addCommentToStatusHistory') + $this->orderMock->expects($this->once())->method('addCommentToStatusHistory') ->with(__('All the funds captured/settled will be refunded by Adyen.')); $this->adyenLoggerMock->expects($this->once())->method('addAdyenNotification') ->with('All the funds captured/settled will be refunded by Adyen.', [ - 'pspReference' => $notificationMock->getPspreference(), - 'merchantReference' => $notificationMock->getMerchantReference() + 'pspReference' => $this->notificationMock->getPspreference(), + 'merchantReference' => $this->notificationMock->getMerchantReference() ]); - $this->orderHelperMock->method('holdCancelOrder')->with($orderMock, true); + $this->orderHelperMock->method('holdCancelOrder')->with($this->orderMock, true); + + $this->configHelperMock->method('getNotificationsCanCancel')->with($this->orderMock->getStoreId())->willReturn(true); + + $result = $this->orderClosedWebhookHandler->handleWebhook($this->orderMock, $this->notificationMock, 'completed'); + $this->assertSame($this->orderMock, $result); + } - $this->configHelperMock->method('getNotificationsCanCancel')->with($orderMock->getStoreId())->willReturn(true); + public function testHandleWebhookLogsMessageWhenNoMatchingRecordFound(): void + { + $pspReference = 'testPspReference'; + $merchantReference = 'testMerchantReference'; + $additionalData = [ + 'order-1-pspReference' => $pspReference, + ]; + $adyenOrderPaymentMock = $this->createConfiguredMock(Order\Payment::class, [ + 'getId' => null + ]); - $result = $this->orderClosedWebhookHandler->handleWebhook($orderMock, $notificationMock, 'completed'); - $this->assertSame($orderMock, $result); + $this->notificationMock->expects($this->once()) + ->method('getAdditionalData') + ->willReturn(json_encode($additionalData)); + $this->notificationMock->expects($this->once()) + ->method('isSuccessful') + ->willReturn(true); + $this->notificationMock->expects($this->once()) + ->method('getMerchantReference') + ->willReturn($merchantReference); + + $this->serializerMock->expects($this->once()) + ->method('unserialize') + ->with(json_encode($additionalData)) + ->willReturn($additionalData); + + $this->adyenOrderPaymentCollectionFactoryMock->expects($this->once())->method('create')->willReturn($this->adyenOrderPaymentCollectionMock); + + $this->adyenOrderPaymentCollectionMock + ->method('addFieldToFilter') + ->willReturnSelf(); + $this->adyenOrderPaymentCollectionMock->expects($this->once()) + ->method('getFirstItem') + ->willReturn($adyenOrderPaymentMock); + + // Log message assertion + $this->adyenLoggerMock->expects($this->once()) + ->method('addAdyenNotification') + ->with( + sprintf("No adyen_order_payment record found for pspReference %s", $pspReference), + [ + 'pspReference' => $pspReference, + 'merchantReference' => $merchantReference + ] + ); + + $this->orderClosedWebhookHandler->handleWebhook($this->orderMock, $this->notificationMock, 'someTransitionState'); } } diff --git a/Test/Unit/Model/Order/PaymentTest.php b/Test/Unit/Model/Order/PaymentTest.php new file mode 100644 index 0000000000..9480d492ea --- /dev/null +++ b/Test/Unit/Model/Order/PaymentTest.php @@ -0,0 +1,120 @@ +createMock(Context::class); + $registryMock = $this->createMock(Registry::class); + $this->pricingDataMock = $this->createMock(PricingData::class); + $this->magentoPaymentRepositoryMock = $this->createMock(MagentoPaymentRepository::class); + $this->magentoPaymentMock = $this->createMock(MagentoPaymentInterface::class); + + $this->payment = $objectManager->getObject( + Payment::class, + [ + 'context' => $contextMock, + 'registry' => $registryMock, + 'pricingData' => $this->pricingDataMock, + 'magentoPaymentRepository' => $this->magentoPaymentRepositoryMock + ] + ); + } + + public function testGetAndSetPspReference() + { + $pspReference = 'test_psp_reference'; + $this->payment->setPspreference($pspReference); + $this->assertEquals($pspReference, $this->payment->getPspreference()); + } + + public function testGetAndSetMerchantReference() + { + $merchantReference = 'test_merchant_reference'; + $this->payment->setMerchantReference($merchantReference); + $this->assertEquals($merchantReference, $this->payment->getMerchantReference()); + } + + public function testGetAndSetPaymentId() + { + $paymentId = 123; + $this->payment->setPaymentId($paymentId); + $this->assertEquals($paymentId, $this->payment->getPaymentId()); + } + + public function testGetAndSetPaymentMethod() + { + $paymentMethod = 'test_payment_method'; + $this->payment->setPaymentMethod($paymentMethod); + $this->assertEquals($paymentMethod, $this->payment->getPaymentMethod()); + } + + public function testGetAndSetAmount() + { + $amount = 100.0; + $this->payment->setAmount($amount); + $this->assertEquals($amount, $this->payment->getAmount()); + } + + public function testGetAndSetTotalRefunded() + { + $totalRefunded = 50.0; + $this->payment->setTotalRefunded($totalRefunded); + $this->assertEquals($totalRefunded, $this->payment->getTotalRefunded()); + } + + public function testGetAndSetCreatedAt() + { + $createdAt = new DateTime(); + $this->payment->setCreatedAt($createdAt); + $this->assertEquals($createdAt, $this->payment->getCreatedAt()); + } + + public function testGetAndSetUpdatedAt() + { + $updatedAt = new DateTime(); + $this->payment->setUpdatedAt($updatedAt); + $this->assertEquals($updatedAt, $this->payment->getUpdatedAt()); + } + + public function testGetAndSetCaptureStatus() + { + $captureStatus = 'Captured'; + $this->payment->setCaptureStatus($captureStatus); + $this->assertEquals($captureStatus, $this->payment->getCaptureStatus()); + } + + public function testGetAndSetTotalCaptured() + { + $totalCaptured = 75.0; + $this->payment->setTotalCaptured($totalCaptured); + $this->assertEquals($totalCaptured, $this->payment->getTotalCaptured()); + } + + public function testSetAndGetSortOrder() + { + $sortOrder = 1; + $this->payment->setSortOrder($sortOrder); + $this->assertEquals($sortOrder, $this->payment->getSortOrder()); + } +} From 14aa0c0584ffeeafd6056c3de44939b893624015 Mon Sep 17 00:00:00 2001 From: khushboos Date: Wed, 6 Nov 2024 09:27:43 +0100 Subject: [PATCH 9/9] Defining Serializer explicitly in di.xml --- etc/di.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/di.xml b/etc/di.xml index a5d9e8fb9b..32896b3ff2 100755 --- a/etc/di.xml +++ b/etc/di.xml @@ -1602,6 +1602,11 @@ Magento\Framework\Serialize\Serializer\Serialize + + + Magento\Framework\Serialize\Serializer\Serialize + + Magento\Framework\Serialize\Serializer\Serialize