Files
biiproject-kit-v1/tests/Feature/ImpersonateTest.php
T

103 lines
3.1 KiB
PHP

<?php
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
function makeImpersonator(): User
{
$admin = User::factory()->create(['is_active' => true]);
$perm = Permission::firstOrCreate(['name' => 'impersonate users', 'guard_name' => 'web']);
$admin->givePermissionTo($perm);
return $admin;
}
test('guest cannot start impersonation', function () {
$target = User::factory()->create();
$this->post("/impersonate/{$target->id}")->assertRedirect('/login');
});
test('user without permission cannot start impersonation', function () {
$admin = User::factory()->create();
$target = User::factory()->create();
$this->actingAs($admin)->post("/impersonate/{$target->id}")->assertForbidden();
});
test('cannot impersonate self', function () {
$admin = makeImpersonator();
$this->actingAs($admin)
->post("/impersonate/{$admin->id}")
->assertForbidden();
});
test('cannot impersonate an inactive user', function () {
$admin = makeImpersonator();
$target = User::factory()->create(['is_active' => false]);
$this->actingAs($admin)
->post("/impersonate/{$target->id}")
->assertForbidden();
});
test('cannot impersonate a Developer (Super Admin)', function () {
$admin = makeImpersonator();
$dev = User::factory()->create(['is_active' => true]);
Role::firstOrCreate(['name' => 'Developer', 'guard_name' => 'web']);
$dev->assignRole('Developer');
$this->actingAs($admin)
->post("/impersonate/{$dev->id}")
->assertForbidden();
});
test('start switches the authenticated user and stashes original id', function () {
$admin = makeImpersonator();
$target = User::factory()->create(['is_active' => true]);
$this->actingAs($admin)
->post("/impersonate/{$target->id}")
->assertRedirect(route('dashboard', absolute: false))
->assertSessionHas('impersonator_id', $admin->id);
expect(auth()->id())->toBe($target->id);
});
test('cannot start a second impersonation while already impersonating', function () {
$admin = makeImpersonator();
$first = User::factory()->create(['is_active' => true]);
$first->givePermissionTo('impersonate users'); // edge case: target also has permission
$second = User::factory()->create(['is_active' => true]);
$this->actingAs($admin)->post("/impersonate/{$first->id}");
$this->post("/impersonate/{$second->id}")
->assertRedirect()
->assertSessionHas('error');
expect(auth()->id())->toBe($first->id);
});
test('stop without an active session returns 403', function () {
$admin = makeImpersonator();
$this->actingAs($admin)->post('/impersonate/stop')->assertForbidden();
});
test('stop restores the original super admin', function () {
$admin = makeImpersonator();
$target = User::factory()->create(['is_active' => true]);
$this->actingAs($admin)->post("/impersonate/{$target->id}");
expect(auth()->id())->toBe($target->id);
$this->post('/impersonate/stop')
->assertRedirect(route('users', absolute: false));
expect(auth()->id())->toBe($admin->id);
expect(session()->has('impersonator_id'))->toBeFalse();
});