feat(creator): 오디오 탭 mapper를 추가한다
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
package kr.co.vividnext.sodalive.v2.creator.channel.audio
|
||||
|
||||
import kr.co.vividnext.sodalive.v2.common.data.ContentSort
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.data.CreatorChannelAudioTabResponse
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.data.CreatorChannelAudioThemeResponse
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.CreatorChannelAudioContentStatus
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.CreatorChannelAudioRateUiModel
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.effectiveSelectedThemeId
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.toAudioContentUiModels
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.toRateUiModel
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.audio.model.toThemeUiModels
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelAudioContentResponse
|
||||
import kr.co.vividnext.sodalive.v2.widget.AudioContentTag
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class CreatorChannelAudioMapperTest {
|
||||
|
||||
@Test
|
||||
fun `themes 응답 앞에 전체 tab을 추가하고 themeId null이면 전체를 선택한다`() {
|
||||
val themes = audioResponse(themeId = null).toThemeUiModels()
|
||||
|
||||
assertEquals(listOf(null, 10L, 20L), themes.map { it.themeId })
|
||||
assertEquals("전체", themes.first().title)
|
||||
assertTrue(themes.first().isSelected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `응답 themeId가 특정 id이면 해당 서버 theme tab만 selected 상태다`() {
|
||||
val themes = audioResponse(themeId = 20L).toThemeUiModels()
|
||||
|
||||
assertEquals(listOf(false, false, true), themes.map { it.isSelected })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `응답 themeId가 서버 themes에 없으면 전체 tab을 selected 상태로 fallback한다`() {
|
||||
val themes = audioResponse(themeId = 99L).toThemeUiModels()
|
||||
|
||||
assertEquals(listOf(true, false, false), themes.map { it.isSelected })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `응답 themeId가 서버 themes에 없으면 effective selected themeId는 null이다`() {
|
||||
val response = audioResponse(themeId = 99L)
|
||||
|
||||
assertNull(response.effectiveSelectedThemeId())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `seriesName이 있으면 secondary text는 duration bullet seriesName이다`() {
|
||||
val item = listOf(audioContent(duration = "10:00", seriesName = "시리즈명")).toAudioContentUiModels().single()
|
||||
|
||||
assertEquals("10:00 • 시리즈명", item.secondaryText)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `seriesName이 null 또는 blank이면 secondary text는 duration만 사용한다`() {
|
||||
val items = listOf(
|
||||
audioContent(audioContentId = 1L, duration = "10:00", seriesName = null),
|
||||
audioContent(audioContentId = 2L, duration = "11:00", seriesName = " ")
|
||||
).toAudioContentUiModels()
|
||||
|
||||
assertEquals(listOf("10:00", "11:00"), items.map { it.secondaryText })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `duration null item은 mapper 결과에서 제외한다`() {
|
||||
val items = listOf(
|
||||
audioContent(audioContentId = 1L, duration = null),
|
||||
audioContent(audioContentId = 2L, duration = "10:00")
|
||||
).toAudioContentUiModels()
|
||||
|
||||
assertEquals(listOf(2L), items.map { it.audioContentId })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `소장과 대여가 동시에 true이면 소장중 상태를 우선 매핑한다`() {
|
||||
val item = listOf(audioContent(isOwned = true, isRented = true)).toAudioContentUiModels().single()
|
||||
|
||||
assertEquals(CreatorChannelAudioContentStatus.Owned, item.status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `무료 콘텐츠는 무료 tag와 play CTA 상태로 매핑한다`() {
|
||||
val item = listOf(audioContent(price = 0)).toAudioContentUiModels().single()
|
||||
|
||||
assertEquals(CreatorChannelAudioContentStatus.Play, item.status)
|
||||
assertTrue(AudioContentTag.Free in item.tags)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `유료 미보유 콘텐츠는 price 상태로 매핑한다`() {
|
||||
val item = listOf(audioContent(price = 500)).toAudioContentUiModels().single()
|
||||
|
||||
assertEquals(CreatorChannelAudioContentStatus.Price(500), item.status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `성인 포인트 첫 콘텐츠 오리지널 시리즈 tag와 badge는 라이브 item 정책과 동일하게 매핑한다`() {
|
||||
val item = listOf(
|
||||
audioContent(
|
||||
isAdult = true,
|
||||
isPointAvailable = true,
|
||||
isFirstContent = true,
|
||||
isOriginalSeries = true
|
||||
)
|
||||
).toAudioContentUiModels().single()
|
||||
|
||||
assertTrue(item.showAdultBadge)
|
||||
assertTrue(AudioContentTag.Point in item.tags)
|
||||
assertTrue(AudioContentTag.First in item.tags)
|
||||
assertTrue(AudioContentTag.Original in item.tags)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `소장률은 내 채널이 아니고 전체 테마일 때만 생성된다`() {
|
||||
val response = audioResponse(themeId = null)
|
||||
|
||||
assertEquals(CreatorChannelAudioRateUiModel(75.0, 3, 4), response.toRateUiModel(isOwner = false))
|
||||
assertNull(response.toRateUiModel(isOwner = true))
|
||||
assertNull(audioResponse(themeId = 10L).toRateUiModel(isOwner = false))
|
||||
assertEquals(CreatorChannelAudioRateUiModel(75.0, 3, 4), audioResponse(themeId = 99L).toRateUiModel(isOwner = false))
|
||||
}
|
||||
|
||||
private fun audioResponse(themeId: Long?) = CreatorChannelAudioTabResponse(
|
||||
audioContentCount = 1,
|
||||
themes = listOf(
|
||||
CreatorChannelAudioThemeResponse(themeId = 10L, themeName = "ASMR"),
|
||||
CreatorChannelAudioThemeResponse(themeId = 20L, themeName = "수면")
|
||||
),
|
||||
themeId = themeId,
|
||||
purchasedAudioContentRate = 75.0,
|
||||
purchasedAudioContentCount = 3,
|
||||
paidAudioContentCount = 4,
|
||||
audioContents = listOf(audioContent()),
|
||||
sort = ContentSort.LATEST,
|
||||
page = 0,
|
||||
size = 20,
|
||||
hasNext = false
|
||||
)
|
||||
|
||||
private fun audioContent(
|
||||
audioContentId: Long = 1L,
|
||||
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? = "10:00"
|
||||
) = CreatorChannelAudioContentResponse(
|
||||
audioContentId = audioContentId,
|
||||
title = "오디오 $audioContentId",
|
||||
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