Files
fotospiel-app/tests/Feature/StripeWebhookTest.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);
}
}