From a6862c51e44e7af9dd3a54fa8851598b5ff57970 Mon Sep 17 00:00:00 2001 From: klaus Date: Fri, 19 Jun 2026 00:10:05 +0900 Subject: [PATCH] =?UTF-8?q?test(dm):=20=EC=A0=9C=EA=B1=B0=20endpoint?= =?UTF-8?q?=EC=99=80=20=EC=9D=8C=EC=84=B1=20=EB=B2=94=EC=9C=84=20=ED=9A=8C?= =?UTF-8?q?=EA=B7=80=EB=A5=BC=20=EA=B3=A0=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dm/DmChatRemovedEndpointSourceTest.kt | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 app/src/test/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRemovedEndpointSourceTest.kt diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRemovedEndpointSourceTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRemovedEndpointSourceTest.kt new file mode 100644 index 00000000..4db55b12 --- /dev/null +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatRemovedEndpointSourceTest.kt @@ -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") + } +}