diff --git a/app/Http/Controllers/BlogPostController.php b/app/Http/Controllers/BlogPostController.php index d3e0799..d19928f 100644 --- a/app/Http/Controllers/BlogPostController.php +++ b/app/Http/Controllers/BlogPostController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Models\BlogPost; use Illuminate\Http\Request; use Illuminate\View\View; +use Illuminate\Support\Facades\Gate; /* use Spatie\QueryBuilder\AllowedFilter; */ /* use Spatie\QueryBuilder\QueryBuilder; */ @@ -49,6 +50,18 @@ class BlogPostController extends Controller public function edit(BlogPost $blogPost): View { + if (! $this->canEditBlogPost($blogPost)) { + abort(403, 'Unauthorized action.'); + } + return view('blog_post/edit_form', ['blogPost' => $blogPost]); } + + + private function canEditBlogPost(BlogPost $blogPost): bool + { + return Gate::allows('edit', $blogPost); + } + + } diff --git a/app/Policies/BlogPostPolicy.php b/app/Policies/BlogPostPolicy.php new file mode 100644 index 0000000..ccb1f6e --- /dev/null +++ b/app/Policies/BlogPostPolicy.php @@ -0,0 +1,19 @@ +isAuthorPlan($user, $blogPost) || $user->hasRole('admin') || $user->hasRole('moderator'); + } + + private function isAuthorPlan(User $user, BlogPost $blogPost): bool + { + return $user->id === $blogPost->author()->first()->id; + } +} diff --git a/app/Policies/RecipePolicy.php b/app/Policies/RecipePolicy.php new file mode 100644 index 0000000..b05c058 --- /dev/null +++ b/app/Policies/RecipePolicy.php @@ -0,0 +1,19 @@ +isAuthorRecipe($user, $recipe) || $user->hasRole('admin') || $user->hasRole('moderator'); + } + + private function isAuthorRecipe(User $user, Recipe $recipe): bool + { + return $user->id === $recipe->author()->first()->id; + } +} diff --git a/tests/Feature/BlogPost/EditTest.php b/tests/Feature/BlogPost/EditTest.php index ec8520c..db00a2e 100644 --- a/tests/Feature/BlogPost/EditTest.php +++ b/tests/Feature/BlogPost/EditTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\BlogPost; +use App\Livewire\BlogPost\Edit; use App\Models\BlogPost; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -9,7 +10,6 @@ use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; use Livewire\Livewire; use Tests\TestCase; -use App\Livewire\BlogPost\Edit; class EditTest extends TestCase { @@ -32,15 +32,51 @@ class EditTest extends TestCase $this->blogPost = BlogPost::factory()->create(); } - public function test_show_form_edit_blogPost(): void + public function test_show_form_edit_blog_post_success_for_author(): void { + $this->user->author_of_blog_post()->attach($this->blogPost->id); $response = $this ->actingAs($this->user) ->get(route('blog_post.edit', $this->blogPost)); - $response->assertSuccessful(); } + public function test_show_form_edit_blog_post_success_for_admin(): void + { + $blogPost = BlogPost::factory()->create(); + $this->user->author_of_blog_post()->attach($blogPost->id); + + $response = $this + ->actingAs($this->user->assignRole('admin')) + ->get(route('blog_post.edit', $blogPost)); + $response->assertSuccessful(); + } + + public function test_show_form_edit_blog_post_success_for_moderator(): void + { + $blogPost = BlogPost::factory()->create(); + $this->user->author_of_blog_post()->attach($blogPost->id); + + $response = $this + ->actingAs($this->user->assignRole('moderator')) + ->get(route('blog_post.edit', $blogPost)); + $response->assertSuccessful(); + } + + public function test_show_form_edit_blog_post_forbidden_for_not_author(): void + { + $blogPost = BlogPost::factory()->create(); + $user = User::factory()->create(); + + $this->user->author_of_blog_post()->attach($this->blogPost->id); + $user->author_of_blog_post()->attach($blogPost->id); + + $response = $this + ->actingAs($this->user) + ->get(route('blog_post.edit', $blogPost)); + $response->assertForbidden(); + } + public function test_publish_new_blogPost_success(): void { $this->actingAs($this->user); @@ -49,7 +85,7 @@ class EditTest extends TestCase $testCase = Livewire::test( Edit::class, [ - 'blogPost' => $this->blogPost, + 'blogPost' => $this->blogPost, ] ) ->set('title', $updatedBlogPostBeforeToAddDatabase->title) @@ -65,15 +101,13 @@ class EditTest extends TestCase ->assertSuccessful() ->assertHasNoErrors(['title', 'state', 'description', 'youtube_url']); - $updatedBlogPostAfterToAddDatabase = BlogPost::orderByDesc('id')->first(); $newBlogPostUrl = route('blog_post.show', $updatedBlogPostAfterToAddDatabase); Storage::disk('tmp-for-tests')->assertExists($updatedBlogPostAfterToAddDatabase->image); - - // check data after update recipe + // check data after update blog_post self::assertEquals($updatedBlogPostBeforeToAddDatabase->title, $updatedBlogPostAfterToAddDatabase->title); self::assertEquals($updatedBlogPostBeforeToAddDatabase->state, $updatedBlogPostAfterToAddDatabase->state); self::assertEquals($updatedBlogPostBeforeToAddDatabase->description, $updatedBlogPostAfterToAddDatabase->description); @@ -90,7 +124,7 @@ class EditTest extends TestCase $testCase = Livewire::test( Edit::class, [ - 'blogPost' => $this->blogPost, + 'blogPost' => $this->blogPost, ] ) ->set('title', $updatedBlogPostBeforeToAddDatabase->title) @@ -106,15 +140,13 @@ class EditTest extends TestCase ->assertSuccessful() ->assertHasNoErrors(['title', 'state', 'description', 'youtube_url']); - $updatedBlogPostAfterToAddDatabase = BlogPost::orderByDesc('id')->first(); $newBlogPostUrl = route('blog_post.show', $updatedBlogPostAfterToAddDatabase); Storage::disk('tmp-for-tests')->assertExists($updatedBlogPostAfterToAddDatabase->image); - - // check data after update recipe + // check data after update blog_post self::assertEquals($updatedBlogPostBeforeToAddDatabase->title, $updatedBlogPostAfterToAddDatabase->title); self::assertEquals('archived', $updatedBlogPostAfterToAddDatabase->state); self::assertEquals($updatedBlogPostBeforeToAddDatabase->description, $updatedBlogPostAfterToAddDatabase->description); @@ -131,7 +163,7 @@ class EditTest extends TestCase $testCase = Livewire::test( Edit::class, [ - 'blogPost' => $this->blogPost, + 'blogPost' => $this->blogPost, ] ) ->set('title', $updatedBlogPostBeforeToAddDatabase->title) @@ -147,22 +179,19 @@ class EditTest extends TestCase ->assertSuccessful() ->assertHasNoErrors(['title', 'state', 'description', 'youtube_url']); - $updatedBlogPostAfterToAddDatabase = BlogPost::orderByDesc('id')->first(); $newBlogPostUrl = route('blog_post.show', $updatedBlogPostAfterToAddDatabase); Storage::disk('tmp-for-tests')->assertExists($updatedBlogPostAfterToAddDatabase->image); - - // check data after update recipe + // check data after update blog_post self::assertEquals($updatedBlogPostBeforeToAddDatabase->title, $updatedBlogPostAfterToAddDatabase->title); self::assertEquals('archived', $updatedBlogPostAfterToAddDatabase->state); self::assertEquals($updatedBlogPostBeforeToAddDatabase->description, $updatedBlogPostAfterToAddDatabase->description); // self::assertEquals($updatedBlogPostBeforeToAddDatabase->youtube_url, $updatedBlogPostAfterToAddDatabase->youtube_url); $testCase->assertRedirect($newBlogPostUrl); - } public function testNothingChange(): void @@ -171,7 +200,7 @@ class EditTest extends TestCase $blogPostUpdate = Livewire::test( Edit::class, [ - 'blogPost' => $this->blogPost, + 'blogPost' => $this->blogPost, ] ) ->call('publish') @@ -182,7 +211,7 @@ class EditTest extends TestCase Storage::disk('tmp-for-tests')->assertMissing($blogPostUpdate->image); - // check data after update recipe + // check data after update blog_post self::assertEquals($this->blogPost->title, $blogPostUpdate->title); self::assertEquals($this->blogPost->state, $blogPostUpdate->state); self::assertEquals($this->blogPost->description, $blogPostUpdate->description); @@ -190,6 +219,4 @@ class EditTest extends TestCase $blogPostUpdate->assertRedirect($newBlogPostUrl); } - } -