318 lines
13 KiB
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);
|
|
});
|