HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/tests/Unit/Cashier/Services/StripePaymentGatewayTest.php
<?php

namespace Tests\Unit\Cashier\Services;

use Tests\TestCase;
use App\Cashier\Services\StripePaymentGateway;
use App\Cashier\Contracts\IntentGatewayInterface;
use App\Cashier\Contracts\SupportsAutoChargeInterface;
use App\Cashier\DTO\PaymentIntent;
use App\Cashier\DTO\Payer;
use App\Cashier\DTO\SubscriptionSpec;
use App\Cashier\DTO\PaymentResult;

class StripePaymentGatewayTest extends TestCase
{
    private function service(): StripePaymentGateway
    {
        return new StripePaymentGateway('pk_test_x', 'sk_test_x');
    }

    private function intent(float $amount = 29.99, ?SubscriptionSpec $sub = null): PaymentIntent
    {
        $payer = new Payer(
            uid: 'cust_uid', name: 'Alice', email: '[email protected]',
        );
        return new PaymentIntent(
            uid: 'intent_uid_xxx',
            amount: $amount,
            currency: 'USD',
            description: 'Pay invoice',
            paymentGatewayId: 'gw_uid',
            payer: $payer,
            subscription: $sub,
        );
    }

    public function test_implements_required_interfaces()
    {
        $svc = $this->service();

        $this->assertInstanceOf(IntentGatewayInterface::class, $svc);
        $this->assertInstanceOf(SupportsAutoChargeInterface::class, $svc);
    }

    public function test_get_checkout_url_uses_intent_uid_in_path()
    {
        $url = $this->service()->getCheckoutUrl($this->intent(), '/account');

        $this->assertMatchesRegularExpression(
            '#/cashier/stripe/checkout/intent_uid_xxx\?return_url=#',
            $url
        );
    }

    public function test_get_checkout_url_does_not_leak_secret_key()
    {
        $url = $this->service()->getCheckoutUrl($this->intent(), '/account');

        $this->assertStringNotContainsString('sk_test_x', $url);
    }

    public function test_auto_charge_short_circuits_for_free_invoice()
    {
        // $0 invoice → no Stripe call, just success. Catches regression where
        // we accidentally call Stripe with amount=0 (which throws InvalidRequest).
        $result = $this->service()->autoCharge($this->intent(0.0), []);

        $this->assertSame(PaymentResult::STATUS_SUCCESS, $result->status);
        $this->assertSame('FREE_NO_CHARGE', $result->remoteReferenceId);
    }

    public function test_convert_price_handles_standard_currency()
    {
        $this->assertSame(2999, $this->service()->convertPrice(29.99, 'USD'));
        $this->assertSame(10000, $this->service()->convertPrice(100, 'USD'));
    }

    public function test_convert_price_handles_zero_decimal_currencies()
    {
        // JPY has no cents — Stripe expects raw yen
        $this->assertSame(1000, $this->service()->convertPrice(1000, 'JPY'));
        $this->assertSame(500, $this->service()->convertPrice(500, 'VND'));
    }

    public function test_get_method_title_reads_card_type()
    {
        $this->assertSame('Visa', $this->service()->getMethodTitle(['card_type' => 'Visa']));
        $this->assertSame('Unknown', $this->service()->getMethodTitle([]));
    }

    public function test_get_method_info_masks_card()
    {
        $info = $this->service()->getMethodInfo(['last_4' => '4242']);
        $this->assertStringEndsWith('4242', $info);
        $this->assertStringContainsString('***', $info);
    }

    public function test_supports_auto_billing_returns_true()
    {
        $this->assertTrue($this->service()->supportsAutoBilling());
    }
}