194 lines
6.3 KiB
PHP
194 lines
6.3 KiB
PHP
<?php
|
|
|
|
use App\Models\Permission;
|
|
use App\Models\Role;
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\WithFaker;
|
|
|
|
uses(WithFaker::class);
|
|
|
|
function grantManageAccessRights(User $user): void
|
|
{
|
|
$perm = Permission::firstOrCreate(['name' => 'manage access rights', 'guard_name' => 'web']);
|
|
Permission::firstOrCreate(['name' => 'view access rights', 'guard_name' => 'web']);
|
|
$user->givePermissionTo($perm);
|
|
}
|
|
|
|
test('guest cannot access roles index', function () {
|
|
$this->get('/roles')->assertRedirect('/login');
|
|
});
|
|
|
|
test('authenticated user without permission gets 403 on roles index', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user)->get('/roles')->assertForbidden();
|
|
});
|
|
|
|
test('user with manage access rights can store a new role', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$p = Permission::firstOrCreate(['name' => 'view dashboard', 'guard_name' => 'web']);
|
|
|
|
$response = $this->actingAs($user)
|
|
->postJson('/roles', [
|
|
'name' => 'editor-role',
|
|
'guard_name' => 'web',
|
|
'permissions' => [$p->id],
|
|
]);
|
|
|
|
$response->assertOk()->assertJson(['success' => true]);
|
|
$this->assertDatabaseHas('roles', ['name' => 'editor-role']);
|
|
|
|
$role = Role::where('name', 'editor-role')->first();
|
|
expect($role->hasPermissionTo('view dashboard'))->toBeTrue();
|
|
});
|
|
|
|
test('store rejects duplicate role name', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$p = Permission::firstOrCreate(['name' => 'view dashboard', 'guard_name' => 'web']);
|
|
Role::create(['name' => 'dup-role', 'guard_name' => 'web']);
|
|
|
|
$response = $this->actingAs($user)
|
|
->postJson('/roles', [
|
|
'name' => 'dup-role',
|
|
'guard_name' => 'web',
|
|
'permissions' => [$p->id],
|
|
]);
|
|
|
|
$response->assertStatus(422);
|
|
});
|
|
|
|
test('store rejects empty permissions array', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
|
|
$response = $this->actingAs($user)
|
|
->postJson('/roles', [
|
|
'name' => 'no-perm-role',
|
|
'guard_name' => 'web',
|
|
'permissions' => [],
|
|
]);
|
|
|
|
$response->assertStatus(422);
|
|
});
|
|
|
|
test('store rejects invalid characters in role name', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$p = Permission::firstOrCreate(['name' => 'view dashboard', 'guard_name' => 'web']);
|
|
|
|
$response = $this->actingAs($user)
|
|
->postJson('/roles', [
|
|
'name' => 'role with space!',
|
|
'guard_name' => 'web',
|
|
'permissions' => [$p->id],
|
|
]);
|
|
|
|
$response->assertStatus(422);
|
|
});
|
|
|
|
test('update replaces role permissions', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$p1 = Permission::firstOrCreate(['name' => 'view dashboard', 'guard_name' => 'web']);
|
|
$p2 = Permission::firstOrCreate(['name' => 'view user directory', 'guard_name' => 'web']);
|
|
$role = Role::create(['name' => 'original-role', 'guard_name' => 'web']);
|
|
$role->givePermissionTo('view dashboard');
|
|
|
|
$response = $this->actingAs($user)
|
|
->putJson("/roles/{$role->id}", [
|
|
'name' => 'renamed-role',
|
|
'guard_name' => 'web',
|
|
'permissions' => [$p2->id],
|
|
]);
|
|
|
|
$response->assertOk();
|
|
$role->refresh();
|
|
expect($role->name)->toBe('renamed-role');
|
|
expect($role->hasPermissionTo('view user directory'))->toBeTrue();
|
|
expect($role->hasPermissionTo('view dashboard'))->toBeFalse();
|
|
});
|
|
|
|
test('toggleStatus activates and deactivates role', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$role = Role::create(['name' => 'toggleable', 'guard_name' => 'web', 'is_active' => true]);
|
|
|
|
$this->actingAs($user)
|
|
->postJson('/roles/toggle-status', ['id' => $role->id, 'status' => 'deactivate'])
|
|
->assertOk();
|
|
expect((bool) $role->fresh()->is_active)->toBeFalse();
|
|
|
|
$this->actingAs($user)
|
|
->postJson('/roles/toggle-status', ['id' => $role->id, 'status' => 'activate'])
|
|
->assertOk();
|
|
expect((bool) $role->fresh()->is_active)->toBeTrue();
|
|
});
|
|
|
|
test('destroy soft deletes role when no users assigned', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$role = Role::create(['name' => 'doomed', 'guard_name' => 'web']);
|
|
|
|
$this->actingAs($user)
|
|
->deleteJson("/roles/{$role->id}")
|
|
->assertOk();
|
|
|
|
expect(Role::withTrashed()->find($role->id)->trashed())->toBeTrue();
|
|
});
|
|
|
|
test('destroy blocks deletion when role is still assigned to a user', function () {
|
|
$admin = User::factory()->create();
|
|
grantManageAccessRights($admin);
|
|
$role = Role::create(['name' => 'in-use', 'guard_name' => 'web']);
|
|
$victim = User::factory()->create();
|
|
$victim->assignRole($role);
|
|
|
|
$this->actingAs($admin)
|
|
->deleteJson("/roles/{$role->id}")
|
|
->assertStatus(422)
|
|
->assertJson(['success' => false]);
|
|
|
|
expect(Role::find($role->id))->not->toBeNull();
|
|
});
|
|
|
|
test('restore brings back a soft-deleted role', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$role = Role::create(['name' => 'restorable', 'guard_name' => 'web']);
|
|
$role->delete();
|
|
|
|
$this->actingAs($user)
|
|
->postJson("/roles/{$role->id}/restore")
|
|
->assertOk();
|
|
|
|
expect(Role::find($role->id)->trashed())->toBeFalse();
|
|
});
|
|
|
|
test('forceDelete permanently removes role', function () {
|
|
$user = User::factory()->create();
|
|
grantManageAccessRights($user);
|
|
$role = Role::create(['name' => 'gone-forever', 'guard_name' => 'web']);
|
|
$role->delete();
|
|
|
|
$this->actingAs($user)
|
|
->deleteJson("/roles/{$role->id}/force")
|
|
->assertOk();
|
|
|
|
expect(Role::withTrashed()->find($role->id))->toBeNull();
|
|
});
|
|
|
|
test('forceDelete blocks when role has users assigned', function () {
|
|
$admin = User::factory()->create();
|
|
grantManageAccessRights($admin);
|
|
$role = Role::create(['name' => 'sticky', 'guard_name' => 'web']);
|
|
$victim = User::factory()->create();
|
|
$victim->assignRole($role);
|
|
|
|
$this->actingAs($admin)
|
|
->deleteJson("/roles/{$role->id}/force")
|
|
->assertStatus(422);
|
|
|
|
expect(Role::find($role->id))->not->toBeNull();
|
|
});
|