admin = User::factory()->admin()->create();
});
// ===========================================
// Access Tests
// ===========================================
test('admin can access consultation export page', function () {
$this->actingAs($this->admin)
->get(route('admin.consultations.export'))
->assertOk();
});
test('non-admin cannot access consultation export page', function () {
$client = User::factory()->individual()->create();
$this->actingAs($client)
->get(route('admin.consultations.export'))
->assertForbidden();
});
test('unauthenticated user cannot access consultation export page', function () {
$this->get(route('admin.consultations.export'))
->assertRedirect(route('login'));
});
// ===========================================
// CSV Export Tests
// ===========================================
test('admin can export all consultations as CSV', function () {
Consultation::factory()->count(5)->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'all')
->call('exportCsv')
->assertFileDownloaded('consultations-export-'.now()->format('Y-m-d').'.csv');
});
test('admin can export consultations filtered by free type', function () {
Consultation::factory()->count(3)->free()->create();
Consultation::factory()->count(2)->paid()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'free')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by paid type', function () {
Consultation::factory()->count(3)->free()->create();
Consultation::factory()->count(2)->paid()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by pending status', function () {
Consultation::factory()->count(3)->pending()->create();
Consultation::factory()->count(2)->completed()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('status', 'pending')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by completed status', function () {
Consultation::factory()->count(3)->pending()->create();
Consultation::factory()->count(2)->completed()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('status', 'completed')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by approved status', function () {
Consultation::factory()->count(3)->approved()->create();
Consultation::factory()->count(2)->pending()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('status', 'approved')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by cancelled status', function () {
Consultation::factory()->count(2)->cancelled()->create();
Consultation::factory()->count(3)->completed()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('status', 'cancelled')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by no-show status', function () {
Consultation::factory()->count(2)->noShow()->create();
Consultation::factory()->count(3)->completed()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('status', 'no_show')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by payment status pending', function () {
Consultation::factory()->count(3)->paid()->create(['payment_status' => 'pending']);
Consultation::factory()->count(2)->paid()->create(['payment_status' => 'received']);
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('paymentStatus', 'pending')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by payment status received', function () {
Consultation::factory()->count(3)->paid()->create(['payment_status' => 'pending']);
Consultation::factory()->count(2)->paid()->create(['payment_status' => 'received']);
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('paymentStatus', 'received')
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export consultations filtered by date range', function () {
Consultation::factory()->create(['booking_date' => now()->subDays(10)]);
Consultation::factory()->create(['booking_date' => now()->subDays(5)]);
Consultation::factory()->create(['booking_date' => now()]);
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('dateFrom', now()->subDays(7)->format('Y-m-d'))
->set('dateTo', now()->format('Y-m-d'))
->call('exportCsv')
->assertFileDownloaded();
});
test('admin can export with combined filters', function () {
Consultation::factory()->paid()->pending()->create(['booking_date' => now()->subDays(5)]);
Consultation::factory()->free()->completed()->create(['booking_date' => now()->subDays(5)]);
Consultation::factory()->paid()->completed()->create(['booking_date' => now()->subDays(5)]);
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->set('status', 'pending')
->set('dateFrom', now()->subDays(7)->format('Y-m-d'))
->set('dateTo', now()->format('Y-m-d'))
->call('exportCsv')
->assertFileDownloaded();
});
// ===========================================
// PDF Export Tests
// ===========================================
test('admin can export consultations as PDF', function () {
Consultation::factory()->count(5)->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->call('exportPdf')
->assertFileDownloaded('consultations-export-'.now()->format('Y-m-d').'.pdf');
});
test('admin can export PDF with filters', function () {
Consultation::factory()->count(3)->free()->create();
Consultation::factory()->count(2)->paid()->create();
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'free')
->call('exportPdf')
->assertFileDownloaded();
});
// ===========================================
// Empty Dataset Tests
// ===========================================
test('CSV export dispatches notification when no consultations match filters', function () {
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->set('status', 'completed')
->call('exportCsv')
->assertDispatched('notify');
});
test('PDF export dispatches notification when no consultations match filters', function () {
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->set('status', 'completed')
->call('exportPdf')
->assertDispatched('notify');
});
test('preview count shows zero when no consultations match filters', function () {
$this->actingAs($this->admin);
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->set('status', 'completed')
->assertSee('0');
});
// ===========================================
// Filter Tests
// ===========================================
test('preview count updates when filters change', function () {
Consultation::factory()->count(3)->free()->create();
Consultation::factory()->count(2)->paid()->create();
$this->actingAs($this->admin);
// All consultations - should show 5
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'all')
->assertSeeHtml('5');
// Filter to free only - should show 3
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'free')
->assertSeeHtml('3');
// Filter to paid only - should show 2
Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->assertSeeHtml('2');
});
test('clear filters resets all filter values', function () {
$this->actingAs($this->admin);
$component = Volt::test('admin.consultations.export-consultations')
->set('consultationType', 'paid')
->set('status', 'completed')
->set('paymentStatus', 'received')
->set('dateFrom', '2024-01-01')
->set('dateTo', '2024-12-31')
->call('clearFilters');
expect($component->get('consultationType'))->toBe('all');
expect($component->get('status'))->toBe('all');
expect($component->get('paymentStatus'))->toBe('all');
expect($component->get('dateFrom'))->toBe('');
expect($component->get('dateTo'))->toBe('');
});
// ===========================================
// Language Tests
// ===========================================
test('export uses admin preferred language for headers', function () {
$adminArabic = User::factory()->admin()->create(['preferred_language' => 'ar']);
Consultation::factory()->create();
$this->actingAs($adminArabic);
Volt::test('admin.consultations.export-consultations')
->call('exportCsv')
->assertFileDownloaded();
});
test('export uses English when admin prefers English', function () {
$adminEnglish = User::factory()->admin()->create(['preferred_language' => 'en']);
Consultation::factory()->create();
$this->actingAs($adminEnglish);
Volt::test('admin.consultations.export-consultations')
->call('exportCsv')
->assertFileDownloaded();
});