71 lines
2.0 KiB
PHP
71 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Jobs\ProcessRevenueCatWebhook;
|
|
use App\Models\IntegrationWebhookEvent;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use Tests\TestCase;
|
|
|
|
class RevenueCatWebhookTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_webhook_dispatches_job_with_valid_signature(): void
|
|
{
|
|
config()->set('services.revenuecat.webhook', 'shared-secret');
|
|
|
|
$payload = [
|
|
'event' => [
|
|
'type' => 'INITIAL_PURCHASE',
|
|
'app_user_id' => 'tenant-123',
|
|
'product_id' => 'pro_month',
|
|
],
|
|
];
|
|
|
|
$json = json_encode($payload);
|
|
$signature = base64_encode(hash_hmac('sha1', $json, 'shared-secret', true));
|
|
|
|
Bus::fake();
|
|
|
|
$response = $this->postJson('/api/v1/webhooks/revenuecat', $payload, [
|
|
'X-Event-Id' => 'evt_123',
|
|
'X-Signature' => $signature,
|
|
]);
|
|
|
|
$response->assertStatus(202)
|
|
->assertJson(['status' => 'accepted']);
|
|
|
|
$this->assertDatabaseHas('integration_webhook_events', [
|
|
'provider' => 'revenuecat',
|
|
'event_id' => 'evt_123',
|
|
'event_type' => 'INITIAL_PURCHASE',
|
|
'status' => IntegrationWebhookEvent::STATUS_RECEIVED,
|
|
]);
|
|
|
|
Bus::assertDispatched(ProcessRevenueCatWebhook::class);
|
|
}
|
|
|
|
public function test_webhook_rejects_invalid_signature(): void
|
|
{
|
|
config()->set('services.revenuecat.webhook', 'shared-secret');
|
|
|
|
Bus::fake();
|
|
|
|
$response = $this->postJson('/api/v1/webhooks/revenuecat', [
|
|
'event' => ['app_user_id' => 'tenant-123'],
|
|
], [
|
|
'X-Signature' => 'invalid-signature',
|
|
]);
|
|
|
|
$response->assertStatus(400)
|
|
->assertJsonPath('error.code', 'signature_invalid')
|
|
->assertJsonPath('error.title', 'Invalid Signature');
|
|
|
|
$this->assertDatabaseCount('integration_webhook_events', 0);
|
|
|
|
Bus::assertNotDispatched(ProcessRevenueCatWebhook::class);
|
|
}
|
|
}
|