diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponse.kt new file mode 100644 index 00000000..81926c57 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponse.kt @@ -0,0 +1,47 @@ +package kr.co.vividnext.sodalive.v2.api.content.ranking.dto + +import com.fasterxml.jackson.annotation.JsonProperty +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRanking +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingItem +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingType + +data class AudioRankingResponse( + val showRankChange: Boolean, + val type: AudioRankingType, + val items: List +) { + companion object { + fun from(ranking: AudioRanking): AudioRankingResponse { + return AudioRankingResponse( + showRankChange = ranking.showRankChange, + type = ranking.type, + items = ranking.items.map(AudioRankingItemResponse::from) + ) + } + } +} + +data class AudioRankingItemResponse( + val contentId: Long, + val title: String, + val creatorNickname: String, + val rank: Int, + val rankChange: Int?, + @JsonProperty("isNew") + val isNew: Boolean, + val coverImageUrl: String? +) { + companion object { + fun from(item: AudioRankingItem): AudioRankingItemResponse { + return AudioRankingItemResponse( + contentId = item.contentId, + title = item.title, + creatorNickname = item.creatorNickname, + rank = item.rank, + rankChange = item.rankChange, + isNew = item.isNew, + coverImageUrl = item.coverImageUrl + ) + } + } +} diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRanking.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRanking.kt new file mode 100644 index 00000000..0f488f97 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRanking.kt @@ -0,0 +1,17 @@ +package kr.co.vividnext.sodalive.v2.content.ranking.domain + +data class AudioRanking( + val showRankChange: Boolean, + val type: AudioRankingType, + val items: List +) + +data class AudioRankingItem( + val contentId: Long, + val title: String, + val creatorNickname: String, + val rank: Int, + val rankChange: Int?, + val isNew: Boolean, + val coverImageUrl: String? +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRankingType.kt b/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRankingType.kt new file mode 100644 index 00000000..c6d4d140 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/v2/content/ranking/domain/AudioRankingType.kt @@ -0,0 +1,10 @@ +package kr.co.vividnext.sodalive.v2.content.ranking.domain + +enum class AudioRankingType { + WEEKLY_POPULAR, + RISING, + REVENUE, + SALES_COUNT, + COMMENT_COUNT, + LIKE_COUNT +} diff --git a/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponseTest.kt b/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponseTest.kt new file mode 100644 index 00000000..65528537 --- /dev/null +++ b/src/test/kotlin/kr/co/vividnext/sodalive/v2/api/content/ranking/dto/AudioRankingResponseTest.kt @@ -0,0 +1,48 @@ +package kr.co.vividnext.sodalive.v2.api.content.ranking.dto + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRanking +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingItem +import kr.co.vividnext.sodalive.v2.content.ranking.domain.AudioRankingType +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test + +class AudioRankingResponseTest { + private val objectMapper = jacksonObjectMapper() + + @Test + @DisplayName("오디오 랭킹 도메인을 응답 DTO로 변환하고 isNew JSON 필드명을 유지한다") + fun shouldMapAudioRankingToResponseAndSerializeIsNew() { + val ranking = AudioRanking( + showRankChange = true, + type = AudioRankingType.RISING, + items = listOf( + AudioRankingItem( + contentId = 1001L, + title = "rising audio", + creatorNickname = "creator", + rank = 1, + rankChange = 3, + isNew = true, + coverImageUrl = "https://cdn.test/audio.png" + ) + ) + ) + + val response = AudioRankingResponse.from(ranking) + val json = objectMapper.readTree(objectMapper.writeValueAsString(response)) + + assertEquals(true, response.showRankChange) + assertEquals(AudioRankingType.RISING, response.type) + assertEquals(1001L, response.items[0].contentId) + assertEquals("rising audio", response.items[0].title) + assertEquals("creator", response.items[0].creatorNickname) + assertEquals(1, response.items[0].rank) + assertEquals(3, response.items[0].rankChange) + assertEquals(true, response.items[0].isNew) + assertEquals("https://cdn.test/audio.png", response.items[0].coverImageUrl) + assertEquals(true, json["items"][0]["isNew"].asBoolean()) + assertEquals(false, json["items"][0].has("new")) + } +}