From c2b4f4dbaa91eb181e3d6ab1c223b64ea600b156 Mon Sep 17 00:00:00 2001 From: Nafies Luthfi Date: Sun, 5 Aug 2018 20:57:23 +0800 Subject: [PATCH] Add comment deletion Add comment policy for delete action --- .../Controllers/Projects/CommentsController.php | 25 ++++++++++++++++++++++ app/Policies/Projects/CommentPolicy.php | 14 ++++++++++++ .../projects/partials/comment-section.blade.php | 16 +++++++++++--- routes/web/projects.php | 1 + tests/Feature/Projects/ProjectCommentsTest.php | 23 ++++++++++++++++++++ tests/Unit/Policies/CommentPolicyTest.php | 20 +++++++++++++++++ 6 files changed, 96 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Projects/CommentsController.php b/app/Http/Controllers/Projects/CommentsController.php index dfe8a6c..bfdf1f6 100644 --- a/app/Http/Controllers/Projects/CommentsController.php +++ b/app/Http/Controllers/Projects/CommentsController.php @@ -74,4 +74,29 @@ class CommentsController extends Controller return redirect()->route('projects.comments.index', [$project] + request(['page'])); } + + /** + * Remove the specified comment. + * + * @param \App\Entities\Projects\Comment $comment + * @return \Illuminate\Routing\Redirector + */ + public function destroy(Project $project, Comment $comment) + { + $this->authorize('delete', $comment); + + request()->validate([ + 'comment_id' => 'required|exists:comments,id', + ]); + + if (request('comment_id') == $comment->id && $comment->delete()) { + $routeParam = [$project] + request(['page']); + flash(__('comment.deleted'), 'warning'); + + return redirect()->route('projects.comments.index', $routeParam); + } + flash(__('comment.undeleted'), 'error'); + + return back(); + } } diff --git a/app/Policies/Projects/CommentPolicy.php b/app/Policies/Projects/CommentPolicy.php index 1a17331..48f70c6 100644 --- a/app/Policies/Projects/CommentPolicy.php +++ b/app/Policies/Projects/CommentPolicy.php @@ -24,7 +24,21 @@ class CommentPolicy */ public function update(User $user, Comment $comment) { + // Only admin and comment creator can update comment. return $user->hasRole('admin') || ($user->hasRole('worker') && $comment->creator_id == $user->id); } + + /** + * Determine whether the user can delete the comment. + * + * @param \App\Entities\Users\User $user + * @param \App\Entities\Projects\Comment $comment + * @return bool + */ + public function delete(User $user, Comment $comment) + { + // Only admin and comment creator can delete comment. + return $this->update($user, $comment); + } } diff --git a/resources/views/projects/partials/comment-section.blade.php b/resources/views/projects/partials/comment-section.blade.php index 0cfdad7..35e7023 100644 --- a/resources/views/projects/partials/comment-section.blade.php +++ b/resources/views/projects/partials/comment-section.blade.php @@ -14,9 +14,19 @@ {{ $comment->created_at }} {{ $comment->creator->name }} - @can('update', $comment) - {{ link_to_route('projects.comments.index', __('app.edit'), [$project, 'action' => 'comment-edit', 'comment_id' => $comment->id], ['id' => 'edit-comment-'.$comment->id, 'class' => 'small pull-right', 'title' => __('comment.edit')]) }} - @endcan +
+ @can('update', $comment) + {{ link_to_route('projects.comments.index', __('app.edit'), [$project, 'action' => 'comment-edit', 'comment_id' => $comment->id], ['id' => 'edit-comment-'.$comment->id, 'class' => 'small', 'title' => __('comment.edit')]) }} + @endcan + @can('delete', $comment) + {!! FormField::delete( + ['route' => ['projects.comments.destroy', $project, $comment], 'class' => ''], + '×', + ['class' => 'btn-link', 'id' => 'delete-comment-'.$comment->id], + ['comment_id' => $comment->id, 'page' => request('page')] + ) !!} + @endcan +
{!! nl2br($comment->body) !!} @endforeach diff --git a/routes/web/projects.php b/routes/web/projects.php index 8a6b120..239b4ff 100644 --- a/routes/web/projects.php +++ b/routes/web/projects.php @@ -43,6 +43,7 @@ Route::group(['middleware' => ['auth'], 'namespace' => 'Projects'], function () Route::get('projects/{project}/comments', 'CommentsController@index')->name('projects.comments.index'); Route::post('projects/{project}/comments', 'CommentsController@store')->name('projects.comments.store'); Route::patch('projects/{project}/comments/{comment}', 'CommentsController@update')->name('projects.comments.update'); + Route::delete('projects/{project}/comments/{comment}', 'CommentsController@destroy')->name('projects.comments.destroy'); /* * Tasks Routes diff --git a/tests/Feature/Projects/ProjectCommentsTest.php b/tests/Feature/Projects/ProjectCommentsTest.php index 24f85a5..9826f4b 100644 --- a/tests/Feature/Projects/ProjectCommentsTest.php +++ b/tests/Feature/Projects/ProjectCommentsTest.php @@ -81,4 +81,27 @@ class ProjectCommentsTest extends TestCase 'body' => 'Komentar pertama.', ]); } + + /** @test */ + public function user_can_delete_comment() + { + $this->adminUserSigningIn(); + $project = factory(Project::class)->create(); + $comment = factory(Comment::class)->create([ + 'commentable_type' => 'projects', + 'commentable_id' => $project->id, + 'body' => 'This is project comment.', + ]); + + $this->visitRoute('projects.comments.index', $project); + $this->seeElement('button', ['id' => 'delete-comment-'.$comment->id]); + $this->press('delete-comment-'.$comment->id); + + $this->seePageIs(route('projects.comments.index', $project)); + $this->see(__('comment.deleted')); + + $this->dontSeeInDatabase('comments', [ + 'id' => $comment->id, + ]); + } } diff --git a/tests/Unit/Policies/CommentPolicyTest.php b/tests/Unit/Policies/CommentPolicyTest.php index 21bada2..b06b879 100644 --- a/tests/Unit/Policies/CommentPolicyTest.php +++ b/tests/Unit/Policies/CommentPolicyTest.php @@ -26,4 +26,24 @@ class CommentPolicyTest extends TestCase $this->assertTrue($admin->can('update', $comment)); $this->assertTrue($worker->can('update', $comment)); } + + /** @test */ + public function admin_can_delete_any_comments() + { + $admin = $this->createUser('admin'); + $comment = factory(Comment::class)->create(); + + $this->assertTrue($admin->can('delete', $comment)); + } + + /** @test */ + public function worker_can_only_delete_their_comments() + { + $admin = $this->createUser('admin'); + $worker = $this->createUser('worker'); + $comment = factory(Comment::class)->create(['creator_id' => $worker->id]); + + $this->assertTrue($admin->can('delete', $comment)); + $this->assertTrue($worker->can('delete', $comment)); + } }