From 42c548bc1d409f03a4fedb68d3b56c908509c23b Mon Sep 17 00:00:00 2001 From: Gautier DELEGLISE Date: Thu, 24 Apr 2025 20:29:49 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=90=9B=20policy=20calls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AccessServiceProvider.php | 2 +- src/Console/ControlMakeCommand.php | 2 - src/Console/PerimeterMakeCommand.php | 2 - src/Console/stubs/control.stub | 1 - src/Console/stubs/perimeter.overlay.stub | 1 - src/Console/stubs/perimeter.plain.stub | 1 - src/Controls/Control.php | 7 ++ src/Policies/ControlledPolicy.php | 14 +-- tests/Feature/PoliciesTest.php | 105 +++++++++++++++++++++++ tests/Support/Models/Model.php | 3 + tests/Support/Policies/ModelPolicy.php | 2 +- tests/Unit/StubsTest.php | 2 +- 12 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 tests/Feature/PoliciesTest.php diff --git a/src/AccessServiceProvider.php b/src/AccessServiceProvider.php index 6001f59..323b40e 100644 --- a/src/AccessServiceProvider.php +++ b/src/AccessServiceProvider.php @@ -86,7 +86,7 @@ protected function registerCommands(array $commands) protected function registerStubs() { Event::listen(function (PublishingStubs $event) { - $event->add(realpath(__DIR__.'/Console/stubs/control.stub'), 'controller.stub'); + $event->add(realpath(__DIR__.'/Console/stubs/control.stub'), 'control.stub'); $event->add(realpath(__DIR__.'/Console/stubs/perimeter.plain.stub'), 'perimeter.plain.stub'); $event->add(realpath(__DIR__.'/Console/stubs/perimeter.overlay.stub'), 'perimeter.overlay.stub'); }); diff --git a/src/Console/ControlMakeCommand.php b/src/Console/ControlMakeCommand.php index ad470f6..0c0a1fb 100644 --- a/src/Console/ControlMakeCommand.php +++ b/src/Console/ControlMakeCommand.php @@ -75,8 +75,6 @@ protected function getDefaultNamespace($rootNamespace) /** * Build the class with the given name. * - * Remove the base controller import if we are already in the base namespace. - * * @param string $name * * @return string diff --git a/src/Console/PerimeterMakeCommand.php b/src/Console/PerimeterMakeCommand.php index 9a5b025..c89f387 100644 --- a/src/Console/PerimeterMakeCommand.php +++ b/src/Console/PerimeterMakeCommand.php @@ -81,8 +81,6 @@ protected function getDefaultNamespace($rootNamespace) /** * Build the class with the given name. * - * Remove the base controller import if we are already in the base namespace. - * * @param string $name * * @return string diff --git a/src/Console/stubs/control.stub b/src/Console/stubs/control.stub index 46bf4ea..7cfa2bf 100644 --- a/src/Console/stubs/control.stub +++ b/src/Console/stubs/control.stub @@ -2,7 +2,6 @@ namespace {{ namespace }}; -use {{ rootNamespace }}Http\Controllers\Controller; use Illuminate\Http\Request; use Lomkit\Access\Controls\Control; use Illuminate\Database\Eloquent\Model; diff --git a/src/Console/stubs/perimeter.overlay.stub b/src/Console/stubs/perimeter.overlay.stub index 14470d7..edcec05 100644 --- a/src/Console/stubs/perimeter.overlay.stub +++ b/src/Console/stubs/perimeter.overlay.stub @@ -2,7 +2,6 @@ namespace {{ namespace }}; -use {{ rootNamespace }}Http\Controllers\Controller; use Lomkit\Access\Perimeters\OverlayPerimeter; class {{ class }} extends OverlayPerimeter diff --git a/src/Console/stubs/perimeter.plain.stub b/src/Console/stubs/perimeter.plain.stub index 836d374..426a050 100644 --- a/src/Console/stubs/perimeter.plain.stub +++ b/src/Console/stubs/perimeter.plain.stub @@ -2,7 +2,6 @@ namespace {{ namespace }}; -use {{ rootNamespace }}Http\Controllers\Controller; use Lomkit\Access\Perimeters\Perimeter; class {{ class }} extends Perimeter diff --git a/src/Controls/Control.php b/src/Controls/Control.php index d8beb13..3774c5b 100644 --- a/src/Controls/Control.php +++ b/src/Controls/Control.php @@ -234,6 +234,13 @@ public static function new(): self */ public static function resolveControlName(string $modelName): string { + // @TODO: The auto guess here is strange, we specify the models / controls everywhere, is there a better way of doing this ? (In policies guess the model as Laravel is doing ?) + // @TODO: Discussed with Lucas G + + if (method_exists($modelName, 'control')) { + return $modelName::control()::class; + } + $resolver = static::$controlNameResolver ?? function (string $modelName) { $appNamespace = static::appNamespace(); diff --git a/src/Policies/ControlledPolicy.php b/src/Policies/ControlledPolicy.php index 0e3b0f0..c5c4556 100644 --- a/src/Policies/ControlledPolicy.php +++ b/src/Policies/ControlledPolicy.php @@ -45,7 +45,7 @@ protected function getControl(): Control */ public function viewAny(Model $user) { - return $this->getControl()->should($user, __FUNCTION__, new ($this->getModel())); + return $this->getControl()->applies($user, __FUNCTION__, new ($this->getModel())); } /** @@ -58,7 +58,7 @@ public function viewAny(Model $user) */ public function view(Model $user, Model $model) { - return $this->getControl()->should($user, __FUNCTION__, $model); + return $this->getControl()->applies($user, __FUNCTION__, $model); } /** @@ -70,7 +70,7 @@ public function view(Model $user, Model $model) */ public function create(Model $user) { - return $this->getControl()->should($user, __FUNCTION__, new ($this->getModel())); + return $this->getControl()->applies($user, __FUNCTION__, new ($this->getModel())); } /** @@ -83,7 +83,7 @@ public function create(Model $user) */ public function update(Model $user, Model $model) { - return $this->getControl()->should($user, __FUNCTION__, $model); + return $this->getControl()->applies($user, __FUNCTION__, $model); } /** @@ -96,7 +96,7 @@ public function update(Model $user, Model $model) */ public function delete(Model $user, Model $model) { - return $this->getControl()->should($user, __FUNCTION__, $model); + return $this->getControl()->applies($user, __FUNCTION__, $model); } /** @@ -109,7 +109,7 @@ public function delete(Model $user, Model $model) */ public function restore(Model $user, Model $model) { - return $this->getControl()->should($user, __FUNCTION__, $model); + return $this->getControl()->applies($user, __FUNCTION__, $model); } /** @@ -122,6 +122,6 @@ public function restore(Model $user, Model $model) */ public function forceDelete(Model $user, Model $model) { - return $this->getControl()->should($user, __FUNCTION__, $model); + return $this->getControl()->applies($user, __FUNCTION__, $model); } } diff --git a/tests/Feature/PoliciesTest.php b/tests/Feature/PoliciesTest.php new file mode 100644 index 0000000..71d9d10 --- /dev/null +++ b/tests/Feature/PoliciesTest.php @@ -0,0 +1,105 @@ +createOne(); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->view($user, $model)); + } + + public function test_policies_calls_view_any_method_properly(): void + { + Gate::define('viewAny global models', function (User $user) { + return true; + }); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->viewAny($user)); + } + + public function test_policies_calls_create_method_properly(): void + { + Gate::define('create global models', function (User $user) { + return true; + }); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->create($user)); + } + + public function test_policies_calls_update_method_properly(): void + { + Gate::define('update global models', function (User $user) { + return true; + }); + $model = Model::factory() + ->createOne(); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->update($user, $model)); + } + + public function test_policies_calls_delete_method_properly(): void + { + Gate::define('delete global models', function (User $user) { + return true; + }); + $model = Model::factory() + ->createOne(); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->delete($user, $model)); + } + + public function test_policies_calls_restore_method_properly(): void + { + Gate::define('restore global models', function (User $user) { + return true; + }); + $model = Model::factory() + ->createOne(); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->restore($user, $model)); + } + + public function test_policies_calls_force_delete_methoforceDeleted_properly(): void + { + Gate::define('forceDelete global models', function (User $user) { + return true; + }); + $model = Model::factory() + ->createOne(); + $user = \Illuminate\Support\Facades\Auth::user(); + + $policy = new \Lomkit\Access\Tests\Support\Policies\ModelPolicy(); + + $this->assertTrue($policy->forceDelete($user, $model)); + } +} \ No newline at end of file diff --git a/tests/Support/Models/Model.php b/tests/Support/Models/Model.php index 53b63c6..a105e12 100644 --- a/tests/Support/Models/Model.php +++ b/tests/Support/Models/Model.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model as BaseModel; use Laravel\Scout\Searchable; use Lomkit\Access\Controls\HasControl; +use Lomkit\Access\Tests\Support\Access\Controls\ModelControl; use Lomkit\Access\Tests\Support\Database\Factories\ModelFactory; class Model extends BaseModel @@ -14,6 +15,8 @@ class Model extends BaseModel use HasControl; use Searchable; + public static $control = ModelControl::class; + protected static function newFactory() { return new ModelFactory(); diff --git a/tests/Support/Policies/ModelPolicy.php b/tests/Support/Policies/ModelPolicy.php index 41e553c..d45916e 100644 --- a/tests/Support/Policies/ModelPolicy.php +++ b/tests/Support/Policies/ModelPolicy.php @@ -2,8 +2,8 @@ namespace Lomkit\Access\Tests\Support\Policies; -use Illuminate\Database\Eloquent\Model; use Lomkit\Access\Policies\ControlledPolicy; +use Lomkit\Access\Tests\Support\Models\Model; class ModelPolicy extends ControlledPolicy { diff --git a/tests/Unit/StubsTest.php b/tests/Unit/StubsTest.php index 7d9b40b..1e0a0a1 100644 --- a/tests/Unit/StubsTest.php +++ b/tests/Unit/StubsTest.php @@ -12,7 +12,7 @@ public function test_stubs_correctly_registered(): void $this->assertEquals( [ - realpath(__DIR__.'/../../src/Console/stubs/control.stub') => 'controller.stub', + realpath(__DIR__.'/../../src/Console/stubs/control.stub') => 'control.stub', realpath(__DIR__.'/../../src/Console/stubs/perimeter.plain.stub') => 'perimeter.plain.stub', realpath(__DIR__.'/../../src/Console/stubs/perimeter.overlay.stub') => 'perimeter.overlay.stub', ], From b69e9c93276dbed814d83abb1f7b211e45af1b3c Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Thu, 24 Apr 2025 18:30:16 +0000 Subject: [PATCH 2/3] Apply fixes from StyleCI --- src/Controls/Control.php | 2 +- tests/Feature/PoliciesTest.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Controls/Control.php b/src/Controls/Control.php index 3774c5b..06fac77 100644 --- a/src/Controls/Control.php +++ b/src/Controls/Control.php @@ -236,7 +236,7 @@ public static function resolveControlName(string $modelName): string { // @TODO: The auto guess here is strange, we specify the models / controls everywhere, is there a better way of doing this ? (In policies guess the model as Laravel is doing ?) // @TODO: Discussed with Lucas G - + if (method_exists($modelName, 'control')) { return $modelName::control()::class; } diff --git a/tests/Feature/PoliciesTest.php b/tests/Feature/PoliciesTest.php index 71d9d10..da7e0d0 100644 --- a/tests/Feature/PoliciesTest.php +++ b/tests/Feature/PoliciesTest.php @@ -5,7 +5,6 @@ use Illuminate\Support\Facades\Gate; use Lomkit\Access\Tests\Support\Models\Model; use Lomkit\Access\Tests\Support\Models\User; -use Mockery; class PoliciesTest extends \Lomkit\Access\Tests\Unit\TestCase { @@ -102,4 +101,4 @@ public function test_policies_calls_force_delete_methoforceDeleted_properly(): v $this->assertTrue($policy->forceDelete($user, $model)); } -} \ No newline at end of file +} From da7a0e747eec8644f3a0905835fb580ef9d676cf Mon Sep 17 00:00:00 2001 From: Gautier DELEGLISE Date: Thu, 24 Apr 2025 20:35:23 +0200 Subject: [PATCH 3/3] Update PoliciesTest.php --- tests/Feature/PoliciesTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/PoliciesTest.php b/tests/Feature/PoliciesTest.php index da7e0d0..3f53f1a 100644 --- a/tests/Feature/PoliciesTest.php +++ b/tests/Feature/PoliciesTest.php @@ -88,7 +88,7 @@ public function test_policies_calls_restore_method_properly(): void $this->assertTrue($policy->restore($user, $model)); } - public function test_policies_calls_force_delete_methoforceDeleted_properly(): void + public function test_policies_calls_force_delete_method_properly(): void { Gate::define('forceDelete global models', function (User $user) { return true;