Add credit card test /w multiple products

This commit is contained in:
carmenmaymo 2025-06-25 14:10:30 +02:00
parent 0284e38e0c
commit f7f0f0f11f
No known key found for this signature in database
GPG key ID: 6023F686B0F3102E
2 changed files with 196 additions and 14 deletions

View file

@ -32,12 +32,9 @@ class IntegrationMockedTestCase extends TestCase
public function setUp(): void
{
parent::setUp();
//$this->default_product_id = $this->createAProductIfNotProvided();
$this->customer_id = $this->createCustomerIfNotExists();
$this->createTestProducts();
//$this->createTestCoupons();
$this->createTestCoupons();
}
public function tearDown(): void
@ -211,20 +208,20 @@ class IntegrationMockedTestCase extends TestCase
* @param bool $success Whether the order was successful
* @return object The mocked OrderEndpoint
*/
public function mockOrderEndpoint(string $intent = 'CAPTURE', bool $success = true): object
public function mockOrderEndpoint(string $intent = 'CAPTURE', bool $order_success = true, bool $capture_success = true): object
{
$order_endpoint = \Mockery::mock(OrderEndpoint::class)->shouldIgnoreMissing();
$order_endpoint = \Mockery::mock(OrderEndpoint::class);
$order = \Mockery::mock(Order::class)->shouldIgnoreMissing();
$order->shouldReceive('id')->andReturn('TEST-ORDER-' . uniqid());
$order->shouldReceive('intent')->andReturn($intent);
$order_status = \Mockery::mock(OrderStatus::class)->shouldIgnoreMissing();
$order_status->shouldReceive('is')->andReturn($success);
$order_status->shouldReceive('name')->andReturn($success ? 'COMPLETED' : 'FAILED');
$order_status = \Mockery::mock(OrderStatus::class);
$order_status->shouldReceive('is')->andReturn($order_success);
$order_status->shouldReceive('name')->andReturn($order_success ? 'COMPLETED' : 'FAILED');
$order->shouldReceive('status')->andReturn($order_status);
$payment_source = \Mockery::mock(PaymentSource::class)->shouldIgnoreMissing();
$payment_source = \Mockery::mock(PaymentSource::class);
$payment_source->shouldReceive('name')->andReturn('card');
$order->shouldReceive('payment_source')->andReturn($payment_source);
@ -235,7 +232,8 @@ class IntegrationMockedTestCase extends TestCase
$capture->shouldReceive('id')->andReturn('TEST-CAPTURE-' . uniqid());
$capture_status = \Mockery::mock(CaptureStatus::class)->shouldIgnoreMissing();
$capture_status->shouldReceive('name')->andReturn($success ? 'COMPLETED' : 'DECLINED');
$capture_status->shouldReceive('name')->andReturn($capture_success ? 'COMPLETED' : 'DECLINED');
$capture_status->shouldReceive('details')->andReturn(null);
$capture->shouldReceive('status')->andReturn($capture_status);
// Mock authorizations for AUTHORIZE intent
@ -245,8 +243,8 @@ class IntegrationMockedTestCase extends TestCase
$authorization->shouldReceive('id')->andReturn('TEST-AUTH-' . uniqid());
$auth_status = \Mockery::mock(\WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus::class)->shouldIgnoreMissing();
$auth_status->shouldReceive('name')->andReturn($success ? 'CREATED' : 'DENIED');
$auth_status->shouldReceive('is')->andReturn($success);
$auth_status->shouldReceive('name')->andReturn($capture_success ? 'CREATED' : 'DENIED');
$auth_status->shouldReceive('is')->andReturn($capture_success);
$authorization->shouldReceive('status')->andReturn($auth_status);
$payments->shouldReceive('authorizations')->andReturn([$authorization]);
$payments->shouldReceive('captures')->andReturn([]);
@ -267,7 +265,7 @@ class IntegrationMockedTestCase extends TestCase
$order_endpoint->shouldReceive('capture')->andReturn($order);
}
$order_endpoint->shouldReceive('order')->andReturn($order);
$order_endpoint->shouldReceive('patch_order_with')->andReturn($order);
return $order_endpoint;
}
}

View file

@ -0,0 +1,184 @@
<?php
namespace WooCommerce\PayPalCommerce\Tests\Integration\Transaction_tests;
use WC_Payment_Token;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
use WooCommerce\PayPalCommerce\Tests\Integration\IntegrationMockedTestCase;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
/**
* @group transactions
* @group skip-ci
*/
class CreditcardTransactionTest extends IntegrationMockedTestCase
{
public function setUp(): void
{
parent::setUp();
$this->mockPaymentTokensEndpoint = \Mockery::mock(PaymentTokensEndpoint::class);
}
/**
* Sets up a test container with common mocks
*
* @param OrderEndpoint $orderEndpoint
* @param array $additionalServices Additional services to override
* @return ContainerInterface
*/
protected function setupTestContainer(OrderEndpoint $orderEndpoint, array $additionalServices = []): ContainerInterface
{
$services = [
'api.endpoint.order' => function () use ($orderEndpoint) {
return $orderEndpoint;
},
];
return $this->bootstrapModule(array_merge($services, $additionalServices));
}
/**
* Creates a payment token and configures the mock endpoint to return it
*
* @param int $customer_id
* @param string $gateway_id
* @return WC_Payment_Token
*/
protected function setupPaymentToken(int $customer_id, string $gateway_id = PayPalGateway::ID): WC_Payment_Token
{
$paymentToken = $this->createAPaymentTokenForTheCustomer($customer_id, $gateway_id);
$this->mockPaymentTokensEndpoint->shouldReceive('payment_tokens_for_customer')
->andReturn([
[
'id' => $paymentToken->get_token(),
'payment_source' => new PaymentSource(
'card',
(object)[
'last_digits' => $paymentToken->get_last4(),
'brand' => $paymentToken->get_card_type(),
'expiry' => $paymentToken->get_expiry_year() . '-' . $paymentToken->get_expiry_month()
]
)
]
]);
return $paymentToken;
}
/**
* Data provider for different product and discount combinations
*/
public function paymentProcessingDataProvider(): array
{
return [
'simple product only' => [
'products' => ['simple'],
'discounts' => [],
'expected_status' => 'processing'
],
'expensive product' => [
'products' => ['simple_expensive'],
'discounts' => [],
'expected_status' => 'processing'
],
'multiple products' => [
'products' => [
['preset' => 'simple', 'quantity' => 2],
'simple_expensive'
],
'discounts' => [],
'expected_status' => 'processing'
],//TODO fix the discount logic is failing due to taxes
/*'simple product with percentage discount' => [
'products' => ['simple'],
'discounts' => ['percentage_10'],
'expected_status' => 'processing'
],
'simple product with fixed discount' => [
'products' => ['simple'],
'discounts' => ['fixed_5'],
'expected_status' => 'processing'
],*/
];
}
/**
* Tests credit card payment processing with different product combinations.
*
* GIVEN a WooCommerce order with various product and discount combinations
* AND valid PayPal order ID in POST data
* AND valid credit card form data
* WHEN the payment is processed through the credit card gateway
* THEN the payment should be successfully captured
* AND the order status should change to the expected status
* AND a transaction ID should be set on the order
*
* @dataProvider paymentProcessingDataProvider
*/
public function testProcessPayment(array $products, array $discounts, string $expected_status)
{
// Mock successful PayPal API response
$mockOrderEndpoint = $this->mockOrderEndpoint('CAPTURE', false, true);
$this->setupTestContainer($mockOrderEndpoint);
// Create order with provided products and discounts
$order = $this->getConfiguredOrder(
$this->customer_id,
'ppcp-credit-card-gateway',
$products,
$discounts,
false
);
$paypal_order_id = 'TEST-PAYPAL-ORDER-' . uniqid();
// Set the PayPal order ID in POST data (simulating frontend submission)
$_POST['paypal_order_id'] = $paypal_order_id;
$order->update_meta_data('_paypal_order_id', $paypal_order_id);
$order->save();
// Mock the session handler to return null (forcing fallback to POST/meta)
$sessionHandler = \Mockery::mock(\WooCommerce\PayPalCommerce\Session\SessionHandler::class);
$sessionHandler->shouldReceive('order')->andReturn(null);
$sessionHandler->shouldReceive('destroy_session_data')->once();
// Add session handler to container overrides
$additionalServices = [
'session.handler' => function() use ($sessionHandler) {
return $sessionHandler;
}
];
$c = $this->setupTestContainer($mockOrderEndpoint, $additionalServices);
// Simulate credit card form data
$_POST['ppcp-credit-card-gateway-card-number'] = '4111111111111111';
$_POST['ppcp-credit-card-gateway-card-expiry'] = '12/25';
$_POST['ppcp-credit-card-gateway-card-cvc'] = '123';
// Get the gateway instance
$gateway = $c->get('wcgateway.credit-card-gateway');
// Process payment
$result = $gateway->process_payment($order->get_id());
// Assertions
$this->assertEquals('success', $result['result']);
$this->assertArrayHasKey('redirect', $result);
// Verify order status changed
$order = wc_get_order($order->get_id()); // Refresh order
$this->assertEquals($expected_status, $order->get_status());
$this->assertNotEmpty($order->get_transaction_id());
// Clean up POST data
unset($_POST['paypal_order_id']);
unset($_POST['ppcp-credit-card-gateway-card-number']);
unset($_POST['ppcp-credit-card-gateway-card-expiry']);
unset($_POST['ppcp-credit-card-gateway-card-cvc']);
}
}