test(home): 인기 커뮤니티 섹션 검증을 추가한다

This commit is contained in:
2026-06-05 13:17:06 +09:00
parent dca06cdc3c
commit 293f34ca13

View File

@@ -23,18 +23,26 @@ import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationCreatorUiMo
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorGroupUiModel import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorGroupUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorSection import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationGenreCreatorSection
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveUiModel import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationLiveUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostSection
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPopularCommunityPostUiModel
import kr.co.vividnext.sodalive.v2.main.home.model.HomeRecommendationPaidStatus
import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomePopularCommunityPosts
import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups import kr.co.vividnext.sodalive.v2.main.home.model.visibleHomeGenreCreatorGroups
import kr.co.vividnext.sodalive.v2.main.home.data.HomePopularCommunityPostItem
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeAiCharacterAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeAiCharacterAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeCheerCreatorAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeCheerCreatorAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFirstAudioAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFirstAudioAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowAllButtonBinder import kr.co.vividnext.sodalive.v2.main.home.ui.HomeFollowAllButtonBinder
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeGenreCreatorAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeGenreCreatorAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeLiveAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeLiveAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomePopularCommunityAdapter
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeRecentDebutCreatorAdapter import kr.co.vividnext.sodalive.v2.main.home.ui.HomeRecentDebutCreatorAdapter
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardView import kr.co.vividnext.sodalive.v2.widget.AudioContentCardView
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
import kr.co.vividnext.sodalive.v2.widget.TextTabBarView import kr.co.vividnext.sodalive.v2.widget.TextTabBarView
import kr.co.vividnext.sodalive.v2.widget.banner.BannerView import kr.co.vividnext.sodalive.v2.widget.banner.BannerView
import kr.co.vividnext.sodalive.v2.widget.feed.FeedItem
import kr.co.vividnext.sodalive.v2.main.home.model.toUiModel
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotNull
@@ -89,8 +97,7 @@ class HomeMainFragmentLayoutTest {
R.id.rv_home_first_audio_contents, R.id.rv_home_first_audio_contents,
R.id.rv_home_ai_characters, R.id.rv_home_ai_characters,
R.id.rv_home_genre_creators, R.id.rv_home_genre_creators,
R.id.rv_home_cheer_creators, R.id.rv_home_cheer_creators
R.id.rv_home_popular_community_posts
) )
sectionIds.forEach { sectionId -> assertNotNull(root.findViewById<LinearLayout>(sectionId)) } sectionIds.forEach { sectionId -> assertNotNull(root.findViewById<LinearLayout>(sectionId)) }
@@ -101,6 +108,7 @@ class HomeMainFragmentLayoutTest {
assertEquals(RecyclerView.HORIZONTAL, recyclerView.layoutManager?.canScrollHorizontally()?.toOrientation()) assertEquals(RecyclerView.HORIZONTAL, recyclerView.layoutManager?.canScrollHorizontally()?.toOrientation())
} }
assertNotNull(root.findViewById<BannerView>(R.id.rv_home_banners)) assertNotNull(root.findViewById<BannerView>(R.id.rv_home_banners))
assertNotNull(root.findViewById<RecyclerView>(R.id.rv_home_popular_community_posts))
assertNotNull(root.findViewById<View>(R.id.ll_home_business_info)) assertNotNull(root.findViewById<View>(R.id.ll_home_business_info))
} }
@@ -663,6 +671,74 @@ class HomeMainFragmentLayoutTest {
assertEquals(View.GONE, popularCommunitySection.visibility) assertEquals(View.GONE, popularCommunitySection.visibility)
} }
@Test
fun `home popular community section matches figma vertical list spacing`() {
val root = inflateView(R.layout.fragment_v2_main_home)
val communityList = root.findViewById<RecyclerView>(R.id.rv_home_popular_community_posts)
assertEquals(ViewGroup.LayoutParams.WRAP_CONTENT, communityList.layoutParams.height)
assertEquals(14.dpToPx(), communityList.paddingStart)
assertEquals(14.dpToPx(), communityList.paddingEnd)
assertEquals(false, communityList.layoutManager?.canScrollHorizontally())
}
@Test
fun `home popular community adapter renders max ten posts`() {
val context = ApplicationProvider.getApplicationContext<Context>()
val parent = RecyclerView(context)
parent.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
val adapter = HomePopularCommunityAdapter(onClickItem = {})
adapter.submitSection(HomeRecommendationPopularCommunityPostSection((1L..11L).map(::popularCommunityPost)))
val viewHolder = adapter.onCreateViewHolder(parent, 0)
adapter.onBindViewHolder(viewHolder, 0)
assertEquals(10, adapter.itemCount)
assertEquals(
"post-1",
(viewHolder.itemView as kr.co.vividnext.sodalive.v2.widget.feed.FeedCommunityView).boundItem()?.postId
)
}
@Test
fun `home popular community visible posts caps to ten`() {
val section = HomeRecommendationPopularCommunityPostSection((1L..11L).map(::popularCommunityPost))
assertEquals(10, section.visibleHomePopularCommunityPosts().size)
}
@Test
fun `popular community mapper preserves audio url for detail data`() {
val item = popularCommunityData(audioUrl = "https://example.com/audio.m4a")
assertEquals("https://example.com/audio.m4a", item.toUiModel().item.audioUrl)
}
@Test
fun `home popular community adapter does not load original image for locked paid post`() {
val context = ApplicationProvider.getApplicationContext<Context>()
val parent = RecyclerView(context)
parent.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
val adapter = HomePopularCommunityAdapter(onClickItem = {})
val post = popularCommunityPost(1L).copy(
item = popularCommunityPost(1L).item.copy(
imageUrl = "https://example.com/paid.png",
price = 30,
existOrdered = false
),
paidStatus = HomeRecommendationPaidStatus.Paid(30)
)
adapter.submitSection(HomeRecommendationPopularCommunityPostSection(listOf(post)))
val viewHolder = adapter.onCreateViewHolder(parent, 0)
val communityImage = viewHolder.itemView.findViewById<ImageView>(R.id.iv_feed_community_image)
communityImage.setImageResource(R.drawable.ic_launcher_background)
adapter.onBindViewHolder(viewHolder, 0)
assertEquals(null, communityImage.drawable)
assertEquals(View.VISIBLE, viewHolder.itemView.findViewById<View>(R.id.ll_feed_community_paid_overlay).visibility)
}
@Test @Test
fun `home live section height follows its items`() { fun `home live section height follows its items`() {
val root = inflateView(R.layout.fragment_v2_main_home) val root = inflateView(R.layout.fragment_v2_main_home)
@@ -814,6 +890,46 @@ class HomeMainFragmentLayoutTest {
) )
} }
private fun popularCommunityPost(id: Long): HomeRecommendationPopularCommunityPostUiModel {
return HomeRecommendationPopularCommunityPostUiModel(
item = FeedItem.Community(
feedId = "post-$id",
creatorId = "creator-$id",
creatorName = "크리에이터$id",
creatorImageUrl = "",
postId = "post-$id",
bodyText = "본문$id",
keywordText = "",
createdAtText = "2분 전",
commentCount = 5,
likeCount = 6,
imageUrl = null,
audioUrl = null,
price = 0,
existOrdered = false,
showKeyword = false
),
paidStatus = HomeRecommendationPaidStatus.Free
)
}
private fun popularCommunityData(audioUrl: String?): HomePopularCommunityPostItem {
return HomePopularCommunityPostItem(
postId = 1L,
creatorId = 1L,
creatorNickname = "크리에이터",
creatorProfileImage = null,
imageUrl = null,
audioUrl = audioUrl,
content = "본문",
price = 0,
createdAt = "2분 전",
likeCount = 6L,
commentCount = 5L,
existOrdered = false
)
}
private fun genreGroup( private fun genreGroup(
genre: String, genre: String,
creators: List<HomeRecommendationCreatorUiModel> creators: List<HomeRecommendationCreatorUiModel>