postJson('/api/webhooks/incoming_email', [ 'hash' => 'dummy-hash', ]); $response->assertStatus(401) ->assertJson(['error' => 'Unauthorized']); }); it('rejects webhooks with an invalid secret token', function () { $response = $this->postJson('/api/webhooks/incoming_email', [ 'hash' => 'dummy-hash', ], [ 'Authorization' => 'Bearer wrong-secret', ]); $response->assertStatus(401); }); it('accepts valid webhooks and dispatches the processing job', function () { Queue::fake(); $payload = [ 'hash' => 'test-unique-hash-12345', 'metadata' => [ 'recipientEmail' => 'test@imail.app', 'recipientName' => 'Test User', 'senderEmail' => 'sender@example.com', 'senderName' => 'Sender Name', 'domain' => 'imail.app', 'subject' => 'Test Subject', 'received_at' => now()->toIso8601String(), 'attachmentSize' => 0, 'attachments' => [], ], 'bodyText' => 'This is a test email body.', 'bodyHtml' => '
This is a test email body.
', ]; $response = $this->postJson('/api/webhooks/incoming_email', $payload, [ 'Authorization' => 'Bearer test-secret', ]); $response->assertStatus(200) ->assertJson(['status' => 'queued']); Queue::assertPushed(ProcessIncomingEmail::class, function ($job) use ($payload) { return $job->payload['hash'] === $payload['hash']; }); }); it('validates required payload fields', function () { Queue::fake(); $response = $this->postJson('/api/webhooks/incoming_email', [ // Missing hash and other required fields 'metadata' => [ 'recipientEmail' => 'test@imail.app', ], ], [ 'Authorization' => 'Bearer test-secret', ]); $response->assertStatus(422) ->assertJsonValidationErrors(['hash', 'metadata.senderEmail', 'metadata.domain', 'metadata.received_at']); Queue::assertNothingPushed(); });