feat(home): 추천 시간과 프로필 표시를 보완한다
This commit is contained in:
@@ -15,12 +15,14 @@ import android.widget.GridLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import coil.transform.CircleCropTransformation
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import kr.co.vividnext.sodalive.R
|
||||
import kr.co.vividnext.sodalive.common.formatUtcRelativeTimeText
|
||||
import kr.co.vividnext.sodalive.settings.event.EventItem
|
||||
import kr.co.vividnext.sodalive.v2.main.home.data.HomeActiveCreatorItem
|
||||
import kr.co.vividnext.sodalive.v2.main.home.data.HomeBannerItem
|
||||
@@ -51,6 +53,7 @@ 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.HomePopularCommunityAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.HomeRecentDebutCreatorAdapter
|
||||
import kr.co.vividnext.sodalive.v2.main.home.ui.homeCreatorProfileImageTransformations
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentCardView
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||
import kr.co.vividnext.sodalive.v2.widget.TextTabBarView
|
||||
@@ -68,6 +71,7 @@ import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.Shadows.shadowOf
|
||||
import org.robolectric.annotation.Config
|
||||
import java.util.Locale
|
||||
import java.util.TimeZone
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [28], application = Application::class)
|
||||
@@ -729,6 +733,47 @@ class HomeMainFragmentLayoutTest {
|
||||
assertEquals("https://example.com/audio.m4a", item.toUiModel().item.audioUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home relative time formatter converts active creator utc timestamp to relative time text`() {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val defaultTimeZone = TimeZone.getDefault()
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"))
|
||||
try {
|
||||
val oneHourAgoUtc = System.currentTimeMillis() - 60 * 60_000L
|
||||
|
||||
assertEquals(
|
||||
context.getString(R.string.character_comment_time_hours, 1),
|
||||
formatUtcRelativeTimeText(context, oneHourAgoUtc.toString())
|
||||
)
|
||||
} finally {
|
||||
TimeZone.setDefault(defaultTimeZone)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home relative time formatter converts popular community createdAt to relative time text`() {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
val defaultTimeZone = TimeZone.getDefault()
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"))
|
||||
try {
|
||||
val twoMinutesAgoUtc = System.currentTimeMillis() - 2 * 60_000L
|
||||
|
||||
assertEquals(
|
||||
context.getString(R.string.character_comment_time_minutes, 2),
|
||||
formatUtcRelativeTimeText(context, twoMinutesAgoUtc.toString())
|
||||
)
|
||||
} finally {
|
||||
TimeZone.setDefault(defaultTimeZone)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home creator profile image loading uses circle crop transformation`() {
|
||||
val transformations = homeCreatorProfileImageTransformations()
|
||||
|
||||
assertTrue(transformations.single() is CircleCropTransformation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home recommendation mapper uses changed response fields`() {
|
||||
val live = HomeLiveItem(
|
||||
@@ -1069,6 +1114,24 @@ class HomeMainFragmentLayoutTest {
|
||||
assertTrue(source.contains("followCreators(genreSectionKey"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home recommendation viewmodel does not keep android context`() {
|
||||
val viewModelSource = homeRecommendationViewModelSource()
|
||||
val appDiSource = appDiSource()
|
||||
|
||||
assertFalse(viewModelSource.contains("android.content.Context"))
|
||||
assertFalse(viewModelSource.contains("private val context"))
|
||||
assertTrue(appDiSource.contains("viewModel { HomeRecommendationViewModel(get()) }"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home main fragment formats recommendation timestamps at ui binding boundary`() {
|
||||
val source = homeMainFragmentSource()
|
||||
|
||||
assertTrue(source.contains("formatUtcRelativeTimeText(requireContext(), activityAt)"))
|
||||
assertTrue(source.contains("formatUtcRelativeTimeText(requireContext(), item.createdAtText)"))
|
||||
}
|
||||
|
||||
private fun TextView.clickableSpanCount(): Int {
|
||||
val spanned = text as? Spanned ?: return 0
|
||||
return spanned.getSpans(0, spanned.length, ClickableSpan::class.java).size
|
||||
@@ -1087,6 +1150,22 @@ class HomeMainFragmentLayoutTest {
|
||||
).readText()
|
||||
}
|
||||
|
||||
private fun homeRecommendationViewModelSource(): String {
|
||||
val projectRoot = java.io.File("..").canonicalFile
|
||||
return java.io.File(
|
||||
projectRoot,
|
||||
"app/src/main/java/kr/co/vividnext/sodalive/v2/main/home/HomeRecommendationViewModel.kt"
|
||||
).readText()
|
||||
}
|
||||
|
||||
private fun appDiSource(): String {
|
||||
val projectRoot = java.io.File("..").canonicalFile
|
||||
return java.io.File(
|
||||
projectRoot,
|
||||
"app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt"
|
||||
).readText()
|
||||
}
|
||||
|
||||
private fun inflateView(layoutResId: Int): View {
|
||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||
return LayoutInflater.from(context).inflate(layoutResId, null, false)
|
||||
@@ -1155,7 +1234,10 @@ class HomeMainFragmentLayoutTest {
|
||||
)
|
||||
}
|
||||
|
||||
private fun popularCommunityData(audioUrl: String?): HomePopularCommunityPostItem {
|
||||
private fun popularCommunityData(
|
||||
audioUrl: String?,
|
||||
createdAt: String = "2분 전"
|
||||
): HomePopularCommunityPostItem {
|
||||
return HomePopularCommunityPostItem(
|
||||
postId = 1L,
|
||||
creatorId = 1L,
|
||||
@@ -1165,7 +1247,7 @@ class HomeMainFragmentLayoutTest {
|
||||
audioUrl = audioUrl,
|
||||
content = "본문",
|
||||
price = 0,
|
||||
createdAt = "2분 전",
|
||||
createdAt = createdAt,
|
||||
likeCount = 6L,
|
||||
commentCount = 5L,
|
||||
existOrdered = false
|
||||
|
||||
Reference in New Issue
Block a user