diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index be76279..d5bde82 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -1,7 +1,8 @@ name: run-tests on: - push: + pull_request: + types: [ready_for_review, synchronize] paths: - '**.php' - '.github/workflows/run-tests.yml' @@ -17,7 +18,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - php: [8.4, 8.3, 8.2] + php: [8.5, 8.4, 8.3, 8.2] laravel: ["^12.0", "^11.0"] stability: [prefer-lowest, prefer-stable] include: diff --git a/src/Actions/SyncDefinedRole.php b/src/Actions/SyncDefinedRole.php index 2278aee..b71e0e8 100644 --- a/src/Actions/SyncDefinedRole.php +++ b/src/Actions/SyncDefinedRole.php @@ -3,28 +3,27 @@ namespace BinaryCats\LaravelRbac\Actions; use BackedEnum; +use Illuminate\Support\Facades\Artisan; use Lorisleiva\Actions\Action; -use Spatie\Permission\Contracts\Role; +use Spatie\Permission\Commands\CreateRole; class SyncDefinedRole extends Action { - public function __construct( - protected readonly Role $role - ) { - } - /** * Handle syncing a defined role. */ public function handle(string $name, string $guard, array $permissions): void { $permissions = collect($permissions) - ->map(fn ($permission) => match (true) { + ->map(fn ($permission): string => match (true) { $permission instanceof BackedEnum => $permission->value, default => (string) $permission - }); + })->implode('|'); - $this->role::findOrCreate($name, $guard) - ->syncPermissions($permissions); + Artisan::call(CreateRole::class, [ + 'name' => $name, + 'guard' => $guard, + 'permissions' => $permissions, + ]); } } diff --git a/src/Commands/AbilityMakeCommand.php b/src/Commands/AbilityMakeCommand.php index 67b99f2..88af981 100644 --- a/src/Commands/AbilityMakeCommand.php +++ b/src/Commands/AbilityMakeCommand.php @@ -40,7 +40,12 @@ protected function getStub() */ protected function getDefaultNamespace($rootNamespace) { - return $rootNamespace.'\Abilities'; + $path = config('rbac.path', 'Abilities'); + + return str($path) + ->after(app()->path()) + ->trim('/') + ->prepend($rootNamespace, '\\'); } /** diff --git a/src/Commands/DefinedRoleMakeCommand.php b/src/Commands/DefinedRoleMakeCommand.php index f6bf224..57ae1ca 100644 --- a/src/Commands/DefinedRoleMakeCommand.php +++ b/src/Commands/DefinedRoleMakeCommand.php @@ -25,7 +25,7 @@ class DefinedRoleMakeCommand extends GeneratorCommand */ protected function getStub() { - return file_exists($customPath = base_path('/stubs/defined-role.stub')) + return file_exists($customPath = $this->laravel->basePath('/stubs/defined-role.stub')) ? $customPath : __DIR__.'/../../stubs/defined-role.stub'; } diff --git a/src/Jobs/ResetPermissions.php b/src/Jobs/ResetPermissions.php index 0d53b52..80bc83c 100644 --- a/src/Jobs/ResetPermissions.php +++ b/src/Jobs/ResetPermissions.php @@ -18,18 +18,15 @@ class ResetPermissions use Queueable; use SerializesModels; - protected string $guard; + protected readonly string $guard; - /** - * @param string|null $guard - */ public function __construct(?string $guard = null) { $this->guard = $guard ?? config('auth.defaults.guard'); } /** - * @return void + * Handle resetting permissions. */ public function handle(): void { diff --git a/tests/Actions/SyncDefinedRoleTest.php b/tests/Actions/SyncDefinedRoleTest.php index 316280e..e911cac 100644 --- a/tests/Actions/SyncDefinedRoleTest.php +++ b/tests/Actions/SyncDefinedRoleTest.php @@ -7,7 +7,6 @@ use BinaryCats\LaravelRbac\Tests\Fixtures\Abilities\FooAbility; use BinaryCats\LaravelRbac\Tests\TestCase; use PHPUnit\Framework\Attributes\Test; -use Spatie\Permission\Exceptions\PermissionDoesNotExist; class SyncDefinedRoleTest extends TestCase { @@ -29,13 +28,29 @@ public function it_will_defer_syncing_defined_role_to_artisan(): void } #[Test] - public function it_will_throw_an_exception_on_missing_permission(): void + public function it_will_defer_syncing_defined_role_to_artisan_with_custom_guard(): void { - $this->expectException(PermissionDoesNotExist::class); - $this->expectExceptionMessage('There is no permission named `bar` for guard `web`'); + StorePermission::run('bar', 'admin'); + StorePermission::run(FooAbility::One, 'admin'); - SyncDefinedRole::run('foo role', 'web', [ + SyncDefinedRole::run('foo role', 'admin', [ 'bar', + FooAbility::One, + 'this-permission-is-new-and-will-be-created', ]); + + $this->assertDatabaseHas(config('permission.table_names.roles'), [ + 'name' => 'foo role', + 'guard_name' => 'admin', + ]); + + $role = app(config('permission.models.role'))->where([ + 'name' => 'foo role', + 'guard_name' => 'admin', + ])->firstOrFail(); + + $this->assertTrue($role->hasPermissionTo('bar', 'admin')); + $this->assertTrue($role->hasPermissionTo(FooAbility::One, 'admin')); + $this->assertTrue($role->hasPermissionTo('this-permission-is-new-and-will-be-created', 'admin')); } }