diff --git a/.claude/settings.local.json b/.claude/settings.local.json index b94054c..59f1246 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -3,7 +3,8 @@ "allow": [ "mcp__laravel-boost__database-schema", "Bash(php artisan *)", - "Bash(vendor/bin/pint --dirty --format agent)" + "Bash(vendor/bin/pint --dirty --format agent)", + "mcp__laravel-boost__search-docs" ] } } diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php index f2dbc01..cb60165 100644 --- a/app/Http/Controllers/RoleController.php +++ b/app/Http/Controllers/RoleController.php @@ -2,8 +2,11 @@ namespace App\Http\Controllers; +use App\Http\Requests\StoreRoleRequest; use App\Models\Role; +use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\View\View; class RoleController extends Controller { @@ -17,4 +20,17 @@ class RoleController extends Controller return view('roles.index', compact('roles')); } + + public function create(): View + { + return view('roles.create'); + } + + public function store(StoreRoleRequest $request): RedirectResponse + { + Role::create($request->validated()); + + return redirect()->route('roles.index') + ->with('status', 'role-created'); + } } diff --git a/app/Http/Requests/StoreRoleRequest.php b/app/Http/Requests/StoreRoleRequest.php new file mode 100644 index 0000000..ef2c983 --- /dev/null +++ b/app/Http/Requests/StoreRoleRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => ['required', 'string', 'max:255', 'unique:roles,name'], + 'description' => ['nullable', 'string', 'max:500'], + ]; + } +} diff --git a/resources/views/roles/create.blade.php b/resources/views/roles/create.blade.php new file mode 100644 index 0000000..3a24f01 --- /dev/null +++ b/resources/views/roles/create.blade.php @@ -0,0 +1,56 @@ + + +

+ {{ __('New Role') }} +

+
+ +
+
+
+
+
+
+

+ {{ __('Role Details') }} +

+ +

+ {{ __('Create a new role to assign to users in the system.') }} +

+
+ +
+ @csrf + +
+ + + +
+ +
+ + + +
+ +
+ {{ __('Create Role') }} + + + {{ __('Cancel') }} + +
+
+
+
+
+
+
+
diff --git a/resources/views/roles/index.blade.php b/resources/views/roles/index.blade.php index 114f6de..dae2c3c 100644 --- a/resources/views/roles/index.blade.php +++ b/resources/views/roles/index.blade.php @@ -1,12 +1,29 @@ -

- {{ __('Roles') }} -

+
+

+ {{ __('Roles') }} +

+ + {{ __('New Role') }} + +
+ @if (session('status') === 'role-created') +
+ {{ __('Role created successfully.') }} +
+ @endif +
group(function () { Route::get('/roles', [RoleController::class, 'index'])->name('roles.index'); + Route::get('/roles/create', [RoleController::class, 'create'])->name('roles.create'); + Route::post('/roles', [RoleController::class, 'store'])->name('roles.store'); Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy'); diff --git a/tests/Feature/StoreRoleTest.php b/tests/Feature/StoreRoleTest.php new file mode 100644 index 0000000..c6b0994 --- /dev/null +++ b/tests/Feature/StoreRoleTest.php @@ -0,0 +1,52 @@ +get('/roles/create')->assertRedirect('/login'); +}); + +test('authenticated users can access the create role page', function () { + $this->actingAs(User::factory()->create()) + ->get('/roles/create') + ->assertOk() + ->assertViewIs('roles.create'); +}); + +test('authenticated users can create a role', function () { + $this->actingAs(User::factory()->create()) + ->post('/roles', ['name' => 'Manager', 'description' => 'Manages things']) + ->assertRedirect(route('roles.index')) + ->assertSessionHas('status', 'role-created'); + + $this->assertDatabaseHas('roles', ['name' => 'Manager', 'description' => 'Manages things']); +}); + +test('role name is required', function () { + $this->actingAs(User::factory()->create()) + ->post('/roles', ['name' => '', 'description' => 'Some description']) + ->assertSessionHasErrors('name'); +}); + +test('role name must be unique', function () { + Role::factory()->create(['name' => 'Admin']); + + $this->actingAs(User::factory()->create()) + ->post('/roles', ['name' => 'Admin']) + ->assertSessionHasErrors('name'); +}); + +test('description is optional', function () { + $this->actingAs(User::factory()->create()) + ->post('/roles', ['name' => 'Viewer']) + ->assertRedirect(route('roles.index')); + + $this->assertDatabaseHas('roles', ['name' => 'Viewer', 'description' => null]); +}); + +test('guests cannot create a role', function () { + $this->post('/roles', ['name' => 'Admin'])->assertRedirect('/login'); + + $this->assertDatabaseMissing('roles', ['name' => 'Admin']); +});