fix(queue): discard email jobs for deleted purchases

This commit is contained in:
ncoronel 2026-08-26 09:15:11 -03:00
parent 8220fb5aaf
commit 28d09dedab
3 changed files with 68 additions and 0 deletions

View File

@ -5,8 +5,10 @@ namespace App\Domains\Notification\Listeners;
use App\Domains\Notification\Services\NotificationMailService;
use App\Domains\Purchase\Events\PurchasePaid;
use Illuminate\Contracts\Queue\ShouldQueueAfterCommit;
use Illuminate\Queue\Attributes\DeleteWhenMissingModels;
use Illuminate\Queue\InteractsWithQueue;
#[DeleteWhenMissingModels]
class SendPurchasePaidEmail implements ShouldQueueAfterCommit
{
use InteractsWithQueue;

View File

@ -5,8 +5,10 @@ namespace App\Domains\Notification\Listeners;
use App\Domains\Notification\Events\TicketsAvailable;
use App\Domains\Notification\Services\NotificationMailService;
use Illuminate\Contracts\Queue\ShouldQueueAfterCommit;
use Illuminate\Queue\Attributes\DeleteWhenMissingModels;
use Illuminate\Queue\InteractsWithQueue;
#[DeleteWhenMissingModels]
class SendTicketsAvailableEmail implements ShouldQueueAfterCommit
{
use InteractsWithQueue;

View File

@ -0,0 +1,64 @@
<?php
namespace Tests\Feature\Notification;
use App\Domains\Notification\Events\TicketsAvailable;
use App\Domains\Notification\Listeners\SendPurchasePaidEmail;
use App\Domains\Notification\Listeners\SendTicketsAvailableEmail;
use App\Domains\Purchase\Events\PurchasePaid;
use App\Domains\Purchase\Models\Purchase;
use Illuminate\Events\CallQueuedListener;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
class QueuedNotificationListenerTest extends TestCase
{
public function test_purchase_paid_email_is_discarded_when_the_purchase_no_longer_exists(): void
{
$job = $this->dispatchQueuedListener(
PurchasePaid::class,
SendPurchasePaidEmail::class,
new PurchasePaid($this->purchase()),
);
$this->assertTrue($job->deleteWhenMissingModels);
}
public function test_tickets_available_email_is_discarded_when_the_purchase_no_longer_exists(): void
{
$job = $this->dispatchQueuedListener(
TicketsAvailable::class,
SendTicketsAvailableEmail::class,
new TicketsAvailable($this->purchase(), [10, 11]),
);
$this->assertTrue($job->deleteWhenMissingModels);
}
private function dispatchQueuedListener(string $event, string $listener, object $payload): CallQueuedListener
{
Queue::fake();
Event::forget($event);
Event::listen($event, $listener);
event($payload);
$queuedListener = null;
Queue::assertPushed(CallQueuedListener::class, function (CallQueuedListener $job) use (&$queuedListener): bool {
$queuedListener = $job;
return true;
});
$this->assertInstanceOf(CallQueuedListener::class, $queuedListener);
return $queuedListener;
}
private function purchase(): Purchase
{
return (new Purchase)->forceFill(['id' => 123]);
}
}