approved()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), 'reminder_24h_sent_at' => null, ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertSentTo( $consultation->user, ConsultationReminder24h::class ); expect($consultation->fresh()->reminder_24h_sent_at)->not->toBeNull(); }); it('does not send 24h reminder for cancelled consultation', function () { Notification::fake(); $consultation = Consultation::factory()->cancelled()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder24h::class); }); it('does not send 24h reminder for no-show consultation', function () { Notification::fake(); $consultation = Consultation::factory()->noShow()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder24h::class); }); it('does not send duplicate 24h reminders', function () { Notification::fake(); $consultation = Consultation::factory()->approved()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), 'reminder_24h_sent_at' => now()->subHour(), ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder24h::class); }); it('sends 2h reminder for upcoming consultation', function () { Notification::fake(); $consultation = Consultation::factory()->approved()->create([ 'booking_date' => now()->addHours(2)->toDateString(), 'booking_time' => now()->addHours(2)->format('H:i:s'), 'reminder_2h_sent_at' => null, ]); $this->artisan('reminders:send-2h') ->assertSuccessful(); Notification::assertSentTo( $consultation->user, ConsultationReminder2h::class ); expect($consultation->fresh()->reminder_2h_sent_at)->not->toBeNull(); }); it('does not send 2h reminder for cancelled consultation', function () { Notification::fake(); $consultation = Consultation::factory()->cancelled()->create([ 'booking_date' => now()->addHours(2)->toDateString(), 'booking_time' => now()->addHours(2)->format('H:i:s'), ]); $this->artisan('reminders:send-2h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder2h::class); }); it('does not send duplicate 2h reminders', function () { Notification::fake(); $consultation = Consultation::factory()->approved()->create([ 'booking_date' => now()->addHours(2)->toDateString(), 'booking_time' => now()->addHours(2)->format('H:i:s'), 'reminder_2h_sent_at' => now()->subMinutes(30), ]); $this->artisan('reminders:send-2h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder2h::class); }); it('includes payment reminder for unpaid consultations in 24h reminder', function () { Notification::fake(); $consultation = Consultation::factory()->approved()->paid()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), 'payment_status' => 'pending', 'payment_amount' => 200.00, ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertSentTo( $consultation->user, ConsultationReminder24h::class, function ($notification) { return $notification->consultation->consultation_type->value === 'paid' && $notification->consultation->payment_status->value === 'pending'; } ); }); it('respects user language preference for 24h reminders', function () { Notification::fake(); $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->approved()->create([ 'user_id' => $user->id, 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertSentTo($user, ConsultationReminder24h::class); }); it('does not send 24h reminder for pending consultation', function () { Notification::fake(); $consultation = Consultation::factory()->pending()->create([ 'booking_date' => now()->addHours(24)->toDateString(), 'booking_time' => now()->addHours(24)->format('H:i:s'), ]); $this->artisan('reminders:send-24h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder24h::class); }); it('does not send 2h reminder for rejected consultation', function () { Notification::fake(); $consultation = Consultation::factory()->rejected()->create([ 'booking_date' => now()->addHours(2)->toDateString(), 'booking_time' => now()->addHours(2)->format('H:i:s'), ]); $this->artisan('reminders:send-2h') ->assertSuccessful(); Notification::assertNotSentTo($consultation->user, ConsultationReminder2h::class); });