feat(creator): 채널 홈 API 모델을 추가한다
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
package kr.co.vividnext.sodalive.v2.creator.channel.data
|
||||
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Header
|
||||
import retrofit2.http.Path
|
||||
|
||||
interface CreatorChannelHomeApi {
|
||||
@GET("/api/v2/creator-channels/{creatorId}/home")
|
||||
fun getHome(
|
||||
@Path("creatorId") creatorId: Long,
|
||||
@Header("Authorization") authHeader: String
|
||||
): Single<ApiResponse<CreatorChannelHomeResponse>>
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package kr.co.vividnext.sodalive.v2.creator.channel.data
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kr.co.vividnext.sodalive.v2.common.CreatorActivityType
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelHomeResponse(
|
||||
@SerializedName("creator") val creator: CreatorChannelCreatorResponse,
|
||||
@SerializedName("currentLive") val currentLive: CreatorChannelLiveResponse?,
|
||||
@SerializedName("latestAudioContent") val latestAudioContent: CreatorChannelAudioContentResponse?,
|
||||
@SerializedName("channelDonations") val channelDonations: List<CreatorChannelDonationResponse>,
|
||||
@SerializedName("notices") val notices: List<CreatorChannelCommunityPostResponse>,
|
||||
@SerializedName("schedules") val schedules: List<CreatorChannelScheduleResponse>,
|
||||
@SerializedName("audioContents") val audioContents: List<CreatorChannelAudioContentResponse>,
|
||||
@SerializedName("series") val series: List<CreatorChannelSeriesResponse>,
|
||||
@SerializedName("communities") val communities: List<CreatorChannelCommunityPostResponse>,
|
||||
@SerializedName("fanTalk") val fanTalk: CreatorChannelFanTalkSummaryResponse,
|
||||
@SerializedName("introduce") val introduce: String,
|
||||
@SerializedName("activity") val activity: CreatorChannelActivityResponse,
|
||||
@SerializedName("sns") val sns: CreatorChannelSnsResponse
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelCreatorResponse(
|
||||
@SerializedName("creatorId") val creatorId: Long,
|
||||
@SerializedName("characterId") val characterId: Long?,
|
||||
@SerializedName("nickname") val nickname: String,
|
||||
@SerializedName("profileImageUrl") val profileImageUrl: String,
|
||||
@SerializedName("followerCount") val followerCount: Int,
|
||||
@SerializedName("isAiChatAvailable") val isAiChatAvailable: Boolean,
|
||||
@SerializedName("isDmAvailable") val isDmAvailable: Boolean,
|
||||
@SerializedName("isFollow") val isFollow: Boolean,
|
||||
@SerializedName("isNotify") val isNotify: Boolean
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelLiveResponse(
|
||||
@SerializedName("liveId") val liveId: Long,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("coverImageUrl") val coverImageUrl: String?,
|
||||
@SerializedName("beginDateTimeUtc") val beginDateTimeUtc: String,
|
||||
@SerializedName("price") val price: Int,
|
||||
@SerializedName("isAdult") val isAdult: Boolean
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelAudioContentResponse(
|
||||
@SerializedName("audioContentId") val audioContentId: Long,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("duration") val duration: String?,
|
||||
@SerializedName("imageUrl") val imageUrl: String?,
|
||||
@SerializedName("price") val price: Int,
|
||||
@SerializedName("isPointAvailable") val isPointAvailable: Boolean,
|
||||
@SerializedName("isFirstContent") val isFirstContent: Boolean,
|
||||
@SerializedName("seriesName") val seriesName: String?,
|
||||
@SerializedName("isOriginalSeries") val isOriginalSeries: Boolean?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelDonationResponse(
|
||||
@SerializedName("donationId") val donationId: Long,
|
||||
@SerializedName("memberId") val memberId: Long,
|
||||
@SerializedName("nickname") val nickname: String,
|
||||
@SerializedName("profileImageUrl") val profileImageUrl: String,
|
||||
@SerializedName("can") val can: Int,
|
||||
@SerializedName("isSecret") val isSecret: Boolean,
|
||||
@SerializedName("message") val message: String,
|
||||
@SerializedName("createdAtUtc") val createdAtUtc: String
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelScheduleResponse(
|
||||
@SerializedName("scheduledAtUtc") val scheduledAtUtc: String,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("type") val type: CreatorActivityType,
|
||||
@SerializedName("targetId") val targetId: Long
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelSeriesResponse(
|
||||
@SerializedName("seriesId") val seriesId: Long,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("coverImageUrl") val coverImageUrl: String,
|
||||
@SerializedName("publishedDaysOfWeek") val publishedDaysOfWeek: String,
|
||||
@SerializedName("isComplete") val isComplete: Boolean,
|
||||
@SerializedName("numberOfContent") val numberOfContent: Int,
|
||||
@SerializedName("isNew") val isNew: Boolean,
|
||||
@SerializedName("isPopular") val isPopular: Boolean,
|
||||
@SerializedName("isOriginal") val isOriginal: Boolean
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelCommunityPostResponse(
|
||||
@SerializedName("postId") val postId: Long,
|
||||
@SerializedName("creatorId") val creatorId: Long,
|
||||
@SerializedName("creatorNickname") val creatorNickname: String,
|
||||
@SerializedName("creatorProfileUrl") val creatorProfileUrl: String,
|
||||
@SerializedName("imageUrl") val imageUrl: String?,
|
||||
@SerializedName("audioUrl") val audioUrl: String?,
|
||||
@SerializedName("content") val content: String,
|
||||
@SerializedName("price") val price: Int,
|
||||
@SerializedName("dateUtc") val dateUtc: String,
|
||||
@SerializedName("existOrdered") val existOrdered: Boolean,
|
||||
@SerializedName("likeCount") val likeCount: Int,
|
||||
@SerializedName("commentCount") val commentCount: Int
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelFanTalkSummaryResponse(
|
||||
@SerializedName("totalCount") val totalCount: Int,
|
||||
@SerializedName("latestFanTalk") val latestFanTalk: CreatorChannelFanTalkResponse?
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelFanTalkResponse(
|
||||
@SerializedName("fanTalkId") val fanTalkId: Long,
|
||||
@SerializedName("memberId") val memberId: Long,
|
||||
@SerializedName("nickname") val nickname: String,
|
||||
@SerializedName("profileImageUrl") val profileImageUrl: String,
|
||||
@SerializedName("content") val content: String,
|
||||
@SerializedName("languageCode") val languageCode: String?,
|
||||
@SerializedName("createdAtUtc") val createdAtUtc: String
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelActivityResponse(
|
||||
@SerializedName("debutDateUtc") val debutDateUtc: String?,
|
||||
@SerializedName("dDay") val dDay: String,
|
||||
@SerializedName("liveCount") val liveCount: Long,
|
||||
@SerializedName("liveDurationHours") val liveDurationHours: Long,
|
||||
@SerializedName("liveContributorCount") val liveContributorCount: Long,
|
||||
@SerializedName("audioContentCount") val audioContentCount: Long,
|
||||
@SerializedName("seriesCount") val seriesCount: Long
|
||||
)
|
||||
|
||||
@Keep
|
||||
data class CreatorChannelSnsResponse(
|
||||
@SerializedName("instagramUrl") val instagramUrl: String,
|
||||
@SerializedName("fancimmUrl") val fancimmUrl: String,
|
||||
@SerializedName("xUrl") val xUrl: String,
|
||||
@SerializedName("youtubeUrl") val youtubeUrl: String,
|
||||
@SerializedName("kakaoOpenChatUrl") val kakaoOpenChatUrl: String
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
package kr.co.vividnext.sodalive.v2.creator.channel
|
||||
|
||||
import com.google.gson.Gson
|
||||
import kr.co.vividnext.sodalive.v2.common.CreatorActivityType
|
||||
import kr.co.vividnext.sodalive.v2.creator.channel.data.CreatorChannelHomeResponse
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
|
||||
class CreatorChannelHomeModelsTest {
|
||||
private val gson = Gson()
|
||||
|
||||
@Test
|
||||
fun `home response parses schedule type to creator activity type`() {
|
||||
val response = gson.fromJson(homeJson(scheduleType = "LIVE_REPLAY"), CreatorChannelHomeResponse::class.java)
|
||||
|
||||
assertEquals(CreatorActivityType.LiveReplay, response.schedules.single().type)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `home response preserves nullable fields`() {
|
||||
val response = gson.fromJson(homeJson(scheduleType = "AUDIO"), CreatorChannelHomeResponse::class.java)
|
||||
|
||||
assertNull(response.creator.characterId)
|
||||
assertNull(response.currentLive)
|
||||
assertNull(response.latestAudioContent)
|
||||
assertNull(response.fanTalk.latestFanTalk)
|
||||
assertNull(response.activity.debutDateUtc)
|
||||
}
|
||||
|
||||
private fun homeJson(scheduleType: String): String = """
|
||||
{
|
||||
"creator": {
|
||||
"creatorId": 1,
|
||||
"characterId": null,
|
||||
"nickname": "creator",
|
||||
"profileImageUrl": "https://example.com/profile.png",
|
||||
"followerCount": 10,
|
||||
"isAiChatAvailable": true,
|
||||
"isDmAvailable": true,
|
||||
"isFollow": false,
|
||||
"isNotify": false
|
||||
},
|
||||
"currentLive": null,
|
||||
"latestAudioContent": null,
|
||||
"channelDonations": [],
|
||||
"notices": [],
|
||||
"schedules": [
|
||||
{
|
||||
"scheduledAtUtc": "2026-06-12T00:00:00Z",
|
||||
"title": "schedule",
|
||||
"type": "$scheduleType",
|
||||
"targetId": 11
|
||||
}
|
||||
],
|
||||
"audioContents": [],
|
||||
"series": [],
|
||||
"communities": [],
|
||||
"fanTalk": {
|
||||
"totalCount": 0,
|
||||
"latestFanTalk": null
|
||||
},
|
||||
"introduce": "intro",
|
||||
"activity": {
|
||||
"debutDateUtc": null,
|
||||
"dDay": "D+1",
|
||||
"liveCount": 1,
|
||||
"liveDurationHours": 2,
|
||||
"liveContributorCount": 3,
|
||||
"audioContentCount": 4,
|
||||
"seriesCount": 5
|
||||
},
|
||||
"sns": {
|
||||
"instagramUrl": "",
|
||||
"fancimmUrl": "",
|
||||
"xUrl": "",
|
||||
"youtubeUrl": "",
|
||||
"kakaoOpenChatUrl": ""
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
}
|
||||
Reference in New Issue
Block a user