diff --git a/app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt index 0f4811a1..c55c7498 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt @@ -8,7 +8,6 @@ import androidx.core.view.isVisible import androidx.media3.common.util.UnstableApi import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.google.gson.Gson import kr.co.vividnext.sodalive.R import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService import kr.co.vividnext.sodalive.audio_content.player.AudioContentPlayerService @@ -23,16 +22,10 @@ import kr.co.vividnext.sodalive.live.room.detail.GetRoomDetailResponse import kr.co.vividnext.sodalive.live.room.LiveRoomActivity import kr.co.vividnext.sodalive.live.room.dialog.LivePaymentDialog import kr.co.vividnext.sodalive.live.room.dialog.LiveRoomPasswordDialog -import kr.co.vividnext.sodalive.mypage.MyPageViewModel -import kr.co.vividnext.sodalive.mypage.auth.Auth -import kr.co.vividnext.sodalive.mypage.auth.AuthVerifyRequest -import kr.co.vividnext.sodalive.mypage.auth.BootpayResponse -import kr.co.vividnext.sodalive.settings.ContentSettingsActivity import kr.co.vividnext.sodalive.settings.language.LanguageManager import kr.co.vividnext.sodalive.settings.language.LocaleHelper -import kr.co.vividnext.sodalive.splash.SplashActivity -import kr.co.vividnext.sodalive.user.login.LoginActivity -import kr.co.vividnext.sodalive.v2.components.modal.V2ModalDialog +import kr.co.vividnext.sodalive.v2.access.AccessRequirement +import kr.co.vividnext.sodalive.v2.access.ensureV2Access import kr.co.vividnext.sodalive.v2.live.onair.model.HomeOnAirLivePageUiState import kr.co.vividnext.sodalive.v2.live.onair.model.canEnterHomeOnAirLiveRoom import kr.co.vividnext.sodalive.v2.live.onair.ui.HomeOnAirLiveAdapter @@ -49,7 +42,6 @@ class HomeOnAirLiveActivity : BaseActivity( ) { private val viewModel: HomeOnAirLiveViewModel by viewModel() private val liveViewModel: LiveViewModel by inject() - private val myPageViewModel: MyPageViewModel by inject() private val loadingDialog: LoadingDialog by lazy { LoadingDialog(this, layoutInflater) } private val adapter = HomeOnAirLiveAdapter { enterLiveRoom(it.roomId) } private var isPageLoading = false @@ -118,14 +110,14 @@ class HomeOnAirLiveActivity : BaseActivity( } private fun enterLiveRoom(roomId: Long) { - ensureLoginAndAdultAuth(isAdult = false) { + ensureV2Access(AccessRequirement.Login) { liveViewModel.getRoomDetail(roomId) { roomDetail -> if (!canEnterHomeOnAirLiveRoom(roomDetail)) { Toast.makeText(applicationContext, R.string.common_error_unknown, Toast.LENGTH_LONG).show() return@getRoomDetail } - ensureLoginAndAdultAuth(isAdult = roomDetail.isAdult) { + ensureV2Access(AccessRequirement.forAdultContent(roomDetail.isAdult)) { enterLiveRoom(roomId, roomDetail) } } @@ -173,70 +165,6 @@ class HomeOnAirLiveActivity : BaseActivity( } } - private fun ensureLoginAndAdultAuth(isAdult: Boolean, onAuthed: () -> Unit) { - if (SharedPreferenceManager.token.isBlank()) { - showLoginActivity() - return - } - - if (isAdult) { - val isKoreanCountry = SharedPreferenceManager.countryCode.ifBlank { "KR" } == "KR" - if (isKoreanCountry && !SharedPreferenceManager.isAuth) { - V2ModalDialog( - activity = this, - layoutInflater = layoutInflater, - title = getString(R.string.auth_title), - desc = getString(R.string.auth_desc_live), - confirmButtonTitle = getString(R.string.auth_go), - confirmButtonClick = { startAuthFlow() }, - cancelButtonTitle = getString(R.string.cancel), - cancelButtonClick = {} - ).show(screenWidth) - return - } - - if (!SharedPreferenceManager.isAdultContentVisible) { - startActivity( - Intent(applicationContext, ContentSettingsActivity::class.java).apply { - putExtra(Constants.EXTRA_SHOW_SENSITIVE_CONTENT_GUIDE, true) - } - ) - return - } - } - - onAuthed() - } - - private fun showLoginActivity() { - if (SharedPreferenceManager.token.isBlank()) { - startActivity( - Intent(applicationContext, LoginActivity::class.java).apply { - putExtra(Constants.EXTRA_DATA, intent.extras) - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) - addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) - } - ) - } - } - - private fun startAuthFlow() { - Auth.auth(this, this) { json -> - val bootpayResponse = Gson().fromJson(json, BootpayResponse::class.java) - val request = AuthVerifyRequest(receiptId = bootpayResponse.data.receiptId) - runOnUiThread { - myPageViewModel.authVerify(request) { - startActivity( - Intent(applicationContext, SplashActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - } - ) - finish() - } - } - } - } - private fun showPasswordDialog(roomId: Long, can: Int, onEnterRoomSuccess: () -> Unit) { LiveRoomPasswordDialog( activity = this, diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveEntryPolicyTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveEntryPolicyTest.kt index 6e63e9c8..10a9a9df 100644 --- a/app/src/test/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveEntryPolicyTest.kt +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveEntryPolicyTest.kt @@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.v2.live.onair.model.canEnterHomeOnAirLiveRoom import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test +import java.io.File class HomeOnAirLiveEntryPolicyTest { @@ -25,6 +26,27 @@ class HomeOnAirLiveEntryPolicyTest { assertFalse(canEnterHomeOnAirLiveRoom(roomDetail(channelName = " "))) } + @Test + fun `라이브 입장은 로그인 상세 조회 성인 가드 기존 입장 순서를 유지한다`() { + val source = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/v2/live/onair/HomeOnAirLiveActivity.kt" + ).readText() + val entrySource = sourceSection( + source = source, + startMarker = "private fun enterLiveRoom(roomId: Long) {", + endMarker = "private fun enterLiveRoom(roomId: Long, roomDetail: GetRoomDetailResponse)" + ) + val loginGuard = "ensureV2Access(AccessRequirement.Login)" + val roomDetailQuery = "liveViewModel.getRoomDetail(roomId) { roomDetail ->" + val adultGuard = "ensureV2Access(AccessRequirement.forAdultContent(roomDetail.isAdult))" + val enterRoom = "enterLiveRoom(roomId, roomDetail)" + + assertBefore(entrySource, loginGuard, roomDetailQuery) + assertBefore(entrySource, roomDetailQuery, adultGuard) + assertBefore(entrySource, adultGuard, enterRoom) + assertFalse(source.contains("private fun ensureLoginAndAdultAuth")) + } + private fun roomDetail(channelName: String?) = GetRoomDetailResponse( roomId = 1L, price = 0, @@ -55,4 +77,28 @@ class HomeOnAirLiveEntryPolicyTest { ), participatingUsers = emptyList() ) + + private fun sourceSection(source: String, startMarker: String, endMarker: String): String { + val start = source.indexOf(startMarker) + val end = source.indexOf(endMarker, start) + + assertTrue("start marker not found: $startMarker", start >= 0) + assertTrue("end marker not found after: $startMarker", end > start) + + return source.substring(start, end) + } + + private fun assertBefore(source: String, expectedBefore: String, expectedAfter: String) { + val beforeIndex = source.indexOf(expectedBefore) + val afterIndex = source.indexOf(expectedAfter, beforeIndex) + + assertTrue("missing source: $expectedBefore", beforeIndex >= 0) + assertTrue("missing source after $expectedBefore: $expectedAfter", afterIndex > beforeIndex) + } + + private fun projectFile(relativePath: String): File { + val candidates = listOf(File(relativePath), File("../$relativePath")) + return candidates.firstOrNull { it.exists() } + ?: error("Project file not found: $relativePath") + } }