feat(creator): 라이브 다시듣기 mapper를 추가한다
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
|
||||||
|
fun CreatorChannelAudioContentResponse.toReplayUiModel(): CreatorChannelLiveReplayUiModel =
|
||||||
|
CreatorChannelLiveReplayUiModel(
|
||||||
|
audioContentId = audioContentId,
|
||||||
|
title = title,
|
||||||
|
secondaryText = duration,
|
||||||
|
imageUrl = imageUrl,
|
||||||
|
price = price,
|
||||||
|
showAdultBadge = isAdult,
|
||||||
|
tags = toAudioContentTags(),
|
||||||
|
status = toReplayStatus()
|
||||||
|
)
|
||||||
|
|
||||||
|
@StringRes
|
||||||
|
fun ContentSort.toLabelResId(): Int = when (this) {
|
||||||
|
ContentSort.LATEST -> R.string.screen_audio_content_sort_newest
|
||||||
|
ContentSort.POPULAR -> R.string.screen_audio_content_sort_popularity
|
||||||
|
ContentSort.OWNED -> R.string.creator_channel_live_sort_owned
|
||||||
|
ContentSort.PRICE_HIGH -> R.string.screen_audio_content_sort_price_high
|
||||||
|
ContentSort.PRICE_LOW -> R.string.screen_audio_content_sort_price_low
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ContentSort.toSortOptionUiModel(selectedSort: ContentSort): CreatorChannelLiveSortOptionUiModel =
|
||||||
|
CreatorChannelLiveSortOptionUiModel(
|
||||||
|
sort = this,
|
||||||
|
labelResId = toLabelResId(),
|
||||||
|
isSelected = this == selectedSort
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun CreatorChannelAudioContentResponse.toAudioContentTags(): Set<AudioContentTag> = buildSet {
|
||||||
|
if (isOriginalSeries == true) add(AudioContentTag.Original)
|
||||||
|
if (isFirstContent) add(AudioContentTag.First)
|
||||||
|
if (isPointAvailable) add(AudioContentTag.Point)
|
||||||
|
if (price == 0) add(AudioContentTag.Free)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CreatorChannelAudioContentResponse.toReplayStatus(): CreatorChannelLiveReplayStatus = when {
|
||||||
|
isOwned -> CreatorChannelLiveReplayStatus.Owned
|
||||||
|
isRented -> CreatorChannelLiveReplayStatus.Rented
|
||||||
|
price == 0 -> CreatorChannelLiveReplayStatus.Play
|
||||||
|
else -> CreatorChannelLiveReplayStatus.Price(price)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.creator.channel.live.model
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
|
||||||
|
data class CreatorChannelLiveReplayUiModel(
|
||||||
|
val audioContentId: Long,
|
||||||
|
val title: String,
|
||||||
|
val secondaryText: String?,
|
||||||
|
val imageUrl: String?,
|
||||||
|
val price: Int,
|
||||||
|
val showAdultBadge: Boolean,
|
||||||
|
val tags: Set<AudioContentTag>,
|
||||||
|
val status: CreatorChannelLiveReplayStatus
|
||||||
|
)
|
||||||
|
|
||||||
|
sealed interface CreatorChannelLiveReplayStatus {
|
||||||
|
data object Play : CreatorChannelLiveReplayStatus
|
||||||
|
data object Owned : CreatorChannelLiveReplayStatus
|
||||||
|
data object Rented : CreatorChannelLiveReplayStatus
|
||||||
|
data class Price(val price: Int) : CreatorChannelLiveReplayStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
data class CreatorChannelLiveSortOptionUiModel(
|
||||||
|
val sort: ContentSort,
|
||||||
|
@param:StringRes val labelResId: Int,
|
||||||
|
val isSelected: Boolean
|
||||||
|
)
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.creator.channel.live
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.R
|
||||||
|
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.CreatorChannelLiveReplayStatus
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toLabelResId
|
||||||
|
import kr.co.vividnext.sodalive.v2.creator.channel.live.model.toReplayUiModel
|
||||||
|
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertFalse
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class CreatorChannelLiveMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `소장과 대여가 동시에 true이면 소장중 상태를 우선 매핑한다`() {
|
||||||
|
val item = audioContent(isOwned = true, isRented = true).toReplayUiModel()
|
||||||
|
|
||||||
|
assertEquals(CreatorChannelLiveReplayStatus.Owned, item.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `무료 콘텐츠는 무료 tag와 play CTA 상태로 매핑한다`() {
|
||||||
|
val item = audioContent(price = 0).toReplayUiModel()
|
||||||
|
|
||||||
|
assertEquals(CreatorChannelLiveReplayStatus.Play, item.status)
|
||||||
|
assertTrue(AudioContentTag.Free in item.tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `성인 콘텐츠와 포인트 가능 콘텐츠는 shield와 point tag를 표시한다`() {
|
||||||
|
val item = audioContent(isAdult = true, isPointAvailable = true).toReplayUiModel()
|
||||||
|
|
||||||
|
assertTrue(item.showAdultBadge)
|
||||||
|
assertTrue(AudioContentTag.Point in item.tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `seriesName은 secondary text에 포함하지 않는다`() {
|
||||||
|
val item = audioContent(duration = "10:00", seriesName = "시리즈명").toReplayUiModel()
|
||||||
|
|
||||||
|
assertEquals("10:00", item.secondaryText)
|
||||||
|
assertFalse(item.secondaryText.orEmpty().contains("시리즈명"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `첫 콘텐츠와 오리지널 시리즈는 기존 오디오 tag 정책과 동일하게 매핑한다`() {
|
||||||
|
val item = audioContent(isFirstContent = true, isOriginalSeries = true).toReplayUiModel()
|
||||||
|
|
||||||
|
assertTrue(AudioContentTag.First in item.tags)
|
||||||
|
assertTrue(AudioContentTag.Original in item.tags)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `정렬 값은 label resource로 매핑한다`() {
|
||||||
|
assertEquals(R.string.screen_audio_content_sort_newest, ContentSort.LATEST.toLabelResId())
|
||||||
|
assertEquals(R.string.screen_audio_content_sort_popularity, ContentSort.POPULAR.toLabelResId())
|
||||||
|
assertEquals(R.string.creator_channel_live_sort_owned, ContentSort.OWNED.toLabelResId())
|
||||||
|
assertEquals(R.string.screen_audio_content_sort_price_high, ContentSort.PRICE_HIGH.toLabelResId())
|
||||||
|
assertEquals(R.string.screen_audio_content_sort_price_low, ContentSort.PRICE_LOW.toLabelResId())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun audioContent(
|
||||||
|
price: Int = 10,
|
||||||
|
isPointAvailable: Boolean = false,
|
||||||
|
isFirstContent: Boolean = false,
|
||||||
|
seriesName: String? = null,
|
||||||
|
isOriginalSeries: Boolean? = false,
|
||||||
|
isAdult: Boolean = false,
|
||||||
|
isOwned: Boolean = false,
|
||||||
|
isRented: Boolean = false,
|
||||||
|
duration: String? = null
|
||||||
|
) = CreatorChannelAudioContentResponse(
|
||||||
|
audioContentId = 1L,
|
||||||
|
title = "다시듣기",
|
||||||
|
duration = duration,
|
||||||
|
imageUrl = "https://example.com/audio.png",
|
||||||
|
price = price,
|
||||||
|
isPointAvailable = isPointAvailable,
|
||||||
|
isFirstContent = isFirstContent,
|
||||||
|
seriesName = seriesName,
|
||||||
|
isOriginalSeries = isOriginalSeries,
|
||||||
|
isAdult = isAdult,
|
||||||
|
isOwned = isOwned,
|
||||||
|
isRented = isRented
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user