From 08d3278c9e09ddddb17e435382dc8c21db54fe1c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 23 Mar 2026 21:37:08 +0000 Subject: [PATCH] Add artisan command to resend lead notifications from a given date Co-Authored-By: Claude Opus 4.6 --- .../Commands/ResendLeadNotifications.php | 43 +++++++++++++ tests/Feature/ResendLeadNotificationsTest.php | 60 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 app/Console/Commands/ResendLeadNotifications.php create mode 100644 tests/Feature/ResendLeadNotificationsTest.php diff --git a/app/Console/Commands/ResendLeadNotifications.php b/app/Console/Commands/ResendLeadNotifications.php new file mode 100644 index 00000000..2af6e5c3 --- /dev/null +++ b/app/Console/Commands/ResendLeadNotifications.php @@ -0,0 +1,43 @@ +argument('date'))->startOfDay(); + + $leads = Lead::query() + ->where('created_at', '>=', $date) + ->orderBy('created_at') + ->get(); + + if ($leads->isEmpty()) { + $this->info('No leads found from '.$date->toDateString().' onwards.'); + + return; + } + + $this->info("Found {$leads->count()} lead(s) from {$date->toDateString()} onwards."); + + foreach ($leads as $lead) { + Notification::route('mail', 'sales@nativephp.com') + ->notify(new NewLeadSubmitted($lead)); + + $this->line("Sent notification for lead: {$lead->company} ({$lead->email})"); + } + + $this->info('Done.'); + } +} diff --git a/tests/Feature/ResendLeadNotificationsTest.php b/tests/Feature/ResendLeadNotificationsTest.php new file mode 100644 index 00000000..934d6fde --- /dev/null +++ b/tests/Feature/ResendLeadNotificationsTest.php @@ -0,0 +1,60 @@ +create(['created_at' => '2025-01-01 12:00:00']); + $matchingLead = Lead::factory()->create(['created_at' => '2025-03-15 09:00:00']); + $newerLead = Lead::factory()->create(['created_at' => '2025-03-16 14:00:00']); + + $this->artisan('app:resend-lead-notifications', ['date' => '2025-03-15']) + ->expectsOutputToContain('Found 2 lead(s)') + ->expectsOutputToContain('Done.') + ->assertExitCode(0); + + Notification::assertSentOnDemand( + NewLeadSubmitted::class, + function ($notification, $channels, $notifiable) use ($matchingLead) { + return $notifiable->routes['mail'] === 'sales@nativephp.com' + && $notification->lead->is($matchingLead); + } + ); + + Notification::assertSentOnDemand( + NewLeadSubmitted::class, + function ($notification, $channels, $notifiable) use ($newerLead) { + return $notifiable->routes['mail'] === 'sales@nativephp.com' + && $notification->lead->is($newerLead); + } + ); + + Notification::assertNotSentTo($oldLead, NewLeadSubmitted::class); + } + + #[Test] + public function it_shows_message_when_no_leads_are_found(): void + { + Notification::fake(); + + $this->artisan('app:resend-lead-notifications', ['date' => '2099-01-01']) + ->expectsOutputToContain('No leads found') + ->assertExitCode(0); + + Notification::assertNothingSent(); + } +}