202 lines
6.4 KiB
PHP
Executable File
202 lines
6.4 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
namespace Magento\Paypal\Controller\Payflow;
|
|
|
|
use Magento\Framework\Api\FilterBuilder;
|
|
use Magento\Framework\Api\SearchCriteriaBuilder;
|
|
use Magento\Framework\DataObject;
|
|
use Magento\Framework\Logger\Monolog;
|
|
use Magento\Payment\Gateway\Command\CommandException;
|
|
use Magento\Paypal\Model\Payflow\Service\Gateway;
|
|
use Magento\Paypal\Model\Payflowlink;
|
|
use Magento\Sales\Api\Data\OrderInterface;
|
|
use Magento\Sales\Api\OrderRepositoryInterface;
|
|
use Magento\Sales\Model\Order;
|
|
use Magento\Sales\Model\Order\Email\Sender\OrderSender;
|
|
use Magento\TestFramework\TestCase\AbstractController;
|
|
use PHPUnit\Framework\MockObject_MockObject as MockObject;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* @magentoAppIsolation enabled
|
|
*/
|
|
class SilentPostTest extends AbstractController
|
|
{
|
|
/**
|
|
* @var Gateway|MockObject
|
|
*/
|
|
private $gateway;
|
|
|
|
/**
|
|
* @var OrderSender|MockObject
|
|
*/
|
|
private $orderSender;
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->gateway = $this->getMockBuilder(Gateway::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$this->orderSender = $this->getMockBuilder(OrderSender::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$this->_objectManager->addSharedInstance($this->gateway, Gateway::class);
|
|
$this->_objectManager->addSharedInstance($this->orderSender, OrderSender::class);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
protected function tearDown(): void
|
|
{
|
|
$this->_objectManager->removeSharedInstance(Gateway::class);
|
|
$this->_objectManager->removeSharedInstance(OrderSender::class);
|
|
parent::tearDown();
|
|
}
|
|
|
|
/**
|
|
* Checks a test case when Payflow Link callback action receives Silent Post notification with transaction details.
|
|
*
|
|
* @param int $resultCode
|
|
* @param string $orderState
|
|
* @param string $orderStatus
|
|
* @magentoDataFixture Magento/Paypal/_files/order_payflow_link.php
|
|
* @dataProvider responseCodeDataProvider
|
|
*/
|
|
public function testSuccessfulNotification($resultCode, $orderState, $orderStatus)
|
|
{
|
|
$orderIncrementId = '000000045';
|
|
$this->withRequest($orderIncrementId, $resultCode);
|
|
$this->withGatewayResponse($orderIncrementId, $resultCode);
|
|
|
|
$this->dispatch('paypal/payflow/silentPost');
|
|
|
|
self::assertEquals(200, $this->getResponse()->getStatusCode());
|
|
|
|
$order = $this->getOrder($orderIncrementId);
|
|
self::assertEquals($orderState, $order->getState());
|
|
self::assertEquals($orderStatus, $order->getStatus());
|
|
}
|
|
|
|
/**
|
|
* Get list of different variations for Silent Post action testing,
|
|
* like different response codes from PayPal.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function responseCodeDataProvider()
|
|
{
|
|
return [
|
|
[Payflowlink::RESPONSE_CODE_APPROVED, Order::STATE_COMPLETE, Order::STATE_COMPLETE],
|
|
[Payflowlink::RESPONSE_CODE_FRAUDSERVICE_FILTER, Order::STATE_PAYMENT_REVIEW, Order::STATUS_FRAUD],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Checks a test case when Payflow Link callback receives Silent Post notification from PayPal
|
|
* with fraudulent transaction and PayPal gateway configured to reject this kind of transactions.
|
|
*
|
|
* @magentoDataFixture Magento/Paypal/_files/order_payflow_link.php
|
|
*/
|
|
public function testFraudulentNotification()
|
|
{
|
|
$orderIncrementId = '000000045';
|
|
$resultCode = Payflowlink::RESPONSE_CODE_DECLINED_BY_FILTER;
|
|
$this->withRequest($orderIncrementId, $resultCode);
|
|
$this->withGatewayResponse($orderIncrementId, $resultCode);
|
|
|
|
$logger = $this->getMockBuilder(Monolog::class)
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
$this->_objectManager->addSharedInstance($logger, LoggerInterface::class, true);
|
|
|
|
$exception = new CommandException(__('Response message from PayPal gateway'));
|
|
$logger->expects(self::once())
|
|
->method('critical')
|
|
->with(self::equalTo($exception));
|
|
|
|
$this->dispatch('paypal/payflow/silentPost');
|
|
|
|
self::assertEquals(200, $this->getResponse()->getStatusCode());
|
|
|
|
$this->_objectManager->removeSharedInstance(LoggerInterface::class, true);
|
|
}
|
|
|
|
/**
|
|
* Imitates real POST request with test data.
|
|
*
|
|
* @param string $orderIncrementId
|
|
* @param int $resultCode
|
|
* @return void
|
|
*/
|
|
private function withRequest($orderIncrementId, $resultCode)
|
|
{
|
|
$data = [
|
|
'INVNUM' => $orderIncrementId,
|
|
'AMT' => 100,
|
|
'PNREF' => 'A21CP234KLB8',
|
|
'USER2' => 'cf7i85d01ed7c92223031afb4rdl2f1f',
|
|
'RESULT' => $resultCode,
|
|
'TYPE' => 'A',
|
|
];
|
|
$this->getRequest()->setPostValue($data);
|
|
}
|
|
|
|
/**
|
|
* Imitates response from PayPal gateway.
|
|
*
|
|
* @param string $orderIncrementId
|
|
* @param int $resultCode
|
|
* @return void
|
|
*/
|
|
private function withGatewayResponse($orderIncrementId, $resultCode)
|
|
{
|
|
$response = new DataObject([
|
|
'custref' => $orderIncrementId,
|
|
'origresult' => $resultCode,
|
|
'respmsg' => 'Response message from PayPal gateway'
|
|
]);
|
|
$this->gateway->method('postRequest')
|
|
->willReturn($response);
|
|
}
|
|
|
|
/**
|
|
* Gets order stored by fixture.
|
|
*
|
|
* @param string $incrementId
|
|
* @return OrderInterface
|
|
*/
|
|
private function getOrder($incrementId)
|
|
{
|
|
/** @var FilterBuilder $filterBuilder */
|
|
$filterBuilder = $this->_objectManager->get(FilterBuilder::class);
|
|
$filters = [
|
|
$filterBuilder->setField(OrderInterface::INCREMENT_ID)
|
|
->setValue($incrementId)
|
|
->create()
|
|
];
|
|
|
|
/** @var SearchCriteriaBuilder $searchCriteriaBuilder */
|
|
$searchCriteriaBuilder = $this->_objectManager->get(SearchCriteriaBuilder::class);
|
|
$searchCriteria = $searchCriteriaBuilder->addFilters($filters)
|
|
->create();
|
|
|
|
$orderRepository = $this->_objectManager->get(OrderRepositoryInterface::class);
|
|
$orders = $orderRepository->getList($searchCriteria)
|
|
->getItems();
|
|
|
|
/** @var OrderInterface $order */
|
|
return array_pop($orders);
|
|
}
|
|
}
|