269 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
<?php
 | 
						|
/**
 | 
						|
 * Copyright © Magento, Inc. All rights reserved.
 | 
						|
 * See COPYING.txt for license details.
 | 
						|
 */
 | 
						|
declare(strict_types=1);
 | 
						|
 | 
						|
namespace Magento\Paypal\Model;
 | 
						|
 | 
						|
use Magento\Framework\Api\AttributeValueFactory;
 | 
						|
use Magento\Framework\Api\ExtensionAttributesFactory;
 | 
						|
use Magento\Framework\Api\SearchCriteriaBuilder;
 | 
						|
use Magento\Framework\App\Config\ScopeConfigInterface;
 | 
						|
use Magento\Framework\DataObject;
 | 
						|
use Magento\Framework\Model\Context;
 | 
						|
use Magento\Framework\Module\ModuleListInterface;
 | 
						|
use Magento\Framework\ObjectManagerInterface;
 | 
						|
use Magento\Framework\Registry;
 | 
						|
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
 | 
						|
use Magento\Payment\Gateway\Command\CommandException;
 | 
						|
use Magento\Payment\Helper\Data;
 | 
						|
use Magento\Payment\Model\InfoInterface;
 | 
						|
use Magento\Payment\Model\Method\ConfigInterfaceFactory;
 | 
						|
use Magento\Payment\Model\Method\Logger;
 | 
						|
use Magento\Paypal\Model\Payflow\Service\Gateway;
 | 
						|
use Magento\Paypal\Model\Payflow\Service\Response\Handler\HandlerInterface;
 | 
						|
use Magento\Quote\Api\Data\PaymentMethodInterface;
 | 
						|
use Magento\Sales\Api\Data\OrderInterface;
 | 
						|
use Magento\Sales\Api\OrderRepositoryInterface;
 | 
						|
use Magento\Sales\Model\Order;
 | 
						|
use Magento\Sales\Model\Order\Item;
 | 
						|
use Magento\Store\Model\StoreManagerInterface;
 | 
						|
use Magento\TestFramework\Helper\Bootstrap;
 | 
						|
use PHPUnit\Framework\MockObject\MockObject;
 | 
						|
use PHPUnit\Framework\TestCase;
 | 
						|
 | 
						|
/**
 | 
						|
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 | 
						|
 */
 | 
						|
class PayflowproVoidTest extends TestCase
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var ObjectManagerInterface
 | 
						|
     */
 | 
						|
    private $objectManager;
 | 
						|
 | 
						|
    public function setUp(): void
 | 
						|
    {
 | 
						|
        $this->objectManager = Bootstrap::getObjectManager();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests PayflowPro payment void operation.
 | 
						|
     *
 | 
						|
     * @magentoDataFixture Magento/Paypal/_files/order_payflowpro.php
 | 
						|
     * @magentoConfigFixture current_store payment/payflowpro/active 1
 | 
						|
     */
 | 
						|
    public function testPaymentVoid(): void
 | 
						|
    {
 | 
						|
        $response = new DataObject(
 | 
						|
            [
 | 
						|
                'result' => '0',
 | 
						|
                'pnref' => 'V19A3D27B61E',
 | 
						|
                'respmsg' => 'Approved',
 | 
						|
                'authcode' => '510PNI',
 | 
						|
                'hostcode' => 'A',
 | 
						|
                'request_id' => 'f930d3dc6824c1f7230c5529dc37ae5e',
 | 
						|
                'result_code' => '0',
 | 
						|
            ]
 | 
						|
        );
 | 
						|
 | 
						|
        $order = $this->getOrder();
 | 
						|
        $payment = $order->getPayment();
 | 
						|
        $instance = $this->getPaymentMethodInstance($response);
 | 
						|
        $payment->setMethodInstance($instance);
 | 
						|
 | 
						|
        $this->assertTrue($order->canVoidPayment());
 | 
						|
 | 
						|
        $payment->void(new DataObject());
 | 
						|
        /** @var OrderRepositoryInterface $orderRepository */
 | 
						|
        $orderRepository = $this->objectManager->get(OrderRepositoryInterface::class);
 | 
						|
        $orderRepository->save($order);
 | 
						|
 | 
						|
        $order = $this->getOrderByIncrementId('100000001');
 | 
						|
        $this->assertFalse($order->canVoidPayment());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests canceling order with acceptable void transaction results.
 | 
						|
     *
 | 
						|
     * @param DataObject $response
 | 
						|
     * @magentoDataFixture Magento/Paypal/_files/order_payflowpro.php
 | 
						|
     * @magentoConfigFixture current_store payment/payflowpro/active 1
 | 
						|
     * @dataProvider orderCancelSuccessDataProvider
 | 
						|
     */
 | 
						|
    public function testOrderCancelSuccess(DataObject $response): void
 | 
						|
    {
 | 
						|
        $order = $this->getOrder();
 | 
						|
        $payment = $order->getPayment();
 | 
						|
        $instance = $this->getPaymentMethodInstance($response);
 | 
						|
        $payment->setMethodInstance($instance);
 | 
						|
        $order->cancel();
 | 
						|
 | 
						|
        $this->assertEquals(Order::STATE_CANCELED, $order->getState());
 | 
						|
        $this->assertEquals(Order::STATE_CANCELED, $order->getStatus());
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return array
 | 
						|
     */
 | 
						|
    public function orderCancelSuccessDataProvider(): array
 | 
						|
    {
 | 
						|
        return [
 | 
						|
            'Authorization has expired' => [
 | 
						|
                new DataObject(
 | 
						|
                    [
 | 
						|
                        'respmsg' => 'Declined: 10601-Authorization has expired.',
 | 
						|
                        'result_code' => '10601',
 | 
						|
                    ]
 | 
						|
                )
 | 
						|
            ],
 | 
						|
            'Authorization voided successfully' => [
 | 
						|
                new DataObject(
 | 
						|
                    [
 | 
						|
                        'respmsg' => 'Approved',
 | 
						|
                        'result_code' => '0',
 | 
						|
                    ]
 | 
						|
                )
 | 
						|
            ]
 | 
						|
        ];
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests canceling the order when got an error during transaction voiding.
 | 
						|
     *
 | 
						|
     * @magentoDataFixture Magento/Paypal/_files/order_payflowpro.php
 | 
						|
     * @magentoConfigFixture current_store payment/payflowpro/active 1
 | 
						|
     */
 | 
						|
    public function testOrderCancelWithVoidError(): void
 | 
						|
    {
 | 
						|
        $response = new DataObject(
 | 
						|
            [
 | 
						|
                'respmsg' => 'Declined: for some reason other then expired authorization',
 | 
						|
                'result_code' => '111',
 | 
						|
            ]
 | 
						|
        );
 | 
						|
        $order = $this->getOrder();
 | 
						|
        $payment = $order->getPayment();
 | 
						|
        $instance = $this->getPaymentMethodInstance($response);
 | 
						|
        $payment->setMethodInstance($instance);
 | 
						|
 | 
						|
        $this->expectException(CommandException::class);
 | 
						|
        $order->cancel();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns prepared order.
 | 
						|
     *
 | 
						|
     * @return Order
 | 
						|
     * @throws \ReflectionException
 | 
						|
     */
 | 
						|
    private function getOrder(): Order
 | 
						|
    {
 | 
						|
        /** @var $order Order */
 | 
						|
        $order = $this->getOrderByIncrementId('100000001');
 | 
						|
        $orderItem = $this->createMock(Item::class);
 | 
						|
        $orderItem->method('getQtyToInvoice')
 | 
						|
            ->willReturn(true);
 | 
						|
        $order->setItems([$orderItem]);
 | 
						|
 | 
						|
        $payment = $order->getPayment();
 | 
						|
        $canVoidLookupProperty = new \ReflectionProperty(get_class($payment), '_canVoidLookup');
 | 
						|
        $canVoidLookupProperty->setAccessible(true);
 | 
						|
        $canVoidLookupProperty->setValue($payment, true);
 | 
						|
 | 
						|
        return $order;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns payment method instance.
 | 
						|
     *
 | 
						|
     * @param DataObject $response
 | 
						|
     * @return PaymentMethodInterface
 | 
						|
     * @throws \ReflectionException
 | 
						|
     */
 | 
						|
    private function getPaymentMethodInstance(DataObject $response): PaymentMethodInterface
 | 
						|
    {
 | 
						|
        $gatewayMock = $this->createMock(Gateway::class);
 | 
						|
        $gatewayMock->expects($this->once())
 | 
						|
            ->method('postRequest')
 | 
						|
            ->willReturn($response);
 | 
						|
 | 
						|
        $configMock = $this->createMock(PayflowConfig::class);
 | 
						|
        $configFactoryMock = $this->createPartialMock(
 | 
						|
            ConfigInterfaceFactory::class,
 | 
						|
            ['create']
 | 
						|
        );
 | 
						|
 | 
						|
        $configFactoryMock->expects($this->once())
 | 
						|
            ->method('create')
 | 
						|
            ->willReturn($configMock);
 | 
						|
 | 
						|
        $configMock->expects($this->any())
 | 
						|
            ->method('getValue')
 | 
						|
            ->willReturnMap(
 | 
						|
                [
 | 
						|
                    ['use_proxy', false],
 | 
						|
                    ['sandbox_flag', '1'],
 | 
						|
                    ['transaction_url_test_mode', 'https://test_transaction_url']
 | 
						|
                ]
 | 
						|
            );
 | 
						|
 | 
						|
        /** @var Payflowpro|MockObject $instance */
 | 
						|
        $instance = $this->getMockBuilder(Payflowpro::class)
 | 
						|
            ->setMethods(['setStore', 'getInfoInstance'])
 | 
						|
            ->setConstructorArgs(
 | 
						|
                [
 | 
						|
                    $this->objectManager->get(Context::class),
 | 
						|
                    $this->objectManager->get(Registry::class),
 | 
						|
                    $this->objectManager->get(ExtensionAttributesFactory::class),
 | 
						|
                    $this->objectManager->get(AttributeValueFactory::class),
 | 
						|
                    $this->objectManager->get(Data::class),
 | 
						|
                    $this->objectManager->get(ScopeConfigInterface::class),
 | 
						|
                    $this->objectManager->get(Logger::class),
 | 
						|
                    $this->objectManager->get(ModuleListInterface::class),
 | 
						|
                    $this->objectManager->get(TimezoneInterface::class),
 | 
						|
                    $this->objectManager->get(StoreManagerInterface::class),
 | 
						|
                    $configFactoryMock,
 | 
						|
                    $gatewayMock,
 | 
						|
                    $this->objectManager->get(HandlerInterface::class),
 | 
						|
                    null,
 | 
						|
                    null,
 | 
						|
                    []
 | 
						|
                ]
 | 
						|
            )
 | 
						|
            ->getMock();
 | 
						|
 | 
						|
        $instance->expects($this->once())
 | 
						|
            ->method('setStore')
 | 
						|
            ->willReturnSelf();
 | 
						|
        $paymentInfoInstance = $this->createMock(InfoInterface::class);
 | 
						|
        $instance->method('getInfoInstance')
 | 
						|
            ->willReturn($paymentInfoInstance);
 | 
						|
 | 
						|
        return $instance;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get stored order.
 | 
						|
     *
 | 
						|
     * @param string $incrementId
 | 
						|
     * @return OrderInterface
 | 
						|
     */
 | 
						|
    private function getOrderByIncrementId(string $incrementId): OrderInterface
 | 
						|
    {
 | 
						|
        /** @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);
 | 
						|
    }
 | 
						|
}
 |