feat(creator): 채널 후원 요청을 연결한다
This commit is contained in:
@@ -463,7 +463,15 @@ class AppDI(private val context: Context, isDebugMode: Boolean) {
|
|||||||
factory { DmChatRepository(api = get(), realtimeClient = get()) }
|
factory { DmChatRepository(api = get(), realtimeClient = get()) }
|
||||||
factory { HomeCreatorRankingRepository(get()) }
|
factory { HomeCreatorRankingRepository(get()) }
|
||||||
factory { HomeRecommendationRepository(get()) }
|
factory { HomeRecommendationRepository(get()) }
|
||||||
factory { CreatorChannelHomeRepository(api = get(), userRepository = get(), talkApi = get(), reportRepository = get()) }
|
factory {
|
||||||
|
CreatorChannelHomeRepository(
|
||||||
|
api = get(),
|
||||||
|
userRepository = get(),
|
||||||
|
talkApi = get(),
|
||||||
|
reportRepository = get(),
|
||||||
|
explorerRepository = get()
|
||||||
|
)
|
||||||
|
}
|
||||||
factory { CharacterTabRepository(get()) }
|
factory { CharacterTabRepository(get()) }
|
||||||
factory { CharacterDetailRepository(get(), get()) }
|
factory { CharacterDetailRepository(get(), get()) }
|
||||||
factory { CharacterGalleryRepository(get()) }
|
factory { CharacterGalleryRepository(get()) }
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class CreatorChannelHomeViewModel(
|
|||||||
|
|
||||||
private var isFollowInProgress = false
|
private var isFollowInProgress = false
|
||||||
private var isCreateChatRoomInProgress = false
|
private var isCreateChatRoomInProgress = false
|
||||||
|
private var isPostChannelDonationInProgress = false
|
||||||
|
|
||||||
fun loadHome(creatorId: Long) {
|
fun loadHome(creatorId: Long) {
|
||||||
if (creatorId <= 0) return
|
if (creatorId <= 0) return
|
||||||
@@ -131,6 +132,40 @@ class CreatorChannelHomeViewModel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun postChannelDonation(can: Int, isSecret: Boolean, message: String) {
|
||||||
|
val content = _homeStateLiveData.value as? CreatorChannelHomeUiState.Content ?: return
|
||||||
|
if (isPostChannelDonationInProgress) return
|
||||||
|
|
||||||
|
isPostChannelDonationInProgress = true
|
||||||
|
compositeDisposable.add(
|
||||||
|
repository.postChannelDonation(
|
||||||
|
creatorId = content.header.creatorId,
|
||||||
|
can = can,
|
||||||
|
isSecret = isSecret,
|
||||||
|
message = message,
|
||||||
|
token = authToken()
|
||||||
|
)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
{
|
||||||
|
isPostChannelDonationInProgress = false
|
||||||
|
if (it.success) {
|
||||||
|
SharedPreferenceManager.can = (SharedPreferenceManager.can - can).coerceAtLeast(0)
|
||||||
|
loadHome(content.header.creatorId)
|
||||||
|
} else {
|
||||||
|
showUnknownErrorToast()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isPostChannelDonationInProgress = false
|
||||||
|
it.message?.let { message -> Logger.e(message) }
|
||||||
|
showUnknownErrorToast()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun blockUser() {
|
fun blockUser() {
|
||||||
val content = _homeStateLiveData.value as? CreatorChannelHomeUiState.Content ?: return
|
val content = _homeStateLiveData.value as? CreatorChannelHomeUiState.Content ?: return
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package kr.co.vividnext.sodalive.v2.creator.channel.data
|
|||||||
|
|
||||||
import kr.co.vividnext.sodalive.chat.talk.TalkApi
|
import kr.co.vividnext.sodalive.chat.talk.TalkApi
|
||||||
import kr.co.vividnext.sodalive.chat.talk.room.CreateChatRoomRequest
|
import kr.co.vividnext.sodalive.chat.talk.room.CreateChatRoomRequest
|
||||||
|
import kr.co.vividnext.sodalive.explorer.ExplorerRepository
|
||||||
|
import kr.co.vividnext.sodalive.explorer.profile.channel_donation.PostChannelDonationRequest
|
||||||
import kr.co.vividnext.sodalive.report.ReportRepository
|
import kr.co.vividnext.sodalive.report.ReportRepository
|
||||||
import kr.co.vividnext.sodalive.report.ReportRequest
|
import kr.co.vividnext.sodalive.report.ReportRequest
|
||||||
import kr.co.vividnext.sodalive.report.ReportType
|
import kr.co.vividnext.sodalive.report.ReportType
|
||||||
@@ -11,7 +13,8 @@ class CreatorChannelHomeRepository(
|
|||||||
private val api: CreatorChannelHomeApi,
|
private val api: CreatorChannelHomeApi,
|
||||||
private val userRepository: UserRepository,
|
private val userRepository: UserRepository,
|
||||||
private val talkApi: TalkApi,
|
private val talkApi: TalkApi,
|
||||||
private val reportRepository: ReportRepository
|
private val reportRepository: ReportRepository,
|
||||||
|
private val explorerRepository: ExplorerRepository
|
||||||
) {
|
) {
|
||||||
fun getHome(creatorId: Long, token: String) = api.getHome(
|
fun getHome(creatorId: Long, token: String) = api.getHome(
|
||||||
creatorId = creatorId,
|
creatorId = creatorId,
|
||||||
@@ -35,6 +38,22 @@ class CreatorChannelHomeRepository(
|
|||||||
request = CreateChatRoomRequest(characterId)
|
request = CreateChatRoomRequest(characterId)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun postChannelDonation(
|
||||||
|
creatorId: Long,
|
||||||
|
can: Int,
|
||||||
|
isSecret: Boolean,
|
||||||
|
message: String,
|
||||||
|
token: String
|
||||||
|
) = explorerRepository.postChannelDonation(
|
||||||
|
request = PostChannelDonationRequest(
|
||||||
|
creatorId = creatorId,
|
||||||
|
can = can,
|
||||||
|
isSecret = isSecret,
|
||||||
|
message = message
|
||||||
|
),
|
||||||
|
token = token
|
||||||
|
)
|
||||||
|
|
||||||
fun blockUser(userId: Long, token: String) = userRepository.memberBlock(
|
fun blockUser(userId: Long, token: String) = userRepository.memberBlock(
|
||||||
userId = userId,
|
userId = userId,
|
||||||
token = token
|
token = token
|
||||||
|
|||||||
@@ -269,6 +269,73 @@ class CreatorChannelHomeViewModelTest {
|
|||||||
assertEquals(null, toastEvent?.consume())
|
assertEquals(null, toastEvent?.consume())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `채널 후원 성공은 기존 후원 API를 호출하고 홈을 다시 로드한다`() {
|
||||||
|
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
||||||
|
whenever(repository.postChannelDonation(100L, 50, true, "응원", "Bearer test-token")).thenReturn(
|
||||||
|
Single.just(ApiResponse(true, Any(), null))
|
||||||
|
)
|
||||||
|
SharedPreferenceManager.can = 200
|
||||||
|
viewModel.loadHome(100L)
|
||||||
|
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = true, message = "응원")
|
||||||
|
|
||||||
|
verify(repository).postChannelDonation(100L, 50, true, "응원", "Bearer test-token")
|
||||||
|
verify(repository, times(2)).getHome(100L, "Bearer test-token")
|
||||||
|
assertEquals(150, SharedPreferenceManager.can)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `채널 후원 성공 시 보유 can보다 큰 금액 차감은 0으로 보정한다`() {
|
||||||
|
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
||||||
|
whenever(repository.postChannelDonation(100L, 50, true, "응원", "Bearer test-token")).thenReturn(
|
||||||
|
Single.just(ApiResponse(true, Any(), null))
|
||||||
|
)
|
||||||
|
SharedPreferenceManager.can = 30
|
||||||
|
viewModel.loadHome(100L)
|
||||||
|
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = true, message = "응원")
|
||||||
|
|
||||||
|
assertEquals(0, SharedPreferenceManager.can)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `채널 후원 진행 중 중복 요청은 무시한다`() {
|
||||||
|
val pending = SingleSubject.create<ApiResponse<Any>>()
|
||||||
|
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
||||||
|
whenever(repository.postChannelDonation(100L, 50, true, "응원", "Bearer test-token")).thenReturn(pending)
|
||||||
|
viewModel.loadHome(100L)
|
||||||
|
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = true, message = "응원")
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = true, message = "응원")
|
||||||
|
|
||||||
|
verify(repository, times(1)).postChannelDonation(100L, 50, true, "응원", "Bearer test-token")
|
||||||
|
pending.onSuccess(ApiResponse(true, Any(), null))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `채널 후원은 홈 content가 없으면 API를 호출하지 않는다`() {
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = false, message = "응원")
|
||||||
|
|
||||||
|
verify(repository, never()).postChannelDonation(any(), any(), any(), any(), any())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `채널 후원 실패는 홈을 다시 로드하지 않고 unknown toast를 emit한다`() {
|
||||||
|
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
||||||
|
whenever(repository.postChannelDonation(100L, 50, false, "응원", "Bearer test-token")).thenReturn(
|
||||||
|
Single.just(ApiResponse(false, null, "failed"))
|
||||||
|
)
|
||||||
|
viewModel.loadHome(100L)
|
||||||
|
|
||||||
|
viewModel.postChannelDonation(can = 50, isSecret = false, message = "응원")
|
||||||
|
|
||||||
|
verify(repository).postChannelDonation(100L, 50, false, "응원", "Bearer test-token")
|
||||||
|
verify(repository, times(1)).getHome(100L, "Bearer test-token")
|
||||||
|
val toastEvent = viewModel.toastLiveData.requireValue()
|
||||||
|
assertEquals(R.string.common_error_unknown, toastEvent?.consume()?.resId)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `차단 성공은 block API를 호출하고 차단 완료 토스트를 emit한다`() {
|
fun `차단 성공은 block API를 호출하고 차단 완료 토스트를 emit한다`() {
|
||||||
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
whenever(repository.getHome(100L, "Bearer test-token")).thenReturn(Single.just(ApiResponse(true, response(), null)))
|
||||||
|
|||||||
Reference in New Issue
Block a user