feat(home): 팔로잉 탭 화면을 연결한다
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.home
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class HomeFollowingFragmentSourceTest {
|
||||
|
||||
@Test
|
||||
fun `home layout exposes following content and section recycler ids`() {
|
||||
val layout = homeMainLayoutSource()
|
||||
|
||||
assertTrue(layout.contains("@+id/nsv_home_following_content"))
|
||||
assertTrue(layout.contains("@+id/rv_home_following_creators"))
|
||||
assertTrue(layout.contains("@+id/rv_home_following_on_air_lives"))
|
||||
assertTrue(layout.contains("@+id/rv_home_following_recent_chats"))
|
||||
assertTrue(layout.contains("@+id/rv_home_following_monthly_schedules"))
|
||||
assertTrue(layout.contains("@+id/rv_home_following_recent_news"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home main fragment injects following viewmodel and wires adapters`() {
|
||||
val source = homeMainFragmentSource()
|
||||
|
||||
assertTrue(source.contains("HomeFollowingViewModel"))
|
||||
assertTrue(source.contains("private val homeFollowingViewModel: HomeFollowingViewModel by viewModel()"))
|
||||
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowingCreatorAdapter"))
|
||||
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowingLiveAdapter"))
|
||||
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowingChatAdapter"))
|
||||
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowingScheduleAdapter"))
|
||||
assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowingNewsAdapter"))
|
||||
assertTrue(source.contains("HomeFollowingCreatorAdapter"))
|
||||
assertTrue(source.contains("HomeFollowingLiveAdapter"))
|
||||
assertTrue(source.contains("HomeFollowingChatAdapter"))
|
||||
assertTrue(source.contains("HomeFollowingScheduleAdapter"))
|
||||
assertTrue(source.contains("HomeFollowingNewsAdapter"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `following tab branch shows following content and hides other home surfaces`() {
|
||||
val source = homeMainFragmentSource()
|
||||
val branch = source.substringAfter("HOME_TAB_FOLLOWING ->")
|
||||
.substringBefore("}\n }")
|
||||
|
||||
assertTrue(branch.contains("binding.nsvHomeFollowingContent.visibility = View.VISIBLE"))
|
||||
assertTrue(branch.contains("binding.nsvHomeRecommendationContent.visibility = View.GONE"))
|
||||
assertTrue(branch.contains("binding.rvHomeCreatorRankings.visibility = View.GONE"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `following tab loads following content only once`() {
|
||||
val source = homeMainFragmentSource()
|
||||
|
||||
assertTrue(source.contains("private var hasLoadedFollowing = false"))
|
||||
assertTrue(source.contains("if (!hasLoadedFollowing)"))
|
||||
assertTrue(source.contains("hasLoadedFollowing = true"))
|
||||
assertTrue(source.contains("homeFollowingViewModel.loadFollowing()"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `following section chevrons call callback without starting activity`() {
|
||||
val source = homeMainFragmentSource()
|
||||
val callback = source.substringAfter("private fun onFollowingSectionMoreClick")
|
||||
.substringBefore("\n private fun")
|
||||
|
||||
assertTrue(source.contains("onFollowingSectionMoreClick("))
|
||||
assertTrue(source.contains("binding.viewHomeFollowingCreatorsTitle"))
|
||||
assertTrue(source.contains("binding.viewHomeFollowingOnAirTitle"))
|
||||
assertTrue(source.contains("binding.viewHomeFollowingRecentChatsTitle"))
|
||||
assertTrue(source.contains("binding.viewHomeFollowingMonthlySchedulesTitle"))
|
||||
assertTrue(source.contains("binding.viewHomeFollowingRecentNewsTitle"))
|
||||
assertTrue(source.contains("setOnClickListener"))
|
||||
assertTrue(source.contains("onFollowingSectionMoreClick(HomeFollowingSection."))
|
||||
assertFalse(callback.contains("startActivity"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `following state binding clears or binds each following section`() {
|
||||
val source = homeMainFragmentSource()
|
||||
|
||||
assertTrue(source.contains("followingStateLiveData.observe(viewLifecycleOwner)"))
|
||||
assertTrue(source.contains("is HomeFollowingUiState.Content -> bindHomeFollowingContent(state)"))
|
||||
assertTrue(source.contains("HomeFollowingUiState.LoginRequired,"))
|
||||
assertTrue(source.contains("HomeFollowingUiState.Empty,"))
|
||||
assertTrue(source.contains("is HomeFollowingUiState.Error -> bindHomeFollowingEmpty()"))
|
||||
assertTrue(source.contains("followingCreatorAdapter.submitItems(emptyList())"))
|
||||
assertTrue(source.contains("followingLiveAdapter.submitItems(emptyList())"))
|
||||
assertTrue(source.contains("followingChatAdapter.submitItems(emptyList())"))
|
||||
assertTrue(source.contains("followingScheduleAdapter.submitItems(emptyList())"))
|
||||
assertTrue(source.contains("followingNewsAdapter.submitItems(emptyList())"))
|
||||
assertTrue(source.contains("bindFollowingCreatorSection(content.followingCreators)"))
|
||||
assertTrue(source.contains("bindFollowingLiveSection(content.onAirLives)"))
|
||||
assertTrue(source.contains("bindFollowingChatSection(content.recentChats)"))
|
||||
assertTrue(source.contains("bindFollowingScheduleSection(content.monthlySchedules)"))
|
||||
assertTrue(source.contains("bindFollowingNewsSection(content.recentNews)"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `following adapters bind figma required item fields`() {
|
||||
val liveAdapter = projectFile(
|
||||
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeFollowingLiveAdapter.kt"
|
||||
).readText()
|
||||
val liveLayout = projectFile("app/src/main/res/layout/item_home_following_live.xml").readText()
|
||||
val scheduleAdapter = projectFile(
|
||||
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeFollowingScheduleAdapter.kt"
|
||||
).readText()
|
||||
val scheduleLayout = projectFile("app/src/main/res/layout/item_home_following_schedule.xml").readText()
|
||||
val newsAdapter = projectFile(
|
||||
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/ui/HomeFollowingNewsAdapter.kt"
|
||||
).readText()
|
||||
val newsLayout = projectFile("app/src/main/res/layout/item_home_following_news_content.xml").readText()
|
||||
|
||||
assertTrue(liveLayout.contains("@+id/tv_home_following_live_started_at"))
|
||||
assertTrue(liveAdapter.contains("startedAtText.text"))
|
||||
assertTrue(liveAdapter.contains("item.startedAtUtc"))
|
||||
|
||||
assertTrue(scheduleLayout.contains("@+id/iv_home_following_schedule_creator_profile"))
|
||||
assertTrue(scheduleLayout.contains("@+id/tv_home_following_schedule_type"))
|
||||
assertTrue(scheduleAdapter.contains("profileImage.loadHomeCreatorProfileImage(item.creatorProfileImageUrl)"))
|
||||
assertTrue(scheduleAdapter.contains("typeText.setText(item.typeLabelResId)"))
|
||||
assertTrue(scheduleAdapter.contains("item.isOnAir"))
|
||||
assertTrue(scheduleAdapter.contains("R.string.screen_home_following_on_air"))
|
||||
|
||||
assertTrue(newsLayout.contains("@+id/tv_home_following_news_label"))
|
||||
assertTrue(newsLayout.contains("@+id/tv_home_following_news_title"))
|
||||
assertTrue(newsAdapter.contains("labelText.setText(content.labelResId)"))
|
||||
assertTrue(newsAdapter.contains("titleText.text = content.title"))
|
||||
assertTrue(newsAdapter.contains("createdAtText.text = content.visibleFromText"))
|
||||
}
|
||||
|
||||
private fun homeMainFragmentSource(): String {
|
||||
return projectFile("app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeMainFragment.kt").readText()
|
||||
}
|
||||
|
||||
private fun homeMainLayoutSource(): String {
|
||||
return projectFile("app/src/main/res/layout/fragment_v2_main_home.xml").readText()
|
||||
}
|
||||
|
||||
private fun projectFile(relativePath: String): File {
|
||||
val candidates = listOf(File(relativePath), File("../$relativePath"))
|
||||
return candidates.first { it.exists() }.canonicalFile
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user