woocommerce-paypal-payments/tests/PHPUnit/WcGateway/Gateway/WcGatewayTest.php

335 lines
10 KiB
PHP
Raw Normal View History

2020-04-29 08:58:16 +03:00
<?php
declare(strict_types=1);
2020-09-14 07:51:45 +03:00
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
2020-04-29 08:58:16 +03:00
use Exception;
use Psr\Log\LoggerInterface;
2023-04-25 12:19:44 +02:00
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
2024-04-10 16:36:41 +02:00
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
2023-06-14 15:39:24 +03:00
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
2021-10-06 17:44:41 +03:00
use WooCommerce\PayPalCommerce\Onboarding\Environment;
2020-09-28 11:47:24 +03:00
use WooCommerce\PayPalCommerce\Onboarding\State;
2020-09-14 07:51:45 +03:00
use WooCommerce\PayPalCommerce\Session\SessionHandler;
2024-04-10 16:36:41 +02:00
use WooCommerce\PayPalCommerce\Vaulting\WooCommercePaymentTokens;
2023-10-18 17:15:27 +02:00
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
2020-09-14 07:51:45 +03:00
use WooCommerce\PayPalCommerce\TestCase;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer;
2020-09-14 07:51:45 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
2020-09-28 11:47:24 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
2020-09-14 07:51:45 +03:00
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
2020-04-29 08:58:16 +03:00
use Mockery;
use function Brain\Monkey\Functions\expect;
2021-03-17 10:30:02 +02:00
use function Brain\Monkey\Functions\when;
2020-04-29 08:58:16 +03:00
class WcGatewayTest extends TestCase
{
private $isAdmin = false;
private $sessionHandler;
private $fundingSource = null;
private $settingsRenderer;
private $funding_source_renderer;
private $orderProcessor;
private $settings;
private $refundProcessor;
private $onboardingState;
private $transactionUrlProvider;
private $subscriptionHelper;
2021-10-06 17:44:41 +03:00
private $environment;
private $paymentTokenRepository;
private $logger;
2022-04-22 15:26:44 +02:00
private $apiShopCountry;
2023-04-25 12:19:44 +02:00
private $orderEndpoint;
2024-04-10 16:36:41 +02:00
private $paymentTokensEndpoint;
private $vaultV3Enabled;
private $wcPaymentTokens;
2020-04-29 08:58:16 +03:00
2021-10-06 17:44:41 +03:00
public function setUp(): void {
parent::setUp();
expect('is_admin')->andReturnUsing(function () {
return $this->isAdmin;
});
2022-10-21 12:25:22 +02:00
when('wc_clean')->returnArg();
$this->settingsRenderer = Mockery::mock(SettingsRenderer::class);
$this->orderProcessor = Mockery::mock(OrderProcessor::class);
$this->settings = Mockery::mock(Settings::class);
$this->sessionHandler = Mockery::mock(SessionHandler::class);
$this->refundProcessor = Mockery::mock(RefundProcessor::class);
$this->onboardingState = Mockery::mock(State::class);
$this->transactionUrlProvider = Mockery::mock(TransactionUrlProvider::class);
$this->subscriptionHelper = Mockery::mock(SubscriptionHelper::class);
2021-10-06 17:44:41 +03:00
$this->environment = Mockery::mock(Environment::class);
$this->paymentTokenRepository = Mockery::mock(PaymentTokenRepository::class);
$this->logger = Mockery::mock(LoggerInterface::class);
2023-03-01 10:20:04 +02:00
$this->funding_source_renderer = new FundingSourceRenderer(
$this->settings,
['venmo' => 'Venmo', 'paylater' => 'Pay Later', 'blik' => 'BLIK']
);
2022-04-22 15:26:44 +02:00
$this->apiShopCountry = 'DE';
2023-04-25 12:19:44 +02:00
$this->orderEndpoint = Mockery::mock(OrderEndpoint::class);
$this->onboardingState->shouldReceive('current_state')->andReturn(State::STATE_ONBOARDED);
$this->sessionHandler
->shouldReceive('funding_source')
->andReturnUsing(function () {
return $this->fundingSource;
});
2023-06-14 15:39:24 +03:00
$order = Mockery::mock(Order::class);
$order->shouldReceive('status')->andReturn(new OrderStatus(OrderStatus::APPROVED));
$this->sessionHandler
->shouldReceive('order')
->andReturn($order);
$this->settings->shouldReceive('has')->andReturnFalse();
$this->logger->shouldReceive('info');
$this->logger->shouldReceive('error');
2024-04-10 16:36:41 +02:00
$this->paymentTokensEndpoint = Mockery::mock(PaymentTokensEndpoint::class);
$this->vaultV3Enabled = true;
$this->wcPaymentTokens = Mockery::mock(WooCommercePaymentTokens::class);
2021-10-06 17:44:41 +03:00
}
private function createGateway()
{
return new PayPalGateway(
$this->settingsRenderer,
$this->funding_source_renderer,
$this->orderProcessor,
$this->settings,
$this->sessionHandler,
$this->refundProcessor,
$this->onboardingState,
$this->transactionUrlProvider,
$this->subscriptionHelper,
PayPalGateway::ID,
$this->environment,
$this->paymentTokenRepository,
$this->logger,
2023-04-25 12:19:44 +02:00
$this->apiShopCountry,
2023-11-14 10:50:56 +02:00
$this->orderEndpoint,
function ($id) {
return 'checkoutnow=' . $id;
},
2024-04-10 16:36:41 +02:00
'Pay via PayPal',
$this->paymentTokensEndpoint,
$this->vaultV3Enabled,
$this->wcPaymentTokens
);
}
2020-04-29 08:58:16 +03:00
public function testProcessPaymentSuccess() {
2020-04-29 08:58:16 +03:00
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$wcOrder->shouldReceive('get_customer_id')->andReturn(1);
$wcOrder->shouldReceive('get_meta')->andReturn('');
$this->orderProcessor
2020-04-29 08:58:16 +03:00
->expects('process')
->andReturnUsing(
2021-03-17 10:30:02 +02:00
function(\WC_Order $order) use ($wcOrder) : bool {
2020-04-29 08:58:16 +03:00
return $order === $wcOrder;
}
);
$this->sessionHandler
->shouldReceive('destroy_session_data');
$this->subscriptionHelper
2021-06-04 11:57:25 +02:00
->shouldReceive('has_subscription')
->with($orderId)
->andReturn(true)
->andReturn(false);
$this->subscriptionHelper
2021-06-04 11:57:25 +02:00
->shouldReceive('is_subscription_change_payment')
->andReturn(true);
$testee = $this->createGateway();
2020-04-29 08:58:16 +03:00
expect('wc_get_order')
->with($orderId)
->andReturn($wcOrder);
2021-03-17 10:30:02 +02:00
when('wc_get_checkout_url')
->justReturn('test');
$woocommerce = Mockery::mock(\WooCommerce::class);
$cart = Mockery::mock(\WC_Cart::class);
when('WC')->justReturn($woocommerce);
$woocommerce->cart = $cart;
$cart->shouldReceive('empty_cart');
2023-09-18 10:41:51 +02:00
2023-04-25 12:19:44 +02:00
$session = Mockery::mock(\WC_Session::class);
$woocommerce->session = $session;
$session->shouldReceive('get');
2023-09-18 10:41:51 +02:00
$session->shouldReceive('set');
2020-04-29 08:58:16 +03:00
$result = $testee->process_payment($orderId);
2021-03-17 10:30:02 +02:00
2020-04-29 08:58:16 +03:00
$this->assertIsArray($result);
2021-03-17 10:30:02 +02:00
2020-04-29 08:58:16 +03:00
$this->assertEquals('success', $result['result']);
$this->assertEquals($result['redirect'], $wcOrder);
}
public function testProcessPaymentOrderNotFound() {
$orderId = 1;
$testee = $this->createGateway();
2020-04-29 08:58:16 +03:00
2023-09-18 10:41:51 +02:00
$woocommerce = Mockery::mock(\WooCommerce::class);
$session = Mockery::mock(\WC_Session::class);
when('WC')->justReturn($woocommerce);
$woocommerce->session = $session;
$session->shouldReceive('set')->andReturn([]);
2020-04-29 08:58:16 +03:00
expect('wc_get_order')
->with($orderId)
->andReturn(false);
2021-03-17 10:30:02 +02:00
$redirectUrl = 'http://example.com/checkout';
when('wc_get_checkout_url')
->justReturn($redirectUrl);
$this->sessionHandler
->shouldReceive('destroy_session_data');
expect('wc_add_notice');
2021-03-17 10:30:02 +02:00
2023-05-22 12:08:20 +03:00
$result = $testee->process_payment($orderId);
$this->assertArrayHasKey('errorMessage', $result);
unset($result['errorMessage']);
2021-03-17 10:30:02 +02:00
$this->assertEquals(
[
'result' => 'failure',
2023-05-22 12:08:20 +03:00
'redirect' => $redirectUrl,
2021-03-17 10:30:02 +02:00
],
2023-05-22 12:08:20 +03:00
$result
2021-03-17 10:30:02 +02:00
);
2020-04-29 08:58:16 +03:00
}
public function testProcessPaymentFails() {
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$error = 'some-error';
$this->orderProcessor
2020-04-29 08:58:16 +03:00
->expects('process')
->andThrow(new Exception($error));
$this->subscriptionHelper->shouldReceive('has_subscription')->with($orderId)->andReturn(true);
$this->subscriptionHelper->shouldReceive('is_subscription_change_payment')->andReturn(true);
2021-08-13 14:39:27 +02:00
$wcOrder->shouldReceive('update_status')->andReturn(true);
2021-06-04 11:57:25 +02:00
$testee = $this->createGateway();
2020-04-29 08:58:16 +03:00
expect('wc_get_order')
->with($orderId)
->andReturn($wcOrder);
$this->sessionHandler
->shouldReceive('destroy_session_data');
2020-04-29 08:58:16 +03:00
expect('wc_add_notice')
->with($error, 'error');
2020-04-29 08:58:16 +03:00
2021-03-17 10:30:02 +02:00
$redirectUrl = 'http://example.com/checkout';
when('wc_get_checkout_url')
->justReturn($redirectUrl);
2021-06-04 11:57:25 +02:00
2023-04-25 12:19:44 +02:00
$woocommerce = Mockery::mock(\WooCommerce::class);
when('WC')->justReturn($woocommerce);
$session = Mockery::mock(\WC_Session::class);
$woocommerce->session = $session;
$session->shouldReceive('get');
2023-09-18 10:41:51 +02:00
$session->shouldReceive('set');
2023-04-25 12:19:44 +02:00
$result = $testee->process_payment($orderId);
2023-05-22 12:08:20 +03:00
$this->assertArrayHasKey('errorMessage', $result);
unset($result['errorMessage']);
$this->assertEquals(
[
'result' => 'failure',
'redirect' => $redirectUrl,
2021-03-17 10:30:02 +02:00
],
$result
);
2020-04-29 08:58:16 +03:00
}
2021-07-28 10:03:43 +03:00
/**
* @dataProvider dataForTestNeedsSetup
*/
public function testNeedsSetup($currentState, $needSetup)
{
$this->isAdmin = true;
$this->onboardingState = Mockery::mock(State::class);
$this->onboardingState
2021-07-28 10:03:43 +03:00
->expects('current_state')
->andReturn($currentState);
$testee = $this->createGateway();
2021-08-27 17:28:15 +03:00
2021-07-28 10:03:43 +03:00
$this->assertSame($needSetup, $testee->needs_setup());
}
2020-04-29 08:58:16 +03:00
/**
* @dataProvider dataForFundingSource
*/
public function testFundingSource($fundingSource, $title, $description)
{
$this->fundingSource = $fundingSource;
$testee = $this->createGateway();
self::assertEquals($title, $testee->title);
self::assertEquals($description, $testee->description);
}
2020-04-29 08:58:16 +03:00
public function dataForTestCaptureAuthorizedPaymentNoActionableFailures() : array
{
return [
'inaccessible' => [
AuthorizedPaymentsProcessor::INACCESSIBLE,
AuthorizeOrderActionNotice::NO_INFO,
],
'not_found' => [
AuthorizedPaymentsProcessor::NOT_FOUND,
AuthorizeOrderActionNotice::NOT_FOUND,
],
'not_mapped' => [
'some-other-failure',
AuthorizeOrderActionNotice::FAILED,
],
];
}
2021-08-27 17:28:15 +03:00
2021-07-28 10:03:43 +03:00
public function dataForTestNeedsSetup(): array
{
return [
[State::STATE_START, true],
[State::STATE_ONBOARDED, false]
];
}
public function dataForFundingSource(): array
{
return [
[null, 'PayPal', 'Pay via PayPal.'],
['venmo', 'Venmo', 'Pay via Venmo.'],
2023-03-01 10:20:04 +02:00
['paylater', 'Pay Later', 'Pay via Pay Later.'],
['blik', 'BLIK (via PayPal)', 'Pay via BLIK.'],
['qwerty', 'PayPal', 'Pay via PayPal.'],
];
}
2021-02-19 19:57:25 +02:00
}