From 5e114e18a0eab66b98c34f854a8ca78eff203c3c Mon Sep 17 00:00:00 2001 From: klaus Date: Fri, 18 Sep 2026 14:48:39 +0900 Subject: [PATCH] =?UTF-8?q?feat(main):=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=A7=84=EC=9E=85=EC=9D=84=20V2=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EC=9C=BC=EB=A1=9C=20=EC=A0=84=ED=99=98?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 4 +- .../java/kr/co/vividnext/sodalive/di/AppDI.kt | 2 +- .../kr/co/vividnext/sodalive/live/LiveApi.kt | 4 +- .../vividnext/sodalive/live/LiveRepository.kt | 2 +- .../status}/CancelLiveReservationRequest.kt | 2 +- .../status}/GetLiveReservationResponse.kt | 2 +- .../status}/LiveReservationCancelActivity.kt | 6 +- .../status}/LiveReservationStatusActivity.kt | 2 +- .../status}/LiveReservationStatusAdapter.kt | 2 +- .../status}/LiveReservationStatusViewModel.kt | 2 +- .../sodalive/live/room/LiveRoomActivity.kt | 4 +- .../live/LiveReservationPackageSourceTest.kt | 73 +++++++++++++++++++ .../v2/main/MainV2DirectEntrySourceTest.kt | 47 ++++++++++++ 13 files changed, 136 insertions(+), 16 deletions(-) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/CancelLiveReservationRequest.kt (81%) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/GetLiveReservationResponse.kt (92%) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/LiveReservationCancelActivity.kt (97%) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/LiveReservationStatusActivity.kt (98%) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/LiveReservationStatusAdapter.kt (98%) rename app/src/main/java/kr/co/vividnext/sodalive/live/{reservation_status => reservation/status}/LiveReservationStatusViewModel.kt (99%) create mode 100644 app/src/test/java/kr/co/vividnext/sodalive/live/LiveReservationPackageSourceTest.kt create mode 100644 app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2DirectEntrySourceTest.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 368e154c..ec812230 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -177,8 +177,8 @@ - - + + diff --git a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt index 42dfaec3..29d9029d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt @@ -96,7 +96,7 @@ import kr.co.vividnext.sodalive.live.LiveRepository import kr.co.vividnext.sodalive.live.LiveViewModel import kr.co.vividnext.sodalive.live.recommend.LiveRecommendApi import kr.co.vividnext.sodalive.live.recommend.LiveRecommendRepository -import kr.co.vividnext.sodalive.live.reservation_status.LiveReservationStatusViewModel +import kr.co.vividnext.sodalive.live.reservation.status.LiveReservationStatusViewModel import kr.co.vividnext.sodalive.live.room.LiveRoomViewModel import kr.co.vividnext.sodalive.live.room.create.LiveRoomCreateViewModel import kr.co.vividnext.sodalive.live.room.detail.LiveRoomDetailViewModel diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt index d59cf90f..c28e7201 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt @@ -5,8 +5,8 @@ import io.reactivex.rxjava3.core.Single import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.live.reservation.MakeLiveReservationRequest import kr.co.vividnext.sodalive.live.reservation.MakeLiveReservationResponse -import kr.co.vividnext.sodalive.live.reservation_status.CancelLiveReservationRequest -import kr.co.vividnext.sodalive.live.reservation_status.GetLiveReservationResponse +import kr.co.vividnext.sodalive.live.reservation.status.CancelLiveReservationRequest +import kr.co.vividnext.sodalive.live.reservation.status.GetLiveReservationResponse import kr.co.vividnext.sodalive.live.room.CancelLiveRequest import kr.co.vividnext.sodalive.live.room.EnterOrQuitLiveRoomRequest import kr.co.vividnext.sodalive.live.room.LiveRoomStatus diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt index 62717fef..1c561a03 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt @@ -4,7 +4,7 @@ import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Single import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.live.reservation.MakeLiveReservationRequest -import kr.co.vividnext.sodalive.live.reservation_status.CancelLiveReservationRequest +import kr.co.vividnext.sodalive.live.reservation.status.CancelLiveReservationRequest import kr.co.vividnext.sodalive.live.room.CancelLiveRequest import kr.co.vividnext.sodalive.live.room.EnterOrQuitLiveRoomRequest import kr.co.vividnext.sodalive.live.room.LiveRoomStatus diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/CancelLiveReservationRequest.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/CancelLiveReservationRequest.kt similarity index 81% rename from app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/CancelLiveReservationRequest.kt rename to app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/CancelLiveReservationRequest.kt index 0a4fbc68..00a729aa 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/CancelLiveReservationRequest.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/CancelLiveReservationRequest.kt @@ -1,4 +1,4 @@ -package kr.co.vividnext.sodalive.live.reservation_status +package kr.co.vividnext.sodalive.live.reservation.status import androidx.annotation.Keep import com.google.gson.annotations.SerializedName diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/GetLiveReservationResponse.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/GetLiveReservationResponse.kt similarity index 92% rename from app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/GetLiveReservationResponse.kt rename to app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/GetLiveReservationResponse.kt index 0424d7f7..1061446d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/GetLiveReservationResponse.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/GetLiveReservationResponse.kt @@ -1,4 +1,4 @@ -package kr.co.vividnext.sodalive.live.reservation_status +package kr.co.vividnext.sodalive.live.reservation.status import android.os.Parcelable import androidx.annotation.Keep diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/LiveReservationCancelActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/LiveReservationCancelActivity.kt similarity index 97% rename from app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/LiveReservationCancelActivity.kt rename to app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/LiveReservationCancelActivity.kt index c1527940..72d8734d 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status/LiveReservationCancelActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/LiveReservationCancelActivity.kt @@ -1,4 +1,4 @@ -package kr.co.vividnext.sodalive.live.reservation_status +package kr.co.vividnext.sodalive.live.reservation.status import android.annotation.SuppressLint import android.content.Intent @@ -18,10 +18,10 @@ import kr.co.vividnext.sodalive.common.SodaLiveApplicationHolder import kr.co.vividnext.sodalive.databinding.ActivityLiveReservationCancelBinding import kr.co.vividnext.sodalive.extensions.convertDateFormat import kr.co.vividnext.sodalive.extensions.dpToPx -import kr.co.vividnext.sodalive.main.MainActivity import kr.co.vividnext.sodalive.mypage.can.status.CanStatusActivity import kr.co.vividnext.sodalive.settings.language.LanguageManager import kr.co.vividnext.sodalive.settings.language.LocaleHelper +import kr.co.vividnext.sodalive.v2.main.MainV2Activity import org.koin.android.ext.android.inject import java.util.Locale import java.util.TimeZone @@ -117,7 +117,7 @@ class LiveReservationCancelActivity : BaseActivity(ActivityLiveRoomB val bundle = intent?.getBundleExtra(Constants.EXTRA_DATA) ?: return showDeepLinkNavigationDialog { - val nextIntent = Intent(applicationContext, MainActivity::class.java).apply { + val nextIntent = Intent(applicationContext, MainV2Activity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) putExtra(Constants.EXTRA_DATA, bundle) } diff --git a/app/src/test/java/kr/co/vividnext/sodalive/live/LiveReservationPackageSourceTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/live/LiveReservationPackageSourceTest.kt new file mode 100644 index 00000000..61ee0191 --- /dev/null +++ b/app/src/test/java/kr/co/vividnext/sodalive/live/LiveReservationPackageSourceTest.kt @@ -0,0 +1,73 @@ +package kr.co.vividnext.sodalive.live + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import java.io.File + +class LiveReservationPackageSourceTest { + + @Test + fun `라이브 예약 현황 소스 경로는 패키지 구조와 일치한다`() { + val expectedDirectory = projectPath( + "app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status" + ) + val legacyDirectory = projectPath( + "app/src/main/java/kr/co/vividnext/sodalive/live/reservation_status" + ) + + assertTrue("Package directory not found: $expectedDirectory", expectedDirectory.isDirectory) + assertFalse("Legacy package directory remains: $legacyDirectory", legacyDirectory.exists()) + } + + @Test + fun `라이브 예약 현황 패키지는 underscore를 사용하지 않는다`() { + val sourceFiles = listOf( + "CancelLiveReservationRequest.kt", + "GetLiveReservationResponse.kt", + "LiveReservationCancelActivity.kt", + "LiveReservationStatusActivity.kt", + "LiveReservationStatusAdapter.kt", + "LiveReservationStatusViewModel.kt" + ).map { fileName -> + projectFile("app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/$fileName") + } + + sourceFiles.forEach { file -> + val source = file.readText() + assertTrue(source.contains("package kr.co.vividnext.sodalive.live.reservation.status")) + assertFalse(source.contains("package kr.co.vividnext.sodalive.live.reservation_status")) + } + } + + @Test + fun `라이브 예약 현황 참조는 underscore 없는 패키지를 사용한다`() { + val checkedSources = listOf( + projectFile("app/src/main/AndroidManifest.xml"), + projectFile("app/src/main/java/kr/co/vividnext/sodalive/di/AppDI.kt"), + projectFile("app/src/main/java/kr/co/vividnext/sodalive/live/LiveApi.kt"), + projectFile("app/src/main/java/kr/co/vividnext/sodalive/live/LiveRepository.kt") + ) + + checkedSources.forEach { file -> + val source = file.readText() + assertFalse(source.contains("kr.co.vividnext.sodalive.live.reservation_status")) + assertFalse(source.contains(".live.reservation_status.")) + } + + val manifest = checkedSources.first().readText() + assertTrue(manifest.contains(".live.reservation.status.LiveReservationStatusActivity")) + assertTrue(manifest.contains(".live.reservation.status.LiveReservationCancelActivity")) + } + + private fun projectFile(relativePath: String): File { + val candidates = listOf(File(relativePath), File("../$relativePath")) + return candidates.firstOrNull { it.exists() } + ?: error("Project file not found: $relativePath") + } + + private fun projectPath(relativePath: String): File { + val projectRoot = listOf(File("."), File("..")).first { File(it, "app").isDirectory } + return File(projectRoot, relativePath) + } +} diff --git a/app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2DirectEntrySourceTest.kt b/app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2DirectEntrySourceTest.kt new file mode 100644 index 00000000..26cecc06 --- /dev/null +++ b/app/src/test/java/kr/co/vividnext/sodalive/v2/main/MainV2DirectEntrySourceTest.kt @@ -0,0 +1,47 @@ +package kr.co.vividnext.sodalive.v2.main + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import java.io.File + +class MainV2DirectEntrySourceTest { + + @Test + fun `라이브룸 딥링크 confirm은 MainV2Activity로 이동한다`() { + val source = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/live/room/LiveRoomActivity.kt" + ).readText() + val receiverSource = source.substringAfter("private val deepLinkConfirmReceiver") + .substringBefore("// region lifecycle") + + assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.MainV2Activity")) + assertTrue(receiverSource.contains("MainV2Activity::class.java")) + assertTrue(receiverSource.contains("Intent.FLAG_ACTIVITY_CLEAR_TOP")) + assertTrue(receiverSource.contains("Intent.FLAG_ACTIVITY_SINGLE_TOP")) + assertTrue(receiverSource.contains("putExtra(Constants.EXTRA_DATA, bundle)")) + assertFalse(source.contains("import kr.co.vividnext.sodalive.main.MainActivity")) + assertFalse(receiverSource.contains("MainActivity::class.java")) + } + + @Test + fun `예약 취소의 다른 수다 예약은 MainV2Activity로 이동한다`() { + val source = projectFile( + "app/src/main/java/kr/co/vividnext/sodalive/live/reservation/status/LiveReservationCancelActivity.kt" + ).readText() + val clickSource = source.substringAfter("binding.tvOtherSudaReservation.setOnClickListener") + .substringBefore("binding.tvCheckCanStatus.setOnClickListener") + + assertTrue(source.contains("import kr.co.vividnext.sodalive.v2.main.MainV2Activity")) + assertTrue(clickSource.contains("finishAffinity()")) + assertTrue(clickSource.contains("MainV2Activity::class.java")) + assertFalse(source.contains("import kr.co.vividnext.sodalive.main.MainActivity")) + assertFalse(clickSource.contains("MainActivity::class.java")) + } + + private fun projectFile(relativePath: String): File { + val candidates = listOf(File(relativePath), File("../$relativePath")) + return candidates.firstOrNull { it.exists() } + ?: error("Project file not found: $relativePath") + } +}