diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/dto/UserCreatorChatDtos.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/dto/UserCreatorChatDtos.kt index 4baae69c..1a03efdd 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/dto/UserCreatorChatDtos.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/dto/UserCreatorChatDtos.kt @@ -24,6 +24,8 @@ data class SendUserCreatorChatMessageResponse( data class UserCreatorChatRoomOpenResponse( val roomId: Long, + val opponentNickname: String, + val opponentProfileImageUrl: String, val messages: List, val hasMore: Boolean, val nextCursor: Long? diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/service/UserCreatorChatService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/service/UserCreatorChatService.kt index a4e1ed6c..06fcdcdf 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/service/UserCreatorChatService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/service/UserCreatorChatService.kt @@ -73,9 +73,14 @@ class UserCreatorChatService( fun openRoom(member: Member, roomId: Long, limit: Int = 20): UserCreatorChatRoomOpenResponse { val room = findRoom(roomId) requireParticipant(roomId, member.id!!) + val opponent = participantRepository.findActiveOpponent(roomId, member.id!!)?.member + ?: throw SodaException(messageKey = "chat.room.invalid_access") + val opponentProfilePath = opponent.profileImage ?: "profile/default-profile.png" val page = getMessages(member, roomId, cursor = null, limit = limit) return UserCreatorChatRoomOpenResponse( roomId = room.id!!, + opponentNickname = opponent.nickname, + opponentProfileImageUrl = "$cloudFrontHost/$opponentProfilePath", messages = page.messages, hasMore = page.hasMore, nextCursor = page.nextCursor diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceTest.kt index 13b77ef2..6eea1f47 100644 --- a/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceTest.kt +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceTest.kt @@ -81,6 +81,61 @@ class UserCreatorChatServiceTest { Mockito.verify(participantRepository, Mockito.times(2)).save(Mockito.any(UserCreatorChatParticipant::class.java)) } + @Test + @DisplayName("방 입장 응답은 상대방 닉네임과 프로필 이미지 URL을 포함한다") + fun shouldOpenRoomWithOpponentProfileWhenOpponentHasProfileImage() { + val user = member(1L, "user") + val creator = member(2L, "creator").apply { + profileImage = "profile/creator.png" + } + val room = room(10L) + val userParticipant = participant(100L, room, user) + val creatorParticipant = participant(101L, room, creator) + Mockito.`when`(roomRepository.findByIdAndIsActiveTrue(10L)).thenReturn(room) + Mockito.`when`(participantRepository.findActiveByRoomIdAndMemberId(10L, 1L)).thenReturn(userParticipant) + Mockito.`when`(participantRepository.findActiveOpponent(10L, 1L)).thenReturn(creatorParticipant) + Mockito.`when`( + messageRepository.findByChatRoomAndIsActiveTrueOrderByIdDesc( + room, + PageRequest.of(0, 20) + ) + ).thenReturn(emptyList()) + + val response = service.openRoom(user, roomId = 10L) + + assertEquals(10L, response.roomId) + assertEquals("creator", response.opponentNickname) + assertEquals("https://cdn.test/profile/creator.png", response.opponentProfileImageUrl) + assertEquals(emptyList(), response.messages) + assertFalse(response.hasMore) + assertEquals(null, response.nextCursor) + Mockito.verify(participantRepository).findActiveOpponent(10L, 1L) + } + + @Test + @DisplayName("상대방 프로필 이미지가 없으면 방 입장 응답은 기본 프로필 이미지 URL을 반환한다") + fun shouldOpenRoomWithDefaultOpponentProfileWhenOpponentProfileImageIsNull() { + val user = member(1L, "user") + val creator = member(2L, "creator") + val room = room(10L) + val userParticipant = participant(100L, room, user) + val creatorParticipant = participant(101L, room, creator) + Mockito.`when`(roomRepository.findByIdAndIsActiveTrue(10L)).thenReturn(room) + Mockito.`when`(participantRepository.findActiveByRoomIdAndMemberId(10L, 1L)).thenReturn(userParticipant) + Mockito.`when`(participantRepository.findActiveOpponent(10L, 1L)).thenReturn(creatorParticipant) + Mockito.`when`( + messageRepository.findByChatRoomAndIsActiveTrueOrderByIdDesc( + room, + PageRequest.of(0, 20) + ) + ).thenReturn(emptyList()) + + val response = service.openRoom(user, roomId = 10L) + + assertEquals("creator", response.opponentNickname) + assertEquals("https://cdn.test/profile/default-profile.png", response.opponentProfileImageUrl) + } + @Test @DisplayName("상대방이 같은 방에 입장 중이면 텍스트 메시지를 실시간 전송하고 푸시를 보내지 않는다") fun shouldSendRealtimeMessageWithoutPushWhenOpponentIsPresent() {