feat(feed): 피드 아이템 계약을 추가한다

This commit is contained in:
2026-05-21 15:53:39 +09:00
parent 01765f3e7f
commit a2f3910e27
4 changed files with 174 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
package kr.co.vividnext.sodalive.v2.widget.feed
import androidx.annotation.StringRes
import kr.co.vividnext.sodalive.R
enum class FeedContentCategory(
@StringRes val labelResId: Int,
val ratioWidth: Int,
val ratioHeight: Int
) {
Content(labelResId = R.string.feed_content_category_content, ratioWidth = 1, ratioHeight = 1),
Series(labelResId = R.string.feed_content_category_series, ratioWidth = 163, ratioHeight = 230),
Magazine(labelResId = R.string.feed_content_category_magazine, ratioWidth = 163, ratioHeight = 218)
}

View File

@@ -0,0 +1,47 @@
package kr.co.vividnext.sodalive.v2.widget.feed
sealed class FeedItem(open val feedId: String, val variant: FeedVariant) {
data class Rank(
override val feedId: String,
val imageUrl: String,
val rankText: String,
val message: String,
val highlightRanges: List<FeedRankHighlight>
) : FeedItem(feedId, FeedVariant.Rank)
data class Live(
override val feedId: String,
val creatorId: String,
val creatorName: String,
val creatorImageUrl: String,
val liveId: String,
val liveTitle: String,
val createdAtText: String,
val endedMessage: String
) : FeedItem(feedId, FeedVariant.Live)
data class Content(
override val feedId: String,
val creatorId: String,
val creatorName: String,
val creatorImageUrl: String,
val contentId: String,
val contentTitle: String,
val contentImageUrl: String,
val createdAtText: String,
val category: FeedContentCategory = FeedContentCategory.Content
) : FeedItem(feedId, FeedVariant.Content)
data class Community(
override val feedId: String,
val creatorId: String,
val creatorName: String,
val creatorImageUrl: String,
val postId: String,
val bodyText: String,
val keywordText: String,
val createdAtText: String,
val commentCount: Int,
val likeCount: Int
) : FeedItem(feedId, FeedVariant.Community)
}

View File

@@ -0,0 +1,8 @@
package kr.co.vividnext.sodalive.v2.widget.feed
enum class FeedVariant {
Rank,
Live,
Content,
Community
}

View File

@@ -0,0 +1,105 @@
package kr.co.vividnext.sodalive.v2.widget.feed
import org.junit.Assert.assertEquals
import kr.co.vividnext.sodalive.R
import org.junit.Test
class FeedItemTest {
@Test
fun `rank item exposes rank variant and message`() {
val item = FeedItem.Rank(
feedId = "feed-rank-1",
imageUrl = "https://example.com/rank.png",
rankText = "12위",
message = "크리에이터님이 5월 2주차 크리에이터 12위를 차지하였어요!",
highlightRanges = listOf(FeedRankHighlight(start = 22, endExclusive = 25))
)
assertEquals(FeedVariant.Rank, item.variant)
assertEquals("12위", item.rankText)
assertEquals(1, item.highlightRanges.size)
}
@Test
fun `live item exposes title and created time`() {
val item = FeedItem.Live(
feedId = "feed-live-1",
creatorId = "creator-1",
creatorName = "크리에이터이름",
creatorImageUrl = "https://example.com/profile.png",
liveId = "live-1",
liveTitle = "라이브 방송 이름",
createdAtText = "2분 전",
endedMessage = "서버에서 내려온 종료 문구"
)
assertEquals(FeedVariant.Live, item.variant)
assertEquals("라이브 방송 이름", item.liveTitle)
assertEquals("2분 전", item.createdAtText)
assertEquals("서버에서 내려온 종료 문구", item.endedMessage)
}
@Test
fun `content item uses default category label`() {
val item = FeedItem.Content(
feedId = "feed-content-1",
creatorId = "creator-1",
creatorName = "크리에이터이름",
creatorImageUrl = "https://example.com/profile.png",
contentId = "content-1",
contentTitle = "콘텐츠 이름",
contentImageUrl = "https://example.com/content.png",
createdAtText = "2분 전"
)
assertEquals(FeedVariant.Content, item.variant)
assertEquals(FeedContentCategory.Content, item.category)
assertEquals(R.string.feed_content_category_content, item.category.labelResId)
}
@Test
fun `content item accepts series and magazine category`() {
val series = FeedItem.Content(
feedId = "feed-content-series",
creatorId = "creator-1",
creatorName = "크리에이터이름",
creatorImageUrl = "https://example.com/profile.png",
contentId = "series-1",
contentTitle = "시리즈 이름",
contentImageUrl = "https://example.com/series.png",
createdAtText = "2분 전",
category = FeedContentCategory.Series
)
val magazine = series.copy(
feedId = "feed-content-magazine",
contentId = "magazine-1",
contentTitle = "매거진 이름",
contentImageUrl = "https://example.com/magazine.png",
category = FeedContentCategory.Magazine
)
assertEquals(R.string.feed_content_category_series, series.category.labelResId)
assertEquals(R.string.feed_content_category_magazine, magazine.category.labelResId)
}
@Test
fun `community item exposes reaction counts`() {
val item = FeedItem.Community(
feedId = "feed-community-1",
creatorId = "creator-1",
creatorName = "크리에이터 이름",
creatorImageUrl = "https://example.com/profile.png",
postId = "post-1",
bodyText = "커뮤니티 본문",
keywordText = "#키워드 #키워드",
createdAtText = "2분 전",
commentCount = 5,
likeCount = 6
)
assertEquals(FeedVariant.Community, item.variant)
assertEquals(5, item.commentCount)
assertEquals(6, item.likeCount)
}
}