fix(content): 랭킹 카드 간격과 이미지를 보정한다

This commit is contained in:
2026-06-25 18:30:55 +09:00
parent ab9d14598c
commit c030cbabd3
8 changed files with 238 additions and 29 deletions

View File

@@ -41,6 +41,7 @@ class ContentMainFragmentSourceTest {
assertTrue(source.contains("ContentCommentedAudioAdapter"))
assertTrue(source.contains("ContentRankingAdapter"))
assertTrue(source.contains("ContentRankingAdapter.createGridLayoutManager(requireContext())"))
assertTrue(source.contains("ContentRankingAdapter.createItemDecoration(requireContext())"))
assertTrue(source.contains("recommendationsStateLiveData.observe(viewLifecycleOwner)"))
assertTrue(source.contains("rankingStateLiveData.observe(viewLifecycleOwner)"))
assertTrue(source.contains("contentMainViewModel.loadRecommendations()"))

View File

@@ -0,0 +1,24 @@
package kr.co.vividnext.sodalive.v2.widget.contentranking
import android.os.Build
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
class ContentRankingBlurTest {
@Test
fun `pre S blur는 enabled true이면 Coil transformation을 사용한다`() {
assertTrue(ContentRankingBlur.shouldUseCoilBlur(enabled = true, sdkInt = Build.VERSION_CODES.R))
}
@Test
fun `S 이상 blur는 RenderEffect를 사용하므로 Coil transformation을 사용하지 않는다`() {
assertFalse(ContentRankingBlur.shouldUseCoilBlur(enabled = true, sdkInt = Build.VERSION_CODES.S))
}
@Test
fun `pre S blur는 enabled false이면 Coil transformation을 사용하지 않는다`() {
assertFalse(ContentRankingBlur.shouldUseCoilBlur(enabled = false, sdkInt = Build.VERSION_CODES.R))
}
}

View File

@@ -11,10 +11,12 @@ import androidx.test.core.app.ApplicationProvider
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.v2.widget.ranking.RankingChangeType.Increase
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.io.File
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [28], application = Application::class)
@@ -136,6 +138,33 @@ class ContentRankingCardViewTest {
assertEquals(View.VISIBLE, view.findViewById<View>(R.id.ll_content_ranking_delta).visibility)
}
@Test
fun `large card는 전경 1대1 이미지와 배경 이미지를 함께 유지한다`() {
val view = inflateView<ContentRankingLargeCardView>(R.layout.view_content_ranking_large_card)
view.bind(sampleItem())
assertEquals(View.VISIBLE, view.findViewById<View>(R.id.iv_content_ranking_image).visibility)
assertEquals(View.VISIBLE, view.findViewById<View>(R.id.iv_content_ranking_background).visibility)
}
@Test
fun `large view holder는 배경 blur와 전경 non blur coverImage를 모두 로드한다`() {
val source = projectFile(
"app/src/main/java/kr/co/vividnext/sodalive/v2/widget/contentranking/ContentRankingAdapter.kt"
).readText()
val largeViewHolderSource = source
.substringAfter("private inner class LargeViewHolder")
.substringBefore("private inner class MediumGridViewHolder")
assertTrue(
largeViewHolderSource.contains("view.backgroundImageView().loadContentImage(item, blurEnabled = true)")
)
assertTrue(
largeViewHolderSource.contains("view.imageView().loadContentImage(item, blurEnabled = false)")
)
}
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
@@ -175,4 +204,10 @@ class ContentRankingCardViewTest {
isBlocked = false,
showRankChange = showRankChange
)
private fun projectFile(relativePath: String): File {
val candidates = listOf(File(relativePath), File("../$relativePath"))
return candidates.firstOrNull { it.exists() }
?: error("Project file not found: $relativePath")
}
}

View File

@@ -9,7 +9,7 @@ class ContentRankingLayoutCalculatorTest {
fun `large item keeps figma large ratio`() {
val size = ContentRankingLayoutCalculator.calculate(
parentWidthPx = 374,
horizontalGapPx = 4,
horizontalGapPx = 8,
placement = ContentRankingPlacement(ContentRankingCardVariant.Large, itemsPerRow = 1)
)
@@ -21,31 +21,31 @@ class ContentRankingLayoutCalculatorTest {
fun `medium grid item width divides available width by items per row`() {
val size = ContentRankingLayoutCalculator.calculate(
parentWidthPx = 374,
horizontalGapPx = 4,
horizontalGapPx = 8,
placement = ContentRankingPlacement(ContentRankingCardVariant.MediumGrid, itemsPerRow = 2)
)
assertEquals(185, size.widthPx)
assertEquals(185, size.heightPx)
assertEquals(183, size.widthPx)
assertEquals(183, size.heightPx)
}
@Test
fun `small grid item subtracts two gaps`() {
val size = ContentRankingLayoutCalculator.calculate(
parentWidthPx = 374,
horizontalGapPx = 4,
horizontalGapPx = 8,
placement = ContentRankingPlacement(ContentRankingCardVariant.SmallGrid, itemsPerRow = 3)
)
assertEquals(122, size.widthPx)
assertEquals(122, size.heightPx)
assertEquals(119, size.widthPx)
assertEquals(119, size.heightPx)
}
@Test
fun `horizontal item keeps figma ratio`() {
val size = ContentRankingLayoutCalculator.calculate(
parentWidthPx = 374,
horizontalGapPx = 4,
horizontalGapPx = 8,
placement = ContentRankingPlacement(ContentRankingCardVariant.Horizontal, itemsPerRow = 1)
)