magento2-docker/dev/tests/integration/testsuite/Magento/Paypal/Model/IpnTest.php

285 lines
10 KiB
PHP
Executable File

<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Paypal\Model;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Creditmemo;
use Magento\Sales\Model\Order\Invoice;
use Magento\TestFramework\Helper\Bootstrap;
/**
* @magentoAppArea frontend
*/
class IpnTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $_objectManager;
protected function setUp(): void
{
$this->_objectManager = Bootstrap::getObjectManager();
}
/**
* @param string $currencyCode
* @dataProvider currencyProvider
* @magentoDataFixture Magento/Paypal/_files/order_express.php
* @magentoConfigFixture current_store payment/paypal_direct/active 1
* @magentoConfigFixture current_store payment/paypal_express/active 1
* @magentoConfigFixture current_store paypal/general/merchant_country US
*/
public function testProcessIpnRequestExpressCurrency($currencyCode)
{
$this->_processIpnRequestCurrency($currencyCode);
}
/**
* Refund full order amount by Paypal Express IPN message service.
*
* @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
* @magentoConfigFixture current_store payment/paypal_express/active 1
* @magentoConfigFixture current_store paypal/general/merchant_country US
*/
public function testProcessIpnRequestFullRefund()
{
$ipnData = require __DIR__ . '/../_files/ipn_refund.php';
$ipnFactory = $this->_objectManager->create(IpnFactory::class);
$ipnModel = $ipnFactory->create(
[
'data' => $ipnData,
'curlFactory' => $this->_createMockedHttpAdapter()
]
);
$ipnModel->processIpnRequest();
$order = $this->_objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
$creditmemoItems = $order->getCreditmemosCollection()->getItems();
$creditmemo = current($creditmemoItems);
$this->assertEquals(Order::STATE_CLOSED, $order->getState()) ;
$this->assertCount(1, $creditmemoItems);
$this->assertEquals(Creditmemo::STATE_REFUNDED, $creditmemo->getState());
$this->assertEquals(10, $order->getSubtotalRefunded());
$this->assertEquals(10, $order->getBaseSubtotalRefunded());
$this->assertEquals(20, $order->getShippingRefunded());
$this->assertEquals(20, $order->getBaseShippingRefunded());
$this->assertEquals(30, $order->getTotalRefunded());
$this->assertEquals(30, $order->getBaseTotalRefunded());
$this->assertEquals(30, $order->getTotalOnlineRefunded());
$this->assertEmpty($order->getTotalOfflineRefunded());
}
/**
* Partial refund of order amount by Paypal Express IPN message service.
*
* @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
* @magentoConfigFixture current_store payment/paypal_express/active 1
* @magentoConfigFixture current_store paypal/general/merchant_country US
*/
public function testProcessIpnRequestPartialRefund()
{
$ipnData = require __DIR__ . '/../_files/ipn_refund.php';
$refundAmount = -15;
$ipnData['mc_gross'] = $refundAmount;
$ipnFactory = $this->_objectManager->create(IpnFactory::class);
$ipnModel = $ipnFactory->create(
[
'data' => $ipnData,
'curlFactory' => $this->_createMockedHttpAdapter()
]
);
$ipnModel->processIpnRequest();
$order = $this->_objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
$creditmemoItems = $order->getCreditmemosCollection()->getItems();
$comments = $order->load($order->getId())->getAllStatusHistory();
$commentData = reset($comments);
$commentOrigin = sprintf(
'IPN "Refunded". Refund issued by merchant. Registered notification about refunded amount of $%d.00. '.
'Transaction ID: "%s". Credit Memo has not been created. Please create offline Credit Memo.',
abs($refundAmount),
$ipnData['txn_id']
);
$this->assertEquals(Order::STATE_PROCESSING, $order->getState()) ;
$this->assertEmpty(count($creditmemoItems));
$this->assertCount(1, $comments);
$this->assertEquals($commentOrigin, $commentData->getComment());
}
/**
* Refund rest of order amount by Paypal Express IPN message service.
*
* @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_and_shipping.php
* @magentoConfigFixture current_store payment/paypal_express/active 1
* @magentoConfigFixture current_store paypal/general/merchant_country US
*/
public function testProcessIpnRequestRestRefund()
{
$ipnData = require __DIR__ . '/../_files/ipn_refund.php';
$ipnFactory = $this->_objectManager->create(IpnFactory::class);
$ipnModel = $ipnFactory->create(
[
'data' => $ipnData,
'curlFactory' => $this->_createMockedHttpAdapter()
]
);
$ipnModel->processIpnRequest();
$order = $this->_objectManager->create(Order::class);
$order->loadByIncrementId('100000001');
$creditmemoItems = $order->getCreditmemosCollection()->getItems();
$this->assertEquals(Order::STATE_CLOSED, $order->getState()) ;
$this->assertCount(1, $creditmemoItems);
$this->assertEquals(10, $order->getSubtotalRefunded());
$this->assertEquals(10, $order->getBaseSubtotalRefunded());
$this->assertEquals(20, $order->getShippingRefunded());
$this->assertEquals(20, $order->getBaseShippingRefunded());
$this->assertEquals(30, $order->getTotalRefunded());
$this->assertEquals(30, $order->getBaseTotalRefunded());
$this->assertEquals(30, $order->getTotalOnlineRefunded());
$this->assertEmpty($order->getTotalOfflineRefunded());
}
/**
* Verifies canceling an order that was in payment review state by PayPal Express IPN message service.
*
* @magentoDataFixture Magento/Paypal/_files/order_express_with_invoice_payment_review.php
* @magentoConfigFixture current_store payment/paypal_express/active 1
* @magentoConfigFixture current_store paypal/general/merchant_country US
*/
public function testProcessIpnRequestWithFailedStatus()
{
$ipnData = require __DIR__ . '/../_files/ipn_failed.php';
/** @var IpnFactory $ipnFactory */
$ipnFactory = $this->_objectManager->create(IpnFactory::class);
$ipnModel = $ipnFactory->create(
[
'data' => $ipnData,
'curlFactory' => $this->_createMockedHttpAdapter()
]
);
$ipnModel->processIpnRequest();
$order = $this->getOrder($ipnData['invoice']);
$invoiceItems = $order->getInvoiceCollection()
->getItems();
/** @var Invoice $invoice */
$invoice = array_pop($invoiceItems);
$invoice->getState();
$this->assertEquals(Order::STATE_CANCELED, $order->getState());
$this->assertEquals(Invoice::STATE_CANCELED, $invoice->getState());
}
/**
* Test processIpnRequest() currency check for paypal_express and paypal_standard payment methods
*
* @param string $currencyCode
*/
protected function _processIpnRequestCurrency($currencyCode)
{
$ipnData = require __DIR__ . '/../_files/ipn.php';
$ipnData['mc_currency'] = $currencyCode;
/** @var $ipnFactory \Magento\Paypal\Model\IpnFactory */
$ipnFactory = $this->_objectManager->create(\Magento\Paypal\Model\IpnFactory::class);
$model = $ipnFactory->create(['data' => $ipnData, 'curlFactory' => $this->_createMockedHttpAdapter()]);
$model->processIpnRequest();
$order = $this->_objectManager->create(\Magento\Sales\Model\Order::class);
$order->loadByIncrementId('100000001');
$this->_assertOrder($order, $currencyCode);
}
/**
* Perform order state and status assertions depending on currency code
*
* @param \Magento\Sales\Model\Order $order
* @param string $currencyCode
*/
protected function _assertOrder($order, $currencyCode)
{
if ($currencyCode == 'USD') {
$this->assertEquals('complete', $order->getState());
$this->assertEquals('complete', $order->getStatus());
} else {
$this->assertEquals('payment_review', $order->getState());
$this->assertEquals('fraud', $order->getStatus());
}
}
/**
* Data provider for currency check tests
*
* @static
* @return array
*/
public static function currencyProvider()
{
return [['USD'], ['EUR']];
}
/**
* Mocked HTTP adapter to get VERIFIED PayPal IPN postback result
*
* @return \Magento\Framework\HTTP\Adapter\Curl
*/
protected function _createMockedHttpAdapter()
{
$factory = $this->createPartialMock(\Magento\Framework\HTTP\Adapter\CurlFactory::class, ['create']);
$adapter = $this->createPartialMock(\Magento\Framework\HTTP\Adapter\Curl::class, ['read', 'write']);
$adapter->expects($this->once())->method('read')->with()->willReturn("\nVERIFIED");
$adapter->expects($this->once())->method('write');
$factory->expects($this->once())->method('create')->with()->willReturn($adapter);
return $factory;
}
/**
* Get stored order.
*
* @param string $incrementId
* @return OrderInterface
*/
private function getOrder(string $incrementId)
{
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
$searchCriteriaBuilder = $this->_objectManager->get(SearchCriteriaBuilder::class);
$searchCriteria = $searchCriteriaBuilder->addFilter(OrderInterface::INCREMENT_ID, $incrementId)
->create();
$orderRepository = $this->_objectManager->get(OrderRepositoryInterface::class);
$orders = $orderRepository->getList($searchCriteria)
->getItems();
/** @var OrderInterface $order */
return array_pop($orders);
}
}