feat(feed): 피드 어댑터와 뷰 테스트를 추가한다

This commit is contained in:
2026-05-21 15:53:40 +09:00
parent 59ea5de00a
commit a8e0f2377d
2 changed files with 244 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
package kr.co.vividnext.sodalive.v2.widget.feed
import android.app.Application
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.test.core.app.ApplicationProvider
import kr.co.vividnext.sodalive.R
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertSame
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 FeedViewTest {
@Test
fun `live bind displays server provided ended message in one constrained text view`() {
val view = inflateView<FeedLiveView>(R.layout.view_feed_live)
val item = sampleLiveItem(endedMessage = "서버에서 내려온 라이브 종료 문구")
view.bind(item)
assertEquals("서버에서 내려온 라이브 종료 문구", view.endedMessageTextView().text.toString())
}
@Test
fun `content category tag and time share bottom meta row`() {
val view = inflateView<FeedContentView>(R.layout.view_feed_content)
val category = view.findViewById<TextView>(R.id.tv_feed_content_category)
val time = view.findViewById<TextView>(R.id.tv_feed_content_created_at)
assertSame(view.findViewById<View>(R.id.ll_feed_content_meta), category.parent)
assertSame(category.parent, time.parent)
}
@Test
fun `community can hide empty body and keyword rows by caller policy`() {
val view = inflateView<FeedCommunityView>(R.layout.view_feed_community)
view.setHideEmptyTextRows(true)
view.bind(sampleCommunityItem(bodyText = "", keywordText = ""))
assertEquals(View.GONE, view.findViewById<TextView>(R.id.tv_feed_community_body).visibility)
assertEquals(View.GONE, view.findViewById<TextView>(R.id.tv_feed_community_keyword).visibility)
}
@Test
fun `rank overlay uses figma overflow position`() {
val view = inflateView<FeedRankView>(R.layout.view_feed_rank)
val imageContainer = view.findViewById<FrameLayout>(R.id.fl_feed_rank_image_container)
val overlay = view.findViewById<TextView>(R.id.tv_feed_rank_overlay)
val params = overlay.layoutParams as FrameLayout.LayoutParams
assertFalse(imageContainer.clipChildren)
assertFalse(imageContainer.clipToPadding)
assertEquals((-6).dpToPx(), params.marginEnd)
assertEquals((-22).dpToPx(), params.bottomMargin)
}
@Test
fun `feed content images expose simple accessibility descriptions`() {
val rankView = inflateView<FeedRankView>(R.layout.view_feed_rank)
val liveView = inflateView<FeedLiveView>(R.layout.view_feed_live)
val contentView = inflateView<FeedContentView>(R.layout.view_feed_content)
val communityView = inflateView<FeedCommunityView>(R.layout.view_feed_community)
assertNotEmptyContentDescription(rankView.findViewById(R.id.iv_feed_rank_image))
assertNotEmptyContentDescription(liveView.findViewById(R.id.iv_feed_live_profile))
assertNotEmptyContentDescription(contentView.findViewById(R.id.iv_feed_content_image))
assertNotEmptyContentDescription(contentView.findViewById(R.id.iv_feed_content_profile))
assertNotEmptyContentDescription(communityView.findViewById(R.id.iv_feed_community_profile))
}
private inline fun <reified T : View> inflateView(layoutResId: Int): T {
val context = ApplicationProvider.getApplicationContext<Context>()
return LayoutInflater.from(context).inflate(layoutResId, null, false) as T
}
private fun sampleLiveItem(endedMessage: String) = FeedItem.Live(
feedId = "feed-live-1",
creatorId = "creator-1",
creatorName = "크리에이터이름",
creatorImageUrl = "https://example.com/profile.png",
liveId = "live-1",
liveTitle = "라이브 방송 이름",
createdAtText = "2분 전",
endedMessage = endedMessage
)
private fun sampleCommunityItem(
bodyText: String,
keywordText: String
) = FeedItem.Community(
feedId = "feed-community-1",
creatorId = "creator-1",
creatorName = "크리에이터 이름",
creatorImageUrl = "https://example.com/profile.png",
postId = "post-1",
bodyText = bodyText,
keywordText = keywordText,
createdAtText = "2분 전",
commentCount = 5,
likeCount = 6
)
private fun Int.dpToPx(): Int {
val context = ApplicationProvider.getApplicationContext<Context>()
return (this * context.resources.displayMetrics.density).toInt()
}
private fun assertNotEmptyContentDescription(imageView: ImageView) {
assertTrue(!imageView.contentDescription.isNullOrEmpty())
}
}