diff --git a/src/Commands/AssignRole.php b/src/Commands/AssignRole.php new file mode 100644 index 000000000..108114b8e --- /dev/null +++ b/src/Commands/AssignRole.php @@ -0,0 +1,51 @@ +argument('name'); + $userId = $this->argument('userId'); + $guardName = $this->argument('guard'); + $userModelClass = $this->argument('userModelNamespace'); + + // Validate that the model class exists and is instantiable + if (! class_exists($userModelClass)) { + $this->error("User model class [{$userModelClass}] does not exist."); + + return Command::FAILURE; + } + + $user = (new $userModelClass)::find($userId); + + if (! $user) { + $this->error("User with ID {$userId} not found."); + + return Command::FAILURE; + } + + /** @var \Spatie\Permission\Contracts\Role $roleClass */ + $roleClass = app(RoleContract::class); + + $role = $roleClass::findOrCreate($roleName, $guardName); + + $user->assignRole($role); + + $this->info("Role `{$role->name}` assigned to user ID {$userId} successfully."); + + return Command::SUCCESS; + } +} diff --git a/src/PermissionServiceProvider.php b/src/PermissionServiceProvider.php index 3aa63def0..588a1f220 100644 --- a/src/PermissionServiceProvider.php +++ b/src/PermissionServiceProvider.php @@ -89,6 +89,7 @@ protected function registerCommands(): void Commands\CreatePermission::class, Commands\Show::class, Commands\UpgradeForTeams::class, + Commands\AssignRole::class, ]); } diff --git a/tests/CommandTest.php b/tests/CommandTest.php index e1961d812..a808aa5ee 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\Attributes\Test; use Spatie\Permission\Models\Permission; use Spatie\Permission\Models\Role; +use Spatie\Permission\Tests\TestModels\User; class CommandTest extends TestCase { @@ -248,4 +249,62 @@ public function it_can_respond_to_about_command_with_teams() $this->assertRegExp($pattern, $output); } } + + /** @test */ + #[Test] + public function test_is_assign_role_to_user() + { + $user = User::first(); + + Artisan::call('permission:assign-role', [ + 'name' => 'testRole', + 'userId' => $user->id, + 'guard' => 'web', + 'userModelNamespace' => User::class, + ]); + + $output = Artisan::output(); + + $this->assertStringContainsString('Role `testRole` assigned to user ID '.$user->id.' successfully.', $output); + $this->assertCount(1, Role::where('name', 'testRole')->get()); + $this->assertCount(1, $user->roles); + $this->assertTrue($user->hasRole('testRole')); + } + + /** @test */ + #[Test] + public function test_assigning_role_fails_when_user_not_found() + { + + Artisan::call('permission:assign-role', [ + 'name' => 'testRole', + 'userId' => 99999, + 'guard' => 'web', + 'userModelNamespace' => User::class, + ]); + + $output = Artisan::output(); + + $this->assertStringContainsString('User with ID 99999 not found.', $output); + } + + /** @test */ + #[Test] + public function test_assigning_role_fails_when_namspace_not_existed() + { + $user = User::first(); + + $userModelClass = 'App\Models\NonExistentUser'; + + Artisan::call('permission:assign-role', [ + 'name' => 'testRole', + 'userId' => $user->id, + 'guard' => 'web', + 'userModelNamespace' => $userModelClass, + ]); + + $output = Artisan::output(); + + $this->assertStringContainsString("User model class [{$userModelClass}] does not exist.", $output); + } }