120 lines
3.8 KiB
PHP
120 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Http\Controllers\Api\StripeWebhookController;
|
|
use App\Models\Package;
|
|
use App\Models\PackagePurchase;
|
|
use App\Models\EventPackage;
|
|
use App\Models\TenantPackage;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Stripe\Webhook;
|
|
use Tests\TestCase;
|
|
|
|
class StripeWebhookTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
// Mock Stripe secret
|
|
config(['services.stripe.webhook_secret' => 'whsec_test_secret']);
|
|
}
|
|
|
|
public function test_handle_payment_intent_succeeded_creates_event_package(): void
|
|
{
|
|
$tenant = \App\Models\Tenant::factory()->create();
|
|
$event = \App\Models\Event::factory()->create(['tenant_id' => $tenant->id]);
|
|
$package = Package::factory()->create(['type' => 'endcustomer']);
|
|
|
|
$payload = [
|
|
'id' => 'evt_test',
|
|
'type' => 'payment_intent.succeeded',
|
|
'data' => [
|
|
'object' => [
|
|
'id' => 'pi_test',
|
|
'metadata' => [
|
|
'type' => 'endcustomer_event',
|
|
'tenant_id' => (string) $tenant->id,
|
|
'event_id' => (string) $event->id,
|
|
'package_id' => (string) $package->id,
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$sigHeader = 't=12345,v1=' . base64_encode(hash_hmac('sha256', json_encode($payload), 'whsec_test_secret', true));
|
|
|
|
$response = $this->postJson('/api/v1/stripe/webhook', $payload, [
|
|
'Stripe-Signature' => $sigHeader,
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('package_purchases', [
|
|
'package_id' => $package->id,
|
|
'tenant_id' => $tenant->id,
|
|
'event_id' => $event->id,
|
|
'type' => 'endcustomer_event',
|
|
'provider_id' => 'pi_test',
|
|
]);
|
|
|
|
$this->assertDatabaseHas('event_packages', [
|
|
'event_id' => $event->id,
|
|
'package_id' => $package->id,
|
|
]);
|
|
}
|
|
|
|
public function test_handle_invoice_paid_renews_tenant_package(): void
|
|
{
|
|
$tenant = \App\Models\Tenant::factory()->create();
|
|
$package = Package::factory()->create(['type' => 'reseller']);
|
|
|
|
$payload = [
|
|
'id' => 'evt_test',
|
|
'type' => 'invoice.paid',
|
|
'data' => [
|
|
'object' => [
|
|
'subscription' => 'sub_test',
|
|
'metadata' => [
|
|
'type' => 'reseller_subscription',
|
|
'tenant_id' => (string) $tenant->id,
|
|
'package_id' => (string) $package->id,
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$sigHeader = 't=12345,v1=' . base64_encode(hash_hmac('sha256', json_encode($payload), 'whsec_test_secret', true));
|
|
|
|
$response = $this->postJson('/api/v1/stripe/webhook', $payload, [
|
|
'Stripe-Signature' => $sigHeader,
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('package_purchases', [
|
|
'package_id' => $package->id,
|
|
'tenant_id' => $tenant->id,
|
|
'type' => 'reseller_subscription',
|
|
]);
|
|
|
|
$tenantPackage = TenantPackage::where('tenant_id', $tenant->id)->first();
|
|
$this->assertNotNull($tenantPackage);
|
|
$this->assertTrue($tenantPackage->expires_at->isFuture());
|
|
}
|
|
|
|
public function test_webhook_rejects_invalid_signature(): void
|
|
{
|
|
$payload = ['type' => 'invalid'];
|
|
$sigHeader = 'invalid';
|
|
|
|
$response = $this->postJson('/api/v1/stripe/webhook', $payload, [
|
|
'Stripe-Signature' => $sigHeader,
|
|
]);
|
|
|
|
$response->assertStatus(400);
|
|
}
|
|
} |