feat(chat): 채팅방 UI 모델 매핑을 추가한다
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.chat.model
|
||||
|
||||
import android.content.Context
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.data.ChatRoomListItemResponse
|
||||
|
||||
fun ChatRoomListItemResponse.toUiItem(context: Context): ChatRoomListUiItem? {
|
||||
val type = when (chatType) {
|
||||
ChatRoomType.AI.name -> ChatRoomType.AI
|
||||
ChatRoomType.DM.name -> ChatRoomType.DM
|
||||
else -> return null
|
||||
}
|
||||
|
||||
return ChatRoomListUiItem(
|
||||
roomId = roomId,
|
||||
chatType = type,
|
||||
targetName = targetName,
|
||||
targetImageUrl = targetImageUrl,
|
||||
lastMessage = lastMessage,
|
||||
lastMessageTimeText = formatChatRoomLastMessageTime(context, lastMessageAt),
|
||||
showDirectBadge = type == ChatRoomType.DM
|
||||
)
|
||||
}
|
||||
|
||||
fun List<ChatRoomListItemResponse>.toUiItems(context: Context): List<ChatRoomListUiItem> = mapNotNull { it.toUiItem(context) }
|
||||
@@ -0,0 +1,29 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.chat.model
|
||||
|
||||
enum class ChatRoomType {
|
||||
AI,
|
||||
DM
|
||||
}
|
||||
|
||||
data class ChatRoomListUiItem(
|
||||
val roomId: Long,
|
||||
val chatType: ChatRoomType,
|
||||
val targetName: String,
|
||||
val targetImageUrl: String,
|
||||
val lastMessage: String,
|
||||
val lastMessageTimeText: String,
|
||||
val showDirectBadge: Boolean
|
||||
)
|
||||
|
||||
sealed class ChatRoomListUiState {
|
||||
data object Loading : ChatRoomListUiState()
|
||||
|
||||
data class Content(
|
||||
val items: List<ChatRoomListUiItem>,
|
||||
val isAppending: Boolean = false
|
||||
) : ChatRoomListUiState()
|
||||
|
||||
data object Empty : ChatRoomListUiState()
|
||||
|
||||
data class Error(val message: String?) : ChatRoomListUiState()
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.chat
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.data.ChatRoomListItemResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.model.ChatRoomType
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.model.formatChatRoomLastMessageTime
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.model.toUiItem
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.model.toUiItems
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [28], application = Application::class)
|
||||
class ChatRoomMapperTest {
|
||||
|
||||
private val context: Context = ApplicationProvider.getApplicationContext()
|
||||
|
||||
@Test
|
||||
fun `AI 채팅방은 Direct badge 미표시 item으로 매핑된다`() {
|
||||
val item = response(chatType = "AI").toUiItem(context)
|
||||
|
||||
requireNotNull(item)
|
||||
assertEquals(ChatRoomType.AI, item.chatType)
|
||||
assertFalse(item.showDirectBadge)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DM 채팅방은 Direct badge 표시 item으로 매핑된다`() {
|
||||
val item = response(chatType = "DM").toUiItem(context)
|
||||
|
||||
requireNotNull(item)
|
||||
assertEquals(ChatRoomType.DM, item.chatType)
|
||||
assertTrue(item.showDirectBadge)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `응답 필드는 그대로 전달하고 시간은 표시 문구로 매핑한다`() {
|
||||
val item = response(
|
||||
roomId = 20L,
|
||||
targetName = "상대방",
|
||||
targetImageUrl = "https://example.com/profile.png",
|
||||
lastMessage = "마지막 메시지",
|
||||
lastMessageAt = "2026-06-09T11:57:00Z"
|
||||
).toUiItem(context)
|
||||
|
||||
requireNotNull(item)
|
||||
assertEquals(20L, item.roomId)
|
||||
assertEquals("상대방", item.targetName)
|
||||
assertEquals("https://example.com/profile.png", item.targetImageUrl)
|
||||
assertEquals("마지막 메시지", item.lastMessage)
|
||||
assertEquals(formatChatRoomLastMessageTime(context, "2026-06-09T11:57:00Z"), item.lastMessageTimeText)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `알 수 없는 chatType은 표시 대상에서 제외한다`() {
|
||||
assertNull(response(chatType = "GROUP").toUiItem(context))
|
||||
assertEquals(emptyList<Any>(), listOf(response(chatType = "GROUP")).toUiItems(context))
|
||||
}
|
||||
|
||||
private fun response(
|
||||
roomId: Long = 10L,
|
||||
chatType: String = "AI",
|
||||
targetName: String = "크리에이터",
|
||||
targetImageUrl: String = "https://example.com/image.png",
|
||||
lastMessage: String = "안녕하세요",
|
||||
lastMessageAt: String = "2026-06-09T12:00:00Z"
|
||||
) = ChatRoomListItemResponse(
|
||||
roomId = roomId,
|
||||
chatType = chatType,
|
||||
targetName = targetName,
|
||||
targetImageUrl = targetImageUrl,
|
||||
lastMessage = lastMessage,
|
||||
lastMessageAt = lastMessageAt
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user