feat(home-following): 팔로잉 탭 응답 모델을 추가한다

This commit is contained in:
2026-06-25 22:14:21 +09:00
parent 3add66ff7a
commit e4052d097a
4 changed files with 317 additions and 0 deletions
@@ -0,0 +1,114 @@
package kr.co.vividnext.sodalive.v2.api.home.following.dto
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import kr.co.vividnext.sodalive.v2.chat.dto.ChatRoomListItemResponse
import kr.co.vividnext.sodalive.v2.common.domain.CreatorActivityType
import kr.co.vividnext.sodalive.v2.home.following.domain.FollowingNewsType
import kr.co.vividnext.sodalive.v2.home.following.domain.HomeFollowing
import kr.co.vividnext.sodalive.v2.home.following.domain.HomeFollowingCreator
import kr.co.vividnext.sodalive.v2.home.following.domain.HomeFollowingLive
import kr.co.vividnext.sodalive.v2.home.following.domain.HomeFollowingNews
import kr.co.vividnext.sodalive.v2.home.following.domain.HomeFollowingSchedule
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
class HomeFollowingTabResponseTest {
private val objectMapper = jacksonObjectMapper()
@Test
@DisplayName("비로그인 응답은 로그인이 필요하며 모든 섹션을 빈 배열로 반환한다")
fun shouldReturnLoginRequiredResponseWithEmptySections() {
val response = HomeFollowingTabResponse.loginRequired()
val json = objectMapper.readTree(objectMapper.writeValueAsString(response))
assertTrue(response.isLoginRequired)
assertTrue(response.followingCreators.isEmpty())
assertTrue(response.onAirLives.isEmpty())
assertTrue(response.recentChats.isEmpty())
assertTrue(response.monthlySchedules.isEmpty())
assertTrue(response.recentNews.isEmpty())
assertEquals(true, json["isLoginRequired"].asBoolean())
assertTrue(json["followingCreators"].isArray)
assertTrue(json["onAirLives"].isArray)
assertTrue(json["recentChats"].isArray)
assertTrue(json["monthlySchedules"].isArray)
assertTrue(json["recentNews"].isArray)
}
@Test
@DisplayName("팔로잉 탭 도메인은 creatorId 없는 최근 소식과 nullable rank 응답으로 변환한다")
fun shouldMapDomainToResponseWithoutCreatorIdInRecentNews() {
val response = HomeFollowingTabResponse.from(createHomeFollowing())
val json = objectMapper.readTree(objectMapper.writeValueAsString(response))
assertFalse(response.isLoginRequired)
assertEquals(1L, response.followingCreators.first().creatorId)
assertEquals(10L, response.onAirLives.first().liveId)
assertEquals(100L, response.recentChats.first().roomId)
assertEquals("LIVE:20", response.monthlySchedules.first().scheduleId)
assertEquals(3, response.recentNews.first().rank)
assertEquals(false, json["isLoginRequired"].asBoolean())
assertFalse(json["recentNews"][0].has("creatorId"))
assertFalse(json["recentNews"][0].has("ranking"))
assertFalse(json["recentNews"][0].has("rankChange"))
assertFalse(json["recentNews"][0].has("isNew"))
assertEquals(3, json["recentNews"][0]["rank"].asInt())
assertEquals(true, json["monthlySchedules"][0]["isOnAir"].asBoolean())
}
private fun createHomeFollowing(): HomeFollowing {
return HomeFollowing(
followingCreators = listOf(HomeFollowingCreator(1L, "creator", "https://cdn/profile.jpg")),
onAirLives = listOf(
HomeFollowingLive(
liveId = 10L,
creatorProfileImageUrl = "https://cdn/live-profile.jpg",
creatorNickname = "live-creator",
title = "live title",
startedAtUtc = "2026-06-25T00:00:00Z"
)
),
recentChats = listOf(
ChatRoomListItemResponse(
roomId = 100L,
chatType = "DM",
targetName = "creator",
targetImageUrl = "https://cdn/chat.jpg",
lastMessage = "hello",
lastMessageAt = "2026-06-25T00:01:00Z"
)
),
monthlySchedules = listOf(
HomeFollowingSchedule(
scheduleId = "LIVE:20",
creatorId = 1L,
creatorProfileImageUrl = "https://cdn/schedule.jpg",
creatorNickname = "schedule-creator",
title = "schedule title",
type = CreatorActivityType.LIVE,
targetId = 20L,
scheduledAtUtc = "2026-06-26T00:00:00Z",
isOnAir = true
)
),
recentNews = listOf(
HomeFollowingNews(
newsId = "30",
type = FollowingNewsType.CREATOR_RANKING,
creatorProfileImageUrl = "https://cdn/news-profile.jpg",
creatorNickname = "news-creator",
title = "ranking",
body = "ranked",
thumbnailImageUrl = null,
targetId = 1L,
occurredAtUtc = "2026-06-25T00:00:00Z",
visibleFromAtUtc = "2026-06-25T09:00:00Z",
rank = 3
)
)
)
}
}