superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); expect($impersonationService->canImpersonate($admin, $targetUser))->toBeTrue(); }); test('normal user cannot impersonate anyone', function (): void { $normalUser = User::factory()->normalUser()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); expect($impersonationService->canImpersonate($normalUser, $targetUser))->toBeFalse(); }); test('super admin cannot impersonate another super admin', function (): void { $admin = User::factory()->superAdmin()->create(); $targetAdmin = User::factory()->superAdmin()->create(); $impersonationService = app(ImpersonationService::class); expect($impersonationService->canImpersonate($admin, $targetAdmin))->toBeFalse(); }); test('cannot impersonate self', function (): void { $admin = User::factory()->superAdmin()->create(); $impersonationService = app(ImpersonationService::class); expect($impersonationService->canImpersonate($admin, $admin))->toBeFalse(); }); test('cannot impersonate banned user', function (): void { $admin = User::factory()->superAdmin()->create(); $bannedUser = User::factory()->bannedUser()->create(); $impersonationService = app(ImpersonationService::class); expect($impersonationService->canImpersonate($admin, $bannedUser))->toBeFalse(); }); test('cannot impersonate when already impersonating', function (): void { $admin = User::factory()->superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); // Simulate active impersonation Session::put('impersonation', true); Session::put('original_admin_user_id', $admin->id); Session::put('impersonation_start_time', now()); expect($impersonationService->canImpersonate($admin, $targetUser))->toBeFalse(); }); test('start impersonation creates log entry', function (): void { $admin = User::factory()->superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); $request = Request::create('/'); $result = $impersonationService->startImpersonation($admin, $targetUser, $request); expect($result)->toBeTrue(); expect($impersonationService->isImpersonating())->toBeTrue(); expect(Session::get('original_admin_user_id'))->toBe($admin->id); $this->assertDatabaseHas('impersonation_logs', [ 'admin_id' => $admin->id, 'target_user_id' => $targetUser->id, 'status' => 'active', ]); }); test('stop impersonation ends session and updates log', function (): void { $admin = User::factory()->superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); $request = Request::create('/'); // Start impersonation $impersonationService->startImpersonation($admin, $targetUser, $request); $logId = Session::get('impersonation'); // Stop impersonation $result = $impersonationService->stopImpersonation($request); expect($result)->toBeTrue(); expect($impersonationService->isImpersonating())->toBeFalse(); expect(Session::get('original_admin_user_id'))->toBeNull(); $this->assertDatabaseHas('impersonation_logs', [ 'id' => $logId, 'admin_id' => $admin->id, 'target_user_id' => $targetUser->id, 'status' => 'completed', ]); }); test('impersonation timeout is detected correctly', function (): void { $admin = User::factory()->superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); $request = Request::create('/'); // Start impersonation $impersonationService->startImpersonation($admin, $targetUser, $request); // Simulate expired session Session::put('impersonation_start_time', now()->subMinutes(35)); expect($impersonationService->isImpersonationExpired())->toBeTrue(); }); test('remaining minutes calculation works correctly', function (): void { $admin = User::factory()->superAdmin()->create(); $targetUser = User::factory()->normalUser()->create(); $impersonationService = app(ImpersonationService::class); $request = Request::create('/'); // Start impersonation $impersonationService->startImpersonation($admin, $targetUser, $request); // Test with 10 minutes elapsed Session::put('impersonation_start_time', now()->subMinutes(10)); expect($impersonationService->getRemainingMinutes())->toBeBetween(19, 20); }); test('force stop all impersonations terminates active sessions', function (): void { // Create multiple active impersonation logs ImpersonationLog::factory()->count(3)->active()->create(); $impersonationService = app(ImpersonationService::class); $impersonationService->forceStopAllImpersonations(); $this->assertDatabaseMissing('impersonation_logs', [ 'status' => 'active', ]); $this->assertDatabaseCount('impersonation_logs', 3); });