libra/tests/Feature/Admin/GuestBookingManagementTest.php

263 lines
8.6 KiB
PHP

<?php
use App\Enums\ConsultationStatus;
use App\Mail\GuestBookingApprovedMail;
use App\Mail\GuestBookingRejectedMail;
use App\Models\Consultation;
use App\Models\User;
use App\Notifications\BookingApproved;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Livewire\Volt\Volt;
test('admin can see guest bookings in pending list', function () {
$admin = User::factory()->admin()->create();
$guestConsultation = Consultation::factory()->guest()->pending()->create([
'guest_name' => 'Test Guest User',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.pending')
->assertSee('Test Guest User')
->assertSee(__('admin.guest'));
});
test('admin can view guest booking details in review page', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create([
'guest_name' => 'Test Guest',
'guest_email' => 'testguest@example.com',
'guest_phone' => '+1234567890',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertSee('Test Guest')
->assertSee('testguest@example.com')
->assertSee('+1234567890')
->assertSee(__('admin.guest'));
});
test('admin can approve guest booking via modal', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->set('consultationType', 'free')
->call('approve')
->assertHasNoErrors();
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Approved);
Mail::assertQueued(GuestBookingApprovedMail::class);
});
test('admin can reject guest booking via modal', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->set('rejectionReason', 'Not available for this time')
->call('reject')
->assertHasNoErrors();
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Rejected);
Mail::assertQueued(GuestBookingRejectedMail::class);
});
test('admin can quick approve guest booking from pending list', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.pending')
->call('quickApprove', $consultation->id)
->assertHasNoErrors();
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Approved);
Mail::assertQueued(GuestBookingApprovedMail::class);
});
test('admin can quick reject guest booking from pending list', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.pending')
->call('quickReject', $consultation->id)
->assertHasNoErrors();
expect($consultation->fresh()->status)->toBe(ConsultationStatus::Rejected);
Mail::assertQueued(GuestBookingRejectedMail::class);
});
test('guest booking review shows no consultation history', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
$component = Volt::test('admin.bookings.review', ['consultation' => $consultation]);
// Guest bookings should return empty consultation history
expect($component->viewData('consultationHistory'))->toBeEmpty();
});
test('client booking still uses notification system', function () {
Notification::fake();
$admin = User::factory()->admin()->create();
$client = User::factory()->individual()->create();
$consultation = Consultation::factory()->pending()->create(['user_id' => $client->id]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->set('consultationType', 'free')
->call('approve');
Notification::assertSentTo($client, BookingApproved::class);
});
test('pending list shows guest email with mailto link', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create([
'guest_email' => 'guest@example.com',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.pending')
->assertSeeHtml('href="mailto:guest@example.com"');
});
test('review page shows guest email with mailto link', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create([
'guest_email' => 'guest@example.com',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertSeeHtml('href="mailto:guest@example.com"');
});
test('review page shows guest phone with tel link', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create([
'guest_phone' => '+1234567890',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertSeeHtml('href="tel:+1234567890"');
});
test('review page hides client type field for guest bookings', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
// Guest bookings should not show client type row
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertDontSee(__('admin.client_type'));
});
test('review page shows client type field for client bookings', function () {
$admin = User::factory()->admin()->create();
$client = User::factory()->individual()->create();
$consultation = Consultation::factory()->pending()->create(['user_id' => $client->id]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertSee(__('admin.client_type'));
});
test('approve modal shows guest name in summary', function () {
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create([
'guest_name' => 'Guest Modal Test',
]);
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->assertSee('Guest Modal Test');
});
test('guest booking approval with payment instructions sends correct email', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->set('consultationType', 'paid')
->set('paymentAmount', '200.00')
->set('paymentInstructions', 'Bank transfer instructions')
->call('approve')
->assertHasNoErrors();
Mail::assertQueued(GuestBookingApprovedMail::class, function ($mail) {
return $mail->paymentInstructions === 'Bank transfer instructions';
});
});
test('guest booking rejection with reason sends correct email', function () {
Mail::fake();
$admin = User::factory()->admin()->create();
$consultation = Consultation::factory()->guest()->pending()->create();
$this->actingAs($admin);
Volt::test('admin.bookings.review', ['consultation' => $consultation])
->set('rejectionReason', 'Time slot unavailable')
->call('reject')
->assertHasNoErrors();
Mail::assertQueued(GuestBookingRejectedMail::class, function ($mail) {
return $mail->reason === 'Time slot unavailable';
});
});
test('mixed guest and client bookings appear in pending list', function () {
$admin = User::factory()->admin()->create();
$client = User::factory()->individual()->create(['full_name' => 'Regular Client']);
$guestConsultation = Consultation::factory()->guest()->pending()->create([
'guest_name' => 'Guest Person',
]);
$clientConsultation = Consultation::factory()->pending()->create([
'user_id' => $client->id,
]);
$this->actingAs($admin);
Volt::test('admin.bookings.pending')
->assertSee('Guest Person')
->assertSee('Regular Client')
->assertSee(__('admin.guest'));
});