16 changed files with 334 additions and 4 deletions
-
11app/Entities/Projects/Issue.php
-
83app/Http/Controllers/Issues/CommentController.php
-
16app/Http/Controllers/Projects/IssueController.php
-
12app/Policies/Projects/IssuePolicy.php
-
1app/Providers/AppServiceProvider.php
-
1resources/lang/de/app.php
-
1resources/lang/en/app.php
-
1resources/lang/id/app.php
-
2resources/lang/id/comment.php
-
6resources/views/projects/issues/index.blade.php
-
54resources/views/projects/issues/partials/comment-section.blade.php
-
13resources/views/projects/issues/show.blade.php
-
7routes/web/projects.php
-
106tests/Feature/Projects/IssueCommentsTest.php
-
15tests/Unit/Models/IssueTest.php
-
9tests/Unit/Policies/IssuePolicyTest.php
@ -0,0 +1,83 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Issues; |
|||
|
|||
use Illuminate\Http\Request; |
|||
use App\Entities\Projects\Issue; |
|||
use App\Entities\Projects\Comment; |
|||
use App\Http\Controllers\Controller; |
|||
|
|||
class CommentController extends Controller |
|||
{ |
|||
/** |
|||
* Store a new comment in storage. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @param \App\Entities\Projects\Issue $issue |
|||
* @return \Illuminate\Http\RedirectResponse |
|||
*/ |
|||
public function store(Request $request, Issue $issue) |
|||
{ |
|||
$this->authorize('comment-on', $issue); |
|||
|
|||
$newComment = $request->validate([ |
|||
'body' => 'required|string|max:255', |
|||
]); |
|||
|
|||
$issue->comments()->create([ |
|||
'body' => $newComment['body'], |
|||
'creator_id' => auth()->id(), |
|||
]); |
|||
$issue->touch(); |
|||
|
|||
flash(__('comment.created'), 'success'); |
|||
|
|||
return back(); |
|||
} |
|||
|
|||
/** |
|||
* Update the specified comment. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @param \App\Entities\Projects\Issue $issue |
|||
* @param \App\Entities\Projects\Comment $comment |
|||
* @return \Illuminate\Http\Response |
|||
*/ |
|||
public function update(Request $request, Issue $issue, Comment $comment) |
|||
{ |
|||
$this->authorize('update', $comment); |
|||
|
|||
$commentData = $request->validate([ |
|||
'body' => 'required|string|max:255', |
|||
]); |
|||
$comment->update($commentData); |
|||
flash(__('comment.updated'), 'success'); |
|||
|
|||
return redirect()->route('projects.issues.show', [$issue->project, $issue]); |
|||
} |
|||
|
|||
/** |
|||
* Remove the specified comment. |
|||
* |
|||
* @param \App\Entities\Projects\Issue $issue |
|||
* @param \\App\Entities\Projects\Comment $comment |
|||
* @return \Illuminate\Routing\Redirector |
|||
*/ |
|||
public function destroy(Issue $issue, Comment $comment) |
|||
{ |
|||
$this->authorize('delete', $comment); |
|||
|
|||
request()->validate([ |
|||
'comment_id' => 'required|exists:comments,id', |
|||
]); |
|||
|
|||
if (request('comment_id') == $comment->id && $comment->delete()) { |
|||
flash(__('comment.deleted'), 'warning'); |
|||
|
|||
return redirect()->route('projects.issues.show', [$issue->project, $issue]); |
|||
} |
|||
flash(__('comment.undeleted'), 'error'); |
|||
|
|||
return back(); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
@foreach($comments as $comment) |
|||
<div class="alert alert-warning"> |
|||
<legend style="font-size: 14px;margin-bottom: 10px;"> |
|||
<span class="label label-default pull-right">{{ $comment->time_display }}</span> |
|||
<strong>{{ $comment->creator->name }}</strong> |
|||
</legend> |
|||
<div class="pull-right"> |
|||
@can('update', $comment) |
|||
{{ link_to_route('projects.issues.show', __('app.edit'), [$project, $issue, 'action' => 'comment-edit', 'comment_id' => $comment->id], ['id' => 'edit-comment-'.$comment->id, 'class' => 'small', 'title' => __('comment.edit')]) }} |
|||
@endcan |
|||
@can('delete', $comment) |
|||
{!! FormField::delete( |
|||
['route' => ['issues.comments.destroy', $issue, $comment], 'class' => ''], |
|||
'×', |
|||
['class' => 'btn-link', 'id' => 'delete-comment-'.$comment->id], |
|||
['comment_id' => $comment->id] |
|||
) !!} |
|||
@endcan |
|||
</div> |
|||
{!! nl2br($comment->body) !!} |
|||
</div> |
|||
@endforeach |
|||
|
|||
@can('comment-on', $issue) |
|||
{{ Form::open(['route' => ['issues.comments.store', $issue]]) }} |
|||
{!! FormField::textarea('body', ['required' => true, 'label' => false, 'placeholder' => __('comment.create_text')]) !!} |
|||
{{ Form::submit(__('comment.create'), ['class' => 'btn btn-success pull-right']) }} |
|||
{{ Form::close() }} |
|||
<div class="clearfix"></div><br> |
|||
@endcan |
|||
|
|||
@if (Request::get('action') == 'comment-edit' && $editableComment) |
|||
<div id="commentModal" class="modal" role="dialog"> |
|||
<div class="modal-dialog"> |
|||
<!-- Modal content--> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
{{ link_to_route('projects.issues.show', '×', [$issue->project, $issue], ['class' => 'close']) }} |
|||
<h4 class="modal-title">{{ __('comment.edit') }}</h4> |
|||
</div> |
|||
{!! Form::model($editableComment, ['route' => ['issues.comments.update', $issue, $editableComment],'method' => 'patch']) !!} |
|||
<div class="modal-body"> |
|||
{!! FormField::textarea('body', ['label' => __('comment.body')]) !!} |
|||
{{ Form::hidden('page', request('page')) }} |
|||
</div> |
|||
<div class="modal-footer"> |
|||
{!! Form::submit(__('comment.update'), ['class' => 'btn btn-success']) !!} |
|||
{{ link_to_route('projects.issues.show', __('app.cancel'), [$project->issue, $issue] + request(['page']), ['class' => 'btn btn-default']) }} |
|||
</div> |
|||
{!! Form::close() !!} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@endif |
|||
@ -0,0 +1,106 @@ |
|||
<?php |
|||
|
|||
namespace Tests\Feature\Projects; |
|||
|
|||
use Tests\TestCase; |
|||
use App\Entities\Projects\Issue; |
|||
use App\Entities\Projects\Comment; |
|||
use Illuminate\Foundation\Testing\RefreshDatabase; |
|||
|
|||
class IssueCommentsTest extends TestCase |
|||
{ |
|||
use RefreshDatabase; |
|||
|
|||
/** @test */ |
|||
public function user_can_view_issue_comments() |
|||
{ |
|||
$this->adminUserSigningIn(); |
|||
$issue = factory(Issue::class)->create(); |
|||
$comment = factory(Comment::class)->create([ |
|||
'commentable_type' => 'issues', |
|||
'commentable_id' => $issue->id, |
|||
'body' => 'This is issue comment.', |
|||
]); |
|||
|
|||
$this->visitRoute('projects.issues.show', [$issue->project, $issue]); |
|||
|
|||
$this->seeText('This is issue comment.'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function admin_can_add_comment_to_an_issue() |
|||
{ |
|||
$admin = $this->adminUserSigningIn(); |
|||
$issue = factory(Issue::class)->create(); |
|||
|
|||
$this->visitRoute('projects.issues.show', [$issue->project, $issue]); |
|||
|
|||
$this->submitForm(__('comment.create'), [ |
|||
'body' => 'First comment.', |
|||
]); |
|||
|
|||
$this->seePageIs(route('projects.issues.show', [$issue->project, $issue])); |
|||
$this->see(__('comment.created')); |
|||
|
|||
$this->seeInDatabase('comments', [ |
|||
'commentable_type' => 'issues', |
|||
'commentable_id' => $issue->id, |
|||
'body' => 'First comment.', |
|||
'creator_id' => $admin->id, |
|||
]); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_edit_an_issue_comment() |
|||
{ |
|||
$this->adminUserSigningIn(); |
|||
$issue = factory(Issue::class)->create(); |
|||
$comment = factory(Comment::class)->create([ |
|||
'commentable_type' => 'issues', |
|||
'commentable_id' => $issue->id, |
|||
'body' => 'This is issue comment.', |
|||
]); |
|||
|
|||
$this->visitRoute('projects.issues.show', [$issue->project, $issue]); |
|||
$this->seeElement('a', ['id' => 'edit-comment-'.$comment->id]); |
|||
$this->click('edit-comment-'.$comment->id); |
|||
$this->seeRouteIs('projects.issues.show', [$issue->project, $issue, 'action' => 'comment-edit', 'comment_id' => $comment->id]); |
|||
|
|||
$this->submitForm(__('comment.update'), [ |
|||
'body' => 'Edited comment.', |
|||
]); |
|||
|
|||
$this->seePageIs(route('projects.issues.show', [$issue->project, $issue])); |
|||
$this->see(__('comment.updated')); |
|||
|
|||
$this->seeInDatabase('comments', [ |
|||
'id' => $comment->id, |
|||
'commentable_type' => 'issues', |
|||
'commentable_id' => $issue->id, |
|||
'body' => 'Edited comment.', |
|||
]); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_delete_an_issue_comment() |
|||
{ |
|||
$this->adminUserSigningIn(); |
|||
$issue = factory(Issue::class)->create(); |
|||
$comment = factory(Comment::class)->create([ |
|||
'commentable_type' => 'issues', |
|||
'commentable_id' => $issue->id, |
|||
'body' => 'This is issue comment.', |
|||
]); |
|||
|
|||
$this->visitRoute('projects.issues.show', [$issue->project, $issue]); |
|||
$this->seeElement('button', ['id' => 'delete-comment-'.$comment->id]); |
|||
$this->press('delete-comment-'.$comment->id); |
|||
|
|||
$this->seePageIs(route('projects.issues.show', [$issue->project, $issue])); |
|||
$this->see(__('comment.deleted')); |
|||
|
|||
$this->dontSeeInDatabase('comments', [ |
|||
'id' => $comment->id, |
|||
]); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue