feat: add routes, lang, tests, stubs, docs, and docker configurations
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
<?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();
|
||||
});
|
||||
Reference in New Issue
Block a user