test(dm): 제거 endpoint와 음성 범위 회귀를 고정한다

This commit is contained in:
2026-06-19 00:10:05 +09:00
parent de90b34cd4
commit a6862c51e4

View File

@@ -0,0 +1,70 @@
package kr.co.vividnext.sodalive.v2.main.chat.dm
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import java.io.File
class DmChatRemovedEndpointSourceTest {
@Test
fun `active DM 채팅 경로에는 제거된 SSE와 text REST endpoint가 남지 않는다`() {
val activeSources = listOf(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRoomActivity.kt",
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRoomViewModel.kt",
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatApi.kt",
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatRepository.kt",
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatSocketClient.kt"
)
activeSources.forEach { path ->
val source = projectFile(path).readText()
assertFalse("$path must not use removed SSE events endpoint", source.contains("/events"))
assertFalse("$path must not use removed disconnect endpoint", source.contains("events/disconnect"))
assertFalse("$path must not use removed text REST endpoint", source.contains("messages/text"))
assertFalse("$path must not use SSE accept header", source.contains("text/event-stream"))
assertFalse("$path must not use EventSource", source.contains("EventSource"))
}
}
@Test
fun `텍스트 전송과 lifecycle 종료는 WebSocket envelope를 사용한다`() {
val viewModel = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRoomViewModel.kt"
).readText()
val repository = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatRepository.kt"
).readText()
assertTrue(viewModel.contains("repository.sendSocketText("))
assertTrue(viewModel.contains("repository.sendLeaveRoom(roomId)"))
assertTrue(viewModel.contains("repository.closeSocket()"))
assertTrue(repository.contains("fun sendSocketText"))
assertTrue(repository.contains("fun sendLeaveRoom"))
assertFalse(repository.contains("disconnectRealtime"))
}
@Test
fun `음성 메시지는 전송 API 추가 없이 DTO 필드 보존 범위로 유지한다`() {
val api = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatApi.kt"
).readText()
val models = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatModels.kt"
).readText()
val repository = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatRepository.kt"
).readText()
assertTrue(models.contains("@SerializedName(\"voiceMessageUrl\") val voiceMessageUrl: String?"))
assertFalse(api.contains("messages/voice"))
assertFalse(api.contains("Multipart"))
assertFalse(repository.contains("sendDmVoiceMessage"))
}
private fun projectFile(relativePath: String): File {
val candidates = listOf(File(relativePath), File("../$relativePath"))
return candidates.firstOrNull { it.exists() }
?: error("Project file not found: $relativePath")
}
}