diff --git a/backend/src/main/java/mouda/backend/chat/business/ChatService.java b/backend/src/main/java/mouda/backend/chat/business/ChatService.java index fd11d75c5..2acc8ac8d 100644 --- a/backend/src/main/java/mouda/backend/chat/business/ChatService.java +++ b/backend/src/main/java/mouda/backend/chat/business/ChatService.java @@ -8,6 +8,7 @@ import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.Chat; import mouda.backend.chat.domain.ChatOwnership; import mouda.backend.chat.domain.ChatRoom; import mouda.backend.chat.domain.Chats; @@ -19,12 +20,10 @@ import mouda.backend.chat.presentation.request.LastReadChatRequest; import mouda.backend.chat.presentation.request.PlaceConfirmRequest; import mouda.backend.chat.presentation.response.ChatFindUnloadedResponse; -import mouda.backend.chat.util.DateTimeFormatter; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.implement.finder.MoimFinder; import mouda.backend.moim.implement.writer.MoimWriter; -import mouda.backend.notification.domain.NotificationType; @Service @Transactional @@ -37,21 +36,6 @@ public class ChatService { private final MoimFinder moimFinder; private final ChatNotificationSender chatNotificationSender; - public void createChat( - long darakbangId, - long chatRoomId, - ChatCreateRequest request, - DarakbangMember darakbangMember - ) { - ChatRoom chatRoom = chatRoomFinder.read(darakbangId, chatRoomId, darakbangMember); - - String content = request.content(); - chatWriter.append(chatRoom.getId(), content, darakbangMember); - - chatNotificationSender.sendChatNotification(darakbangId, chatRoom, content, darakbangMember, - NotificationType.NEW_CHAT); - } - @Transactional(readOnly = true) public ChatFindUnloadedResponse findUnloadedChats( long darakbangId, long recentChatId, long chatRoomId, DarakbangMember darakbangMember @@ -64,6 +48,19 @@ public ChatFindUnloadedResponse findUnloadedChats( return ChatFindUnloadedResponse.toResponse(chatsWithAuthor); } + public void createChat( + long darakbangId, + long chatRoomId, + ChatCreateRequest request, + DarakbangMember darakbangMember + ) { + ChatRoom chatRoom = chatRoomFinder.read(darakbangId, chatRoomId, darakbangMember); + + Chat appendedChat = chatWriter.append(chatRoom.getId(), request.content(), darakbangMember); + + chatNotificationSender.sendChatNotification(darakbangId, chatRoom, appendedChat); + } + public void confirmPlace(long darakbangId, long chatRoomId, PlaceConfirmRequest request, DarakbangMember darakbangMember) { ChatRoom chatRoom = chatRoomFinder.readMoimChatRoom(darakbangId, chatRoomId); @@ -72,10 +69,9 @@ public void confirmPlace(long darakbangId, long chatRoomId, PlaceConfirmRequest Moim moim = moimFinder.read(chatRoom.getTargetId(), darakbangId); moimWriter.confirmPlace(moim, darakbangMember, place); - chatWriter.appendPlaceTypeChat(chatRoom.getId(), place, darakbangMember); + Chat appendedChat = chatWriter.appendPlaceTypeChat(chatRoom.getId(), place, darakbangMember); - chatNotificationSender.sendChatNotification(darakbangId, chatRoom, place, darakbangMember, - NotificationType.MOIM_PLACE_CONFIRMED); + chatNotificationSender.sendChatNotification(darakbangId, chatRoom, appendedChat); } public void confirmDateTime(long darakbangId, long chatRoomId, DateTimeConfirmRequest request, @@ -87,10 +83,9 @@ public void confirmDateTime(long darakbangId, long chatRoomId, DateTimeConfirmRe LocalTime time = request.time(); moimWriter.confirmDateTime(moim, darakbangMember, date, time); - chatWriter.appendDateTimeTypeChat(chatRoom.getId(), date, time, darakbangMember); + Chat appendedChat = chatWriter.appendDateTimeTypeChat(chatRoom.getId(), date, time, darakbangMember); - chatNotificationSender.sendChatNotification(darakbangId, chatRoom, DateTimeFormatter.formatDateTime(date, time), - darakbangMember, NotificationType.MOIM_TIME_CONFIRMED); + chatNotificationSender.sendChatNotification(darakbangId, chatRoom, appendedChat); } public void updateLastReadChat( diff --git a/backend/src/main/java/mouda/backend/chat/domain/Author.java b/backend/src/main/java/mouda/backend/chat/domain/Author.java index 75dc7f661..6d858fb2d 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/Author.java +++ b/backend/src/main/java/mouda/backend/chat/domain/Author.java @@ -6,14 +6,20 @@ @Getter public class Author { - private final long id; + private final long darakbangMemberId; + private final long memberId; private final String nickname; private final String profile; @Builder - public Author(long id, String nickname, String profile) { - this.id = id; + public Author(long darakbangMemberId, long memberId, String nickname, String profile) { + this.darakbangMemberId = darakbangMemberId; + this.memberId = memberId; this.nickname = nickname; this.profile = profile; } + + public boolean isNotSameMember(long darakbangMemberId, long memberId) { + return this.darakbangMemberId != darakbangMemberId || this.memberId != memberId; + } } diff --git a/backend/src/main/java/mouda/backend/chat/domain/Chat.java b/backend/src/main/java/mouda/backend/chat/domain/Chat.java index 0defca2a9..f849dd36a 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/Chat.java +++ b/backend/src/main/java/mouda/backend/chat/domain/Chat.java @@ -28,6 +28,6 @@ public Chat(long id, String content, Author author, LocalDate date, LocalTime ti } public boolean isMine(long darakbangMemberId) { - return author.getId() == darakbangMemberId; + return author.getDarakbangMemberId() == darakbangMemberId; } } diff --git a/backend/src/main/java/mouda/backend/chat/exception/ChatErrorMessage.java b/backend/src/main/java/mouda/backend/chat/exception/ChatErrorMessage.java index bfb19b1f1..ee84fef6f 100644 --- a/backend/src/main/java/mouda/backend/chat/exception/ChatErrorMessage.java +++ b/backend/src/main/java/mouda/backend/chat/exception/ChatErrorMessage.java @@ -10,7 +10,10 @@ public enum ChatErrorMessage { CHATROOM_NOT_FOUND("존재하지 않는 채팅방입니다."), BET_DARAKBANG_MEMBER_NOT_FOUND("참여하지 않은 안내면진다입니다."), INVALID_CHATROOM_TYPE("잘못된 채팅 방 타입입니다."), - UNAUTHORIZED("권한이 없습니다."); + UNAUTHORIZED("권한이 없습니다."), + + INVALID_DATE_TIME_FORMAT("날짜와 시간 형식이 올바르지 않습니다."), + ; private final String message; } diff --git a/backend/src/main/java/mouda/backend/chat/implement/ChatWriter.java b/backend/src/main/java/mouda/backend/chat/implement/ChatWriter.java index 53f61620f..f44c86fe5 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/ChatWriter.java +++ b/backend/src/main/java/mouda/backend/chat/implement/ChatWriter.java @@ -7,6 +7,7 @@ import lombok.RequiredArgsConstructor; import mouda.backend.bet.implement.BetDarakbangMemberWriter; +import mouda.backend.chat.domain.Chat; import mouda.backend.chat.domain.ChatRoom; import mouda.backend.chat.domain.ChatRoomType; import mouda.backend.chat.entity.ChatEntity; @@ -23,7 +24,7 @@ public class ChatWriter { private final ChamyoWriter chamyoWriter; private final BetDarakbangMemberWriter betDarakbangMemberWriter; - public void appendPlaceTypeChat(long chatRoomId, String content, DarakbangMember darakbangMember) { + public Chat appendPlaceTypeChat(long chatRoomId, String content, DarakbangMember darakbangMember) { ChatEntity chatEntity = ChatEntity.builder() .chatRoomId(chatRoomId) .content(content) @@ -32,10 +33,10 @@ public void appendPlaceTypeChat(long chatRoomId, String content, DarakbangMember .darakbangMember(darakbangMember) .chatType(ChatType.PLACE) .build(); - chatRepository.save(chatEntity); + return chatRepository.save(chatEntity).toChat(); } - public void appendDateTimeTypeChat(long chatRoomId, LocalDate date, LocalTime time, + public Chat appendDateTimeTypeChat(long chatRoomId, LocalDate date, LocalTime time, DarakbangMember darakbangMember) { ChatEntity chatEntity = ChatEntity.builder() .chatRoomId(chatRoomId) @@ -45,10 +46,10 @@ public void appendDateTimeTypeChat(long chatRoomId, LocalDate date, LocalTime ti .darakbangMember(darakbangMember) .chatType(ChatType.DATETIME) .build(); - chatRepository.save(chatEntity); + return chatRepository.save(chatEntity).toChat(); } - public void append(long chatRoomId, String content, DarakbangMember darakbangMember) { + public Chat append(long chatRoomId, String content, DarakbangMember darakbangMember) { ChatEntity chatEntity = ChatEntity.builder() .chatRoomId(chatRoomId) .content(content) @@ -57,7 +58,7 @@ public void append(long chatRoomId, String content, DarakbangMember darakbangMem .darakbangMember(darakbangMember) .chatType(ChatType.BASIC) .build(); - chatRepository.save(chatEntity); + return chatRepository.save(chatEntity).toChat(); } public void updateLastReadChat(ChatRoom chatRoom, DarakbangMember darakbangMember, long lastReadChatId) { diff --git a/backend/src/main/java/mouda/backend/chat/implement/sender/ChatNotificationSender.java b/backend/src/main/java/mouda/backend/chat/implement/sender/ChatNotificationSender.java index 7f4f70295..6d01dc14f 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/sender/ChatNotificationSender.java +++ b/backend/src/main/java/mouda/backend/chat/implement/sender/ChatNotificationSender.java @@ -4,24 +4,26 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationEventPublisher; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; +import lombok.Getter; import lombok.RequiredArgsConstructor; import mouda.backend.bet.domain.Bet; import mouda.backend.bet.implement.BetFinder; +import mouda.backend.chat.domain.Chat; import mouda.backend.chat.domain.ChatRoom; import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.entity.ChatType; +import mouda.backend.chat.util.ChatDateTimeFormatter; import mouda.backend.common.config.UrlConfig; -import mouda.backend.darakbangmember.domain.DarakbangMember; +import mouda.backend.darakbang.domain.Darakbang; +import mouda.backend.darakbang.implement.DarakbangFinder; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.implement.finder.ChatRecipientFinder; import mouda.backend.moim.implement.finder.MoimFinder; import mouda.backend.notification.domain.NotificationEvent; import mouda.backend.notification.domain.NotificationType; import mouda.backend.notification.domain.Recipient; -import mouda.backend.notification.exception.NotificationErrorMessage; -import mouda.backend.notification.exception.NotificationException; @Component @EnableConfigurationProperties(UrlConfig.class) @@ -33,48 +35,50 @@ public class ChatNotificationSender { private final ApplicationEventPublisher eventPublisher; private final MoimFinder moimFinder; private final BetFinder betFinder; + private final DarakbangFinder darakbangFinder; public void sendChatNotification( - long darakbangId, ChatRoom chatRoom, String content, DarakbangMember sender, NotificationType notificationType + long darakbangId, ChatRoom chatRoom, Chat appendedChat ) { ChatRoomType chatRoomType = chatRoom.getType(); long chatRoomId = chatRoom.getId(); + if (chatRoomType == ChatRoomType.BET) { Bet bet = betFinder.find(darakbangId, chatRoom.getTargetId()); - sendBetNotification(bet, content, sender, notificationType); + sendBetNotification(bet, appendedChat, chatRoomId); return; } + Moim moim = moimFinder.read(chatRoom.getTargetId(), darakbangId); - sendMoimNotification(moim, content, sender, notificationType, chatRoomId); + sendMoimNotification(moim, appendedChat, chatRoomId); } - private void sendBetNotification( - Bet bet, String content, DarakbangMember sender, NotificationType notificationType + private void sendMoimNotification( + Moim moim, Chat chat, long chatRoomId ) { - List recipients = chatRecipientFinder.getBetChatNotificationRecipients(bet.getId(), sender); - long darakbangId = bet.getDarakbangId(); - long chatRoomId = bet.getId(); + List recipients = chatRecipientFinder.getMoimChatNotificationRecipients(moim.getId(), + chat.getAuthor()); + long darakbangId = moim.getDarakbangId(); - publishEvent(notificationType, bet.getTitle(), content, sender, recipients, darakbangId, chatRoomId); + publishEvent(darakbangId, chatRoomId, moim.getTitle(), chat, recipients); } - private void sendMoimNotification( - Moim moim, String content, DarakbangMember sender, NotificationType notificationType, long chatRoomId - ) { - List recipients = chatRecipientFinder.getMoimChatNotificationRecipients(moim.getId(), sender); - long darakbangId = moim.getDarakbangId(); + private void sendBetNotification(Bet bet, Chat chat, long chatRoomId) { + List recipients = chatRecipientFinder.getBetChatNotificationRecipients(bet.getId(), + chat.getAuthor()); + long darakbangId = bet.getDarakbangId(); - publishEvent(notificationType, moim.getTitle(), content, sender, recipients, darakbangId, chatRoomId); + publishEvent(darakbangId, chatRoomId, bet.getTitle(), chat, recipients); } - private void publishEvent( - NotificationType notificationType, String title, String content, DarakbangMember sender, - List recipients, long darakbangId, long chatRoomId - ) { + private void publishEvent(long darakbangId, long chatRoomId, String title, Chat chat, List recipients) { + Darakbang darakbang = darakbangFinder.findById(darakbangId); + ChatNotification chatNotification = ChatNotification.create(darakbang.getName(), title, chat); + NotificationEvent notificationEvent = NotificationEvent.chatEvent( - notificationType, - title, - ChatNotificationMessage.create(content, sender, notificationType), + chatNotification.getType(), + darakbang.getName(), + chatNotification.getMessage(), urlConfig.getChatRoomUrl(darakbangId, chatRoomId), recipients, darakbangId, @@ -84,25 +88,43 @@ private void publishEvent( eventPublisher.publishEvent(notificationEvent); } - static class ChatNotificationMessage { + @Getter + @RequiredArgsConstructor + static class ChatNotification { + + private final String title; + private final NotificationType type; + private final String message; + + public static ChatNotification create(String darakbangName, String title, Chat chat) { + ChatType chatType = chat.getChatType(); + String content = chat.getContent(); - public static String create(String content, DarakbangMember sender, NotificationType type) { - if (type.isConfirmedType()) { - return confirmedChatMessage(content, type); + if (chatType == ChatType.PLACE) { + String message = "'" + title + "'" + " 장소가 '" + content + "' 으로 확정되었어요!"; + return placeConfirmChat(darakbangName, message); } - if (type == NotificationType.NEW_CHAT) { - return sender.getNickname() + ": " + content; + if (chatType == ChatType.DATETIME) { + String parsedDateTime = ChatDateTimeFormatter.formatDateTime(content); + String message = "'" + title + "'" + "시간이 '" + parsedDateTime + "' 으로 확정되었어요!"; + return dateTimeConfirmChat(darakbangName, message); } - throw new NotificationException( - HttpStatus.BAD_REQUEST, NotificationErrorMessage.NOT_ALLOWED_NOTIFICATION_TYPE - ); + + String authorNickname = chat.getAuthor().getNickname(); + String message = authorNickname + ": " + content; + return basicChat(title, message); } - private static String confirmedChatMessage(String content, NotificationType type) { - if (type == NotificationType.MOIM_PLACE_CONFIRMED) { - return "장소가 '" + content + "' 로 확정되었어요!"; - } - return "시간이 '" + content + "' 로 확정되었어요!"; + private static ChatNotification placeConfirmChat(String title, String message) { + return new ChatNotification(title, NotificationType.MOIM_PLACE_CONFIRMED, message); + } + + private static ChatNotification dateTimeConfirmChat(String title, String message) { + return new ChatNotification(title, NotificationType.MOIM_TIME_CONFIRMED, message); + } + + private static ChatNotification basicChat(String title, String message) { + return new ChatNotification(title, NotificationType.NEW_CHAT, message); } } } diff --git a/backend/src/main/java/mouda/backend/chat/util/ChatDateTimeFormatter.java b/backend/src/main/java/mouda/backend/chat/util/ChatDateTimeFormatter.java new file mode 100644 index 000000000..870eba2f5 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/util/ChatDateTimeFormatter.java @@ -0,0 +1,51 @@ +package mouda.backend.chat.util; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; + +import org.springframework.http.HttpStatus; + +import lombok.NoArgsConstructor; +import mouda.backend.chat.exception.ChatErrorMessage; +import mouda.backend.chat.exception.ChatException; + +/** + * 채팅방에서 날짜와 시간이 확정될 때 알림 메시지에 사용되는 날짜 / 시간 형식 변환을 위한 유틸리티 클래스 + */ +@NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) +public class ChatDateTimeFormatter { + + private static final String DATETIME_DELIMITER = " "; + private static final int DATE_PART = 0; + private static final int TIME_PART = 1; + + public static String formatDateTime(String dateTime) { + LocalDateTime localDateTime = parseDateTime(dateTime); + StringBuilder formattedDateTime = new StringBuilder(); + + int year = localDateTime.getYear(); + if (year > LocalDate.now().getYear()) { + formattedDateTime.append(year).append("년 "); + } + + return formattedDateTime + .append(localDateTime.getMonthValue()).append("월 ") + .append(localDateTime.getDayOfMonth()).append("일 ") + .append(localDateTime.getHour()).append("시 ") + .append(localDateTime.getMinute()).append("분") + .toString(); + } + + private static LocalDateTime parseDateTime(String dateTime) { + try { + String[] dateTimeParts = dateTime.split(DATETIME_DELIMITER); + LocalDate date = LocalDate.parse(dateTimeParts[DATE_PART]); + LocalTime time = LocalTime.parse(dateTimeParts[TIME_PART]); + + return LocalDateTime.of(date, time); + } catch (Exception e) { + throw new ChatException(HttpStatus.BAD_REQUEST, ChatErrorMessage.INVALID_DATE_TIME_FORMAT); + } + } +} diff --git a/backend/src/main/java/mouda/backend/chat/util/DateTimeFormatter.java b/backend/src/main/java/mouda/backend/chat/util/DateTimeFormatter.java deleted file mode 100644 index 12698a29b..000000000 --- a/backend/src/main/java/mouda/backend/chat/util/DateTimeFormatter.java +++ /dev/null @@ -1,14 +0,0 @@ -package mouda.backend.chat.util; - -import java.time.LocalDate; -import java.time.LocalTime; - -public class DateTimeFormatter { - - public static String formatDateTime(LocalDate date, LocalTime time) { - return date.getMonth().getValue() + "월 " - + date.getDayOfMonth() + "일 " - + time.getHour() + "시 " - + time.getMinute() + "분"; - } -} diff --git a/backend/src/main/java/mouda/backend/darakbangmember/domain/DarakbangMember.java b/backend/src/main/java/mouda/backend/darakbangmember/domain/DarakbangMember.java index 7ca8c19a1..0477af7fa 100644 --- a/backend/src/main/java/mouda/backend/darakbangmember/domain/DarakbangMember.java +++ b/backend/src/main/java/mouda/backend/darakbangmember/domain/DarakbangMember.java @@ -116,7 +116,8 @@ public boolean hasImage() { public Author toAuthor() { return Author.builder() - .id(id) + .darakbangMemberId(id) + .memberId(memberId) .nickname(nickname) .profile(profile) .build(); diff --git a/backend/src/main/java/mouda/backend/moim/business/MoimService.java b/backend/src/main/java/mouda/backend/moim/business/MoimService.java index 3ec4129c3..36285574c 100644 --- a/backend/src/main/java/mouda/backend/moim/business/MoimService.java +++ b/backend/src/main/java/mouda/backend/moim/business/MoimService.java @@ -93,9 +93,10 @@ public void reopenMoim(Long darakbangId, Long moimId, DarakbangMember darakbangM public void editMoim(Long darakbangId, MoimEditRequest request, DarakbangMember darakbangMember) { Moim moim = moimFinder.read(request.moimId(), darakbangId); + String oldTitle = moim.getTitle(); moimWriter.updateMoim(moim, darakbangMember, request.title(), request.date(), request.time(), request.place(), request.maxPeople(), request.description()); - moimNotificationSender.sendMoimStatusChangedNotification(moim, NotificationType.MOIM_MODIFIED); + moimNotificationSender.sendMoimInfoModifiedNotification(moim, oldTitle, NotificationType.MOIM_MODIFIED); } } diff --git a/backend/src/main/java/mouda/backend/moim/domain/Chamyo.java b/backend/src/main/java/mouda/backend/moim/domain/Chamyo.java index 1c5f77793..8294e6996 100644 --- a/backend/src/main/java/mouda/backend/moim/domain/Chamyo.java +++ b/backend/src/main/java/mouda/backend/moim/domain/Chamyo.java @@ -58,4 +58,8 @@ public Chamyo(Moim moim, DarakbangMember darakbangMember, MoimRole moimRole) { public void updateLastChat(Long lastReadChatId) { this.lastReadChatId = lastReadChatId; } + + public boolean isNotSameMember(DarakbangMember darakbangMember) { + return !this.darakbangMember.equals(darakbangMember); + } } diff --git a/backend/src/main/java/mouda/backend/moim/domain/CommentRecipient.java b/backend/src/main/java/mouda/backend/moim/domain/CommentRecipient.java deleted file mode 100644 index dc3efff6a..000000000 --- a/backend/src/main/java/mouda/backend/moim/domain/CommentRecipient.java +++ /dev/null @@ -1,16 +0,0 @@ -package mouda.backend.moim.domain; - -import java.util.List; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import mouda.backend.notification.domain.NotificationType; -import mouda.backend.notification.domain.Recipient; - -@RequiredArgsConstructor -@Getter -public class CommentRecipient { - - private final NotificationType notificationType; - private final List recipients; -} diff --git a/backend/src/main/java/mouda/backend/moim/domain/CommentRecipients.java b/backend/src/main/java/mouda/backend/moim/domain/CommentRecipients.java new file mode 100644 index 000000000..e1470a327 --- /dev/null +++ b/backend/src/main/java/mouda/backend/moim/domain/CommentRecipients.java @@ -0,0 +1,40 @@ +package mouda.backend.moim.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import mouda.backend.notification.domain.NotificationType; +import mouda.backend.notification.domain.Recipient; + +@RequiredArgsConstructor +@Getter +@Builder +public class CommentRecipients { + + private final Map> recipients; + + public CommentRecipients() { + this.recipients = new ConcurrentHashMap<>(); + } + + public void addRecipient(NotificationType notificationType, long memberId, long darakbangMemberId) { + Recipient recipient = Recipient.builder() + .memberId(memberId) + .darakbangMemberId(darakbangMemberId) + .build(); + + if (recipients.containsKey(notificationType)) { + recipients.get(notificationType).add(recipient); + return; + } + + List recipientList = new ArrayList<>(); + recipientList.add(recipient); + recipients.put(notificationType, recipientList); + } +} diff --git a/backend/src/main/java/mouda/backend/moim/exception/MoimErrorMessage.java b/backend/src/main/java/mouda/backend/moim/exception/MoimErrorMessage.java index c5b4d1d54..0e86d97e4 100644 --- a/backend/src/main/java/mouda/backend/moim/exception/MoimErrorMessage.java +++ b/backend/src/main/java/mouda/backend/moim/exception/MoimErrorMessage.java @@ -24,7 +24,10 @@ public enum MoimErrorMessage { MOIM_FULL_FOR_REOPEN("모임이 꽉 차서 다시 열 수 없어요."), ALREADY_MOIMING("이미 모집 중인 모임이에요."), NOT_ALLOWED_TO_EDIT("방장만 수정할 수 있어요."), - MAX_PEOPLE_IS_LOWER_THAN_CURRENT_PEOPLE("모임 최대 인원을 현재 인원보다 작게 설정할 수 없어요."); + MAX_PEOPLE_IS_LOWER_THAN_CURRENT_PEOPLE("모임 최대 인원을 현재 인원보다 작게 설정할 수 없어요."), + + DARAKBANG_NOT_FOUND("이 모임의 다락방 정보를 찾을 수 없어요."), + ; private final String message; } diff --git a/backend/src/main/java/mouda/backend/moim/implement/finder/ChamyoRecipientFinder.java b/backend/src/main/java/mouda/backend/moim/implement/finder/ChamyoRecipientFinder.java index 73072fe6e..0063ae6dc 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/finder/ChamyoRecipientFinder.java +++ b/backend/src/main/java/mouda/backend/moim/implement/finder/ChamyoRecipientFinder.java @@ -16,11 +16,16 @@ public class ChamyoRecipientFinder { private final ChamyoRepository chamyoRepository; - public List getChamyoNotificationRecipients(long moimId, DarakbangMember darakbangMember) { + public List getChamyoNotificationRecipients(long moimId, DarakbangMember updatedMember) { List chamyos = chamyoRepository.findAllByMoimId(moimId); return chamyos.stream() - .filter(chamyo -> chamyo.getDarakbangMember().getId() != darakbangMember.getId()) - .map(chamyo -> new Recipient(chamyo.getDarakbangMember().getMemberId(), chamyo.getDarakbangMember().getId())) + .filter(chamyo -> chamyo.isNotSameMember(updatedMember)) + .map(Chamyo::getDarakbangMember) + .map(darakbangMember -> Recipient.builder() + .darakbangMemberId(darakbangMember.getId()) + .memberId(darakbangMember.getMemberId()) + .build() + ) .toList(); } } diff --git a/backend/src/main/java/mouda/backend/moim/implement/finder/ChatRecipientFinder.java b/backend/src/main/java/mouda/backend/moim/implement/finder/ChatRecipientFinder.java index 1174e06e7..8ebe56b3a 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/finder/ChatRecipientFinder.java +++ b/backend/src/main/java/mouda/backend/moim/implement/finder/ChatRecipientFinder.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import mouda.backend.bet.entity.BetDarakbangMemberEntity; import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.chat.domain.Author; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Chamyo; import mouda.backend.moim.infrastructure.ChamyoRepository; @@ -20,29 +21,52 @@ public class ChatRecipientFinder { private final ChamyoRepository chamyoRepository; private final BetDarakbangMemberRepository betDarakbangMemberRepository; - public List getMoimChatNotificationRecipients(long moimId, DarakbangMember sender) { + public List getMoimChatNotificationRecipients(long moimId, Author author) { List chamyos = chamyoRepository.findAllByMoimId(moimId); Stream darakbangMemberStream = chamyos.stream() .map(Chamyo::getDarakbangMember); - return getNotificationRecipients(darakbangMemberStream, sender); + return getNotificationRecipients(darakbangMemberStream, author); } - public List getBetChatNotificationRecipients(long betId, DarakbangMember sender) { - List members = betDarakbangMemberRepository.findAllByDarakbangMemberId( - betId); + public List getBetChatNotificationRecipients(long betId, Author author) { + List members = betDarakbangMemberRepository.findAllByBetId(betId); Stream darakbangMemberStream = members.stream() .map(BetDarakbangMemberEntity::getDarakbangMember); + return getNotificationRecipients(darakbangMemberStream, author); + } + + public List getNotificationRecipients(Stream memberStream, Author author) { + return memberStream + .filter(darakbangMember -> author.isNotSameMember(darakbangMember.getId(), darakbangMember.getMemberId())) + .map(darakbangMember -> Recipient.builder() + .memberId(darakbangMember.getMemberId()) + .darakbangMemberId(darakbangMember.getId()) + .build()) + .toList(); + } + + // todo: 구버전 채팅 기능 삭제시 같이 지워주세요. + public List getMoimChatNotificationRecipients(long moimId, DarakbangMember sender) { + List chamyos = chamyoRepository.findAllByMoimId(moimId); + + Stream darakbangMemberStream = chamyos.stream() + .map(Chamyo::getDarakbangMember); + return getNotificationRecipients(darakbangMemberStream, sender); } + // todo: 구버전 채팅 기능 삭제시 같이 지워주세요. public List getNotificationRecipients(Stream memberStream, DarakbangMember sender) { return memberStream .filter(darakbangMember -> darakbangMember.isNotSameMemberWith(sender)) - .map(darakbangMember -> new Recipient(darakbangMember.getMemberId(), darakbangMember.getId())) + .map(darakbangMember -> Recipient.builder() + .memberId(darakbangMember.getMemberId()) + .darakbangMemberId(darakbangMember.getId()) + .build()) .toList(); } } diff --git a/backend/src/main/java/mouda/backend/moim/implement/finder/CommentRecipientFinder.java b/backend/src/main/java/mouda/backend/moim/implement/finder/CommentRecipientFinder.java index c22dd383f..ac4d883c2 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/finder/CommentRecipientFinder.java +++ b/backend/src/main/java/mouda/backend/moim/implement/finder/CommentRecipientFinder.java @@ -1,7 +1,5 @@ package mouda.backend.moim.implement.finder; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; import org.springframework.http.HttpStatus; @@ -11,7 +9,7 @@ import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Chamyo; import mouda.backend.moim.domain.Comment; -import mouda.backend.moim.domain.CommentRecipient; +import mouda.backend.moim.domain.CommentRecipients; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.exception.ChamyoErrorMessage; import mouda.backend.moim.exception.ChamyoException; @@ -20,7 +18,6 @@ import mouda.backend.moim.infrastructure.ChamyoRepository; import mouda.backend.moim.infrastructure.CommentRepository; import mouda.backend.notification.domain.NotificationType; -import mouda.backend.notification.domain.Recipient; @Component @RequiredArgsConstructor @@ -29,7 +26,7 @@ public class CommentRecipientFinder { private final ChamyoRepository chamyoRepository; private final CommentRepository commentRepository; - public List getAllRecipient(Comment comment) { + public CommentRecipients getAllRecipient(Comment comment) { if (comment.isComment()) { return getCommentRecipientWhenComment(comment); } @@ -39,18 +36,18 @@ public List getAllRecipient(Comment comment) { // 댓글 // 작성자가 방장인 경우: 아무에게도 알림을 보내지 않음. // 작성자가 방장이 아닌 경우: 방장에게 '댓글' 알림을 보냄. - private List getCommentRecipientWhenComment(Comment comment) { - List result = new ArrayList<>(); + private CommentRecipients getCommentRecipientWhenComment(Comment comment) { + CommentRecipients commentRecipients = new CommentRecipients(); + Moim moim = comment.getMoim(); DarakbangMember moimer = getMoimer(moim); DarakbangMember author = comment.getDarakbangMember(); if (moimer.isNotSameMemberWith(author)) { - result.add(new CommentRecipient(NotificationType.NEW_COMMENT, - List.of(new Recipient(moimer.getMemberId(), moimer.getId())))); + commentRecipients.addRecipient(NotificationType.NEW_COMMENT, moimer.getMemberId(), moimer.getId()); } - return result; + return commentRecipients; } // 답글 @@ -61,9 +58,11 @@ private List getCommentRecipientWhenComment(Comment comment) { // -> 원 댓글 작성자가 방장인 경우: 방장에게만 답글 알림 // -> 원 댓글 작성자가 자신인 경우: 방장에게만 댓글 알림 // -> 원 댓글 작성자가 방장이 아닌 경우: 원 댓글 작성자에게는 답글 알림, 방장에게는 댓글 알림. - private List getCommentRecipientWhenReply(Comment comment) { - List result = new ArrayList<>(); + private CommentRecipients getCommentRecipientWhenReply(Comment comment) { + CommentRecipients commentRecipients = new CommentRecipients(); + Moim moim = comment.getMoim(); + DarakbangMember moimer = getMoimer(moim); DarakbangMember author = comment.getDarakbangMember(); DarakbangMember parentAuthor = commentRepository.findParentCommentByParentId(comment.getParentId()) @@ -74,27 +73,23 @@ private List getCommentRecipientWhenReply(Comment comment) { if (author.isSameMemberWith(moimer)) { // 원 댓글 작성자가 방장이 아닌 경우 if (parentAuthor.isNotSameMemberWith(moimer)) { - result.add(new CommentRecipient(NotificationType.NEW_REPLY, - List.of(new Recipient(parentAuthor.getMemberId(), parentAuthor.getId())))); + commentRecipients.addRecipient(NotificationType.NEW_REPLY, parentAuthor.getMemberId(), parentAuthor.getId()); } } else { // 작성자가 방장이 아닌 경우 if (parentAuthor.isSameMemberWith(moimer)) { // 원 댓글 작성자가 방장인 경우 - result.add(new CommentRecipient(NotificationType.NEW_REPLY, - List.of(new Recipient(moimer.getMemberId(), moimer.getId())))); + commentRecipients.addRecipient(NotificationType.NEW_REPLY, moimer.getMemberId(), moimer.getId()); } else { // 원 댓글 작성자가 방장이 아닌 경우 if (parentAuthor.isNotSameMemberWith(author)) { - result.add(new CommentRecipient(NotificationType.NEW_REPLY, - List.of(new Recipient(parentAuthor.getMemberId(), parentAuthor.getId())))); + commentRecipients.addRecipient(NotificationType.NEW_REPLY, parentAuthor.getMemberId(), parentAuthor.getId()); } - result.add(new CommentRecipient(NotificationType.NEW_COMMENT, - List.of(new Recipient(moimer.getMemberId(), moimer.getId())))); + commentRecipients.addRecipient(NotificationType.NEW_COMMENT, moimer.getMemberId(), moimer.getId()); } } - return result; + return commentRecipients; } private DarakbangMember getMoimer(Moim moim) { diff --git a/backend/src/main/java/mouda/backend/moim/implement/finder/MoimRecipientFinder.java b/backend/src/main/java/mouda/backend/moim/implement/finder/MoimRecipientFinder.java index cf29becaa..2691dd4da 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/finder/MoimRecipientFinder.java +++ b/backend/src/main/java/mouda/backend/moim/implement/finder/MoimRecipientFinder.java @@ -24,16 +24,25 @@ public List getMoimCreatedNotificationRecipients(long darakbangId, lo return darakbangMembers.stream() .filter(darakbangMember -> darakbangMember.getId() != authorId) - .map(darakbangMember -> new Recipient(darakbangMember.getMemberId(), darakbangMember.getId())) + .map(darakbangMember -> Recipient.builder() + .memberId(darakbangMember.getMemberId()) + .darakbangMemberId(darakbangMember.getId()) + .build() + ) .toList(); } - public List getMoimStatusChangedNotificationRecipients(long moimId) { + public List getMoimModifiedNotificationRecipients(long moimId) { List chamyos = chamyoRepository.findAllByMoimId(moimId); return chamyos.stream() .filter(chamyo -> chamyo.getMoimRole() != MoimRole.MOIMER) - .map(chamyo -> new Recipient(chamyo.getDarakbangMember().getMemberId(), chamyo.getDarakbangMember().getId())) + .map(Chamyo::getDarakbangMember) + .map(darakbangMember -> Recipient.builder() + .memberId(darakbangMember.getMemberId()) + .darakbangMemberId(darakbangMember.getId()) + .build() + ) .toList(); } } diff --git a/backend/src/main/java/mouda/backend/moim/implement/sender/CommentNotificationSender.java b/backend/src/main/java/mouda/backend/moim/implement/sender/CommentNotificationSender.java index 948586446..a14f7ec30 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/sender/CommentNotificationSender.java +++ b/backend/src/main/java/mouda/backend/moim/implement/sender/CommentNotificationSender.java @@ -9,7 +9,7 @@ import mouda.backend.common.config.UrlConfig; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Comment; -import mouda.backend.moim.domain.CommentRecipient; +import mouda.backend.moim.domain.CommentRecipients; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.implement.finder.CommentRecipientFinder; import mouda.backend.notification.domain.NotificationEvent; @@ -32,16 +32,14 @@ public CommentNotificationSender(UrlConfig urlConfig, CommentRecipientFinder com } public void sendCommentNotification(Comment comment, DarakbangMember author) { - List commentRecipients = commentRecipientFinder.getAllRecipient(comment); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(comment); - commentRecipients.forEach(commentRecipient -> { - sendNotification(commentRecipient, comment, author); - }); + commentRecipients.getRecipients() + .forEach((type, recipients) -> sendNotification(type, recipients, comment, author)); } - private void sendNotification(CommentRecipient commentRecipient, Comment comment, DarakbangMember author) { - NotificationType notificationType = commentRecipient.getNotificationType(); - List recipients = commentRecipient.getRecipients(); + private void sendNotification(NotificationType notificationType, List recipients, Comment comment, + DarakbangMember author) { Moim moim = comment.getMoim(); NotificationEvent notificationEvent = NotificationEvent.nonChatEvent( notificationType, diff --git a/backend/src/main/java/mouda/backend/moim/implement/sender/MoimNotificationSender.java b/backend/src/main/java/mouda/backend/moim/implement/sender/MoimNotificationSender.java index 09ceeb40f..807151440 100644 --- a/backend/src/main/java/mouda/backend/moim/implement/sender/MoimNotificationSender.java +++ b/backend/src/main/java/mouda/backend/moim/implement/sender/MoimNotificationSender.java @@ -8,9 +8,13 @@ import mouda.backend.common.config.UrlConfig; import mouda.backend.darakbang.domain.Darakbang; +import mouda.backend.darakbang.exception.DarakbangErrorMessage; +import mouda.backend.darakbang.exception.DarakbangException; import mouda.backend.darakbang.infrastructure.DarakbangRepository; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.exception.MoimErrorMessage; +import mouda.backend.moim.exception.MoimException; import mouda.backend.moim.implement.finder.MoimRecipientFinder; import mouda.backend.notification.domain.NotificationEvent; import mouda.backend.notification.domain.NotificationType; @@ -36,50 +40,58 @@ public MoimNotificationSender(UrlConfig urlConfig, ApplicationEventPublisher eve public void sendMoimCreatedNotification(Moim moim, DarakbangMember author, NotificationType notificationType) { List recipients = moimRecipientFinder.getMoimCreatedNotificationRecipients(moim.getDarakbangId(), author.getId()); - Darakbang darakbang = darakbangRepository.findById(moim.getDarakbangId()) - .orElseThrow(IllegalArgumentException::new); - NotificationEvent notificationEvent = NotificationEvent.nonChatEvent( - notificationType, - darakbang.getName(), - MoimNotificationMessage.create(moim.getTitle(), notificationType), - getMoimUrl(darakbang.getId(), moim.getId()), - recipients - ); - eventPublisher.publishEvent(notificationEvent); + String message = MoimNotificationMessage.create(moim.getTitle(), notificationType); + + createEventAndPublish(notificationType, moim, message, recipients); } public void sendMoimStatusChangedNotification(Moim moim, NotificationType notificationType) { - List recipients = moimRecipientFinder.getMoimStatusChangedNotificationRecipients(moim.getId()); + String message = MoimNotificationMessage.create(moim.getTitle(), notificationType); + sendMoimModifiedNotification(moim, notificationType, message); + } + + public void sendMoimInfoModifiedNotification(Moim moim, String oldTitle, NotificationType notificationType) { + String message = MoimNotificationMessage.create(oldTitle, notificationType); + sendMoimModifiedNotification(moim, notificationType, message); + } + + private void sendMoimModifiedNotification(Moim moim, NotificationType notificationType, String message) { + List recipients = moimRecipientFinder.getMoimModifiedNotificationRecipients(moim.getId()); + createEventAndPublish(notificationType, moim, message, recipients); + } + + private void createEventAndPublish(NotificationType notificationType, Moim moim, String message, + List recipients) { Darakbang darakbang = darakbangRepository.findById(moim.getDarakbangId()) - .orElseThrow(IllegalArgumentException::new); + .orElseThrow(() -> new MoimException(HttpStatus.NOT_FOUND, MoimErrorMessage.DARAKBANG_NOT_FOUND)); + NotificationEvent notificationEvent = NotificationEvent.nonChatEvent( notificationType, darakbang.getName(), - MoimNotificationMessage.create(moim.getTitle(), notificationType), + message, getMoimUrl(darakbang.getId(), moim.getId()), recipients ); - eventPublisher.publishEvent(notificationEvent); } static class MoimNotificationMessage { - public static String create(String moimName, NotificationType type) { + public static String create(String moimTitle, NotificationType type) { if (type == NotificationType.MOIM_CREATED) { - return moimName + " 모임이 만들어졌어요!"; + return moimTitle + " 모임이 만들어졌어요!"; } if (type == NotificationType.MOIMING_COMPLETED) { - return moimName + " 모집이 마감되었어요!"; + return moimTitle + " 모집이 마감되었어요!"; } if (type == NotificationType.MOINING_REOPENED) { - return moimName + " 모집이 재개되었어요!"; + return moimTitle + " 모집이 재개되었어요!"; } if (type == NotificationType.MOIM_CANCELLED) { - return moimName + " 모임이 취소되었어요!"; + return moimTitle + " 모임이 취소되었어요!"; } if (type == NotificationType.MOIM_MODIFIED) { - return moimName + " 모임 정보가 변경되었어요!"; + return moimTitle + " 모임 정보가 변경되었어요!"; } throw new NotificationException( HttpStatus.BAD_REQUEST, NotificationErrorMessage.NOT_ALLOWED_NOTIFICATION_TYPE diff --git a/backend/src/main/java/mouda/backend/notification/domain/Recipient.java b/backend/src/main/java/mouda/backend/notification/domain/Recipient.java index d19510997..ab2d4f0bc 100644 --- a/backend/src/main/java/mouda/backend/notification/domain/Recipient.java +++ b/backend/src/main/java/mouda/backend/notification/domain/Recipient.java @@ -1,15 +1,14 @@ package mouda.backend.notification.domain; +import lombok.Builder; import lombok.Getter; +import lombok.RequiredArgsConstructor; @Getter +@RequiredArgsConstructor +@Builder public class Recipient { - private long memberId; - private long darakbangMemberId; - - public Recipient(long memberId, long darakbangMemberId) { - this.memberId = memberId; - this.darakbangMemberId = darakbangMemberId; - } + private final long memberId; + private final long darakbangMemberId; } diff --git a/backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientFinderTest.java b/backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientsFinderTest.java similarity index 66% rename from backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientFinderTest.java rename to backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientsFinderTest.java index 6b3e0e111..aab0fe3af 100644 --- a/backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientFinderTest.java +++ b/backend/src/test/java/mouda/backend/moim/implement/finder/CommentRecipientsFinderTest.java @@ -4,6 +4,7 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -16,14 +17,15 @@ import mouda.backend.common.fixture.MoimFixture; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Comment; -import mouda.backend.moim.domain.CommentRecipient; +import mouda.backend.moim.domain.CommentRecipients; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.implement.writer.MoimWriter; import mouda.backend.moim.infrastructure.CommentRepository; import mouda.backend.notification.domain.NotificationType; +import mouda.backend.notification.domain.Recipient; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class CommentRecipientFinderTest extends DarakbangSetUp { +class CommentRecipientsFinderTest extends DarakbangSetUp { @Autowired private CommentRecipientFinder commentRecipientFinder; @@ -50,7 +52,7 @@ class CommentTest { void getNewCommentNotificationRecipients_WhenAuthorMoimer() { Comment comment = createComment(darakbangAnna, null); - assertThat(commentRecipientFinder.getAllRecipient(comment)).isEmpty(); + assertThat(commentRecipientFinder.getAllRecipient(comment).getRecipients()).isEmpty(); } @DisplayName("댓글 작성자가 방장이 아니면 방장에게 알림을 보낸다.") @@ -58,11 +60,12 @@ void getNewCommentNotificationRecipients_WhenAuthorMoimer() { void getNewCommentNotificationRecipients_WhenAuthorNotMoimer() { Comment comment = createComment(darakbangHogee, null); - List results = commentRecipientFinder.getAllRecipient(comment); - assertThat(results).hasSize(1); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(comment); + Map> results = commentRecipients.getRecipients(); - CommentRecipient recipient = results.get(0); - assertThat(recipient.getRecipients()).extracting("memberId") + assertThat(results).hasSize(1); + assertThat(results.keySet()).containsExactly(NotificationType.NEW_COMMENT); + assertThat(results.get(NotificationType.NEW_COMMENT)).extracting("memberId") .containsExactly(darakbangAnna.getMemberId()); } } @@ -87,7 +90,10 @@ void setUp() { void getReplyNotificationRecipients_WhenAuthorMoimer() { Comment childComment = createComment(darakbangAnna, parentComment.getId()); - assertThat(commentRecipientFinder.getAllRecipient(childComment)).isEmpty(); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(childComment); + Map> results = commentRecipients.getRecipients(); + + assertThat(results).isEmpty(); } @DisplayName("방장 이외의 사람이 답글을 남기는 경우 방장에게 '답글' 알림을 보낸다.") @@ -95,12 +101,12 @@ void getReplyNotificationRecipients_WhenAuthorMoimer() { void getReplyNotificationRecipients_WhenAuthorNotMoimer() { Comment childComment = createComment(darakbangHogee, parentComment.getId()); - List results = commentRecipientFinder.getAllRecipient(childComment); - assertThat(results).hasSize(1); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(childComment); + Map> results = commentRecipients.getRecipients(); - CommentRecipient recipient = results.get(0); - assertThat(recipient.getNotificationType()).isEqualTo(NotificationType.NEW_REPLY); - assertThat(recipient.getRecipients()).extracting("memberId") + assertThat(results).hasSize(1); + assertThat(results.keySet()).containsExactly(NotificationType.NEW_REPLY); + assertThat(results.get(NotificationType.NEW_REPLY)).extracting("memberId") .containsExactly(darakbangAnna.getMemberId()); } } @@ -121,13 +127,14 @@ void setUp() { void getReplyNotificationRecipients_WhenAuthorMoimer() { Comment childComment = createComment(darakbangAnna, parentComment.getId()); - List results = commentRecipientFinder.getAllRecipient(childComment); - assertThat(results).hasSize(1); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(childComment); + Map> results = commentRecipients.getRecipients(); - CommentRecipient recipient = results.get(0); - assertThat(recipient.getNotificationType()).isEqualTo(NotificationType.NEW_REPLY); - assertThat(recipient.getRecipients()).extracting("memberId") + assertThat(results).hasSize(1); + assertThat(results.keySet()).containsExactly(NotificationType.NEW_REPLY); + assertThat(results.get(NotificationType.NEW_REPLY)).extracting("memberId") .containsExactly(darakbangHogee.getMemberId()); + } @DisplayName("방장 이외의 사람이 답글을 남기는 경우 방장에겐 '댓글' 알림을 보내고, 원 댓글 작성자에겐 '답글' 알림을 보낸다.") @@ -135,18 +142,15 @@ void getReplyNotificationRecipients_WhenAuthorMoimer() { void getReplyNotificationRecipients_WhenAuthorNotMoimer() { Comment childComment = createComment(darakbangManager, parentComment.getId()); - List results = commentRecipientFinder.getAllRecipient(childComment); - assertThat(results).hasSize(2); - - CommentRecipient replyRecipient = results.get(0); - assertThat(replyRecipient.getNotificationType()).isEqualTo(NotificationType.NEW_REPLY); - assertThat(replyRecipient.getRecipients()).extracting("memberId") - .containsExactly(darakbangHogee.getMemberId()); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(childComment); + Map> results = commentRecipients.getRecipients(); - CommentRecipient commentRecipient = results.get(1); - assertThat(commentRecipient.getNotificationType()).isEqualTo(NotificationType.NEW_COMMENT); - assertThat(commentRecipient.getRecipients()).extracting("memberId") + assertThat(results).hasSize(2); + assertThat(results.keySet()).containsExactlyInAnyOrder(NotificationType.NEW_COMMENT, NotificationType.NEW_REPLY); + assertThat(results.get(NotificationType.NEW_COMMENT)).extracting("memberId") .containsExactly(darakbangAnna.getMemberId()); + assertThat(results.get(NotificationType.NEW_REPLY)).extracting("memberId") + .containsExactly(darakbangHogee.getMemberId()); } @DisplayName("댓글 작성자가 자신에게 답글을 남기면 방장에게만 '댓글' 알림을 보낸다.") @@ -154,12 +158,12 @@ void getReplyNotificationRecipients_WhenAuthorNotMoimer() { void getReplyNotificationRecipients_WhenAuthorIsParentAuthor() { Comment childComment = createComment(darakbangHogee, parentComment.getId()); - List results = commentRecipientFinder.getAllRecipient(childComment); - assertThat(results).hasSize(1); + CommentRecipients commentRecipients = commentRecipientFinder.getAllRecipient(childComment); + Map> results = commentRecipients.getRecipients(); - CommentRecipient recipient = results.get(0); - assertThat(recipient.getNotificationType()).isEqualTo(NotificationType.NEW_COMMENT); - assertThat(recipient.getRecipients()).extracting("memberId") + assertThat(results).hasSize(1); + assertThat(results.keySet()).containsExactly(NotificationType.NEW_COMMENT); + assertThat(results.get(NotificationType.NEW_COMMENT)).extracting("memberId") .containsExactly(darakbangAnna.getMemberId()); } } diff --git a/backend/src/test/java/mouda/backend/moim/implement/finder/MoimRecipientFinderTest.java b/backend/src/test/java/mouda/backend/moim/implement/finder/MoimRecipientFinderTest.java index 1b3afe4f7..ef43af321 100644 --- a/backend/src/test/java/mouda/backend/moim/implement/finder/MoimRecipientFinderTest.java +++ b/backend/src/test/java/mouda/backend/moim/implement/finder/MoimRecipientFinderTest.java @@ -45,7 +45,7 @@ void getMoimCreatedNotificationRecipients() { @DisplayName("모임 상태 변화(모집마감, 모집재개, 모임정보변경, 모임장소/시간 확정)는 방장 제외 모임참여자 전원에게 알린다.") @Test - void getMoimStatusChangedNotificationRecipients() { + void getMoimModifiedNotificationRecipients() { // given Moim moim = MoimFixture.getCoffeeMoim(darakbang.getId()); Moim savedMoim = moimRepository.save(moim); @@ -64,7 +64,7 @@ void getMoimStatusChangedNotificationRecipients() { chamyoRepository.save(chamyoWithMoimeeHogee); // when - List recipients = moimRecipientFinder.getMoimStatusChangedNotificationRecipients(savedMoim.getId()); + List recipients = moimRecipientFinder.getMoimModifiedNotificationRecipients(savedMoim.getId()); //then assertThat(recipients).hasSize(1); diff --git a/backend/src/test/java/mouda/backend/notification/implement/filter/ChatRoomSubscriptionFilterTest.java b/backend/src/test/java/mouda/backend/notification/implement/filter/ChatRoomSubscriptionFilterTest.java index 9a74ea3ab..ac6bdea72 100644 --- a/backend/src/test/java/mouda/backend/notification/implement/filter/ChatRoomSubscriptionFilterTest.java +++ b/backend/src/test/java/mouda/backend/notification/implement/filter/ChatRoomSubscriptionFilterTest.java @@ -36,7 +36,11 @@ void filter_WhenTypeIsConfirmed() { "모임 제목", "메시지", "url", - List.of(new Recipient(hogee.getId(), darakbangHogee.getId())), + List.of(Recipient.builder() + .memberId(hogee.getId()) + .darakbangMemberId(darakbangHogee.getId()) + .build() + ), darakbang.getId(), 1L ); @@ -59,7 +63,11 @@ void filter_WhenUnsubscribed() { "모임 제목", "메시지", "url", - List.of(new Recipient(darakbangHogee.getMemberId(), darakbangHogee.getId())), + List.of(Recipient.builder() + .memberId(darakbangHogee.getMemberId()) + .darakbangMemberId(darakbangHogee.getId()) + .build() + ), darakbang.getId(), 1L ); @@ -78,7 +86,11 @@ void filter_WhenSubscribed() { "모임 제목", "메시지", "url", - List.of(new Recipient(darakbangHogee.getMemberId(), darakbangHogee.getId())), + List.of(Recipient.builder() + .memberId(darakbangHogee.getMemberId()) + .darakbangMemberId(darakbangHogee.getId()) + .build() + ), darakbang.getId(), 1L );