From 39959c3f4708d0ec388d504a53063585dc88a4a7 Mon Sep 17 00:00:00 2001 From: klaus Date: Sun, 12 Jul 2026 08:32:48 +0900 Subject: [PATCH] =?UTF-8?q?fix(content):=20=EC=83=81=EC=84=B8=20=EC=98=A4?= =?UTF-8?q?=EB=94=94=EC=98=A4=EC=99=80=20=EA=B5=AC=EB=A7=A4=20=ED=9D=90?= =?UTF-8?q?=EB=A6=84=EC=9D=84=20=EB=B3=B4=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CreatorChannelCommunityDetailActivity.kt | 40 ++++++++++++++++- .../CreatorChannelCommunityDetailViewModel.kt | 28 ++++++++++++ ...ivity_creator_channel_community_detail.xml | 10 +++++ ...annelCommunityDetailReplyUiContractTest.kt | 18 ++++++++ ...atorChannelCommunityDetailViewModelTest.kt | 45 +++++++++++++++++++ 5 files changed, 139 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt index f8d793fb..3e9df0f8 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/CreatorChannelCommunityDetailActivity.kt @@ -16,6 +16,7 @@ import com.bumptech.glide.Glide import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.base.BaseActivity import kr.co.vividnext.sodalive.databinding.ActivityCreatorChannelCommunityDetailBinding +import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.PurchaseCommunityPostDialog import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player.CreatorCommunityContentItem import kr.co.vividnext.sodalive.explorer.profile.creator_community.all.player.CreatorCommunityMediaPlayerManager import kr.co.vividnext.sodalive.extensions.loadUrl @@ -46,7 +47,7 @@ class CreatorChannelCommunityDetailActivity : BaseActivity + isPurchasingPost = false + if (response.success) { + _postChangedEventLiveData.value = true + loadDetail(postId) + } else { + showMutationFailureToast(response.message) + } + }, + { + isPurchasingPost = false + showMutationFailureToast() + } + ) + ) + } + private fun submitCommentEdit( content: CreatorChannelCommunityDetailUiState.Content, commentId: Long, diff --git a/app/src/main/res/layout/activity_creator_channel_community_detail.xml b/app/src/main/res/layout/activity_creator_channel_community_detail.xml index 478eb1c1..1ea5454c 100644 --- a/app/src/main/res/layout/activity_creator_channel_community_detail.xml +++ b/app/src/main/res/layout/activity_creator_channel_community_detail.xml @@ -149,6 +149,16 @@ android:contentDescription="@string/a11y_feed_content_image" android:scaleType="centerCrop" /> + + (R.id.rv_creator_channel_community_detail_comments)) assertNotNull(detail.findViewById(R.id.layout_creator_channel_community_detail_paywall)) assertNotNull(detail.findViewById(R.id.tv_creator_channel_community_detail_paywall_price)) + assertNotNull(detail.findViewById(R.id.iv_creator_channel_community_detail_play_or_pause)) assertNotNull(detail.findViewById(R.id.layout_creator_channel_community_detail_input_bar)) assertNotNull(detail.findViewById(R.id.et_creator_channel_community_detail_comment)) assertNotNull(detail.findViewById(R.id.btn_creator_channel_community_detail_send)) @@ -138,6 +139,23 @@ class CreatorChannelCommunityDetailReplyUiContractTest { assertTrue(!replyActivity.contains("AlertDialog")) } + @Test + fun `상세 Activity는 레거시 구매 다이얼로그와 이미지 중앙 오디오 버튼을 사용한다`() { + val detailLayout = projectFile("app/src/main/res/layout/activity_creator_channel_community_detail.xml").readText() + val detailActivity = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/v2/creator/channel/community/detail/" + + "CreatorChannelCommunityDetailActivity.kt" + ).readText() + + assertTrue(detailLayout.contains("@+id/iv_creator_channel_community_detail_play_or_pause")) + assertTrue(detailLayout.contains("android:layout_gravity=\"center\"")) + assertTrue(detailLayout.contains("@drawable/btn_audio_content_play")) + assertTrue(detailActivity.contains("PurchaseCommunityPostDialog")) + assertTrue(detailActivity.contains("viewModel.purchaseCommunityPost()")) + assertTrue(detailActivity.contains("btn_audio_content_pause")) + assertTrue(detailActivity.contains("btn_audio_content_play")) + } + @Test fun `댓글 답글 Adapter는 PopupMenu 대신 regular font popup을 사용한다`() { val commentAdapter = projectFile( diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt index 3eeb4b41..d4420a81 100644 --- a/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/creator/channel/community/CreatorChannelCommunityDetailViewModelTest.kt @@ -394,6 +394,51 @@ class CreatorChannelCommunityDetailViewModelTest { assertFalse(state.post.showPaywall) } + @Test + fun `게시물 구매 성공은 상세를 다시 조회해 잠금 상태를 해제한다`() { + whenever(repository.getCommunityPostDetail(POST_ID, AUTH_TOKEN)) + .thenReturn( + Single.just( + ApiResponse( + true, + detailResponse( + isCommentAvailable = false, + price = 300, + existOrdered = false, + creatorId = 999L + ), + null + ) + ), + Single.just( + ApiResponse( + true, + detailResponse( + isCommentAvailable = false, + price = 300, + existOrdered = true, + creatorId = 999L + ), + null + ) + ) + ) + whenever(legacyRepository.purchaseCommunityPost(POST_ID, AUTH_TOKEN)) + .thenReturn(Single.just(ApiResponse(true, org.mockito.kotlin.mock(), null))) + viewModel.loadDetail(POST_ID) + + viewModel.purchaseCommunityPost() + + val state = viewModel.detailStateLiveData.requireValue() as CreatorChannelCommunityDetailUiState.Content + assertFalse(state.post.isLocked) + assertEquals("image.png", state.post.imageUrl) + assertEquals("audio.mp3", state.post.audioUrl) + assertTrue(state.post.existOrdered) + assertTrue(viewModel.postChangedEventLiveData.requireValue() == true) + verify(legacyRepository).purchaseCommunityPost(POST_ID, AUTH_TOKEN) + verify(repository, times(2)).getCommunityPostDetail(POST_ID, AUTH_TOKEN) + } + @Test fun `댓글 UI 모델은 답글 화면 재포맷을 위해 원본 createdAtUtc를 보존한다`() { stubDetail(detailResponse(isCommentAvailable = true, commentIds = listOf(11L)))