admin = User::factory()->admin()->create(); }); // =========================================== // Access Tests // =========================================== test('admin can access user export page', function () { $this->actingAs($this->admin) ->get(route('admin.users.export')) ->assertOk(); }); test('non-admin cannot access export page', function () { $client = User::factory()->individual()->create(); $this->actingAs($client) ->get(route('admin.users.export')) ->assertForbidden(); }); test('unauthenticated user cannot access export page', function () { $this->get(route('admin.users.export')) ->assertRedirect(route('login')); }); // =========================================== // CSV Export Tests // =========================================== test('admin can export all users as CSV', function () { User::factory()->count(5)->individual()->create(); User::factory()->count(3)->company()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'all') ->call('exportCsv') ->assertFileDownloaded('users-export-'.now()->format('Y-m-d').'.csv'); }); test('admin can export filtered users by individual type', function () { User::factory()->count(5)->individual()->create(); User::factory()->count(3)->company()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->call('exportCsv') ->assertFileDownloaded(); }); test('admin can export filtered users by company type', function () { User::factory()->count(5)->individual()->create(); User::factory()->count(3)->company()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'company') ->call('exportCsv') ->assertFileDownloaded(); }); test('admin can export users filtered by active status', function () { User::factory()->count(3)->individual()->create(); User::factory()->count(2)->individual()->deactivated()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('status', 'active') ->call('exportCsv') ->assertFileDownloaded(); }); test('admin can export users filtered by deactivated status', function () { User::factory()->count(3)->individual()->create(); User::factory()->count(2)->individual()->deactivated()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('status', 'deactivated') ->call('exportCsv') ->assertFileDownloaded(); }); test('admin can export users filtered by date range', function () { User::factory()->individual()->create(['created_at' => now()->subDays(10)]); User::factory()->individual()->create(['created_at' => now()->subDays(5)]); User::factory()->individual()->create(['created_at' => now()]); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->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 () { User::factory()->individual()->create(['created_at' => now()->subDays(5)]); User::factory()->individual()->deactivated()->create(['created_at' => now()->subDays(5)]); User::factory()->company()->create(['created_at' => now()->subDays(5)]); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->set('status', 'active') ->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 users as PDF', function () { User::factory()->count(5)->individual()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->call('exportPdf') ->assertFileDownloaded('users-export-'.now()->format('Y-m-d').'.pdf'); }); test('admin can export PDF with filters', function () { User::factory()->count(3)->individual()->create(); User::factory()->count(2)->company()->create(); $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->call('exportPdf') ->assertFileDownloaded(); }); // =========================================== // Empty Dataset Tests // =========================================== test('CSV export dispatches notification when no users match filters', function () { $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->set('status', 'active') ->call('exportCsv') ->assertDispatched('notify'); }); test('PDF export dispatches notification when no users match filters', function () { $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->set('status', 'active') ->call('exportPdf') ->assertDispatched('notify'); }); test('preview count shows zero when no users match filters', function () { $this->actingAs($this->admin); Volt::test('admin.users.export-users') ->set('userType', 'individual') ->set('status', 'active') ->assertSee('0'); }); // =========================================== // Filter Tests // =========================================== test('preview count updates when filters change', function () { User::factory()->count(3)->individual()->create(); User::factory()->count(2)->company()->create(); $this->actingAs($this->admin); // All users (excluding admin) - should show 5 Volt::test('admin.users.export-users') ->set('userType', 'all') ->assertSeeHtml('5'); // Filter to individual only - should show 3 Volt::test('admin.users.export-users') ->set('userType', 'individual') ->assertSeeHtml('3'); // Filter to company only - should show 2 Volt::test('admin.users.export-users') ->set('userType', 'company') ->assertSeeHtml('2'); }); test('clear filters resets all filter values', function () { $this->actingAs($this->admin); $component = Volt::test('admin.users.export-users') ->set('userType', 'individual') ->set('status', 'active') ->set('dateFrom', '2024-01-01') ->set('dateTo', '2024-12-31') ->call('clearFilters'); expect($component->get('userType'))->toBe('all'); expect($component->get('status'))->toBe('all'); expect($component->get('dateFrom'))->toBe(''); expect($component->get('dateTo'))->toBe(''); }); // =========================================== // Admin Exclusion Tests // =========================================== test('export excludes admin users', function () { User::factory()->count(3)->individual()->create(); User::factory()->admin()->create(); // Create another admin $this->actingAs($this->admin); // Should only count the 3 individual clients, not the 2 admins Volt::test('admin.users.export-users') ->assertSeeHtml('3'); }); // =========================================== // Language Tests // =========================================== test('export uses admin preferred language for headers', function () { $adminArabic = User::factory()->admin()->create(['preferred_language' => 'ar']); User::factory()->individual()->create(); $this->actingAs($adminArabic); // Test that export works - content verification would require more complex testing Volt::test('admin.users.export-users') ->call('exportCsv') ->assertFileDownloaded(); }); test('export uses English when admin prefers English', function () { $adminEnglish = User::factory()->admin()->create(['preferred_language' => 'en']); User::factory()->individual()->create(); $this->actingAs($adminEnglish); Volt::test('admin.users.export-users') ->call('exportCsv') ->assertFileDownloaded(); });