Files
relaticle-comments/tests/Feature/CommentItemComponentTest.php
manukminasyan 6c96fb900b fix: update tests for RichEditor form data paths and service providers
Update all tests to use new form state paths (commentData.body,
editData.body, replyData.body) instead of removed public properties.
Remove searchUsers() tests (method replaced by MentionProvider).
Add BladeUI Icons service providers to TestCase for RichEditor views.
2026-03-27 19:20:56 +04:00

258 lines
8.0 KiB
PHP

<?php
use Livewire\Livewire;
use Relaticle\Comments\Livewire\CommentItem;
use Relaticle\Comments\Models\Comment;
use Relaticle\Comments\Tests\Models\Post;
use Relaticle\Comments\Tests\Models\User;
it('allows author to start and save edit on their comment', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
'body' => '<p>Original body</p>',
]);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startEdit')
->assertSet('isEditing', true)
->set('editData.body', '<p>Updated body</p>')
->call('saveEdit')
->assertSet('isEditing', false);
$comment->refresh();
expect($comment->body)->toBe('<p>Updated body</p>');
expect($comment->isEdited())->toBeTrue();
});
it('marks edited comment with edited indicator', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
'body' => '<p>Original</p>',
]);
$this->actingAs($user);
expect($comment->isEdited())->toBeFalse();
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startEdit')
->set('editData.body', '<p>Changed</p>')
->call('saveEdit');
$comment->refresh();
expect($comment->isEdited())->toBeTrue();
expect($comment->edited_at)->not->toBeNull();
});
it('prevents non-author from editing a comment', function () {
$author = User::factory()->create();
$otherUser = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $author->getKey(),
'commenter_type' => $author->getMorphClass(),
'body' => '<p>Author comment</p>',
]);
$this->actingAs($otherUser);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startEdit')
->assertForbidden();
});
it('allows author to delete their own comment', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
]);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('deleteComment');
expect(Comment::find($comment->id))->toBeNull();
expect(Comment::withTrashed()->find($comment->id)->trashed())->toBeTrue();
});
it('preserves replies when parent comment is deleted', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$attrs = [
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
];
$parent = Comment::factory()->create($attrs);
$reply = Comment::factory()->withParent($parent)->create($attrs);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $parent])
->call('deleteComment');
expect(Comment::withTrashed()->find($parent->id)->trashed())->toBeTrue();
expect(Comment::find($reply->id))->not->toBeNull();
expect(Comment::find($reply->id)->trashed())->toBeFalse();
});
it('prevents non-author from deleting a comment', function () {
$author = User::factory()->create();
$otherUser = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $author->getKey(),
'commenter_type' => $author->getMorphClass(),
]);
$this->actingAs($otherUser);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('deleteComment')
->assertForbidden();
});
it('allows user to reply to a comment', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
]);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startReply')
->assertSet('isReplying', true)
->set('replyData.body', '<p>My reply</p>')
->call('addReply')
->assertSet('isReplying', false);
$reply = Comment::where('parent_id', $comment->id)->first();
expect($reply)->not->toBeNull();
expect($reply->body)->toBe('<p>My reply</p>');
expect($reply->commenter_id)->toBe($user->id);
expect($reply->commentable_id)->toBe($post->id);
});
it('respects max depth for replies', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$attrs = [
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
];
config(['comments.threading.max_depth' => 1]);
$level0 = Comment::factory()->create($attrs);
$level1 = Comment::factory()->withParent($level0)->create($attrs);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $level1])
->call('startReply')
->assertSet('isReplying', false);
});
it('resets state when cancelling edit', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
'body' => '<p>Some body</p>',
]);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startEdit')
->assertSet('isEditing', true)
->call('cancelEdit')
->assertSet('isEditing', false);
});
it('resets state when cancelling reply', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$comment = Comment::factory()->create([
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
]);
$this->actingAs($user);
Livewire::test(CommentItem::class, ['comment' => $comment])
->call('startReply')
->assertSet('isReplying', true)
->set('replyData.body', '<p>Draft reply</p>')
->call('cancelReply')
->assertSet('isReplying', false);
});
it('loads all replies within a thread eagerly', function () {
$user = User::factory()->create();
$post = Post::factory()->create();
$attrs = [
'commentable_id' => $post->id,
'commentable_type' => $post->getMorphClass(),
'commenter_id' => $user->getKey(),
'commenter_type' => $user->getMorphClass(),
];
$parent = Comment::factory()->create($attrs);
Comment::factory()->count(3)->withParent($parent)->create($attrs);
$parentWithReplies = Comment::with('replies.commenter')->find($parent->id);
$this->actingAs($user);
$component = Livewire::test(CommentItem::class, ['comment' => $parentWithReplies]);
expect($component->instance()->comment->replies)->toHaveCount(3);
});