feat(chat): 탭별 empty state를 표시한다

This commit is contained in:
2026-07-11 22:02:13 +09:00
parent 9925a954d1
commit c715c890b5
4 changed files with 74 additions and 9 deletions

View File

@@ -52,12 +52,15 @@ class ChatMainFragmentLayoutTest {
val tabBar = requireNotNull(root.findViewById<CapsuleTabBarView>(R.id.view_chat_filter_tabs))
val recyclerView = requireNotNull(root.findViewById<RecyclerView>(R.id.rv_chat_rooms))
val floatingButton = requireNotNull(root.findViewById<ImageView>(R.id.btn_chat_floating))
val emptyMessage = requireNotNull(root.findViewById<TextView>(R.id.tv_chat_empty_message))
assertEquals(Color.BLACK, (root.background as ColorDrawable).color)
assertSame(root, titleBar.parent)
assertSame(root, tabBar.parent)
assertSame(root, recyclerView.parent)
assertSame(root, floatingButton.parent)
assertSame(root, emptyMessage.parent)
assertEquals(View.GONE, emptyMessage.visibility)
assertFalse(root.containsClassName("com.google.android.material.bottomnavigation.BottomNavigationView"))
assertFalse(root.containsViewIdContaining("unread"))
}
@@ -69,8 +72,10 @@ class ChatMainFragmentLayoutTest {
val tabBar = requireNotNull(root.findViewById<CapsuleTabBarView>(R.id.view_chat_filter_tabs))
val recyclerView = requireNotNull(root.findViewById<RecyclerView>(R.id.rv_chat_rooms))
val floatingButton = requireNotNull(root.findViewById<ImageView>(R.id.btn_chat_floating))
val emptyMessage = requireNotNull(root.findViewById<TextView>(R.id.tv_chat_empty_message))
val tabParams = tabBar.layoutParams as ConstraintLayout.LayoutParams
val listParams = recyclerView.layoutParams as ConstraintLayout.LayoutParams
val emptyParams = emptyMessage.layoutParams as ConstraintLayout.LayoutParams
val buttonParams = floatingButton.layoutParams as ConstraintLayout.LayoutParams
assertEquals(60.dpToPx(), titleBar.layoutParams.height)
@@ -78,6 +83,8 @@ class ChatMainFragmentLayoutTest {
assertEquals(R.id.view_chat_title_bar, tabParams.topToBottom)
assertEquals(R.id.view_chat_filter_tabs, listParams.topToBottom)
assertEquals(ConstraintLayout.LayoutParams.PARENT_ID, listParams.bottomToBottom)
assertEquals(R.id.view_chat_filter_tabs, emptyParams.topToBottom)
assertEquals(ConstraintLayout.LayoutParams.PARENT_ID, emptyParams.bottomToBottom)
assertEquals(false, recyclerView.clipToPadding)
assertTrue(recyclerView.paddingBottom >= 28.dpToPx())
assertEquals(ConstraintLayout.LayoutParams.PARENT_ID, buttonParams.endToEnd)
@@ -101,7 +108,8 @@ class ChatMainFragmentLayoutTest {
assertTrue(source.contains("R.string.screen_chat_filter_all"))
assertTrue(source.contains("R.string.screen_chat_filter_ai"))
assertTrue(source.contains("R.string.screen_chat_filter_dm"))
assertTrue(source.contains("viewModel.loadFirstPage(initialFilter ?: ChatRoomFilter.ALL)"))
assertTrue(source.contains("val initialFilter = getInitialFilter() ?: ChatRoomFilter.ALL"))
assertTrue(source.contains("viewModel.loadFirstPage(initialFilter)"))
}
@Test
@@ -145,6 +153,23 @@ class ChatMainFragmentLayoutTest {
assertTrue(source.contains("!state.isAppending"))
}
@Test
fun `채팅 fragment source는 탭별 empty state 문구를 표시한다`() {
val source = chatMainFragmentSource()
val filter = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/model/ChatRoomFilter.kt"
).readText()
assertTrue(source.contains("private var selectedFilter: ChatRoomFilter = ChatRoomFilter.ALL"))
assertTrue(source.contains("binding.tvChatEmptyMessage.setText(selectedFilter.emptyMessageResId())"))
assertTrue(source.contains("ChatRoomListUiState.Empty -> bindChatRooms(emptyList(), showEmpty = true)"))
assertTrue(source.contains("is ChatRoomListUiState.Error -> bindChatRooms(emptyList(), showEmpty = false)"))
assertTrue(source.contains("binding.rvChatRooms.isVisible = !showEmpty"))
assertTrue(filter.contains("ChatRoomFilter.ALL -> R.string.screen_chat_empty_all"))
assertTrue(filter.contains("ChatRoomFilter.AI -> R.string.screen_chat_empty_ai"))
assertTrue(filter.contains("ChatRoomFilter.DM -> R.string.screen_chat_empty_dm"))
}
private fun inflateView(layoutResId: Int): View {
val context = ApplicationProvider.getApplicationContext<Context>()
return LayoutInflater.from(context).inflate(layoutResId, null, false)