- Implemented RoleEdit component for editing roles with permissions. - Created RoleIndex component for listing roles with delete confirmation. - Added routes for role management in web.php with appropriate permissions. - Developed RoleTest to cover authentication, authorization, and data integrity for role management.
769 lines
24 KiB
PHP
769 lines
24 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Inertia\Testing\AssertableInertia as Assert;
|
|
use Spatie\Permission\Models\Permission;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function () {
|
|
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
|
|
|
$modules = [
|
|
'user' => ['view', 'create', 'update', 'delete', 'toggle-active', 'reset-password'],
|
|
'category' => ['view', 'create', 'update', 'delete'],
|
|
'supplier' => ['view', 'create', 'update', 'delete'],
|
|
'customer' => ['view', 'create', 'update', 'delete'],
|
|
'cash-account' => ['view', 'deposit', 'withdrawal', 'update', 'delete'],
|
|
'expense' => ['view', 'create', 'update', 'delete'],
|
|
'employee-advance' => ['view', 'create', 'update', 'delete', 'approve', 'pay'],
|
|
'payroll-period' => ['view', 'show', 'current', 'close', 'reopen'],
|
|
'payroll' => ['pay', 'cancel'],
|
|
'payroll-adjustment' => ['create', 'delete'],
|
|
'leave-request' => ['view', 'create', 'update', 'delete', 'approve', 'reject'],
|
|
'attendance' => ['view', 'check-in', 'check-out', 'by-date'],
|
|
'settings' => ['view', 'update-system', 'update-homepage', 'update-social-media', 'update-marketplace', 'update-hr'],
|
|
];
|
|
|
|
foreach ($modules as $module => $actions) {
|
|
foreach ($actions as $action) {
|
|
Permission::create(['name' => "{$module}.{$action}"]);
|
|
}
|
|
}
|
|
|
|
$allPermissions = Permission::all()->pluck('name')->toArray();
|
|
|
|
$developer = Role::create(['name' => 'Developer']);
|
|
$developer->syncPermissions($allPermissions);
|
|
});
|
|
|
|
function createUserWithRole(string $roleName = 'Developer'): User
|
|
{
|
|
$user = User::factory()->create();
|
|
$user->assignRole($roleName);
|
|
|
|
return $user;
|
|
}
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| AUTHENTICATION
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('guests are redirected to the login page', function () {
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertRedirect(route('login'));
|
|
});
|
|
|
|
test('authenticated users without permission cannot visit the role index page', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('authenticated users with permission can visit the role index page', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertOk();
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| INDEX PAGE
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('role index page displays roles', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
Role::create(['name' => 'Manager']);
|
|
Role::create(['name' => 'Staff']);
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/index')
|
|
->has('roles', 3)
|
|
);
|
|
});
|
|
|
|
test('index page works with zero additional roles', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/index')
|
|
->has('roles', 1)
|
|
);
|
|
});
|
|
|
|
test('index page displays correct role count after delete', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'To Delete']);
|
|
|
|
$this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/index')
|
|
->has('roles', 1)
|
|
);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| CREATE / STORE
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('authenticated users without permission cannot visit the create page', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$response = $this->get(route('admin.settings.roles.create'));
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('authenticated users with permission can visit the create page', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->get(route('admin.settings.roles.create'));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/create')
|
|
->has('permissions')
|
|
);
|
|
});
|
|
|
|
test('role can be created', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Manager',
|
|
'permissions' => ['user.view', 'user.create'],
|
|
]);
|
|
|
|
$response
|
|
->assertSessionHasNoErrors()
|
|
->assertRedirect(route('admin.settings.roles.index'));
|
|
|
|
$this->assertDatabaseHas('roles', ['name' => 'Manager']);
|
|
});
|
|
|
|
test('role name is required', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => '',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role name must be string', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 12345,
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role name must not exceed 100 characters', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => str_repeat('a', 101),
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role name exactly 100 characters passes validation', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => str_repeat('a', 100),
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasNoErrors();
|
|
});
|
|
|
|
test('role name must be unique', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
Role::create(['name' => 'Existing Role']);
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Existing Role',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role name uniqueness is case sensitive', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
Role::create(['name' => 'Manager']);
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Manager',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role name with special characters is accepted', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Admin & Staff!',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasNoErrors();
|
|
$this->assertDatabaseHas('roles', ['name' => 'Admin & Staff!']);
|
|
});
|
|
|
|
test('permissions are required', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'New Role',
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('permissions');
|
|
});
|
|
|
|
test('permissions must be an array', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'New Role',
|
|
'permissions' => 'user.view',
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('permissions');
|
|
});
|
|
|
|
test('permissions must exist in database', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'New Role',
|
|
'permissions' => ['nonexistent.permission'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('permissions.0');
|
|
});
|
|
|
|
test('role can be created with multiple permissions', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Multi Permission Role',
|
|
'permissions' => ['user.view', 'user.create', 'category.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasNoErrors();
|
|
|
|
$role = Role::where('name', 'Multi Permission Role')->first();
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['category.view', 'user.create', 'user.view']);
|
|
});
|
|
|
|
test('role can be created with empty permissions array', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'No Permission Role',
|
|
'permissions' => [],
|
|
]);
|
|
|
|
$response->assertSessionHasNoErrors();
|
|
|
|
$role = Role::where('name', 'No Permission Role')->first();
|
|
expect($role->permissions->count())->toBe(0);
|
|
});
|
|
|
|
test('store flashes success toast via Inertia', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Toast Role',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertRedirect();
|
|
});
|
|
|
|
test('store creates new role in database', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Database Check',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$this->assertDatabaseCount('roles', 2);
|
|
$this->assertDatabaseHas('roles', ['name' => 'Database Check']);
|
|
});
|
|
|
|
test('multiple roles can be created sequentially', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Role 1', 'permissions' => ['user.view']]);
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Role 2', 'permissions' => ['user.view']]);
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Role 3', 'permissions' => ['user.view']]);
|
|
|
|
$this->assertDatabaseCount('roles', 4);
|
|
$this->assertDatabaseHas('roles', ['name' => 'Role 1']);
|
|
$this->assertDatabaseHas('roles', ['name' => 'Role 2']);
|
|
$this->assertDatabaseHas('roles', ['name' => 'Role 3']);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| EDIT / UPDATE
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('authenticated users without permission cannot visit the edit page', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$role = Role::create(['name' => 'To Edit']);
|
|
|
|
$response = $this->get(route('admin.settings.roles.edit', $role));
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('authenticated users with permission can visit the edit page', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'To Edit']);
|
|
|
|
$response = $this->get(route('admin.settings.roles.edit', $role));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/edit')
|
|
->has('role')
|
|
->has('permissions')
|
|
);
|
|
});
|
|
|
|
test('role can be updated', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Old Name']);
|
|
$role->syncPermissions(['user.view']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'New Name',
|
|
'permissions' => ['user.view', 'user.create'],
|
|
]);
|
|
|
|
$response
|
|
->assertSessionHasNoErrors()
|
|
->assertRedirect(route('admin.settings.roles.index'));
|
|
|
|
$role->refresh();
|
|
expect($role->name)->toBe('New Name');
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['user.create', 'user.view']);
|
|
});
|
|
|
|
test('role name can be updated to itself', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Same Name']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Same Name',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasNoErrors();
|
|
});
|
|
|
|
test('role update name must be unique excluding itself', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'First']);
|
|
Role::create(['name' => 'Second']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Second',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role update name is required', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => '',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role update name must not exceed 100 characters', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => str_repeat('a', 101),
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
});
|
|
|
|
test('role permissions can be updated', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Update Perm']);
|
|
$role->syncPermissions(['user.view']);
|
|
|
|
$this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Update Perm',
|
|
'permissions' => ['category.view', 'category.create'],
|
|
]);
|
|
|
|
$role->refresh();
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['category.create', 'category.view']);
|
|
});
|
|
|
|
test('role can be updated multiple times', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Version 1']);
|
|
|
|
$this->put(route('admin.settings.roles.update', $role), ['name' => 'Version 2', 'permissions' => ['user.view']]);
|
|
$role->refresh();
|
|
expect($role->name)->toBe('Version 2');
|
|
|
|
$this->put(route('admin.settings.roles.update', $role), ['name' => 'Version 3', 'permissions' => ['user.view']]);
|
|
$role->refresh();
|
|
expect($role->name)->toBe('Version 3');
|
|
});
|
|
|
|
test('update flashes success toast via Inertia', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Toast']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Updated Toast',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertRedirect();
|
|
});
|
|
|
|
test('updating non-existent role returns 404', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', 999999), [
|
|
'name' => 'Ghost Role',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertStatus(404);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| DELETE / DESTROY
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('authenticated users without permission cannot delete roles', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$role = Role::create(['name' => 'To Delete']);
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', $role));
|
|
$response->assertForbidden();
|
|
|
|
$this->assertDatabaseHas('roles', ['id' => $role->id]);
|
|
});
|
|
|
|
test('role can be deleted', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'To Delete']);
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$response
|
|
->assertSessionHasNoErrors()
|
|
->assertRedirect(route('admin.settings.roles.index'));
|
|
|
|
$this->assertDatabaseMissing('roles', ['id' => $role->id]);
|
|
});
|
|
|
|
test('role permissions are removed when role is deleted', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'With Perms']);
|
|
$role->syncPermissions(['user.view', 'user.create']);
|
|
|
|
$this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$this->assertDatabaseMissing('roles', ['id' => $role->id]);
|
|
$this->assertDatabaseMissing('role_has_permissions', ['role_id' => $role->id]);
|
|
});
|
|
|
|
test('delete flashes success toast via Inertia', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Toast Delete']);
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$response->assertRedirect();
|
|
});
|
|
|
|
test('deleting non-existent role returns 404', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', 999999));
|
|
|
|
$response->assertStatus(404);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| AUTHORIZATION - GUEST CANNOT PERFORM ACTIONS
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('guest cannot create role', function () {
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Unauthorized',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertRedirect(route('login'));
|
|
$this->assertDatabaseMissing('roles', ['name' => 'Unauthorized']);
|
|
});
|
|
|
|
test('guest cannot update role', function () {
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Unauthorized Update',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertRedirect(route('login'));
|
|
});
|
|
|
|
test('guest cannot delete role', function () {
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$response->assertRedirect(route('login'));
|
|
$this->assertDatabaseHas('roles', ['id' => $role->id]);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| AUTHORIZATION - USER WITHOUT ROLE CANNOT PERFORM ACTIONS
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('user without developer role cannot create role', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Unauthorized',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertForbidden();
|
|
$this->assertDatabaseMissing('roles', ['name' => 'Unauthorized']);
|
|
});
|
|
|
|
test('user without developer role cannot update role', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Unauthorized Update',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$response->assertForbidden();
|
|
});
|
|
|
|
test('user without developer role cannot delete role', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->delete(route('admin.settings.roles.destroy', $role));
|
|
|
|
$response->assertForbidden();
|
|
$this->assertDatabaseHas('roles', ['id' => $role->id]);
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| DATA INTEGRITY
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('created role has correct timestamps', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Timestamp Role',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$role = Role::where('name', 'Timestamp Role')->first();
|
|
expect($role->created_at)->not->toBeNull();
|
|
expect($role->updated_at)->not->toBeNull();
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| PERMISSION ASSIGNMENT
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('role permissions are correctly synced', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Sync Test']);
|
|
$role->syncPermissions(['user.view', 'user.create', 'category.view']);
|
|
|
|
$role->refresh();
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['category.view', 'user.create', 'user.view']);
|
|
});
|
|
|
|
test('role permissions can be replaced', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Replace Test']);
|
|
$role->syncPermissions(['user.view']);
|
|
|
|
$role->syncPermissions(['category.view', 'category.create']);
|
|
$role->refresh();
|
|
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['category.create', 'category.view']);
|
|
});
|
|
|
|
test('role can have all permissions', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$allPermissions = Permission::pluck('name')->toArray();
|
|
|
|
$role = Role::create(['name' => 'Super Admin']);
|
|
$role->syncPermissions($allPermissions);
|
|
|
|
$role->refresh();
|
|
expect($role->permissions->count())->toBe(count($allPermissions));
|
|
});
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| REALISTIC USER SCENARIOS
|
|
|--------------------------------------------------------------------------
|
|
*/
|
|
|
|
test('user creates role then immediately edits it', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), [
|
|
'name' => 'Draft Role',
|
|
'permissions' => ['user.view'],
|
|
]);
|
|
|
|
$role = Role::where('name', 'Draft Role')->first();
|
|
|
|
$this->put(route('admin.settings.roles.update', $role), [
|
|
'name' => 'Final Role',
|
|
'permissions' => ['user.view', 'user.create'],
|
|
]);
|
|
|
|
$role->refresh();
|
|
expect($role->name)->toBe('Final Role');
|
|
expect($role->permissions->pluck('name')->sort()->values()->toArray())->toEqual(['user.create', 'user.view']);
|
|
});
|
|
|
|
test('user creates multiple roles and deletes one', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Keep Role', 'permissions' => ['user.view']]);
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Delete Role', 'permissions' => ['user.view']]);
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Also Keep Role', 'permissions' => ['user.view']]);
|
|
|
|
$toDelete = Role::where('name', 'Delete Role')->first();
|
|
$this->delete(route('admin.settings.roles.destroy', $toDelete));
|
|
|
|
$response = $this->get(route('admin.settings.roles.index'));
|
|
$response->assertOk();
|
|
$response->assertInertia(fn (Assert $page) => $page
|
|
->component('admin/roles/index')
|
|
->has('roles', 3)
|
|
);
|
|
});
|
|
|
|
test('user tries to create role without submitting any data', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$response = $this->post(route('admin.settings.roles.store'), []);
|
|
|
|
$response->assertSessionHasErrors(['name', 'permissions']);
|
|
});
|
|
|
|
test('user tries to update role without submitting any data', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$role = Role::create(['name' => 'Existing']);
|
|
|
|
$response = $this->put(route('admin.settings.roles.update', $role), []);
|
|
|
|
$response->assertSessionHasErrors(['name', 'permissions']);
|
|
});
|
|
|
|
test('user rapidly submits same role creation twice', function () {
|
|
$this->actingAs(createUserWithRole());
|
|
|
|
$this->post(route('admin.settings.roles.store'), ['name' => 'Rapid Submit', 'permissions' => ['user.view']]);
|
|
$response = $this->post(route('admin.settings.roles.store'), ['name' => 'Rapid Submit', 'permissions' => ['user.view']]);
|
|
|
|
$response->assertSessionHasErrors('name');
|
|
$this->assertDatabaseCount('roles', 2);
|
|
});
|