diff --git a/backend/src/main/java/mouda/backend/bet/domain/Bet.java b/backend/src/main/java/mouda/backend/bet/domain/Bet.java index 649678d90..3ad70bbbb 100644 --- a/backend/src/main/java/mouda/backend/bet/domain/Bet.java +++ b/backend/src/main/java/mouda/backend/bet/domain/Bet.java @@ -56,6 +56,10 @@ public long getLoserId() { return loserId; } + public boolean isLoser(long otherId) { + return loserId == otherId; + } + public long getId() { return betDetails.getId(); } diff --git a/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java new file mode 100644 index 000000000..221799f47 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java @@ -0,0 +1,54 @@ +package mouda.backend.chat.business; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.ChatPreview; +import mouda.backend.chat.domain.ChatRoomDetails; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.implement.ChatPreviewManager; +import mouda.backend.chat.implement.ChatPreviewManagerRegistry; +import mouda.backend.chat.implement.ChatRoomDetailsFinder; +import mouda.backend.chat.implement.ChatRoomWriter; +import mouda.backend.chat.presentation.response.ChatPreviewResponses; +import mouda.backend.chat.presentation.response.ChatRoomDetailsResponse; +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; + +@Service +@Transactional +@RequiredArgsConstructor +public class ChatRoomService { + + private final ChatRoomDetailsFinder chatRoomDetailsFinder; + private final ChatPreviewManagerRegistry chatPreviewManagerRegistry; + private final ChatRoomWriter chatRoomWriter; + private final MoimFinder moimFinder; + private final MoimWriter moimWriter; + + @Transactional(readOnly = true) + public ChatRoomDetailsResponse findChatRoomDetails(long darakbangId, long chatRoomId, DarakbangMember darakbangMember) { + ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(darakbangId, chatRoomId, darakbangMember); + + return ChatRoomDetailsResponse.from(chatRoomDetails); + } + + @Transactional(readOnly = true) + public ChatPreviewResponses findChatPreview(DarakbangMember darakbangMember, ChatRoomType chatRoomType) { + ChatPreviewManager manager = chatPreviewManagerRegistry.getManager(chatRoomType); + List chatPreviews = manager.create(darakbangMember); + + return ChatPreviewResponses.toResponse(chatPreviews); + } + + public void openChatRoom(Long darakbangId, Long moimId, DarakbangMember darakbangMember) { + Moim moim = moimFinder.read(moimId, darakbangId); + moimWriter.openChatByMoimer(moim, darakbangMember); + chatRoomWriter.append(moimId, darakbangId, ChatRoomType.MOIM); + } +} 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 4c4a103a6..519aa7670 100644 --- a/backend/src/main/java/mouda/backend/chat/business/ChatService.java +++ b/backend/src/main/java/mouda/backend/chat/business/ChatService.java @@ -6,22 +6,16 @@ import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; -import mouda.backend.chat.domain.ChatPreview; import mouda.backend.chat.domain.ChatRoom; -import mouda.backend.chat.domain.ChatRoomType; import mouda.backend.chat.domain.ChatWithAuthor; import mouda.backend.chat.domain.Chats; -import mouda.backend.chat.implement.ChatPreviewManager; -import mouda.backend.chat.implement.ChatPreviewManagerRegistry; import mouda.backend.chat.implement.ChatRoomFinder; -import mouda.backend.chat.implement.ChatRoomWriter; import mouda.backend.chat.implement.ChatWriter; import mouda.backend.chat.presentation.request.ChatCreateRequest; import mouda.backend.chat.presentation.request.DateTimeConfirmRequest; 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.presentation.response.ChatPreviewResponses; import mouda.backend.darakbangmember.domain.DarakbangMember; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.implement.finder.MoimFinder; @@ -35,9 +29,7 @@ public class ChatService { private final ChatRoomFinder chatRoomFinder; private final ChatWriter chatWriter; private final MoimWriter moimWriter; - private final ChatPreviewManagerRegistry chatPreviewManagerRegistry; private final MoimFinder moimFinder; - private final ChatRoomWriter chatRoomWriter; public void createChat( long darakbangId, @@ -86,13 +78,6 @@ public void confirmDateTime(long darakbangId, long chatRoomId, DateTimeConfirmRe // notificationService.notifyToMembers(NotificationType.MOIM_TIME_CONFIRMED, darakbangId, moim, darakbangMember); } - public ChatPreviewResponses findChatPreview(DarakbangMember darakbangMember, ChatRoomType chatRoomType) { - ChatPreviewManager manager = chatPreviewManagerRegistry.getManager(chatRoomType); - List chatPreviews = manager.create(darakbangMember); - - return ChatPreviewResponses.toResponse(chatPreviews); - } - public void updateLastReadChat( long darakbangId, long chatRoomId, LastReadChatRequest request, DarakbangMember darakbangMember ) { @@ -100,10 +85,4 @@ public void updateLastReadChat( chatWriter.updateLastReadChat(chatRoom, darakbangMember, request.lastReadChatId()); } - - public void openChatRoom(Long darakbangId, Long moimId, DarakbangMember darakbangMember) { - Moim moim = moimFinder.read(moimId, darakbangId); - moimWriter.openChatByMoimer(moim, darakbangMember); - chatRoomWriter.append(moimId, darakbangId, ChatRoomType.MOIM); - } } diff --git a/backend/src/main/java/mouda/backend/chat/domain/Attributes.java b/backend/src/main/java/mouda/backend/chat/domain/Attributes.java new file mode 100644 index 000000000..1baeb1e34 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/Attributes.java @@ -0,0 +1,7 @@ +package mouda.backend.chat.domain; + +import java.util.Map; + +public interface Attributes { + Map getAttributes(); +} diff --git a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java new file mode 100644 index 000000000..78cea25ab --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java @@ -0,0 +1,36 @@ +package mouda.backend.chat.domain; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Getter; + +@Getter +public class BetAttributes implements Attributes { + + private final String title; + private final boolean isLoser; + private final long betId; + private final Participant loser; + + public BetAttributes(String title, Boolean isLoser, Long betId, Participant loser) { + this.title = title; + this.isLoser = isLoser; + this.betId = betId; + this.loser = loser; + } + + @Override + public Map getAttributes() { + Map attributes = new HashMap<>(); + attributes.put("title", title); + attributes.put("isLoser", isLoser); + attributes.put("betId", betId); + attributes.put("loser", Map.of( + "nickname", loser.getNickname(), + "profile", loser.getProfile(), + "role", loser.getRole() + )); + return attributes; + } +} diff --git a/backend/src/main/java/mouda/backend/chat/domain/ChatRoomDetails.java b/backend/src/main/java/mouda/backend/chat/domain/ChatRoomDetails.java new file mode 100644 index 000000000..934301471 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/ChatRoomDetails.java @@ -0,0 +1,29 @@ +package mouda.backend.chat.domain; + +import java.util.List; +import java.util.Map; + +import lombok.Getter; + +@Getter +public class ChatRoomDetails { + private final long id; + private final ChatRoomType chatRoomType; + private final Attributes attributes; + private final List participants; + + public ChatRoomDetails(long id, ChatRoomType chatRoomType, Attributes attributes, List participants) { + this.id = id; + this.chatRoomType = chatRoomType; + this.attributes = attributes; + this.participants = participants; + } + + public String getTitle() { + return (String)getAttributes().get("title"); + } + + public Map getAttributes() { + return attributes.getAttributes(); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java new file mode 100644 index 000000000..37d4f8417 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java @@ -0,0 +1,44 @@ +package mouda.backend.chat.domain; + +import java.util.HashMap; +import java.util.Map; + +import lombok.Getter; + +@Getter +public class MoimAttributes implements Attributes { + + private final String title; + private final String place; + private final Boolean isMoimer; + private final Boolean isStarted; + private final String description; + private final String date; + private final String time; + private final Long moimId; + + public MoimAttributes(String title, String place, Boolean isMoimer, Boolean isStarted, String description, String date, String time, Long moimId) { + this.title = title; + this.place = place; + this.isMoimer = isMoimer; + this.isStarted = isStarted; + this.description = description; + this.date = date; + this.time = time; + this.moimId = moimId; + } + + @Override + public Map getAttributes() { + Map attributes = new HashMap<>(); + attributes.put("title", title); + attributes.put("place", place); + attributes.put("isMoimer", isMoimer); + attributes.put("isStarted", isStarted); + attributes.put("description", description); + attributes.put("date", date); + attributes.put("time", time); + attributes.put("moimId", moimId); + return attributes; + } +} diff --git a/backend/src/main/java/mouda/backend/chat/domain/Participant.java b/backend/src/main/java/mouda/backend/chat/domain/Participant.java new file mode 100644 index 000000000..b804d9f8a --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/Participant.java @@ -0,0 +1,34 @@ +package mouda.backend.chat.domain; + +import java.util.Objects; + +import lombok.Getter; + +@Getter +public class Participant { + + private final String nickname; + private final String profile; + private final String role; + + public Participant(String nickname, String profile, String role) { + this.nickname = nickname; + this.profile = profile; + this.role = role; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Participant that = (Participant)o; + return Objects.equals(nickname, that.nickname) && Objects.equals(profile, that.profile) && Objects.equals(role, that.role); + } + + @Override + public int hashCode() { + return Objects.hash(nickname, profile, role); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/AttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/AttributeManager.java new file mode 100644 index 000000000..ddafc98e6 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/AttributeManager.java @@ -0,0 +1,13 @@ +package mouda.backend.chat.implement; + +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +public interface AttributeManager { + + boolean support(ChatRoomType chatRoomType); + + Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember); +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/AttributeManagerRegistry.java b/backend/src/main/java/mouda/backend/chat/implement/AttributeManagerRegistry.java new file mode 100644 index 000000000..46fd3802c --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/AttributeManagerRegistry.java @@ -0,0 +1,22 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.ChatRoomType; + +@Component +@RequiredArgsConstructor +public class AttributeManagerRegistry { + + private final List attributeManagers; + + public AttributeManager getManager(ChatRoomType chatRoomType) { + return attributeManagers.stream() + .filter(attributeManager -> attributeManager.support(chatRoomType)) + .findFirst() + .orElseThrow(IllegalArgumentException::new); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java new file mode 100644 index 000000000..c968366d5 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java @@ -0,0 +1,47 @@ +package mouda.backend.chat.implement; + +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import mouda.backend.bet.domain.Bet; +import mouda.backend.bet.domain.BetRole; +import mouda.backend.bet.implement.BetFinder; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.BetAttributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +@Component +@RequiredArgsConstructor +public class BetAttributeManager implements AttributeManager { + + private final BetFinder betFinder; + private final BetDarakbangMemberRepository betDarakbangMemberRepository; + + @Override + public boolean support(ChatRoomType chatRoomType) { + return chatRoomType == ChatRoomType.BET; + } + + @Override + public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { + Bet bet = betFinder.find(darakbangMember.getDarakbang().getId(), chatRoom.getTargetId()); + boolean isLoser = bet.isLoser(darakbangMember.getId()); + Participant loser = getLoser(bet, darakbangMember.getId()); + return new BetAttributes(bet.getBetDetails().getTitle(), isLoser, bet.getId(), loser); + } + + private Participant getLoser(Bet bet, long requestDarakbangMemberId) { + DarakbangMember darakbangMember = betDarakbangMemberRepository.findByBetIdAndDarakbangMemberId(bet.getId(), bet.getLoserId()) + .orElseThrow(IllegalArgumentException::new).getDarakbangMember(); // TODO: 예외 처리 리팩토링 + BetRole betRole = getBetRole(requestDarakbangMemberId, bet.getMoimerId()); + return new Participant(darakbangMember.getNickname(), darakbangMember.getProfile(), betRole.toString()); + } + + private BetRole getBetRole(long requestDarakbangMemberId, long moimerId) { + return moimerId == requestDarakbangMemberId ? BetRole.MOIMER : BetRole.MOIMEE; + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java b/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java new file mode 100644 index 000000000..746203ee1 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java @@ -0,0 +1,43 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import mouda.backend.bet.domain.BetRole; +import mouda.backend.bet.entity.BetEntity; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +@Component +@RequiredArgsConstructor +public class BetParticipantResolver implements ParticipantsResolver { + + private final BetDarakbangMemberRepository betDarakbangMemberRepository; + + @Override + public boolean support(ChatRoomType chatRoomType) { + return chatRoomType == ChatRoomType.BET; + } + + @Override + @Transactional(readOnly = true) + public List resolve(ChatRoom chatRoom) { + return betDarakbangMemberRepository.findAllByBetId(chatRoom.getTargetId()).stream() + .map(betDarakbangMemberEntity -> { + DarakbangMember darakbangMember = betDarakbangMemberEntity.getDarakbangMember(); + BetEntity bet = betDarakbangMemberEntity.getBet(); + return new Participant(darakbangMember.getNickname(), darakbangMember.getProfile(), getBetRole(darakbangMember, bet).toString()); + }) + .toList(); + } + + private BetRole getBetRole(DarakbangMember darakbangMember, BetEntity betEntity) { + return betEntity.getMoimerId() == darakbangMember.getId() ? BetRole.MOIMER : BetRole.MOIMEE; + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java new file mode 100644 index 000000000..9cc1f8401 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java @@ -0,0 +1,31 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomDetails; +import mouda.backend.chat.domain.Participant; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +@Component +@RequiredArgsConstructor +public class ChatRoomDetailsFinder { + + private final ChatRoomFinder chatRoomFinder; + private final AttributeManagerRegistry attributeManagerRegistry; + private final ParticipantResolverRegistry participantResolverRegistry; + + @Transactional(readOnly = true) + public ChatRoomDetails find(long darakbangId, long chatRoomId, DarakbangMember darakbangMember) { + ChatRoom chatRoom = chatRoomFinder.read(darakbangId, chatRoomId, darakbangMember); + Attributes attributes = attributeManagerRegistry.getManager(chatRoom.getType()).create(chatRoom, darakbangMember); + List participants = participantResolverRegistry.getResolver(chatRoom.getType()).resolve(chatRoom); + + return new ChatRoomDetails(chatRoomId, chatRoom.getType(), attributes, participants); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java new file mode 100644 index 000000000..1d327be5e --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java @@ -0,0 +1,55 @@ +package mouda.backend.chat.implement; + +import java.time.LocalTime; + +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.MoimAttributes; +import mouda.backend.darakbangmember.domain.DarakbangMember; +import mouda.backend.moim.domain.Chamyo; +import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.domain.MoimRole; +import mouda.backend.moim.implement.finder.ChamyoFinder; +import mouda.backend.moim.implement.finder.MoimFinder; + +@Component +@RequiredArgsConstructor +public class MoimAttributeManager implements AttributeManager { + + private final MoimFinder moimFinder; + private final ChamyoFinder chamyoFinder; + + @Override + public boolean support(ChatRoomType chatRoomType) { + return chatRoomType == ChatRoomType.MOIM; + } + + @Override + public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { + Moim moim = moimFinder.read(chatRoom.getTargetId(), darakbangMember.getDarakbang().getId()); + Chamyo chamyo = chamyoFinder.read(moim, darakbangMember); + boolean isMoimer = getIsMoimer(chamyo); + return new MoimAttributes( + moim.getTitle(), + moim.getPlace(), + isMoimer, + moim.isPastMoim(), + moim.getDescription(), + moim.getDate().toString(), + formatToSecondPrecision(moim.getTime()), + moim.getId() + ); + } + + private boolean getIsMoimer(Chamyo chamyo) { + return chamyo.getMoimRole() == MoimRole.MOIMER; + } + + private String formatToSecondPrecision(LocalTime time) { + return time.withNano(0).toString(); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/MoimParticipantResolver.java b/backend/src/main/java/mouda/backend/chat/implement/MoimParticipantResolver.java new file mode 100644 index 000000000..fc04b4151 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/MoimParticipantResolver.java @@ -0,0 +1,35 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; +import mouda.backend.darakbangmember.domain.DarakbangMember; +import mouda.backend.moim.infrastructure.ChamyoRepository; + +@Component +@RequiredArgsConstructor +public class MoimParticipantResolver implements ParticipantsResolver { + + private final ChamyoRepository chamyoRepository; + + @Override + public boolean support(ChatRoomType chatRoomType) { + return chatRoomType == ChatRoomType.MOIM; + } + + @Override + @Transactional + public List resolve(ChatRoom chatRoom) { + return chamyoRepository.findAllByMoimId(chatRoom.getTargetId()).stream() + .map(chamyo -> { + DarakbangMember darakbangMember = chamyo.getDarakbangMember(); + return new Participant(darakbangMember.getNickname(), darakbangMember.getProfile(), chamyo.getMoimRole().toString()); + }).toList(); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/ParticipantResolverRegistry.java b/backend/src/main/java/mouda/backend/chat/implement/ParticipantResolverRegistry.java new file mode 100644 index 000000000..e99b68712 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/ParticipantResolverRegistry.java @@ -0,0 +1,22 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.ChatRoomType; + +@Component +@RequiredArgsConstructor +public class ParticipantResolverRegistry { + + private final List participantsResolvers; + + public ParticipantsResolver getResolver(ChatRoomType chatRoomType) { + return participantsResolvers.stream() + .filter(participantsResolver -> participantsResolver.support(chatRoomType)) + .findFirst() + .orElseThrow(IllegalArgumentException::new); // TODO: 예외 처리 리팩토링 + } +} diff --git a/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java b/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java new file mode 100644 index 000000000..bf371b0b8 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java @@ -0,0 +1,14 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; + +public interface ParticipantsResolver { + + boolean support(ChatRoomType chatRoomType); + + List resolve(ChatRoom chatRoom); +} diff --git a/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatController.java b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatController.java index b9234c911..91c6bf352 100644 --- a/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatController.java +++ b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatController.java @@ -2,7 +2,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,13 +15,11 @@ import lombok.RequiredArgsConstructor; import mouda.backend.aop.logging.ExceptRequestLogging; import mouda.backend.chat.business.ChatService; -import mouda.backend.chat.domain.ChatRoomType; import mouda.backend.chat.presentation.request.ChatCreateRequest; import mouda.backend.chat.presentation.request.DateTimeConfirmRequest; 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.presentation.response.ChatPreviewResponses; import mouda.backend.common.config.argumentresolver.LoginDarakbangMember; import mouda.backend.common.response.RestResponse; import mouda.backend.darakbangmember.domain.DarakbangMember; @@ -63,19 +60,6 @@ public ResponseEntity> findUnloadedChats( return ResponseEntity.ok(new RestResponse<>(unloadedChats)); } - // @override - @GetMapping("/preview") - @ExceptRequestLogging - public ResponseEntity> findChatPreviews( - @PathVariable Long darakbangId, - @LoginDarakbangMember DarakbangMember darakbangMember, - @RequestParam("chatRoomType") ChatRoomType chatRoomType - ) { - ChatPreviewResponses chatPreviewResponses = chatService.findChatPreview(darakbangMember, chatRoomType); - - return ResponseEntity.ok(new RestResponse<>(chatPreviewResponses)); - } - // @override @PostMapping("/{chatRoomId}/last") public ResponseEntity createLastReadChatId( @@ -114,15 +98,4 @@ public ResponseEntity confirmPlace( return ResponseEntity.ok().build(); } - - @PatchMapping("/open") - public ResponseEntity openChatRoom( - @PathVariable Long darakbangId, - @LoginDarakbangMember DarakbangMember darakbangMember, - @RequestParam("moimId") Long moimId - ) { - chatService.openChatRoom(darakbangId, moimId, darakbangMember); - - return ResponseEntity.ok().build(); - } } diff --git a/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java new file mode 100644 index 000000000..eeb1c15d1 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java @@ -0,0 +1,61 @@ +package mouda.backend.chat.presentation.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; +import mouda.backend.aop.logging.ExceptRequestLogging; +import mouda.backend.chat.business.ChatRoomService; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.presentation.response.ChatPreviewResponses; +import mouda.backend.chat.presentation.response.ChatRoomDetailsResponse; +import mouda.backend.common.config.argumentresolver.LoginDarakbangMember; +import mouda.backend.common.response.RestResponse; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/v1/darakbang/{darakbangId}/chatroom") +public class ChatRoomController { + + private final ChatRoomService chatRoomService; + + @GetMapping("/{chatRoomId}/details") + public ResponseEntity> findChatRoomDetails( + @PathVariable Long darakbangId, + @PathVariable Long chatRoomId, + @LoginDarakbangMember DarakbangMember darakbangMember + ) { + ChatRoomDetailsResponse chatRoomDetails = chatRoomService.findChatRoomDetails(darakbangId, chatRoomId, darakbangMember); + + return ResponseEntity.ok(new RestResponse<>(chatRoomDetails)); + } + + @GetMapping("/preview") + @ExceptRequestLogging + public ResponseEntity> findChatPreviews( + @PathVariable Long darakbangId, + @LoginDarakbangMember DarakbangMember darakbangMember, + @RequestParam("chatRoomType") ChatRoomType chatRoomType + ) { + ChatPreviewResponses chatPreviewResponses = chatRoomService.findChatPreview(darakbangMember, chatRoomType); + + return ResponseEntity.ok(new RestResponse<>(chatPreviewResponses)); + } + + @PatchMapping("/open") + public ResponseEntity openChatRoom( + @PathVariable Long darakbangId, + @LoginDarakbangMember DarakbangMember darakbangMember, + @RequestParam("moimId") Long moimId + ) { + chatRoomService.openChatRoom(darakbangId, moimId, darakbangMember); + + return ResponseEntity.ok().build(); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/presentation/response/ChatPreviewResponses.java b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatPreviewResponses.java index 402dfdd86..f2bd9d5b1 100644 --- a/backend/src/main/java/mouda/backend/chat/presentation/response/ChatPreviewResponses.java +++ b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatPreviewResponses.java @@ -5,7 +5,7 @@ import mouda.backend.chat.domain.ChatPreview; public record ChatPreviewResponses( - List chatPreviewResponses + List previews ) { public static ChatPreviewResponses toResponse(List chatPreviewResponses) { diff --git a/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java new file mode 100644 index 000000000..46ec10c85 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java @@ -0,0 +1,31 @@ +package mouda.backend.chat.presentation.response; + +import java.util.List; +import java.util.Map; + +import mouda.backend.chat.domain.ChatRoomDetails; + +public record ChatRoomDetailsResponse( + long chatRoomId, + Map attributes, + String title, + String type, + List participations +) { + + public static ChatRoomDetailsResponse from(ChatRoomDetails chatRoomDetails) { + return new ChatRoomDetailsResponse( + chatRoomDetails.getId(), + chatRoomDetails.getAttributes(), + chatRoomDetails.getTitle(), + chatRoomDetails.getChatRoomType().toString(), + getParticipants(chatRoomDetails) + ); + } + + private static List getParticipants(ChatRoomDetails chatRoomDetails) { + return chatRoomDetails.getParticipants().stream() + .map(participant -> new ChatRoomParticipantResponse(participant.getNickname(), participant.getProfile(), participant.getRole())) + .toList(); + } +} diff --git a/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomParticipantResponse.java b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomParticipantResponse.java new file mode 100644 index 000000000..ac13bb6f6 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomParticipantResponse.java @@ -0,0 +1,8 @@ +package mouda.backend.chat.presentation.response; + +public record ChatRoomParticipantResponse( + String nickname, + String profile, + String role +) { +} diff --git a/backend/src/main/java/mouda/backend/moim/presentation/controller/ChatController.java b/backend/src/main/java/mouda/backend/moim/presentation/controller/ChatController.java index 15d05362c..1b7126cae 100644 --- a/backend/src/main/java/mouda/backend/moim/presentation/controller/ChatController.java +++ b/backend/src/main/java/mouda/backend/moim/presentation/controller/ChatController.java @@ -15,6 +15,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import mouda.backend.aop.logging.ExceptRequestLogging; +import mouda.backend.chat.business.ChatRoomService; import mouda.backend.chat.business.ChatService; import mouda.backend.chat.domain.ChatRoomType; import mouda.backend.chat.presentation.request.ChatCreateRequest; @@ -41,6 +42,7 @@ public class ChatController implements ChatSwagger { private final ChatService chatService; + private final ChatRoomService chatRoomService; @Override @PostMapping @@ -77,9 +79,9 @@ public ResponseEntity> findChatPreviews( @PathVariable Long darakbangId, @LoginDarakbangMember DarakbangMember darakbangMember ) { - ChatPreviewResponses chatPreviewResponses = chatService.findChatPreview(darakbangMember, ChatRoomType.MOIM); + ChatPreviewResponses chatPreviewResponses = chatRoomService.findChatPreview(darakbangMember, ChatRoomType.MOIM); - List previewResponses = chatPreviewResponses.chatPreviewResponses().stream() + List previewResponses = chatPreviewResponses.previews().stream() .map(chatPreviewResponse -> new ChatPreviewResponse(chatPreviewResponse.chatRoomId(), chatPreviewResponse.title(), chatPreviewResponse.currentPeople(), chatPreviewResponse.isStarted(), chatPreviewResponse.lastContent(), chatPreviewResponse.lastReadChatId())).toList(); OldChatPreviewResponses oldChatPreviewResponses = new OldChatPreviewResponses(previewResponses); @@ -131,7 +133,7 @@ public ResponseEntity openChatRoom( @LoginDarakbangMember DarakbangMember darakbangMember, @RequestParam("moimId") Long moimId ) { - chatService.openChatRoom(darakbangId, moimId, darakbangMember); + chatRoomService.openChatRoom(darakbangId, moimId, darakbangMember); return ResponseEntity.ok().build(); } diff --git a/backend/src/test/java/mouda/backend/chat/business/ChatRoomServiceTest.java b/backend/src/test/java/mouda/backend/chat/business/ChatRoomServiceTest.java new file mode 100644 index 000000000..936b65f3f --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/business/ChatRoomServiceTest.java @@ -0,0 +1,162 @@ +package mouda.backend.chat.business; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import mouda.backend.bet.entity.BetDarakbangMemberEntity; +import mouda.backend.bet.entity.BetEntity; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.bet.infrastructure.BetRepository; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.entity.ChatEntity; +import mouda.backend.chat.entity.ChatRoomEntity; +import mouda.backend.chat.infrastructure.ChatRepository; +import mouda.backend.chat.infrastructure.ChatRoomRepository; +import mouda.backend.chat.presentation.request.ChatCreateRequest; +import mouda.backend.chat.presentation.response.ChatPreviewResponse; +import mouda.backend.chat.presentation.response.ChatPreviewResponses; +import mouda.backend.common.fixture.BetEntityFixture; +import mouda.backend.common.fixture.ChatRoomEntityFixture; +import mouda.backend.common.fixture.DarakbangSetUp; +import mouda.backend.common.fixture.MoimFixture; +import mouda.backend.moim.domain.Chamyo; +import mouda.backend.moim.domain.ChatType; +import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.domain.MoimRole; +import mouda.backend.moim.infrastructure.ChamyoRepository; +import mouda.backend.moim.infrastructure.MoimRepository; + +@SpringBootTest +public class ChatRoomServiceTest extends DarakbangSetUp { + + @Autowired + ChatService chatService; + + @Autowired + ChatRoomService chatRoomService; + + @Autowired + MoimRepository moimRepository; + + @Autowired + ChamyoRepository chamyoRepository; + + @Autowired + ChatRoomRepository chatRoomRepository; + + @Autowired + ChatRepository chatRepository; + + @Autowired + BetRepository betRepository; + + @Autowired + BetDarakbangMemberRepository betDarakbangMemberRepository; + + @DisplayName("모임 채팅 미리보기를 조회한다.") + @Test + void findMoimChatPreview() { + // given + Moim moim = MoimFixture.getBasketballMoim(darakbang.getId()); + moim.openChat(); + Moim savedMoim = moimRepository.save(moim); + + Chamyo chamyo = chamyoRepository.save(new Chamyo(moim, darakbangHogee, MoimRole.MOIMEE)); + chamyoRepository.save(chamyo); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfMoim(savedMoim.getId(), + darakbang.getId()); + ChatRoomEntity chatRoom = chatRoomRepository.save(chatRoomEntity); + + sendChat(chatRoom); + + // when + ChatPreviewResponses moimChatPreviews = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); + + // then + assertThat(moimChatPreviews.previews()).hasSize(1); + assertThat(moimChatPreviews.previews().get(0).lastContent()).isEqualTo("안녕하세요"); + assertThat(moimChatPreviews.previews().get(0).lastReadChatId()).isEqualTo(0); + assertThat(moimChatPreviews.previews().get(0).currentPeople()).isEqualTo(1); + } + + @DisplayName("안내면진다 채팅 미리보기를 조회한다.") + @Test + void findBetChatPreview() { + // given + BetEntity betEntity = BetEntityFixture.getBetEntity(darakbang.getId(), darakbangHogee.getId()); + BetEntity savedBetEntity = betRepository.save(betEntity); + + BetDarakbangMemberEntity betDarakbangMemberEntity = new BetDarakbangMemberEntity(darakbangHogee, + savedBetEntity); + betDarakbangMemberRepository.save(betDarakbangMemberEntity); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfBet(betEntity.getId(), + darakbang.getId()); + ChatRoomEntity chatRoom = chatRoomRepository.save(chatRoomEntity); + + sendChat(chatRoom); + + // when + ChatPreviewResponses betChatPreviews = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.BET); + + // then + assertThat(betChatPreviews.previews().size()).isEqualTo(1); + assertThat(betChatPreviews.previews().get(0).lastContent()).isEqualTo("안녕하세요"); + assertThat(betChatPreviews.previews().get(0).lastReadChatId()).isEqualTo(0); + assertThat(betChatPreviews.previews().get(0).currentPeople()).isEqualTo(1); + } + + private void sendChat(ChatRoomEntity savedChatRoom) { + ChatEntity chatEntity = new ChatEntity("안녕하세요", savedChatRoom.getId(), darakbangHogee, LocalDate.now(), + LocalTime.now(), ChatType.BASIC); + chatRepository.save(chatEntity); + } + + @DisplayName("가장 최근에 생성된 채팅을 기준으로 채팅방 목록을 조회하고, 채팅이 없는 채팅방은 가장 아래에 위치한다.") + @Test + void findChatPreview_sortedByLastChatCreatedAt() { + Moim soccerMoim = moimRepository.save(MoimFixture.getSoccerMoim(darakbang.getId())); + Moim coffeeMoim = moimRepository.save(MoimFixture.getCoffeeMoim(darakbang.getId())); + Moim basketballMoim = moimRepository.save(MoimFixture.getBasketballMoim(darakbang.getId())); + + chamyoRepository.save(Chamyo.builder() + .moim(soccerMoim) + .darakbangMember(darakbangAnna) + .moimRole(MoimRole.MOIMER) + .build()); + + chamyoRepository.save(Chamyo.builder() + .moim(coffeeMoim) + .darakbangMember(darakbangAnna) + .moimRole(MoimRole.MOIMER) + .build()); + + chamyoRepository.save(Chamyo.builder() + .moim(basketballMoim) + .darakbangMember(darakbangAnna) + .moimRole(MoimRole.MOIMER) + .build()); + + chatRoomService.openChatRoom(darakbang.getId(), soccerMoim.getId(), darakbangAnna); + chatRoomService.openChatRoom(darakbang.getId(), coffeeMoim.getId(), darakbangAnna); + chatRoomService.openChatRoom(darakbang.getId(), basketballMoim.getId(), darakbangAnna); + + chatService.createChat(darakbang.getId(), 1L, new ChatCreateRequest("1번 채팅"), darakbangAnna); + chatService.createChat(darakbang.getId(), 2L, new ChatCreateRequest("2번 채팅"), darakbangAnna); + + List chatPreviewResponses = chatRoomService.findChatPreview(darakbangAnna, ChatRoomType.MOIM) + .previews(); + + assertThat(chatPreviewResponses).extracting(ChatPreviewResponse::lastContent) + .containsExactly("2번 채팅", "1번 채팅", ""); + } +} diff --git a/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java b/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java index 45c0d638b..f59768fb2 100644 --- a/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java +++ b/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java @@ -4,7 +4,6 @@ import java.time.LocalDate; import java.time.LocalTime; -import java.util.List; import java.util.Optional; import org.junit.jupiter.api.DisplayName; @@ -12,7 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import mouda.backend.bet.entity.BetDarakbangMemberEntity; import mouda.backend.bet.entity.BetEntity; import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; import mouda.backend.bet.infrastructure.BetRepository; @@ -27,7 +25,6 @@ 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.presentation.response.ChatPreviewResponse; import mouda.backend.chat.presentation.response.ChatPreviewResponses; import mouda.backend.common.fixture.BetEntityFixture; import mouda.backend.common.fixture.ChatEntityFixture; @@ -35,7 +32,6 @@ import mouda.backend.common.fixture.DarakbangSetUp; import mouda.backend.common.fixture.MoimFixture; import mouda.backend.moim.domain.Chamyo; -import mouda.backend.moim.domain.ChatType; import mouda.backend.moim.domain.Moim; import mouda.backend.moim.domain.MoimRole; import mouda.backend.moim.exception.ChamyoException; @@ -48,6 +44,9 @@ class ChatServiceTest extends DarakbangSetUp { @Autowired ChatService chatService; + @Autowired + ChatRoomService chatRoomService; + @Autowired MoimRepository moimRepository; @@ -282,8 +281,8 @@ void findChatPreview() { .build(); chamyoRepository.save(chamyo); - ChatPreviewResponses chatPreview = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); - assertThat(chatPreview.chatPreviewResponses()).isEmpty(); + ChatPreviewResponses chatPreview = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); + assertThat(chatPreview.previews()).isEmpty(); } @DisplayName("다락방별 채팅을 조회한다.") @@ -292,118 +291,19 @@ void readDarakbangChatPreview() { Moim darakbangMoim = MoimFixture.getSoccerMoim(darakbang.getId()); moimRepository.save(darakbangMoim); chamyoRepository.save(new Chamyo(darakbangMoim, darakbangHogee, MoimRole.MOIMER)); - chatService.openChatRoom(darakbang.getId(), darakbangMoim.getId(), darakbangHogee); + chatRoomService.openChatRoom(darakbang.getId(), darakbangMoim.getId(), darakbangHogee); chatRepository.save(ChatEntityFixture.getChatEntity(darakbangHogee)); - ChatPreviewResponses chatPreview = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); - assertThat(chatPreview.chatPreviewResponses()) + ChatPreviewResponses chatPreview = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); + assertThat(chatPreview.previews()) .hasSize(1); Moim moudaMoim = MoimFixture.getSoccerMoim(mouda.getId()); moimRepository.save(moudaMoim); chamyoRepository.save(new Chamyo(moudaMoim, moudaHogee, MoimRole.MOIMER)); - ChatPreviewResponses emptyChatPreview = chatService.findChatPreview(moudaHogee, ChatRoomType.MOIM); - assertThat(emptyChatPreview.chatPreviewResponses()) + ChatPreviewResponses emptyChatPreview = chatRoomService.findChatPreview(moudaHogee, ChatRoomType.MOIM); + assertThat(emptyChatPreview.previews()) .hasSize(0); } - - @DisplayName("모임 채팅 미리보기를 조회한다.") - @Test - void findMoimChatPreview() { - // given - Moim moim = MoimFixture.getBasketballMoim(darakbang.getId()); - moim.openChat(); - Moim savedMoim = moimRepository.save(moim); - - Chamyo chamyo = chamyoRepository.save(new Chamyo(moim, darakbangHogee, MoimRole.MOIMEE)); - chamyoRepository.save(chamyo); - - ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfMoim(savedMoim.getId(), - darakbang.getId()); - ChatRoomEntity chatRoom = chatRoomRepository.save(chatRoomEntity); - - sendChat(chatRoom); - - // when - ChatPreviewResponses moimChatPreviews = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); - - // then - assertThat(moimChatPreviews.chatPreviewResponses()).hasSize(1); - assertThat(moimChatPreviews.chatPreviewResponses().get(0).lastContent()).isEqualTo("안녕하세요"); - assertThat(moimChatPreviews.chatPreviewResponses().get(0).lastReadChatId()).isEqualTo(0); - assertThat(moimChatPreviews.chatPreviewResponses().get(0).currentPeople()).isEqualTo(1); - } - - @DisplayName("안내면진다 채팅 미리보기를 조회한다.") - @Test - void findBetChatPreview() { - // given - BetEntity betEntity = BetEntityFixture.getBetEntity(darakbang.getId(), darakbangHogee.getId()); - BetEntity savedBetEntity = betRepository.save(betEntity); - - BetDarakbangMemberEntity betDarakbangMemberEntity = new BetDarakbangMemberEntity(darakbangHogee, - savedBetEntity); - betDarakbangMemberRepository.save(betDarakbangMemberEntity); - - ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfBet(betEntity.getId(), - darakbang.getId()); - ChatRoomEntity chatRoom = chatRoomRepository.save(chatRoomEntity); - - sendChat(chatRoom); - - // when - ChatPreviewResponses betChatPreviews = chatService.findChatPreview(darakbangHogee, ChatRoomType.BET); - - // then - assertThat(betChatPreviews.chatPreviewResponses().size()).isEqualTo(1); - assertThat(betChatPreviews.chatPreviewResponses().get(0).lastContent()).isEqualTo("안녕하세요"); - assertThat(betChatPreviews.chatPreviewResponses().get(0).lastReadChatId()).isEqualTo(0); - assertThat(betChatPreviews.chatPreviewResponses().get(0).currentPeople()).isEqualTo(1); - } - - private void sendChat(ChatRoomEntity savedChatRoom) { - ChatEntity chatEntity = new ChatEntity("안녕하세요", savedChatRoom.getId(), darakbangHogee, LocalDate.now(), - LocalTime.now(), ChatType.BASIC); - chatRepository.save(chatEntity); - } - - @DisplayName("가장 최근에 생성된 채팅을 기준으로 채팅방 목록을 조회하고, 채팅이 없는 채팅방은 가장 아래에 위치한다.") - @Test - void findChatPreview_sortedByLastChatCreatedAt() { - Moim soccerMoim = moimRepository.save(MoimFixture.getSoccerMoim(darakbang.getId())); - Moim coffeeMoim = moimRepository.save(MoimFixture.getCoffeeMoim(darakbang.getId())); - Moim basketballMoim = moimRepository.save(MoimFixture.getBasketballMoim(darakbang.getId())); - - chamyoRepository.save(Chamyo.builder() - .moim(soccerMoim) - .darakbangMember(darakbangAnna) - .moimRole(MoimRole.MOIMER) - .build()); - - chamyoRepository.save(Chamyo.builder() - .moim(coffeeMoim) - .darakbangMember(darakbangAnna) - .moimRole(MoimRole.MOIMER) - .build()); - - chamyoRepository.save(Chamyo.builder() - .moim(basketballMoim) - .darakbangMember(darakbangAnna) - .moimRole(MoimRole.MOIMER) - .build()); - - chatService.openChatRoom(darakbang.getId(), soccerMoim.getId(), darakbangAnna); - chatService.openChatRoom(darakbang.getId(), coffeeMoim.getId(), darakbangAnna); - chatService.openChatRoom(darakbang.getId(), basketballMoim.getId(), darakbangAnna); - - chatService.createChat(darakbang.getId(), 1L, new ChatCreateRequest("1번 채팅"), darakbangAnna); - chatService.createChat(darakbang.getId(), 2L, new ChatCreateRequest("2번 채팅"), darakbangAnna); - - List chatPreviewResponses = chatService.findChatPreview(darakbangAnna, ChatRoomType.MOIM) - .chatPreviewResponses(); - - assertThat(chatPreviewResponses).extracting(ChatPreviewResponse::lastContent) - .containsExactly("2번 채팅", "1번 채팅", ""); - } } diff --git a/backend/src/test/java/mouda/backend/chat/implement/AttributeManagerRegistryTest.java b/backend/src/test/java/mouda/backend/chat/implement/AttributeManagerRegistryTest.java new file mode 100644 index 000000000..b92e12b0e --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/AttributeManagerRegistryTest.java @@ -0,0 +1,40 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import mouda.backend.chat.domain.ChatRoomType; + +@SpringBootTest +class AttributeManagerRegistryTest { + + @Autowired + AttributeManagerRegistry attributeManagerRegistry; + + @Autowired + MoimAttributeManager moimAttributeManager; + + @Autowired + BetAttributeManager betAttributeManager; + + @DisplayName("채팅방 타입에 맞는 매니저를 가져온다.") + @ParameterizedTest + @CsvSource({ + "MOIM", + "BET" + }) + void getManager(ChatRoomType chatRoomType) { + // given + // when + AttributeManager result = attributeManagerRegistry.getManager(chatRoomType); + + // then + assertThat(result.support(chatRoomType)).isTrue(); + } + +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java new file mode 100644 index 000000000..2cdb509b5 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java @@ -0,0 +1,140 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDateTime; +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import mouda.backend.bet.domain.Bet; +import mouda.backend.bet.domain.BetDetails; +import mouda.backend.bet.entity.BetDarakbangMemberEntity; +import mouda.backend.bet.entity.BetEntity; +import mouda.backend.bet.implement.BetFinder; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.BetAttributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.darakbang.domain.Darakbang; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +class BetAttributeManagerTest { + + @Mock + private BetFinder betFinder; + + @Mock + private BetDarakbangMemberRepository betDarakbangMemberRepository; + + @InjectMocks + private BetAttributeManager betAttributeManager; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @DisplayName("안내면진다 채팅방을 지원한다.") + @Test + void support_shouldReturnTrueForBetType() { + // given + ChatRoomType chatRoomType = ChatRoomType.BET; + + // when + boolean result = betAttributeManager.support(chatRoomType); + + // then + assertThat(result).isTrue(); + } + + @DisplayName("안내면진다 채팅방이 아닌 채팅방은 지원하지 않는다.") + @Test + void support_shouldReturnFalseForNonBetType() { + // given + ChatRoomType chatRoomType = ChatRoomType.MOIM; + + // when + boolean result = betAttributeManager.support(chatRoomType); + + // then + assertThat(result).isFalse(); + } + + @DisplayName("안내면진다 어트리뷰트를 반환한다.") + @Test + void create_shouldReturnBetAttributes() { + // given + ChatRoom chatRoom = mock(ChatRoom.class); + DarakbangMember darakbangMember = mock(DarakbangMember.class); + Darakbang darakbang = mock(Darakbang.class); + Bet bet = mock(Bet.class); + + when(chatRoom.getTargetId()).thenReturn(1L); + when(darakbangMember.getDarakbang()).thenReturn(darakbang); + when(darakbang.getId()).thenReturn(1L); + + when(betFinder.find(1L, 1L)).thenReturn(bet); + when(bet.getBetDetails()).thenReturn(new BetDetails(1L, "test bet", LocalDateTime.of(2024, 6, 5, 12, 3))); + when(bet.isLoser(darakbangMember.getId())).thenReturn(true); + when(bet.getId()).thenReturn(1L); + when(bet.getLoserId()).thenReturn(2L); + when(bet.getMoimerId()).thenReturn(1L); + + DarakbangMember loserMember = mock(DarakbangMember.class); + when(loserMember.getNickname()).thenReturn("loserNick"); + when(loserMember.getProfile()).thenReturn("profilePic"); + BetEntity betEntity = BetEntity.builder() + .id(1L) + .bettingTime(LocalDateTime.now()) + .title("test bet") + .moimerId(1L) + .loserDarakbangMemberId(2L) + .darakbangId(2L) + .build(); + when(betDarakbangMemberRepository.findByBetIdAndDarakbangMemberId(1L, 2L)) + .thenReturn(Optional.of(new BetDarakbangMemberEntity(loserMember, betEntity))); + + // when + Attributes attributes = betAttributeManager.create(chatRoom, darakbangMember); + + // then + assertThat(attributes).isInstanceOf(BetAttributes.class); + BetAttributes betAttributes = (BetAttributes)attributes; + assertThat(betAttributes.isLoser()).isTrue(); + assertThat(betAttributes.getBetId()).isEqualTo(1L); + assertThat(betAttributes.getLoser().getNickname()).isEqualTo("loserNick"); + assertThat(betAttributes.getLoser().getProfile()).isEqualTo("profilePic"); + } + + @DisplayName("참여하지 않는 안내면진다의 어트리뷰트를 요청하면 예외를 발생한다.") + @Test + void create_shouldThrowExceptionWhenLoserNotFound() { + // given + ChatRoom chatRoom = mock(ChatRoom.class); + DarakbangMember darakbangMember = mock(DarakbangMember.class); + Darakbang darakbang = mock(Darakbang.class); + Bet bet = mock(Bet.class); + + when(chatRoom.getTargetId()).thenReturn(1L); + when(darakbangMember.getDarakbang()).thenReturn(darakbang); + when(darakbang.getId()).thenReturn(1L); + + when(betFinder.find(1L, 1L)).thenReturn(bet); + when(bet.getLoserId()).thenReturn(2L); + + when(betDarakbangMemberRepository.findByBetIdAndDarakbangMemberId(1L, 2L)) + .thenReturn(Optional.empty()); + + // when & then + assertThatThrownBy(() -> betAttributeManager.create(chatRoom, darakbangMember)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/BetParticipantResolverTest.java b/backend/src/test/java/mouda/backend/chat/implement/BetParticipantResolverTest.java new file mode 100644 index 000000000..a75971c1e --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/BetParticipantResolverTest.java @@ -0,0 +1,63 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import mouda.backend.bet.entity.BetDarakbangMemberEntity; +import mouda.backend.bet.entity.BetEntity; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.bet.infrastructure.BetRepository; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.Participant; +import mouda.backend.chat.entity.ChatRoomEntity; +import mouda.backend.chat.infrastructure.ChatRoomRepository; +import mouda.backend.common.fixture.BetEntityFixture; +import mouda.backend.common.fixture.ChatRoomEntityFixture; +import mouda.backend.common.fixture.DarakbangSetUp; + +@SpringBootTest +class BetParticipantResolverTest extends DarakbangSetUp { + + @Autowired + private BetDarakbangMemberRepository betDarakbangMemberRepository; + + @Autowired + private BetRepository betRepository; + + @Autowired + private BetParticipantResolver betParticipantResolver; + + @Autowired + private ChatRoomRepository chatRoomRepository; + + @DisplayName("모임 참여자 목록을 반환한다.") + @Test + void resolve_shouldReturnParticipantsForGivenChatRoom() { + // given + BetEntity betEntity = BetEntityFixture.getBetEntity(darakbang.getId(), darakbangAnna.getId()); + BetEntity savedBetEntity = betRepository.save(betEntity); + + BetDarakbangMemberEntity annaEntity = new BetDarakbangMemberEntity(darakbangAnna, savedBetEntity); + BetDarakbangMemberEntity hogeeEntity = new BetDarakbangMemberEntity(darakbangHogee, savedBetEntity); + betDarakbangMemberRepository.save(annaEntity); + betDarakbangMemberRepository.save(hogeeEntity); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfBet(betEntity.getId(), darakbang.getId()); + ChatRoomEntity savedChatRoomEntity = chatRoomRepository.save(chatRoomEntity); + ChatRoom chatRoom = new ChatRoom(savedChatRoomEntity); + + // when + List participants = betParticipantResolver.resolve(chatRoom); + + // then + assertThat(participants).hasSize(2); + assertThat(participants).extracting("nickname").containsExactlyInAnyOrder("anna", "hogee"); + assertThat(participants).extracting("role").containsExactlyInAnyOrder("MOIMER", "MOIMEE"); + } +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/ChatRoomDetailsFinderTest.java b/backend/src/test/java/mouda/backend/chat/implement/ChatRoomDetailsFinderTest.java new file mode 100644 index 000000000..28f36a1d2 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/ChatRoomDetailsFinderTest.java @@ -0,0 +1,143 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import mouda.backend.bet.entity.BetDarakbangMemberEntity; +import mouda.backend.bet.entity.BetEntity; +import mouda.backend.bet.infrastructure.BetDarakbangMemberRepository; +import mouda.backend.bet.infrastructure.BetRepository; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomDetails; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; +import mouda.backend.chat.entity.ChatRoomEntity; +import mouda.backend.chat.infrastructure.ChatRoomRepository; +import mouda.backend.common.fixture.BetEntityFixture; +import mouda.backend.common.fixture.ChatRoomEntityFixture; +import mouda.backend.common.fixture.DarakbangSetUp; +import mouda.backend.common.fixture.MoimFixture; +import mouda.backend.moim.domain.Chamyo; +import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.domain.MoimRole; +import mouda.backend.moim.infrastructure.ChamyoRepository; +import mouda.backend.moim.infrastructure.MoimRepository; + +@SpringBootTest +class ChatRoomDetailsFinderTest extends DarakbangSetUp { + + @Autowired + private ChatRoomDetailsFinder chatRoomDetailsFinder; + + @Autowired + private MoimRepository moimRepository; + + @Autowired + private ChamyoRepository chamyoRepository; + + @Autowired + private BetRepository betRepository; + + @Autowired + private BetDarakbangMemberRepository betDarakbangMemberRepository; + + @Autowired + private ChatRoomRepository chatRoomRepository; + + @DisplayName("모임 타입 채팅룸 디테일을 반환한다.") + @Test + void find_moimChatRoomType() { + // given + Moim moim = MoimFixture.getCoffeeMoim(darakbang.getId()); + Moim savedMoim = moimRepository.save(moim); + + Chamyo annaChamyo = Chamyo.builder() + .moim(moim) + .darakbangMember(darakbangAnna) + .moimRole(MoimRole.MOIMER) + .build(); + Chamyo hogeeChamyo = Chamyo.builder() + .moim(moim) + .darakbangMember(darakbangHogee) + .moimRole(MoimRole.MOIMEE) + .build(); + chamyoRepository.save(annaChamyo); + chamyoRepository.save(hogeeChamyo); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfMoim(moim.getId(), darakbang.getId()); + ChatRoomEntity savedChatRoomEntity = chatRoomRepository.save(chatRoomEntity); + ChatRoom chatRoom = new ChatRoom(savedChatRoomEntity); + + // when + ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(darakbang.getId(), chatRoom.getId(), darakbangAnna); + + // then + assertThat(chatRoomDetails.getChatRoomType()).isEqualTo(ChatRoomType.MOIM); + assertThat(chatRoomDetails.getTitle()).isEqualTo("커피 마실 사람?"); + assertThat(chatRoomDetails.getId()).isEqualTo(chatRoom.getId()); + assertThat(chatRoomDetails.getParticipants()).containsExactly(new Participant("anna", "profile", "MOIMER"), new Participant("hogee", "profile", "MOIMEE")); + assertThat(chatRoomDetails.getAttributes()) + .containsExactlyInAnyOrderEntriesOf(getExpectedMoimAttributes(savedMoim)); + } + + private Map getExpectedMoimAttributes(Moim moim) { + Map attributes = new HashMap<>(); + attributes.put("title", moim.getTitle()); + attributes.put("place", moim.getPlace()); + attributes.put("isMoimer", true); + attributes.put("isStarted", false); + attributes.put("description", moim.getDescription()); + attributes.put("date", moim.getDate().toString()); + attributes.put("time", moim.getTime().withNano(0).toString()); + attributes.put("moimId", 1L); + return attributes; + } + + @DisplayName("안내면진다 채팅룸 디테일을 반환한다.") + @Test + void find_betChatRoomType() { + // given + BetEntity betEntity = BetEntityFixture.getDrawedBetEntity(darakbang.getId(), darakbangAnna.getId()); + BetEntity savedBetEntity = betRepository.save(betEntity); + + BetDarakbangMemberEntity annaEntity = new BetDarakbangMemberEntity(darakbangAnna, savedBetEntity); + BetDarakbangMemberEntity hogeeEntity = new BetDarakbangMemberEntity(darakbangHogee, savedBetEntity); + betDarakbangMemberRepository.save(annaEntity); + betDarakbangMemberRepository.save(hogeeEntity); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfBet(betEntity.getId(), darakbang.getId()); + ChatRoomEntity savedChatRoomEntity = chatRoomRepository.save(chatRoomEntity); + ChatRoom chatRoom = new ChatRoom(savedChatRoomEntity); + + // when + ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(darakbang.getId(), chatRoom.getId(), darakbangAnna); + + // then + assertThat(chatRoomDetails.getChatRoomType()).isEqualTo(ChatRoomType.BET); + assertThat(chatRoomDetails.getTitle()).isEqualTo("테바바보"); + assertThat(chatRoomDetails.getId()).isEqualTo(chatRoom.getId()); + assertThat(chatRoomDetails.getParticipants()).containsExactly(new Participant("anna", "profile", "MOIMER"), new Participant("hogee", "profile", "MOIMEE")); + assertThat(chatRoomDetails.getAttributes()) + .containsExactlyInAnyOrderEntriesOf(getExpectedBetAttributes(savedBetEntity)); + } + + private Map getExpectedBetAttributes(BetEntity bet) { + Map attributes = new HashMap<>(); + attributes.put("title", bet.getTitle()); + attributes.put("isLoser", true); + attributes.put("betId", bet.getId()); + attributes.put("loser", Map.of( + "nickname", "anna", + "profile", "profile", + "role", "MOIMER" + )); + return attributes; + } +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java new file mode 100644 index 000000000..3a8f6ca78 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java @@ -0,0 +1,107 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDate; +import java.time.LocalTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import mouda.backend.chat.domain.Attributes; +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.MoimAttributes; +import mouda.backend.darakbang.domain.Darakbang; +import mouda.backend.darakbangmember.domain.DarakbangMember; +import mouda.backend.moim.domain.Chamyo; +import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.domain.MoimRole; +import mouda.backend.moim.implement.finder.ChamyoFinder; +import mouda.backend.moim.implement.finder.MoimFinder; + +class MoimAttributeManagerTest { + + @Mock + private MoimFinder moimFinder; + + @Mock + private ChamyoFinder chamyoFinder; + + @InjectMocks + private MoimAttributeManager moimAttributeManager; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @DisplayName("모임 타입 채팅방을 지원한다.") + @Test + void support_shouldReturnTrueForMoimType() { + // given + ChatRoomType chatRoomType = ChatRoomType.MOIM; + + // when + boolean result = moimAttributeManager.support(chatRoomType); + + // then + assertThat(result).isTrue(); + } + + @DisplayName("모임 타입 이외의 채팅방을 지원하지 않는다.") + @Test + void support_shouldReturnFalseForNonMoimType() { + // given + ChatRoomType chatRoomType = ChatRoomType.BET; + + // when + boolean result = moimAttributeManager.support(chatRoomType); + + // then + assertThat(result).isFalse(); + } + + @DisplayName("모임 어트리뷰트를 생성한다가.") + @Test + void create_shouldReturnMoimAttributes() { + // given + ChatRoom chatRoom = mock(ChatRoom.class); + DarakbangMember darakbangMember = mock(DarakbangMember.class); + Moim moim = mock(Moim.class); + Chamyo chamyo = mock(Chamyo.class); + + when(chatRoom.getTargetId()).thenReturn(1L); + when(darakbangMember.getDarakbang()).thenReturn(mock(Darakbang.class)); + when(darakbangMember.getDarakbang().getId()).thenReturn(1L); + + when(moimFinder.read(1L, 1L)).thenReturn(moim); + when(chamyoFinder.read(moim, darakbangMember)).thenReturn(chamyo); + when(moim.getPlace()).thenReturn("우테코 잠실캠"); + when(moim.isPastMoim()).thenReturn(false); + when(moim.getDescription()).thenReturn("설명"); + when(moim.getDate()).thenReturn(LocalDate.of(3333, 1, 1)); + when(moim.getTime()).thenReturn(LocalTime.of(12, 12, 7, 13)); + when(moim.getId()).thenReturn(12L); + when(chamyo.getMoimRole()).thenReturn(MoimRole.MOIMER); + + // when + Attributes attributes = moimAttributeManager.create(chatRoom, darakbangMember); + + // then + assertThat(attributes).isInstanceOf(MoimAttributes.class); + MoimAttributes moimAttributes = (MoimAttributes)attributes; + assertThat(moimAttributes.getPlace()).isEqualTo("우테코 잠실캠"); + assertThat(moimAttributes.getIsMoimer()).isTrue(); + assertThat(moimAttributes.getIsStarted()).isFalse(); + assertThat(moimAttributes.getDescription()).isEqualTo("설명"); + assertThat(moimAttributes.getDate()).isEqualTo("3333-01-01"); + assertThat(moimAttributes.getTime()).isEqualTo("12:12:07"); + assertThat(moimAttributes.getMoimId()).isEqualTo(12L); + } +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/MoimParticipantResolverTest.java b/backend/src/test/java/mouda/backend/chat/implement/MoimParticipantResolverTest.java new file mode 100644 index 000000000..a4eed0c84 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/MoimParticipantResolverTest.java @@ -0,0 +1,72 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import mouda.backend.chat.domain.ChatRoom; +import mouda.backend.chat.domain.Participant; +import mouda.backend.chat.entity.ChatRoomEntity; +import mouda.backend.chat.infrastructure.ChatRoomRepository; +import mouda.backend.common.fixture.ChatRoomEntityFixture; +import mouda.backend.common.fixture.DarakbangSetUp; +import mouda.backend.common.fixture.MoimFixture; +import mouda.backend.moim.domain.Chamyo; +import mouda.backend.moim.domain.Moim; +import mouda.backend.moim.domain.MoimRole; +import mouda.backend.moim.infrastructure.ChamyoRepository; +import mouda.backend.moim.infrastructure.MoimRepository; + +@SpringBootTest +class MoimParticipantResolverTest extends DarakbangSetUp { + + @Autowired + private ChamyoRepository chamyoRepository; + + @Autowired + private MoimRepository moimRepository; + + @Autowired + private MoimParticipantResolver moimParticipantResolver; + + @Autowired + private ChatRoomRepository chatRoomRepository; + + @DisplayName("모임 참여자 목록을 반환한다.") + @Test + void resolve_shouldReturnParticipantsForGivenChatRoom() { + // given + Moim moim = MoimFixture.getCoffeeMoim(darakbang.getId()); + Moim savedMoim = moimRepository.save(moim); + + Chamyo annaChamyo = Chamyo.builder() + .moim(savedMoim) + .darakbangMember(darakbangAnna) + .moimRole(MoimRole.MOIMER) + .build(); + Chamyo hogeeChamyo = Chamyo.builder() + .moim(savedMoim) + .darakbangMember(darakbangHogee) + .moimRole(MoimRole.MOIMEE) + .build(); + chamyoRepository.save(annaChamyo); + chamyoRepository.save(hogeeChamyo); + + ChatRoomEntity chatRoomEntity = ChatRoomEntityFixture.getChatRoomEntityOfMoim(moim.getId(), darakbang.getId()); + ChatRoomEntity savedChatRoomEntity = chatRoomRepository.save(chatRoomEntity); + ChatRoom chatRoom = new ChatRoom(savedChatRoomEntity); + + // when + List participants = moimParticipantResolver.resolve(chatRoom); + + // then + assertThat(participants).hasSize(2); + assertThat(participants).extracting("nickname").containsExactlyInAnyOrder("anna", "hogee"); + assertThat(participants).extracting("role").containsExactlyInAnyOrder("MOIMER", "MOIMEE"); + } +} diff --git a/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java b/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java new file mode 100644 index 000000000..5af3160f5 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java @@ -0,0 +1,71 @@ +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.implement.ParticipantResolverRegistry; +import mouda.backend.chat.implement.ParticipantsResolver; + +class ParticipantResolverRegistryTest { + + @Mock + private ParticipantsResolver mockResolver1; + + @Mock + private ParticipantsResolver mockResolver2; + + @InjectMocks + private ParticipantResolverRegistry participantResolverRegistry; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @DisplayName("MOIM 타입 리졸버를 반환한다.") + @Test + void getResolver_shouldReturnCorrectResolverForSupportedChatRoomType() { + // given + ChatRoomType chatRoomType = ChatRoomType.MOIM; + + // when + when(mockResolver1.support(chatRoomType)).thenReturn(false); + when(mockResolver2.support(chatRoomType)).thenReturn(true); + + List resolvers = Arrays.asList(mockResolver1, mockResolver2); + participantResolverRegistry = new ParticipantResolverRegistry(resolvers); + + // when + ParticipantsResolver resolver = participantResolverRegistry.getResolver(chatRoomType); + + // then + assertThat(resolver).isEqualTo(mockResolver2); + } + + @DisplayName("BET 타입 리졸버를 반환한다.") + @Test + void getResolver_shouldThrowExceptionForUnsupportedChatRoomType() { + // given + ChatRoomType chatRoomType = ChatRoomType.BET; + + // when + when(mockResolver1.support(chatRoomType)).thenReturn(false); + when(mockResolver2.support(chatRoomType)).thenReturn(false); + + List resolvers = Arrays.asList(mockResolver1, mockResolver2); + participantResolverRegistry = new ParticipantResolverRegistry(resolvers); + + // then + assertThatThrownBy(() -> participantResolverRegistry.getResolver(chatRoomType)) + .isInstanceOf(IllegalArgumentException.class); + } +} diff --git a/backend/src/test/java/mouda/backend/common/fixture/DarakbangMemberFixture.java b/backend/src/test/java/mouda/backend/common/fixture/DarakbangMemberFixture.java index 90dc87058..7e117f8cf 100644 --- a/backend/src/test/java/mouda/backend/common/fixture/DarakbangMemberFixture.java +++ b/backend/src/test/java/mouda/backend/common/fixture/DarakbangMemberFixture.java @@ -22,7 +22,7 @@ public static DarakbangMember getDarakbangMemberWithWooteco(Darakbang darakbang, return DarakbangMember.builder() .darakbang(darakbang) .memberId(member.getId()) - .nickname("소소파파") + .nickname(member.getName()) .profile("profile") .description("description") .role(DarakBangMemberRole.MEMBER) diff --git a/backend/src/test/java/mouda/backend/darakbang/implement/DarakbangValidatorTest.java b/backend/src/test/java/mouda/backend/darakbang/implement/DarakbangValidatorTest.java index bf483682b..2d48122bb 100644 --- a/backend/src/test/java/mouda/backend/darakbang/implement/DarakbangValidatorTest.java +++ b/backend/src/test/java/mouda/backend/darakbang/implement/DarakbangValidatorTest.java @@ -63,7 +63,7 @@ void validateAlreadyEnteredMember() { Member anna = memberRepository.save(MemberFixture.getAnna()); - assertThatThrownBy(() -> darakbangValidator.validateCanEnterDarakbang(darakbang, "소소파파", anna)) + assertThatThrownBy(() -> darakbangValidator.validateCanEnterDarakbang(darakbang, "hogee", anna)) .isInstanceOf(DarakbangMemberException.class); } @@ -77,4 +77,4 @@ void validateAlreadyExistsCode() { assertThatThrownBy(() -> darakbangValidator.validateAlreadyExistsCode(wooteco.getCode())) .isInstanceOf(DarakbangException.class); } -} \ No newline at end of file +} diff --git a/backend/src/test/java/mouda/backend/darakbangmember/business/DarakbangMemberServiceTest.java b/backend/src/test/java/mouda/backend/darakbangmember/business/DarakbangMemberServiceTest.java index 262a8acf5..a56f4604e 100644 --- a/backend/src/test/java/mouda/backend/darakbangmember/business/DarakbangMemberServiceTest.java +++ b/backend/src/test/java/mouda/backend/darakbangmember/business/DarakbangMemberServiceTest.java @@ -82,7 +82,7 @@ void findMyInfo() { DarakbangMemberInfoResponse response = darakbangMemberService.findMyInfo(darakbangHogee); assertThat(response.name()).isEqualTo("hogee"); - assertThat(response.nickname()).isEqualTo("소소파파"); + assertThat(response.nickname()).isEqualTo("hogee"); assertThat(response.profile()).isEqualTo("profile"); assertThat(response.description()).isEqualTo("description"); }