Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
@Slf4j
public class CommunityNotificationEventListener {

private final NotificationService notificationService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
@Slf4j
public class StudyNotificationEventListener {

private final NotificationService notificationService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.back.domain.board.post.entity.Post;
import com.back.domain.board.comment.repository.CommentRepository;
import com.back.domain.board.post.repository.PostRepository;
import com.back.domain.notification.service.NotificationService;
import com.back.domain.user.entity.User;
import com.back.domain.user.entity.UserProfile;
import com.back.domain.user.entity.UserStatus;
Expand All @@ -24,6 +25,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
Expand All @@ -47,6 +49,9 @@ class CommentServiceTest {
@Autowired
private PostRepository postRepository;

@MockitoBean
private NotificationService notificationService;

// ====================== 댓글 생성 테스트 ======================

@Test
Expand Down Expand Up @@ -496,4 +501,4 @@ void deleteReply_success() {
boolean exists = commentRepository.findById(reply.getId()).isPresent();
assertThat(exists).isFalse();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
package com.back.domain.notification.event.community;

import com.back.domain.notification.service.NotificationService;
import com.back.domain.user.entity.User;
import com.back.domain.user.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.BDDMockito.*;

@ExtendWith(MockitoExtension.class)
@DisplayName("CommunityNotificationEventListener 테스트")
class CommunityNotificationEventListenerTest {

@Mock
private NotificationService notificationService;

@Mock
private UserRepository userRepository;

@InjectMocks
private CommunityNotificationEventListener listener;

private User actor;
private User receiver;

@BeforeEach
void setUp() {
actor = User.builder()
.id(1L)
.username("actor")
.email("actor@test.com")
.build();

receiver = User.builder()
.id(2L)
.username("receiver")
.email("receiver@test.com")
.build();
}

// ====================== 댓글 작성 이벤트 ======================

@Test
@DisplayName("댓글 작성 이벤트 수신 - 알림 생성 성공")
void t1() {
// given
CommentCreatedEvent event = new CommentCreatedEvent(
1L, // actorId (댓글 작성자)
2L, // receiverId (게시글 작성자)
100L, // postId
200L, // commentId
"댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));

// when
listener.handleCommentCreated(event);

// then
verify(notificationService).createCommunityNotification(
eq(receiver),
eq(actor),
anyString(), // title
anyString(), // content
eq("/posts/100")
);
}

@Test
@DisplayName("댓글 작성 이벤트 - 작성자(actor) 없음")
void t2() {
// given
CommentCreatedEvent event = new CommentCreatedEvent(
999L, // 존재하지 않는 actorId
2L,
100L,
200L,
"댓글 내용"
);

given(userRepository.findById(999L)).willReturn(Optional.empty());

// when
listener.handleCommentCreated(event);

// then
verify(notificationService, never()).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);
}

@Test
@DisplayName("댓글 작성 이벤트 - 수신자(receiver) 없음")
void t3() {
// given
CommentCreatedEvent event = new CommentCreatedEvent(
1L,
999L, // 존재하지 않는 receiverId
100L,
200L,
"댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(999L)).willReturn(Optional.empty());

// when
listener.handleCommentCreated(event);

// then
verify(notificationService, never()).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);
}

// ====================== 대댓글 작성 이벤트 ======================

@Test
@DisplayName("대댓글 작성 이벤트 수신 - 알림 생성 성공")
void t4() {
// given
ReplyCreatedEvent event = new ReplyCreatedEvent(
1L, // actorId (대댓글 작성자)
2L, // receiverId (댓글 작성자)
100L, // postId
200L, // parentCommentId
300L, // replyId
"대댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));

// when
listener.handleReplyCreated(event);

// then
verify(notificationService).createCommunityNotification(
eq(receiver),
eq(actor),
anyString(),
anyString(),
eq("/posts/100#comment-200")
);
}

@Test
@DisplayName("대댓글 작성 이벤트 - 작성자(actor) 없음")
void t5() {
// given
ReplyCreatedEvent event = new ReplyCreatedEvent(
999L, // 존재하지 않는 actorId
2L,
100L,
200L,
300L,
"대댓글 내용"
);

given(userRepository.findById(999L)).willReturn(Optional.empty());

// when
listener.handleReplyCreated(event);

// then
verify(notificationService, never()).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);
}

// ====================== 게시글 좋아요 이벤트 ======================

@Test
@DisplayName("게시글 좋아요 이벤트 수신 - 알림 생성 성공")
void t6() {
// given
PostLikedEvent event = new PostLikedEvent(
1L, // actorId (좋아요 누른 사람)
2L, // receiverId (게시글 작성자)
100L, // postId
"게시글 제목"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));

// when
listener.handlePostLiked(event);

// then
verify(notificationService).createCommunityNotification(
eq(receiver),
eq(actor),
anyString(),
anyString(),
eq("/posts/100")
);
}

@Test
@DisplayName("게시글 좋아요 이벤트 - 수신자 없음")
void t7() {
// given
PostLikedEvent event = new PostLikedEvent(
1L,
999L, // 존재하지 않는 receiverId
100L,
"게시글 제목"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(999L)).willReturn(Optional.empty());

// when
listener.handlePostLiked(event);

// then
verify(notificationService, never()).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);
}

// ====================== 댓글 좋아요 이벤트 ======================

@Test
@DisplayName("댓글 좋아요 이벤트 수신 - 알림 생성 성공")
void t8() {
// given
CommentLikedEvent event = new CommentLikedEvent(
1L, // actorId
2L, // receiverId
100L, // postId
200L, // commentId,
"댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));

// when
listener.handleCommentLiked(event);

// then
verify(notificationService).createCommunityNotification(
eq(receiver),
eq(actor),
anyString(),
anyString(),
eq("/posts/100#comment-200")
);
}

@Test
@DisplayName("댓글 좋아요 이벤트 - 작성자와 수신자가 같은 경우")
void t9() {
// given
CommentLikedEvent event = new CommentLikedEvent(
1L, // actorId
1L, // receiverId (같은 사람)
100L,
200L,
"댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));

// when
listener.handleCommentLiked(event);

// then
// NotificationService에서 자기 자신 알림 필터링 처리
verify(notificationService).createCommunityNotification(
eq(actor), // receiver
eq(actor), // actor
anyString(),
anyString(),
anyString()
);
}

// ====================== 예외 처리 테스트 ======================

@Test
@DisplayName("알림 생성 중 예외 발생 - 로그만 출력하고 예외 전파 안함")
void t10() {
// given
CommentCreatedEvent event = new CommentCreatedEvent(
1L, 2L, 100L, 200L, "댓글 내용"
);

given(userRepository.findById(1L)).willReturn(Optional.of(actor));
given(userRepository.findById(2L)).willReturn(Optional.of(receiver));

willThrow(new RuntimeException("알림 생성 실패"))
.given(notificationService).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);

// when & then - 예외가 전파되지 않아야 함
assertThatCode(() -> listener.handleCommentCreated(event))
.doesNotThrowAnyException();

verify(notificationService).createCommunityNotification(
any(), any(), anyString(), anyString(), anyString()
);
}
}
Loading