From 535669d77c063ad92dcde6447c375a60ed653447 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 16:58:57 +0900 Subject: [PATCH 01/26] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EB=B3=84=20=EC=86=8D=EC=84=B1=EC=9D=84=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EA=B8=B0=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=B6=94=EC=83=81=ED=99=94=20=EA=B5=AC=ED=98=84=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=96=B4=20=ED=81=B4=EB=9E=98=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mouda/backend/chat/domain/Attributes.java | 7 ++++ .../chat/implement/AttributeManager.java | 13 ++++++ .../implement/AttributeManagerRegistry.java | 22 ++++++++++ .../AttributeManagerRegistryTest.java | 40 +++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/domain/Attributes.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/AttributeManager.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/AttributeManagerRegistry.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/AttributeManagerRegistryTest.java 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/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/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(); + } + +} From de1441940aec5fceda511b8ccb7f4a09074408d6 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 17:50:05 +0900 Subject: [PATCH 02/26] =?UTF-8?q?feat:=20BetAttributeManager=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mouda/backend/bet/domain/Bet.java | 4 + .../backend/chat/domain/BetAttributes.java | 24 +++ .../java/mouda/backend/chat/domain/Loser.java | 17 +++ .../chat/implement/BetAttributeManager.java | 47 ++++++ .../implement/BetAttributeManagerTest.java | 138 ++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java create mode 100644 backend/src/main/java/mouda/backend/chat/domain/Loser.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java 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/domain/BetAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java new file mode 100644 index 000000000..f06eb21f3 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java @@ -0,0 +1,24 @@ +package mouda.backend.chat.domain; + +import java.util.Map; + +import lombok.Getter; + +@Getter +public class BetAttributes implements Attributes { + + private Boolean isLoser; + private Long betId; + private Loser loser; + + public BetAttributes(Boolean isLoser, Long betId, Loser loser) { + this.isLoser = isLoser; + this.betId = betId; + this.loser = loser; + } + + @Override + public Map getAttributes() { + return null; + } +} diff --git a/backend/src/main/java/mouda/backend/chat/domain/Loser.java b/backend/src/main/java/mouda/backend/chat/domain/Loser.java new file mode 100644 index 000000000..49f243c6e --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/Loser.java @@ -0,0 +1,17 @@ +package mouda.backend.chat.domain; + +import lombok.Getter; + +@Getter +public class Loser { + + private String nickname; + private String profile; + private String role; + + public Loser(String nickname, String profile, String role) { + this.nickname = nickname; + this.profile = profile; + this.role = role; + } +} 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..d19fdd51c --- /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.Loser; +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()); + Loser loser = getLoser(bet, darakbangMember.getId()); + return new BetAttributes(isLoser, bet.getId(), loser); + } + + private Loser 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 Loser(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/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..b24e9b17d --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java @@ -0,0 +1,138 @@ +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.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.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.getIsLoser()).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); + } +} From e6c8c39f360fd606984be2f03c125db5c37392cc Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:03:29 +0900 Subject: [PATCH 03/26] =?UTF-8?q?feat:=20MoimAttributeManager=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/MoimAttributes.java | 32 ++++++ .../chat/implement/MoimAttributeManager.java | 48 +++++++++ .../implement/MoimAttributeManagerTest.java | 102 ++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java 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..dc5dab1ae --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java @@ -0,0 +1,32 @@ +package mouda.backend.chat.domain; + +import java.util.Map; + +import lombok.Getter; + +@Getter +public class MoimAttributes implements Attributes { + + private String place; + private Boolean isMoimer; + private Boolean isStarted; + private String description; + private String date; + private String time; + private Long moimId; + + public MoimAttributes(String place, Boolean isMoimer, Boolean isStarted, String description, String date, String time, Long moimId) { + 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() { + return null; + } +} 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..5e3bca1a1 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java @@ -0,0 +1,48 @@ +package mouda.backend.chat.implement; + +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.getPlace(), + isMoimer, + moim.isPastMoim(), + moim.getDescription(), + moim.getDate().toString(), + moim.getTime().toString(), + moim.getId() + ); + } + + private boolean getIsMoimer(Chamyo chamyo) { + return chamyo.getMoimRole() == MoimRole.MOIMER; + } +} 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..b0d7ab768 --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java @@ -0,0 +1,102 @@ +package mouda.backend.chat.implement; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.BeforeEach; +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); + } + + @Test + void support_shouldReturnTrueForMoimType() { + // given + ChatRoomType chatRoomType = ChatRoomType.MOIM; + + // when + boolean result = moimAttributeManager.support(chatRoomType); + + // then + assertThat(result).isTrue(); + } + + @Test + void support_shouldReturnFalseForNonMoimType() { + // given + ChatRoomType chatRoomType = ChatRoomType.BET; + + // when + boolean result = moimAttributeManager.support(chatRoomType); + + // then + assertThat(result).isFalse(); + } + + @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(mock(java.time.LocalDate.class)); + when(moim.getDate().toString()).thenReturn("3333-01-01"); + when(moim.getTime()).thenReturn(mock(java.time.LocalTime.class)); + when(moim.getTime().toString()).thenReturn("12:12:00"); + 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:00"); + assertThat(moimAttributes.getMoimId()).isEqualTo(12L); + } +} From e46dd3a24fc45249b6e4f2fd71cb18b6225c8381 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:13:51 +0900 Subject: [PATCH 04/26] =?UTF-8?q?feat:=20ParticipantResolver,=20Participan?= =?UTF-8?q?tResolverRegistry=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/Participant.java | 17 +++++ .../ParticipantResolverRegistry.java | 22 ++++++ .../chat/implement/ParticipantsResolver.java | 13 ++++ .../ParticipantResolverRegistryTest.java | 68 +++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/domain/Participant.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/ParticipantResolverRegistry.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java 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..eec889c2b --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/domain/Participant.java @@ -0,0 +1,17 @@ +package mouda.backend.chat.domain; + +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; + } +} 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..391e24c9c --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java @@ -0,0 +1,13 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +import mouda.backend.chat.domain.ChatRoomType; +import mouda.backend.chat.domain.Participant; + +public interface ParticipantsResolver { + + boolean support(ChatRoomType chatRoomType); + + List resolve(); +} 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..37c54f5fd --- /dev/null +++ b/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java @@ -0,0 +1,68 @@ +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.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); + } + + @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); + } + + @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); + } +} From ed25b6ba1e90b2a9cbf5d40ea439a6464e82daf0 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:15:02 +0900 Subject: [PATCH 05/26] =?UTF-8?q?test:=20DisplayName=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/implement/ParticipantResolverRegistryTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java b/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java index 37c54f5fd..5af3160f5 100644 --- a/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java +++ b/backend/src/test/java/mouda/backend/chat/implement/ParticipantResolverRegistryTest.java @@ -5,6 +5,7 @@ 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; @@ -30,6 +31,7 @@ void setUp() { MockitoAnnotations.openMocks(this); } + @DisplayName("MOIM 타입 리졸버를 반환한다.") @Test void getResolver_shouldReturnCorrectResolverForSupportedChatRoomType() { // given @@ -49,6 +51,7 @@ void getResolver_shouldReturnCorrectResolverForSupportedChatRoomType() { assertThat(resolver).isEqualTo(mockResolver2); } + @DisplayName("BET 타입 리졸버를 반환한다.") @Test void getResolver_shouldThrowExceptionForUnsupportedChatRoomType() { // given From f6f0b48c7ddace8843610d784b4ef96ddb2bccb4 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:56:22 +0900 Subject: [PATCH 06/26] =?UTF-8?q?test:=20darakbangmember=20nickname=20?= =?UTF-8?q?=EC=A3=BC=EC=9E=85=EB=B0=A9=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mouda/backend/common/fixture/DarakbangMemberFixture.java | 2 +- .../backend/darakbang/implement/DarakbangValidatorTest.java | 4 ++-- .../darakbangmember/business/DarakbangMemberServiceTest.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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"); } From ccce1a5c6bc28b27502caff934ab9ccc3bbd4f6a Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:56:52 +0900 Subject: [PATCH 07/26] =?UTF-8?q?feat:=20MoimParticipantResolver=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/MoimParticipantResolver.java | 35 +++++++++ .../chat/implement/ParticipantsResolver.java | 3 +- .../MoimParticipantResolverTest.java | 72 +++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/mouda/backend/chat/implement/MoimParticipantResolver.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/MoimParticipantResolverTest.java 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/ParticipantsResolver.java b/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java index 391e24c9c..bf371b0b8 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java +++ b/backend/src/main/java/mouda/backend/chat/implement/ParticipantsResolver.java @@ -2,6 +2,7 @@ import java.util.List; +import mouda.backend.chat.domain.ChatRoom; import mouda.backend.chat.domain.ChatRoomType; import mouda.backend.chat.domain.Participant; @@ -9,5 +10,5 @@ public interface ParticipantsResolver { boolean support(ChatRoomType chatRoomType); - List resolve(); + List resolve(ChatRoom chatRoom); } 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"); + } +} From b9d75bfd9613fd4068ab2794f91eb31886abd262 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Fri, 11 Oct 2024 18:57:02 +0900 Subject: [PATCH 08/26] =?UTF-8?q?feat:=20BetParticipantResolver=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/BetParticipantResolver.java | 43 +++++++++++++ .../implement/BetParticipantResolverTest.java | 63 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java create mode 100644 backend/src/test/java/mouda/backend/chat/implement/BetParticipantResolverTest.java 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..a4fb26457 --- /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 + 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/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"); + } +} From b8edfe3e57827919606df245004e047081ff7400 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 02:53:47 +0900 Subject: [PATCH 09/26] =?UTF-8?q?feat:=20attributes=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=B2=B4=EC=97=90=20title=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EA=B5=AC=ED=98=84=EC=B2=B4=20=EB=B3=84=20getAttri?= =?UTF-8?q?butes=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/BetAttributes.java | 23 ++++++++++---- .../backend/chat/domain/MoimAttributes.java | 30 +++++++++++++------ .../chat/implement/BetAttributeManager.java | 2 +- .../chat/implement/MoimAttributeManager.java | 1 + 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java index f06eb21f3..db0357e14 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java +++ b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java @@ -1,5 +1,6 @@ package mouda.backend.chat.domain; +import java.util.HashMap; import java.util.Map; import lombok.Getter; @@ -7,11 +8,13 @@ @Getter public class BetAttributes implements Attributes { - private Boolean isLoser; - private Long betId; - private Loser loser; + private final String title; + private final Boolean isLoser; + private final Long betId; + private final Loser loser; - public BetAttributes(Boolean isLoser, Long betId, Loser loser) { + public BetAttributes(String title, Boolean isLoser, Long betId, Loser loser) { + this.title = title; this.isLoser = isLoser; this.betId = betId; this.loser = loser; @@ -19,6 +22,16 @@ public BetAttributes(Boolean isLoser, Long betId, Loser loser) { @Override public Map getAttributes() { - return null; + 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/MoimAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java index dc5dab1ae..37d4f8417 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java +++ b/backend/src/main/java/mouda/backend/chat/domain/MoimAttributes.java @@ -1,5 +1,6 @@ package mouda.backend.chat.domain; +import java.util.HashMap; import java.util.Map; import lombok.Getter; @@ -7,15 +8,17 @@ @Getter public class MoimAttributes implements Attributes { - private String place; - private Boolean isMoimer; - private Boolean isStarted; - private String description; - private String date; - private String time; - private Long moimId; + 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 place, Boolean isMoimer, Boolean isStarted, String description, String date, String time, 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; @@ -27,6 +30,15 @@ public MoimAttributes(String place, Boolean isMoimer, Boolean isStarted, String @Override public Map getAttributes() { - return null; + 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/implement/BetAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java index d19fdd51c..2e0fa77de 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java +++ b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java @@ -31,7 +31,7 @@ public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { Bet bet = betFinder.find(darakbangMember.getDarakbang().getId(), chatRoom.getTargetId()); boolean isLoser = bet.isLoser(darakbangMember.getId()); Loser loser = getLoser(bet, darakbangMember.getId()); - return new BetAttributes(isLoser, bet.getId(), loser); + return new BetAttributes(bet.getBetDetails().getTitle(), isLoser, bet.getId(), loser); } private Loser getLoser(Bet bet, long requestDarakbangMemberId) { diff --git a/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java index 5e3bca1a1..17bda4ead 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java +++ b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java @@ -32,6 +32,7 @@ public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { Chamyo chamyo = chamyoFinder.read(moim, darakbangMember); boolean isMoimer = getIsMoimer(chamyo); return new MoimAttributes( + moim.getTitle(), moim.getPlace(), isMoimer, moim.isPastMoim(), From 05d120292d2a5ebadffc560c83b30163e68ef008 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 02:54:28 +0900 Subject: [PATCH 10/26] =?UTF-8?q?feat:=20ChatRoomDetails,=20ChatRoomDetail?= =?UTF-8?q?sFinder=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/ChatRoomDetails.java | 29 +++++++++++++++++++ .../chat/implement/ChatRoomDetailsFinder.java | 29 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/domain/ChatRoomDetails.java create mode 100644 backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java 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/implement/ChatRoomDetailsFinder.java b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java new file mode 100644 index 000000000..76baf69dd --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java @@ -0,0 +1,29 @@ +package mouda.backend.chat.implement; + +import java.util.List; + +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.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; + + public ChatRoomDetails find(long chatRoomId, DarakbangMember darakbangMember) { + ChatRoom chatRoom = chatRoomFinder.read(darakbangMember.getId(), 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); + } +} From 3384bff3b67132195606b360c40df78aa0129122 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 02:54:59 +0900 Subject: [PATCH 11/26] =?UTF-8?q?feat:=20ChatRoomService=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/business/ChatRoomService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java 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..410a75652 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java @@ -0,0 +1,22 @@ +package mouda.backend.chat.business; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.domain.ChatRoomDetails; +import mouda.backend.chat.implement.ChatRoomDetailsFinder; +import mouda.backend.chat.presentation.response.ChatRoomDetailsResponse; +import mouda.backend.darakbangmember.domain.DarakbangMember; + +@Service +@RequiredArgsConstructor +public class ChatRoomService { + + private final ChatRoomDetailsFinder chatRoomDetailsFinder; + + public ChatRoomDetailsResponse findChatRoomDetails(long chatRoomId, DarakbangMember darakbangMember) { + ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(chatRoomId, darakbangMember); + + return ChatRoomDetailsResponse.from(chatRoomDetails); + } +} From 0d3a6523ddf881a6de41f6343c7624eacd706dce Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 02:55:18 +0900 Subject: [PATCH 12/26] =?UTF-8?q?feat:=20ChatRoomDetailsResponse=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/ChatRoomDetailsResponse.java | 31 +++++++++++++++++++ .../response/ChatRoomParticipantResponse.java | 8 +++++ 2 files changed, 39 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java create mode 100644 backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomParticipantResponse.java 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..7ebaa5007 --- /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 participants +) { + + 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 +) { +} From f6099f9ea59049088fcb1a30b53bc32f57748166 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 15:09:02 +0900 Subject: [PATCH 13/26] =?UTF-8?q?refactor:=20findChatRoomDetails=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=8B=9C=EA=B7=B8=EB=8B=88?= =?UTF-8?q?=EC=B2=98=EC=97=90=20darakbangId=20=EC=B6=94=EA=B0=80,=20Transa?= =?UTF-8?q?ctional=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/mouda/backend/chat/business/ChatRoomService.java | 7 +++++-- .../backend/chat/implement/ChatRoomDetailsFinder.java | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java index 410a75652..cbb6e3d1b 100644 --- a/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java +++ b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java @@ -1,6 +1,7 @@ package mouda.backend.chat.business; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import mouda.backend.chat.domain.ChatRoomDetails; @@ -9,13 +10,15 @@ import mouda.backend.darakbangmember.domain.DarakbangMember; @Service +@Transactional @RequiredArgsConstructor public class ChatRoomService { private final ChatRoomDetailsFinder chatRoomDetailsFinder; - public ChatRoomDetailsResponse findChatRoomDetails(long chatRoomId, DarakbangMember darakbangMember) { - ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(chatRoomId, darakbangMember); + @Transactional(readOnly = true) + public ChatRoomDetailsResponse findChatRoomDetails(long darakbangId, long chatRoomId, DarakbangMember darakbangMember) { + ChatRoomDetails chatRoomDetails = chatRoomDetailsFinder.find(darakbangId, chatRoomId, darakbangMember); return ChatRoomDetailsResponse.from(chatRoomDetails); } diff --git a/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java index 76baf69dd..b99a9acf7 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java +++ b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java @@ -19,8 +19,8 @@ public class ChatRoomDetailsFinder { private final AttributeManagerRegistry attributeManagerRegistry; private final ParticipantResolverRegistry participantResolverRegistry; - public ChatRoomDetails find(long chatRoomId, DarakbangMember darakbangMember) { - ChatRoom chatRoom = chatRoomFinder.read(darakbangMember.getId(), chatRoomId, darakbangMember); + 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); From 923e4b32c6ef602c3cd5af25e732b8fc507d9c88 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 15:09:46 +0900 Subject: [PATCH 14/26] =?UTF-8?q?refactor:=20=EC=B0=B8=EC=97=AC=EC=9E=90?= =?UTF-8?q?=20=EC=9D=91=EB=8B=B5=20json=20key=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/presentation/response/ChatRoomDetailsResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7ebaa5007..46ec10c85 100644 --- a/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java +++ b/backend/src/main/java/mouda/backend/chat/presentation/response/ChatRoomDetailsResponse.java @@ -10,7 +10,7 @@ public record ChatRoomDetailsResponse( Map attributes, String title, String type, - List participants + List participations ) { public static ChatRoomDetailsResponse from(ChatRoomDetails chatRoomDetails) { From ea6da3a3d7ad74da4862f648dfacf7d1ab9325e3 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 23:59:18 +0900 Subject: [PATCH 15/26] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EB=82=98=EB=85=B8=EC=B4=88=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=A4=ED=8C=85=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/implement/MoimAttributeManager.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java index 17bda4ead..1d327be5e 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java +++ b/backend/src/main/java/mouda/backend/chat/implement/MoimAttributeManager.java @@ -1,5 +1,7 @@ package mouda.backend.chat.implement; +import java.time.LocalTime; + import org.springframework.stereotype.Component; import lombok.RequiredArgsConstructor; @@ -38,7 +40,7 @@ public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { moim.isPastMoim(), moim.getDescription(), moim.getDate().toString(), - moim.getTime().toString(), + formatToSecondPrecision(moim.getTime()), moim.getId() ); } @@ -46,4 +48,8 @@ public Attributes create(ChatRoom chatRoom, DarakbangMember darakbangMember) { private boolean getIsMoimer(Chamyo chamyo) { return chamyo.getMoimRole() == MoimRole.MOIMER; } + + private String formatToSecondPrecision(LocalTime time) { + return time.withNano(0).toString(); + } } From 8157a78e2ab1e9e37af2b2500489d36d336082b7 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sat, 12 Oct 2024 23:59:37 +0900 Subject: [PATCH 16/26] =?UTF-8?q?feat:=20equals=20&=20hashcode=20=EC=9E=AC?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/Participant.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/mouda/backend/chat/domain/Participant.java b/backend/src/main/java/mouda/backend/chat/domain/Participant.java index eec889c2b..b804d9f8a 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/Participant.java +++ b/backend/src/main/java/mouda/backend/chat/domain/Participant.java @@ -1,10 +1,12 @@ 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; @@ -14,4 +16,19 @@ public Participant(String nickname, String profile, String role) { 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); + } } From 871d3cca1b10b4f05799e327eecf807243722ed7 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:00:38 +0900 Subject: [PATCH 17/26] =?UTF-8?q?feat:=20ChatPreviewResponses=20json=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20key=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/ChatPreviewResponses.java | 2 +- .../chat/business/ChatServiceTest.java | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) 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/test/java/mouda/backend/chat/business/ChatServiceTest.java b/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java index 45c0d638b..4f0a47b96 100644 --- a/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java +++ b/backend/src/test/java/mouda/backend/chat/business/ChatServiceTest.java @@ -283,7 +283,7 @@ void findChatPreview() { chamyoRepository.save(chamyo); ChatPreviewResponses chatPreview = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); - assertThat(chatPreview.chatPreviewResponses()).isEmpty(); + assertThat(chatPreview.previews()).isEmpty(); } @DisplayName("다락방별 채팅을 조회한다.") @@ -296,7 +296,7 @@ void readDarakbangChatPreview() { chatRepository.save(ChatEntityFixture.getChatEntity(darakbangHogee)); ChatPreviewResponses chatPreview = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); - assertThat(chatPreview.chatPreviewResponses()) + assertThat(chatPreview.previews()) .hasSize(1); Moim moudaMoim = MoimFixture.getSoccerMoim(mouda.getId()); @@ -304,7 +304,7 @@ void readDarakbangChatPreview() { chamyoRepository.save(new Chamyo(moudaMoim, moudaHogee, MoimRole.MOIMER)); ChatPreviewResponses emptyChatPreview = chatService.findChatPreview(moudaHogee, ChatRoomType.MOIM); - assertThat(emptyChatPreview.chatPreviewResponses()) + assertThat(emptyChatPreview.previews()) .hasSize(0); } @@ -329,10 +329,10 @@ void findMoimChatPreview() { 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); + 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("안내면진다 채팅 미리보기를 조회한다.") @@ -356,10 +356,10 @@ void findBetChatPreview() { 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); + 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) { @@ -401,7 +401,7 @@ void findChatPreview_sortedByLastChatCreatedAt() { chatService.createChat(darakbang.getId(), 2L, new ChatCreateRequest("2번 채팅"), darakbangAnna); List chatPreviewResponses = chatService.findChatPreview(darakbangAnna, ChatRoomType.MOIM) - .chatPreviewResponses(); + .previews(); assertThat(chatPreviewResponses).extracting(ChatPreviewResponse::lastContent) .containsExactly("2번 채팅", "1번 채팅", ""); From 5eb1a17a3521f9d75a11e9a42088db72e6e899ca Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:10:12 +0900 Subject: [PATCH 18/26] =?UTF-8?q?refactor:=20ChatRoomDetailsFinder=20Trans?= =?UTF-8?q?actional,=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/implement/ChatRoomDetailsFinder.java | 2 + .../implement/ChatRoomDetailsFinderTest.java | 143 ++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 backend/src/test/java/mouda/backend/chat/implement/ChatRoomDetailsFinderTest.java diff --git a/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java index b99a9acf7..9cc1f8401 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java +++ b/backend/src/main/java/mouda/backend/chat/implement/ChatRoomDetailsFinder.java @@ -3,6 +3,7 @@ import java.util.List; import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import mouda.backend.chat.domain.Attributes; @@ -19,6 +20,7 @@ public class ChatRoomDetailsFinder { 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); 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; + } +} From 8b559e12e718120a92a74a28fae5d6fdcac8d0e4 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:10:51 +0900 Subject: [PATCH 19/26] =?UTF-8?q?fix:=20ChatPreviewResponse=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/moim/presentation/controller/ChatController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..5ea10199a 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 @@ -79,7 +79,7 @@ public ResponseEntity> findChatPreviews( ) { ChatPreviewResponses chatPreviewResponses = chatService.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); From 882b66bf514a2fb681455aa745c552732d2225a5 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:11:05 +0900 Subject: [PATCH 20/26] =?UTF-8?q?feat:=20ChatRoomController=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ChatRoomController.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java 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..2510d1bf3 --- /dev/null +++ b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java @@ -0,0 +1,33 @@ +package mouda.backend.chat.presentation.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.RequiredArgsConstructor; +import mouda.backend.chat.business.ChatRoomService; +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/{chatRoomId}") +public class ChatRoomController { + + private final ChatRoomService chatRoomService; + + @GetMapping("/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)); + } +} From 3d1cb8ea170b765d8e9efa6004a9f47fb903512e Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:23:21 +0900 Subject: [PATCH 21/26] =?UTF-8?q?refactor:=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=ED=94=84=EB=A6=AC=EB=B7=B0,=20=EC=B1=84=ED=8C=85=EB=B0=A9?= =?UTF-8?q?=20=EC=97=B4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20ChatRoom?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=20=EC=B1=85=EC=9E=84=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/business/ChatRoomService.java | 29 ++++ .../backend/chat/business/ChatService.java | 21 --- .../controller/ChatController.java | 27 --- .../controller/ChatRoomController.java | 32 +++- .../controller/ChatController.java | 6 +- .../chat/business/ChatRoomServiceTest.java | 162 ++++++++++++++++++ .../chat/business/ChatServiceTest.java | 114 +----------- 7 files changed, 232 insertions(+), 159 deletions(-) create mode 100644 backend/src/test/java/mouda/backend/chat/business/ChatRoomServiceTest.java diff --git a/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java index cbb6e3d1b..221799f47 100644 --- a/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java +++ b/backend/src/main/java/mouda/backend/chat/business/ChatRoomService.java @@ -1,13 +1,24 @@ 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 @@ -15,6 +26,10 @@ 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) { @@ -22,4 +37,18 @@ public ChatRoomDetailsResponse findChatRoomDetails(long darakbangId, long chatRo 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/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 index 2510d1bf3..eeb1c15d1 100644 --- a/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java +++ b/backend/src/main/java/mouda/backend/chat/presentation/controller/ChatRoomController.java @@ -2,12 +2,17 @@ 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; @@ -15,12 +20,12 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/v1/darakbang/{darakbangId}/chatroom/{chatRoomId}") +@RequestMapping("/v1/darakbang/{darakbangId}/chatroom") public class ChatRoomController { private final ChatRoomService chatRoomService; - @GetMapping("/details") + @GetMapping("/{chatRoomId}/details") public ResponseEntity> findChatRoomDetails( @PathVariable Long darakbangId, @PathVariable Long chatRoomId, @@ -30,4 +35,27 @@ public ResponseEntity> findChatRoomDetails 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/moim/presentation/controller/ChatController.java b/backend/src/main/java/mouda/backend/moim/presentation/controller/ChatController.java index 5ea10199a..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,7 +79,7 @@ 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.previews().stream() .map(chatPreviewResponse -> new ChatPreviewResponse(chatPreviewResponse.chatRoomId(), chatPreviewResponse.title(), chatPreviewResponse.currentPeople(), chatPreviewResponse.isStarted(), @@ -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 4f0a47b96..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,7 +281,7 @@ void findChatPreview() { .build(); chamyoRepository.save(chamyo); - ChatPreviewResponses chatPreview = chatService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); + ChatPreviewResponses chatPreview = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); assertThat(chatPreview.previews()).isEmpty(); } @@ -292,10 +291,10 @@ 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); + ChatPreviewResponses chatPreview = chatRoomService.findChatPreview(darakbangHogee, ChatRoomType.MOIM); assertThat(chatPreview.previews()) .hasSize(1); @@ -303,107 +302,8 @@ void readDarakbangChatPreview() { moimRepository.save(moudaMoim); chamyoRepository.save(new Chamyo(moudaMoim, moudaHogee, MoimRole.MOIMER)); - ChatPreviewResponses emptyChatPreview = chatService.findChatPreview(moudaHogee, ChatRoomType.MOIM); + 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.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 = chatService.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()); - - 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) - .previews(); - - assertThat(chatPreviewResponses).extracting(ChatPreviewResponse::lastContent) - .containsExactly("2번 채팅", "1번 채팅", ""); - } } From c880c8a9cf82e1fb02e4f8c95f0c4cdc2206e8d9 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:47:11 +0900 Subject: [PATCH 22/26] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20NPE=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/implement/BetAttributeManagerTest.java | 2 ++ .../chat/implement/MoimAttributeManagerTest.java | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java index b24e9b17d..5cf53d9d6 100644 --- a/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java +++ b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java @@ -14,6 +14,7 @@ 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; @@ -81,6 +82,7 @@ void create_shouldReturnBetAttributes() { 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); diff --git a/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java index b0d7ab768..0bbc8f801 100644 --- a/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java +++ b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java @@ -3,6 +3,9 @@ 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.Test; import org.mockito.InjectMocks; @@ -78,10 +81,8 @@ void create_shouldReturnMoimAttributes() { when(moim.getPlace()).thenReturn("우테코 잠실캠"); when(moim.isPastMoim()).thenReturn(false); when(moim.getDescription()).thenReturn("설명"); - when(moim.getDate()).thenReturn(mock(java.time.LocalDate.class)); - when(moim.getDate().toString()).thenReturn("3333-01-01"); - when(moim.getTime()).thenReturn(mock(java.time.LocalTime.class)); - when(moim.getTime().toString()).thenReturn("12:12:00"); + 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); @@ -96,7 +97,7 @@ void create_shouldReturnMoimAttributes() { assertThat(moimAttributes.getIsStarted()).isFalse(); assertThat(moimAttributes.getDescription()).isEqualTo("설명"); assertThat(moimAttributes.getDate()).isEqualTo("3333-01-01"); - assertThat(moimAttributes.getTime()).isEqualTo("12:12:00"); + assertThat(moimAttributes.getTime()).isEqualTo("12:12:07"); assertThat(moimAttributes.getMoimId()).isEqualTo(12L); } } From 6fb693ad537173dcd0fb6cc81edac7b8e4a2de51 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Sun, 13 Oct 2024 00:48:56 +0900 Subject: [PATCH 23/26] =?UTF-8?q?test:=20DisplayName=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/implement/MoimAttributeManagerTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java index 0bbc8f801..3a8f6ca78 100644 --- a/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java +++ b/backend/src/test/java/mouda/backend/chat/implement/MoimAttributeManagerTest.java @@ -7,6 +7,7 @@ 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; @@ -40,6 +41,7 @@ void setUp() { MockitoAnnotations.openMocks(this); } + @DisplayName("모임 타입 채팅방을 지원한다.") @Test void support_shouldReturnTrueForMoimType() { // given @@ -52,6 +54,7 @@ void support_shouldReturnTrueForMoimType() { assertThat(result).isTrue(); } + @DisplayName("모임 타입 이외의 채팅방을 지원하지 않는다.") @Test void support_shouldReturnFalseForNonMoimType() { // given @@ -64,6 +67,7 @@ void support_shouldReturnFalseForNonMoimType() { assertThat(result).isFalse(); } + @DisplayName("모임 어트리뷰트를 생성한다가.") @Test void create_shouldReturnMoimAttributes() { // given From 528911c0ecff50562e5e0bc0ba8801434bbcae9e Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Mon, 14 Oct 2024 13:45:07 +0900 Subject: [PATCH 24/26] =?UTF-8?q?refactor:=20Loser=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=EC=9D=84=20Participant=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EC=9D=84=20=EC=9E=AC=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/BetAttributes.java | 46 ++++++++-------- .../java/mouda/backend/chat/domain/Loser.java | 17 ------ .../chat/implement/BetAttributeManager.java | 54 +++++++++---------- 3 files changed, 50 insertions(+), 67 deletions(-) delete mode 100644 backend/src/main/java/mouda/backend/chat/domain/Loser.java diff --git a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java index db0357e14..e4cb36773 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java +++ b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java @@ -8,30 +8,30 @@ @Getter public class BetAttributes implements Attributes { - private final String title; - private final Boolean isLoser; - private final Long betId; - private final Loser loser; + private final String title; + private final Boolean isLoser; + private final Long betId; + private final Participant loser; - public BetAttributes(String title, Boolean isLoser, Long betId, Loser loser) { - this.title = title; - this.isLoser = isLoser; - this.betId = betId; - this.loser = 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; - } + @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/Loser.java b/backend/src/main/java/mouda/backend/chat/domain/Loser.java deleted file mode 100644 index 49f243c6e..000000000 --- a/backend/src/main/java/mouda/backend/chat/domain/Loser.java +++ /dev/null @@ -1,17 +0,0 @@ -package mouda.backend.chat.domain; - -import lombok.Getter; - -@Getter -public class Loser { - - private String nickname; - private String profile; - private String role; - - public Loser(String nickname, String profile, String role) { - this.nickname = nickname; - this.profile = profile; - this.role = role; - } -} diff --git a/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java index 2e0fa77de..c968366d5 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java +++ b/backend/src/main/java/mouda/backend/chat/implement/BetAttributeManager.java @@ -11,37 +11,37 @@ import mouda.backend.chat.domain.BetAttributes; import mouda.backend.chat.domain.ChatRoom; import mouda.backend.chat.domain.ChatRoomType; -import mouda.backend.chat.domain.Loser; +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()); - Loser loser = getLoser(bet, darakbangMember.getId()); - return new BetAttributes(bet.getBetDetails().getTitle(), isLoser, bet.getId(), loser); - } - - private Loser 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 Loser(darakbangMember.getNickname(), darakbangMember.getProfile(), betRole.toString()); - } - - private BetRole getBetRole(long requestDarakbangMemberId, long moimerId) { - return moimerId == requestDarakbangMemberId ? BetRole.MOIMER : BetRole.MOIMEE; - } + 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; + } } From 13aad20602eaabb9926236b94b4307db230d373a Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Mon, 14 Oct 2024 13:47:45 +0900 Subject: [PATCH 25/26] =?UTF-8?q?refactor:=20readOnly=20=EC=98=B5=EC=85=98?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../implement/BetParticipantResolver.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java b/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java index a4fb26457..746203ee1 100644 --- a/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java +++ b/backend/src/main/java/mouda/backend/chat/implement/BetParticipantResolver.java @@ -18,26 +18,26 @@ @RequiredArgsConstructor public class BetParticipantResolver implements ParticipantsResolver { - private final BetDarakbangMemberRepository betDarakbangMemberRepository; - - @Override - public boolean support(ChatRoomType chatRoomType) { - return chatRoomType == ChatRoomType.BET; - } - - @Override - @Transactional - 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; - } + 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; + } } From c171766c3941074d9a32d3f248fb72eba20863d6 Mon Sep 17 00:00:00 2001 From: SungKyum Kim Date: Mon, 14 Oct 2024 13:51:11 +0900 Subject: [PATCH 26/26] =?UTF-8?q?refactor:=20=ED=95=84=EB=93=9C=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20=EB=84=90=EC=9D=84=20=ED=97=88=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/chat/domain/BetAttributes.java | 5 +- .../implement/BetAttributeManagerTest.java | 218 +++++++++--------- 2 files changed, 111 insertions(+), 112 deletions(-) diff --git a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java index e4cb36773..78cea25ab 100644 --- a/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java +++ b/backend/src/main/java/mouda/backend/chat/domain/BetAttributes.java @@ -9,8 +9,8 @@ public class BetAttributes implements Attributes { private final String title; - private final Boolean isLoser; - private final Long betId; + private final boolean isLoser; + private final long betId; private final Participant loser; public BetAttributes(String title, Boolean isLoser, Long betId, Participant loser) { @@ -33,5 +33,4 @@ public Map getAttributes() { )); return attributes; } - } diff --git a/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java index 5cf53d9d6..2cdb509b5 100644 --- a/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java +++ b/backend/src/test/java/mouda/backend/chat/implement/BetAttributeManagerTest.java @@ -28,113 +28,113 @@ 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.getIsLoser()).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); - } + @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); + } }