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 06fcdcdf..a3fe8629 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 @@ -8,6 +8,7 @@ import kr.co.vividnext.sodalive.fcm.FcmEvent import kr.co.vividnext.sodalive.fcm.FcmEventType import kr.co.vividnext.sodalive.fcm.notification.PushNotificationCategory import kr.co.vividnext.sodalive.member.Member +import kr.co.vividnext.sodalive.member.MemberKind import kr.co.vividnext.sodalive.member.MemberRepository import kr.co.vividnext.sodalive.member.block.BlockMemberRepository import kr.co.vividnext.sodalive.utils.generateFileName @@ -209,6 +210,9 @@ class UserCreatorChatService( private fun validateRecipient(sender: Member, recipient: Member) { if (!recipient.isActive) throw SodaException(messageKey = "message.error.recipient_inactive") + if (recipient.memberKind == MemberKind.AI_CHARACTER) { + throw SodaException(messageKey = "message.error.recipient_not_found") + } if (sender.id == recipient.id) throw SodaException(messageKey = "common.error.invalid_request") if (blockMemberRepository.isBlocked(blockedMemberId = sender.id!!, memberId = recipient.id!!)) { throw SodaException(messageKey = "message.error.blocked_by_recipient") diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceIntegrationTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceIntegrationTest.kt new file mode 100644 index 00000000..057a6db4 --- /dev/null +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/usercreatorchat/UserCreatorChatServiceIntegrationTest.kt @@ -0,0 +1,86 @@ +package kr.co.vividnext.sodalive.v2.usercreatorchat + +import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.member.Member +import kr.co.vividnext.sodalive.member.MemberKind +import kr.co.vividnext.sodalive.member.MemberRepository +import kr.co.vividnext.sodalive.member.MemberRole +import kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer +import kr.co.vividnext.sodalive.v2.usercreatorchat.dto.SendUserCreatorTextMessageRequest +import kr.co.vividnext.sodalive.v2.usercreatorchat.repository.UserCreatorChatMessageRepository +import kr.co.vividnext.sodalive.v2.usercreatorchat.repository.UserCreatorChatParticipantRepository +import kr.co.vividnext.sodalive.v2.usercreatorchat.repository.UserCreatorChatRoomRepository +import kr.co.vividnext.sodalive.v2.usercreatorchat.service.UserCreatorChatService +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertThrows +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 org.springframework.test.context.ContextConfiguration +import org.springframework.transaction.annotation.Transactional +import javax.persistence.EntityManager + +@SpringBootTest +@Transactional +@ContextConfiguration(initializers = [EmbeddedRedisInitializer::class]) +class UserCreatorChatServiceIntegrationTest @Autowired constructor( + private val service: UserCreatorChatService, + private val memberRepository: MemberRepository, + private val roomRepository: UserCreatorChatRoomRepository, + private val participantRepository: UserCreatorChatParticipantRepository, + private val messageRepository: UserCreatorChatMessageRepository, + private val entityManager: EntityManager +) { + @Test + @DisplayName("AI 캐릭터용 Member와는 유저-크리에이터 DM 방을 생성할 수 없다") + fun shouldRejectCreateRoomWhenCreatorIsAiCharacterMember() { + val user = memberRepository.save(Member(email = "dm-user@test.com", password = "pw", nickname = "user")) + val creator = memberRepository.save( + Member( + email = null, + password = "", + nickname = "ai-character", + role = MemberRole.CREATOR, + memberKind = MemberKind.AI_CHARACTER + ) + ) + entityManager.flush() + entityManager.clear() + + val exception = assertThrows(SodaException::class.java) { + service.createOrGetRoom(user, creator.id!!) + } + + assertEquals("message.error.recipient_not_found", exception.messageKey) + assertEquals(0, roomRepository.findAll().size) + assertEquals(0, participantRepository.findAll().size) + } + + @Test + @DisplayName("AI 캐릭터용 Member가 참여한 기존 DM 방에는 메시지를 보낼 수 없다") + fun shouldRejectSendTextMessageWhenOpponentIsAiCharacterMember() { + val user = memberRepository.save(Member(email = "dm-message-user@test.com", password = "pw", nickname = "user")) + val creator = memberRepository.save( + Member( + email = null, + password = "", + nickname = "ai-character-message", + role = MemberRole.CREATOR, + memberKind = MemberKind.AI_CHARACTER + ) + ) + val room = roomRepository.save(UserCreatorChatRoom()) + participantRepository.save(UserCreatorChatParticipant(room, user)) + participantRepository.save(UserCreatorChatParticipant(room, creator)) + entityManager.flush() + entityManager.clear() + + val exception = assertThrows(SodaException::class.java) { + service.sendTextMessage(user, room.id!!, SendUserCreatorTextMessageRequest("hello")) + } + + assertEquals("message.error.recipient_not_found", exception.messageKey) + assertEquals(0, messageRepository.findAll().size) + } +}