set('comments.notifications.channels', ['database', 'mail']); $user = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $user->getKey(), 'user_type' => $user->getMorphClass(), 'body' => '

Hello

', ]); $notification = new CommentRepliedNotification($comment); expect($notification->via($user))->toBe(['database', 'mail']); }); it('returns toDatabase array with comment data for CommentRepliedNotification', function () { $user = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $user->getKey(), 'user_type' => $user->getMorphClass(), 'body' => '

This is a reply body

', ]); $notification = new CommentRepliedNotification($comment); $data = $notification->toDatabase($user); expect($data)->toHaveKeys(['comment_id', 'commentable_type', 'commentable_id', 'commenter_name', 'body']) ->and($data['comment_id'])->toBe($comment->id) ->and($data['commentable_type'])->toBe($post->getMorphClass()) ->and($data['commentable_id'])->toBe($post->id) ->and($data['commenter_name'])->toBe($user->getCommentName()); }); it('returns correct via channels from config for UserMentionedNotification', function () { config()->set('comments.notifications.channels', ['database']); $user = User::factory()->create(); $mentionedBy = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $mentionedBy->getKey(), 'user_type' => $mentionedBy->getMorphClass(), 'body' => '

Hey @someone

', ]); $notification = new UserMentionedNotification($comment, $mentionedBy); expect($notification->via($user))->toBe(['database']); }); it('returns toDatabase array with mention data for UserMentionedNotification', function () { $mentioner = User::factory()->create(); $mentioned = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $mentioner->getKey(), 'user_type' => $mentioner->getMorphClass(), 'body' => '

Hey @mentioned

', ]); $notification = new UserMentionedNotification($comment, $mentioner); $data = $notification->toDatabase($mentioned); expect($data)->toHaveKeys(['comment_id', 'commentable_type', 'commentable_id', 'mentioner_name', 'body']) ->and($data['comment_id'])->toBe($comment->id) ->and($data['mentioner_name'])->toBe($mentioner->getCommentName()); }); it('sends notification to subscribers when reply comment is created', function () { Notification::fake(); $author = User::factory()->create(); $subscriber = User::factory()->create(); $post = Post::factory()->create(); CommentSubscription::subscribe($post, $subscriber); $parentComment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $subscriber->getKey(), 'user_type' => $subscriber->getMorphClass(), 'body' => '

Original comment

', ]); $reply = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'parent_id' => $parentComment->id, 'body' => '

Reply to original

', ]); $listener = new SendCommentRepliedNotification; $listener->handle(new CommentCreated($reply)); Notification::assertSentTo($subscriber, CommentRepliedNotification::class); }); it('does NOT send notification for top-level comments', function () { Notification::fake(); $author = User::factory()->create(); $subscriber = User::factory()->create(); $post = Post::factory()->create(); CommentSubscription::subscribe($post, $subscriber); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'body' => '

Top-level comment

', ]); $listener = new SendCommentRepliedNotification; $listener->handle(new CommentCreated($comment)); Notification::assertNothingSent(); }); it('does NOT notify the reply author themselves', function () { Notification::fake(); $user = User::factory()->create(); $post = Post::factory()->create(); CommentSubscription::subscribe($post, $user); $parentComment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $user->getKey(), 'user_type' => $user->getMorphClass(), 'body' => '

My comment

', ]); $reply = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $user->getKey(), 'user_type' => $user->getMorphClass(), 'parent_id' => $parentComment->id, 'body' => '

My own reply

', ]); $listener = new SendCommentRepliedNotification; $listener->handle(new CommentCreated($reply)); Notification::assertNotSentTo($user, CommentRepliedNotification::class); }); it('auto-subscribes comment author to the thread', function () { Notification::fake(); $author = User::factory()->create(); $post = Post::factory()->create(); expect(CommentSubscription::isSubscribed($post, $author))->toBeFalse(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'body' => '

Comment

', ]); $listener = new SendCommentRepliedNotification; $listener->handle(new CommentCreated($comment)); expect(CommentSubscription::isSubscribed($post, $author))->toBeTrue(); }); it('only notifies subscribed users for reply notifications', function () { Notification::fake(); $author = User::factory()->create(); $subscriber = User::factory()->create(); $nonSubscriber = User::factory()->create(); $post = Post::factory()->create(); CommentSubscription::subscribe($post, $subscriber); $parentComment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $subscriber->getKey(), 'user_type' => $subscriber->getMorphClass(), 'body' => '

Original

', ]); $reply = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'parent_id' => $parentComment->id, 'body' => '

Reply

', ]); $listener = new SendCommentRepliedNotification; $listener->handle(new CommentCreated($reply)); Notification::assertSentTo($subscriber, CommentRepliedNotification::class); Notification::assertNotSentTo($nonSubscriber, CommentRepliedNotification::class); }); it('sends mention notification to mentioned user', function () { Notification::fake(); $author = User::factory()->create(); $mentioned = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'body' => '

Hey @mentioned

', ]); $event = new UserMentioned($comment, $mentioned); $listener = new SendUserMentionedNotification; $listener->handle($event); Notification::assertSentTo($mentioned, UserMentionedNotification::class); }); it('does NOT send mention notification to the comment author', function () { Notification::fake(); $author = User::factory()->create(); $post = Post::factory()->create(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'body' => '

Hey @myself

', ]); $event = new UserMentioned($comment, $author); $listener = new SendUserMentionedNotification; $listener->handle($event); Notification::assertNotSentTo($author, UserMentionedNotification::class); }); it('auto-subscribes mentioned user to the thread', function () { Notification::fake(); $author = User::factory()->create(); $mentioned = User::factory()->create(); $post = Post::factory()->create(); expect(CommentSubscription::isSubscribed($post, $mentioned))->toBeFalse(); $comment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'body' => '

Hey @mentioned

', ]); $event = new UserMentioned($comment, $mentioned); $listener = new SendUserMentionedNotification; $listener->handle($event); expect(CommentSubscription::isSubscribed($post, $mentioned))->toBeTrue(); }); it('does not send notifications when notifications are disabled', function () { Notification::fake(); config()->set('comments.notifications.enabled', false); $author = User::factory()->create(); $subscriber = User::factory()->create(); $mentioned = User::factory()->create(); $post = Post::factory()->create(); CommentSubscription::subscribe($post, $subscriber); $parentComment = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $subscriber->getKey(), 'user_type' => $subscriber->getMorphClass(), 'body' => '

Original

', ]); $reply = Comment::factory()->create([ 'commentable_id' => $post->id, 'commentable_type' => $post->getMorphClass(), 'user_id' => $author->getKey(), 'user_type' => $author->getMorphClass(), 'parent_id' => $parentComment->id, 'body' => '

Reply

', ]); $replyListener = new SendCommentRepliedNotification; $replyListener->handle(new CommentCreated($reply)); $mentionEvent = new UserMentioned($reply, $mentioned); $mentionListener = new SendUserMentionedNotification; $mentionListener->handle($mentionEvent); Notification::assertNothingSent(); });