libra/tests/Feature/Mail/BookingApprovedMailTest.php

318 lines
13 KiB
PHP

<?php
use App\Enums\ConsultationStatus;
use App\Enums\ConsultationType;
use App\Enums\PaymentStatus;
use App\Mail\BookingApprovedMail;
use App\Models\Consultation;
use App\Models\User;
use App\Services\CalendarService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;
test('queues email when consultation is approved', function () {
Mail::fake();
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->pending()->create(['user_id' => $user->id]);
$consultation->update(['status' => ConsultationStatus::Approved]);
Mail::assertQueued(BookingApprovedMail::class, function ($mail) use ($consultation) {
return $mail->consultation->id === $consultation->id;
});
});
test('does not send email when status changes to non-approved', function () {
Mail::fake();
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->pending()->create(['user_id' => $user->id]);
$consultation->update(['status' => ConsultationStatus::Rejected]);
Mail::assertNotQueued(BookingApprovedMail::class);
});
test('does not send email when consultation is created as approved', function () {
Mail::fake();
$user = User::factory()->create(['preferred_language' => 'ar']);
Consultation::factory()->approved()->create(['user_id' => $user->id]);
Mail::assertNotQueued(BookingApprovedMail::class);
});
test('does not send email when other fields change on approved consultation', function () {
Mail::fake();
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$consultation->update(['problem_summary' => 'Updated summary']);
Mail::assertNotQueued(BookingApprovedMail::class);
});
test('includes ics attachment', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$attachments = $mailable->attachments();
expect($attachments)->toHaveCount(1);
expect($attachments[0]->as)->toBe('consultation.ics');
});
test('uses Arabic template for Arabic-preferring users', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->content()->markdown)->toBe('emails.booking.approved.ar');
});
test('uses English template for English-preferring users', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->content()->markdown)->toBe('emails.booking.approved.en');
});
test('includes payment instructions for paid consultations', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create([
'user_id' => $user->id,
'consultation_type' => ConsultationType::Paid,
'payment_amount' => 150.00,
'payment_status' => PaymentStatus::Pending,
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$paymentInstructions = 'Please pay 150 ILS before your consultation.';
$mailable = new BookingApprovedMail($consultation, $icsContent, $paymentInstructions);
expect($mailable->paymentInstructions)->toBe($paymentInstructions);
});
test('excludes payment instructions for free consultations', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->free()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->paymentInstructions)->toBeNull();
});
test('has correct Arabic subject', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->envelope()->subject)->toBe('تمت الموافقة على استشارتك');
});
test('has correct English subject', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->envelope()->subject)->toBe('Your Consultation Has Been Approved');
});
test('date is formatted as d/m/Y for Arabic users', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create([
'user_id' => $user->id,
'booking_date' => '2025-03-15',
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
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()->approved()->create([
'user_id' => $user->id,
'booking_date' => '2025-03-15',
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
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()->approved()->create([
'user_id' => $user->id,
'booking_time' => '14:30:00',
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->getFormattedTime())->toBe('02:30 PM');
});
test('consultation type label is correct in Arabic', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$freeConsultation = Consultation::factory()->approved()->free()->create(['user_id' => $user->id]);
$paidConsultation = Consultation::factory()->approved()->paid()->create(['user_id' => $user->id]);
$freeIcs = app(CalendarService::class)->generateIcs($freeConsultation);
$paidIcs = app(CalendarService::class)->generateIcs($paidConsultation);
$freeMailable = new BookingApprovedMail($freeConsultation, $freeIcs);
$paidMailable = new BookingApprovedMail($paidConsultation, $paidIcs);
expect($freeMailable->getConsultationTypeLabel('ar'))->toBe('مجانية');
expect($paidMailable->getConsultationTypeLabel('ar'))->toBe('مدفوعة');
});
test('consultation type label is correct in English', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$freeConsultation = Consultation::factory()->approved()->free()->create(['user_id' => $user->id]);
$paidConsultation = Consultation::factory()->approved()->paid()->create(['user_id' => $user->id]);
$freeIcs = app(CalendarService::class)->generateIcs($freeConsultation);
$paidIcs = app(CalendarService::class)->generateIcs($paidConsultation);
$freeMailable = new BookingApprovedMail($freeConsultation, $freeIcs);
$paidMailable = new BookingApprovedMail($paidConsultation, $paidIcs);
expect($freeMailable->getConsultationTypeLabel('en'))->toBe('Free');
expect($paidMailable->getConsultationTypeLabel('en'))->toBe('Paid');
});
test('booking approved email implements ShouldQueue', function () {
expect(BookingApprovedMail::class)->toImplement(ShouldQueue::class);
});
test('content includes all required data', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create([
'user_id' => $user->id,
'booking_date' => '2025-03-15',
'booking_time' => '10:00:00',
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$content = $mailable->content();
expect($content->with)
->toHaveKey('consultation')
->toHaveKey('user')
->toHaveKey('paymentInstructions')
->toHaveKey('formattedDate')
->toHaveKey('formattedTime')
->toHaveKey('duration')
->toHaveKey('consultationType')
->toHaveKey('isPaid')
->toHaveKey('paymentAmount');
});
test('email has correct recipient when queued via observer', function () {
Mail::fake();
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->pending()->create(['user_id' => $user->id]);
$consultation->update(['status' => ConsultationStatus::Approved]);
Mail::assertQueued(BookingApprovedMail::class, function ($mail) use ($user) {
return $mail->hasTo($user->email);
});
});
test('email renders without errors in Arabic', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$rendered = $mailable->render();
expect($rendered)->toContain('تمت الموافقة على استشارتك');
});
test('email renders without errors in English', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$rendered = $mailable->render();
expect($rendered)->toContain('Your Consultation Has Been Approved');
});
test('paid consultation email includes payment amount', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create([
'user_id' => $user->id,
'consultation_type' => ConsultationType::Paid,
'payment_amount' => 250.00,
'payment_status' => PaymentStatus::Pending,
]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$paymentInstructions = 'Please pay before your appointment.';
$mailable = new BookingApprovedMail($consultation, $icsContent, $paymentInstructions);
$rendered = $mailable->render();
expect($rendered)->toContain('250.00');
});
test('free consultation email does not include payment section', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->free()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$rendered = $mailable->render();
expect($rendered)->not->toContain('Payment Information');
});
test('defaults to Arabic when preferred_language is ar', function () {
$user = User::factory()->create(['preferred_language' => 'ar']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
expect($mailable->envelope()->subject)->toBe('تمت الموافقة على استشارتك');
expect($mailable->content()->markdown)->toBe('emails.booking.approved.ar');
});
test('duration defaults to 45 minutes', function () {
$user = User::factory()->create(['preferred_language' => 'en']);
$consultation = Consultation::factory()->approved()->create(['user_id' => $user->id]);
$icsContent = app(CalendarService::class)->generateIcs($consultation);
$mailable = new BookingApprovedMail($consultation, $icsContent);
$content = $mailable->content();
expect($content->with['duration'])->toBe(45);
});