create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); expect($mailable->content()->markdown)->toBe('emails.booking.rejected.ar'); }); test('booking rejected email uses english template for english preference', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); expect($mailable->content()->markdown)->toBe('emails.booking.rejected.en'); }); test('booking rejected email defaults to arabic from database default', function () { // The database schema has default('ar') for preferred_language // This test verifies the mailable respects that default $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); expect($mailable->content()->markdown)->toBe('emails.booking.rejected.ar'); expect($mailable->envelope()->subject)->toBe('تعذر الموافقة على طلب الاستشارة'); }); test('booking rejected email has correct arabic subject', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); expect($mailable->envelope()->subject)->toBe('تعذر الموافقة على طلب الاستشارة'); }); test('booking rejected email has correct english subject', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); expect($mailable->envelope()->subject)->toBe('Your Consultation Request Could Not Be Approved'); }); test('booking rejected email includes reason when provided', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $reason = 'Schedule conflict with another appointment'; $mailable = new BookingRejectedEmail($consultation, $reason); $content = $mailable->content(); expect($content->with['reason'])->toBe($reason); expect($content->with['hasReason'])->toBeTrue(); }); test('booking rejected email handles null reason', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation, null); $content = $mailable->content(); expect($content->with['reason'])->toBeNull(); expect($content->with['hasReason'])->toBeFalse(); }); test('booking rejected email handles empty reason', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation, ''); $content = $mailable->content(); expect($content->with['hasReason'])->toBeFalse(); }); test('date is formatted as d/m/Y for arabic users', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create([ 'booking_date' => '2025-03-15', ]); $mailable = new BookingRejectedEmail($consultation); expect($mailable->getFormattedDate('ar'))->toBe('15/03/2025'); }); test('date is formatted as m/d/Y for english users', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create([ 'booking_date' => '2025-03-15', ]); $mailable = new BookingRejectedEmail($consultation); expect($mailable->getFormattedDate('en'))->toBe('03/15/2025'); }); test('time is formatted as h:i A', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create([ 'booking_time' => '14:30:00', ]); $mailable = new BookingRejectedEmail($consultation); expect($mailable->getFormattedTime())->toBe('02:30 PM'); }); test('booking rejected email implements ShouldQueue', function () { expect(BookingRejectedEmail::class)->toImplement(ShouldQueue::class); }); test('content includes all required data', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create([ 'booking_date' => '2025-03-15', 'booking_time' => '10:00:00', ]); $reason = 'Test reason'; $mailable = new BookingRejectedEmail($consultation, $reason); $content = $mailable->content(); expect($content->with) ->toHaveKey('consultation') ->toHaveKey('user') ->toHaveKey('reason') ->toHaveKey('hasReason') ->toHaveKey('formattedDate') ->toHaveKey('formattedTime'); }); test('email renders without errors in arabic', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); $rendered = $mailable->render(); expect($rendered)->toContain('تعذر الموافقة على طلب الاستشارة'); }); test('email renders without errors in english', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); $rendered = $mailable->render(); expect($rendered)->toContain('Your Consultation Request Could Not Be Approved'); }); test('email renders reason section when reason provided', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $reason = 'The requested time slot is not available'; $mailable = new BookingRejectedEmail($consultation, $reason); $rendered = $mailable->render(); expect($rendered)->toContain($reason); expect($rendered)->toContain('Reason'); }); test('email does not render reason section when reason not provided', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); $rendered = $mailable->render(); expect($rendered)->not->toContain('Reason:'); }); test('arabic email does not render reason section when reason not provided', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $consultation = Consultation::factory()->for($user)->create(); $mailable = new BookingRejectedEmail($consultation); $rendered = $mailable->render(); expect($rendered)->not->toContain('سبب الرفض'); }); test('notification sends booking rejected email', function () { Notification::fake(); $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $reason = 'Test reason'; $user->notify(new BookingRejected($consultation, $reason)); Notification::assertSentTo($user, BookingRejected::class, function ($notification) use ($consultation, $reason) { return $notification->consultation->id === $consultation->id && $notification->rejectionReason === $reason; }); }); test('notification sends email to correct recipient', function () { Notification::fake(); $user = User::factory()->create(['email' => 'client@example.com']); $consultation = Consultation::factory()->for($user)->create(); $user->notify(new BookingRejected($consultation)); Notification::assertSentTo($user, BookingRejected::class); }); test('notification passes rejection reason to mailable', function () { Notification::fake(); $user = User::factory()->create(); $consultation = Consultation::factory()->for($user)->create(); $reason = 'Schedule conflict'; $user->notify(new BookingRejected($consultation, $reason)); Notification::assertSentTo($user, BookingRejected::class, function ($notification) use ($reason) { return $notification->rejectionReason === $reason; }); }); test('notification toMail returns BookingRejectedEmail mailable', function () { $user = User::factory()->create(['preferred_language' => 'en']); $consultation = Consultation::factory()->for($user)->create(); $reason = 'Test reason'; $notification = new BookingRejected($consultation, $reason); $mailable = $notification->toMail($user); expect($mailable)->toBeInstanceOf(BookingRejectedEmail::class); expect($mailable->consultation->id)->toBe($consultation->id); expect($mailable->reason)->toBe($reason); });