File: /home/xedaptot/ai.naniguide.com/tests/Feature/SendingServerWebhookHttpTest.php
<?php
use App\Model\BounceLog;
use App\Model\Contact;
use App\Model\Customer;
use App\Model\MailList;
use App\Model\SendingServer;
use App\Model\Subscriber;
use App\Model\TrackingLog;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
uses(TestCase::class, DatabaseTransactions::class);
/**
* HTTP-level test for the webhook receive endpoint:
* POST /webhook/{driverType}/{serverUid}
*
* Verifies the full chain:
* 1. Route resolves to SendingServerWebhookController::handle.
* 2. Server uid lookup + cross-tenant guard (type mismatch → 404).
* 3. Driver instanceof ReceivesWebhooks check.
* 4. driver->verifyWebhook + driver->parseWebhook dispatched correctly.
* 5. Each parsed event fires on the Laravel event bus.
*/
function makeSendGridSrvForHttp(): SendingServer
{
$contact = Contact::factory()->create();
$customer = Customer::factory()->create([
'contact_id' => $contact->id,
'uid' => 'whcust' . uniqid(),
]);
$server = SendingServer::factory()->create([
'type' => 'sendgrid-api',
'customer_id' => $customer->id,
]);
return $server;
}
test('POST /webhook/{type}/{uid} returns 200 + dispatches BounceReceived event', function () {
Event::fake([\App\SendingServers\Webhooks\BounceReceived::class]);
$server = makeSendGridSrvForHttp();
$payload = [
['event' => 'bounce', 'runtime_message_id' => '[email protected]'],
];
$response = $this->postJson("/webhook/sendgrid-api/{$server->uid}", $payload);
$response->assertOk()->assertJson(['ok' => true]);
Event::assertDispatched(\App\SendingServers\Webhooks\BounceReceived::class);
});
test('POST /webhook/wrong-type/{uid} returns 404 (cross-tenant guard)', function () {
$server = makeSendGridSrvForHttp();
$response = $this->postJson("/webhook/mailgun-api/{$server->uid}", []);
$response->assertNotFound();
});
test('POST /webhook/{type}/nonexistent-uid returns 404', function () {
$response = $this->postJson('/webhook/sendgrid-api/srv-does-not-exist', []);
$response->assertNotFound();
});
test('POST /webhook for driver without ReceivesWebhooks (Smtp variant) returns 404', function () {
// SMTP driver does NOT implement ReceivesWebhooks — webhook URL is only
// valid for Api variants. Posting to Smtp uid → 404.
$contact = Contact::factory()->create();
$customer = Customer::factory()->create([
'contact_id' => $contact->id,
'uid' => 'whsmtp' . uniqid(),
]);
$smtpServer = SendingServer::factory()->create([
'type' => 'smtp',
'customer_id' => $customer->id,
]);
$response = $this->postJson("/webhook/smtp/{$smtpServer->uid}", ['payload' => 'whatever']);
$response->assertNotFound();
});
test('POST /webhook with multiple events fires each one (multi-event payload)', function () {
Event::fake([
\App\SendingServers\Webhooks\BounceReceived::class,
\App\SendingServers\Webhooks\ComplaintReceived::class,
\App\SendingServers\Webhooks\IgnorableWebhookEvent::class,
]);
$server = makeSendGridSrvForHttp();
$payload = [
['event' => 'bounce', 'runtime_message_id' => '[email protected]'],
['event' => 'spamreport', 'runtime_message_id' => '[email protected]'],
['event' => 'open', 'runtime_message_id' => '[email protected]'], // ignorable
];
$this->postJson("/webhook/sendgrid-api/{$server->uid}", $payload)->assertOk();
Event::assertDispatched(\App\SendingServers\Webhooks\BounceReceived::class, 1);
Event::assertDispatched(\App\SendingServers\Webhooks\ComplaintReceived::class, 1);
Event::assertDispatched(\App\SendingServers\Webhooks\IgnorableWebhookEvent::class, 1);
});