feat(home): 홈 추천 상단 UI shell을 추가한다
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
package kr.co.vividnext.sodalive.v2.main.home
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.v2.widget.TextTabBarView
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.Shadows.shadowOf
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [28], application = Application::class)
|
||||
class HomeMainFragmentLayoutTest {
|
||||
|
||||
@Test
|
||||
fun `home layout keeps title and tabs outside recommendation scroll content`() {
|
||||
val root = inflateView(R.layout.fragment_v2_main_home)
|
||||
val titleBar = root.findViewById<View>(R.id.view_home_title_bar)
|
||||
val tabBar = root.findViewById<TextTabBarView>(R.id.text_tab_bar_home)
|
||||
val scrollView = root.findViewById<NestedScrollView>(R.id.nsv_home_recommendation_content)
|
||||
|
||||
assertNotNull(titleBar)
|
||||
assertNotNull(tabBar)
|
||||
assertNotNull(scrollView)
|
||||
assertSame(root, titleBar.parent)
|
||||
assertSame(root, tabBar.parent)
|
||||
assertSame(root, scrollView.parent)
|
||||
assertEquals(60.dpToPx(), titleBar.layoutParams.height)
|
||||
assertEquals(52.dpToPx(), tabBar.layoutParams.height)
|
||||
assertFalse(root.containsClassName("androidx.viewpager2.widget.ViewPager2"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home layout contains recommendation section containers with horizontal lists`() {
|
||||
val root = inflateView(R.layout.fragment_v2_main_home)
|
||||
val sectionIds = listOf(
|
||||
R.id.ll_home_live_section,
|
||||
R.id.ll_home_banner_section,
|
||||
R.id.ll_home_recent_activity_section,
|
||||
R.id.ll_home_recent_debut_section,
|
||||
R.id.ll_home_first_audio_section,
|
||||
R.id.ll_home_ai_character_section,
|
||||
R.id.ll_home_genre_creator_section,
|
||||
R.id.ll_home_cheer_creator_section,
|
||||
R.id.ll_home_popular_community_section
|
||||
)
|
||||
val listIds = listOf(
|
||||
R.id.rv_home_lives,
|
||||
R.id.rv_home_banners,
|
||||
R.id.rv_home_recent_activity_creators,
|
||||
R.id.rv_home_recent_debut_creators,
|
||||
R.id.rv_home_first_audio_contents,
|
||||
R.id.rv_home_ai_characters,
|
||||
R.id.rv_home_genre_creators,
|
||||
R.id.rv_home_cheer_creators,
|
||||
R.id.rv_home_popular_community_posts
|
||||
)
|
||||
|
||||
sectionIds.forEach { sectionId -> assertNotNull(root.findViewById<LinearLayout>(sectionId)) }
|
||||
listIds.forEach { listId ->
|
||||
val recyclerView = root.findViewById<RecyclerView>(listId)
|
||||
|
||||
assertNotNull(recyclerView)
|
||||
assertEquals(RecyclerView.HORIZONTAL, recyclerView.layoutManager?.canScrollHorizontally()?.toOrientation())
|
||||
}
|
||||
assertNotNull(root.findViewById<View>(R.id.ll_home_business_info))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home layout uses section title components and custom genre title row`() {
|
||||
val root = inflateView(R.layout.fragment_v2_main_home)
|
||||
val sectionTitleIds = listOf(
|
||||
R.id.view_home_recent_activity_title,
|
||||
R.id.view_home_recent_debut_title,
|
||||
R.id.view_home_first_audio_title,
|
||||
R.id.view_home_ai_character_title,
|
||||
R.id.view_home_cheer_creator_title,
|
||||
R.id.view_home_popular_community_title
|
||||
)
|
||||
val moreTitleIds = listOf(
|
||||
R.id.view_home_recent_debut_title,
|
||||
R.id.view_home_first_audio_title,
|
||||
R.id.view_home_ai_character_title
|
||||
)
|
||||
|
||||
sectionTitleIds.forEach { titleId -> assertNotNull(root.findViewById<View>(titleId)) }
|
||||
moreTitleIds.forEach { titleId ->
|
||||
val titleView = root.findViewById<View>(titleId)
|
||||
val chevron = titleView.findViewById<ImageView>(R.id.iv_section_title_chevron)
|
||||
|
||||
assertNotNull(chevron)
|
||||
}
|
||||
assertNotNull(root.findViewById<LinearLayout>(R.id.ll_home_genre_creator_title))
|
||||
assertNotNull(root.findViewById<TextView>(R.id.tv_home_genre_creator_title_genre))
|
||||
assertNotNull(root.findViewById<TextView>(R.id.tv_home_genre_creator_title_suffix))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home title bar exposes right icons in cash search bell order`() {
|
||||
val titleBar = inflateView(R.layout.view_title_bar_home)
|
||||
val iconIds = listOf(
|
||||
R.id.iv_title_bar_cash,
|
||||
R.id.iv_title_bar_search,
|
||||
R.id.iv_title_bar_bell
|
||||
)
|
||||
val drawableIds = listOf(
|
||||
R.drawable.ic_bar_cash,
|
||||
R.drawable.ic_bar_search,
|
||||
R.drawable.ic_bar_bell
|
||||
)
|
||||
|
||||
iconIds.zip(drawableIds).forEach { (iconId, drawableId) ->
|
||||
val imageView = titleBar.findViewById<ImageView>(iconId)
|
||||
|
||||
assertNotNull(imageView)
|
||||
assertEquals(drawableId, shadowOf(imageView.drawable).createdFromResId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun inflateView(layoutResId: Int): View {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
return LayoutInflater.from(context).inflate(layoutResId, null, false)
|
||||
}
|
||||
|
||||
private fun View.containsClassName(className: String): Boolean {
|
||||
if (javaClass.name == className) return true
|
||||
if (this !is android.view.ViewGroup) return false
|
||||
return (0 until childCount).any { getChildAt(it).containsClassName(className) }
|
||||
}
|
||||
|
||||
private fun Boolean.toOrientation(): Int = if (this) RecyclerView.HORIZONTAL else RecyclerView.VERTICAL
|
||||
|
||||
private fun Int.dpToPx(): Int {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
return (this * context.resources.displayMetrics.density).toInt()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user