diff --git a/app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.kt b/app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.kt index 6f59ec1a..4c3fab8f 100644 --- a/app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.kt +++ b/app/src/main/java/com/threegap/bitnagil/di/data/DataSourceModule.kt @@ -20,8 +20,10 @@ import com.threegap.bitnagil.data.report.datasource.ReportDataSource import com.threegap.bitnagil.data.report.datasourceImpl.ReportDataSourceImpl import com.threegap.bitnagil.data.routine.datasource.RoutineRemoteDataSource import com.threegap.bitnagil.data.routine.datasourceImpl.RoutineRemoteDataSourceImpl -import com.threegap.bitnagil.data.user.datasource.UserDataSource -import com.threegap.bitnagil.data.user.datasourceImpl.UserDataSourceImpl +import com.threegap.bitnagil.data.user.datasource.UserLocalDataSource +import com.threegap.bitnagil.data.user.datasource.UserRemoteDataSource +import com.threegap.bitnagil.data.user.datasourceImpl.UserLocalDataSourceImpl +import com.threegap.bitnagil.data.user.datasourceImpl.UserRemoteDataSourceImpl import com.threegap.bitnagil.data.version.datasource.VersionDataSource import com.threegap.bitnagil.data.version.datasourceImpl.VersionDataSourceImpl import dagger.Binds @@ -56,7 +58,11 @@ abstract class DataSourceModule { @Binds @Singleton - abstract fun bindUserDataSource(userDataSourceImpl: UserDataSourceImpl): UserDataSource + abstract fun bindUserLocalDataSource(userLocalDataSourceImpl: UserLocalDataSourceImpl): UserLocalDataSource + + @Binds + @Singleton + abstract fun bindUserRemoteDataSource(userRemoteDataSourceImpl: UserRemoteDataSourceImpl): UserRemoteDataSource @Binds @Singleton diff --git a/data/build.gradle.kts b/data/build.gradle.kts index fcee75af..d167730e 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -20,4 +20,7 @@ dependencies { implementation(libs.bundles.retrofit) implementation(libs.play.services.location) implementation(libs.kotlinx.coroutines.play) + + testImplementation(libs.androidx.junit) + testImplementation(libs.kotlin.coroutines.test) } diff --git a/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserLocalDataSource.kt b/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserLocalDataSource.kt new file mode 100644 index 00000000..2edeebcf --- /dev/null +++ b/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserLocalDataSource.kt @@ -0,0 +1,10 @@ +package com.threegap.bitnagil.data.user.datasource + +import com.threegap.bitnagil.domain.user.model.UserProfile +import kotlinx.coroutines.flow.StateFlow + +interface UserLocalDataSource { + val userProfile: StateFlow + suspend fun saveUserProfile(userProfile: UserProfile) + fun clearCache() +} diff --git a/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserDataSource.kt b/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserRemoteDataSource.kt similarity index 85% rename from data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserDataSource.kt rename to data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserRemoteDataSource.kt index c492b8e0..dc194abc 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserDataSource.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/user/datasource/UserRemoteDataSource.kt @@ -2,6 +2,6 @@ package com.threegap.bitnagil.data.user.datasource import com.threegap.bitnagil.data.user.model.response.UserProfileResponse -interface UserDataSource { +interface UserRemoteDataSource { suspend fun fetchUserProfile(): Result } diff --git a/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserLocalDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserLocalDataSourceImpl.kt new file mode 100644 index 00000000..6d12a9a1 --- /dev/null +++ b/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserLocalDataSourceImpl.kt @@ -0,0 +1,24 @@ +package com.threegap.bitnagil.data.user.datasourceImpl + +import com.threegap.bitnagil.data.user.datasource.UserLocalDataSource +import com.threegap.bitnagil.domain.user.model.UserProfile +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class UserLocalDataSourceImpl @Inject constructor() : UserLocalDataSource { + private val _userProfile = MutableStateFlow(null) + override val userProfile: StateFlow = _userProfile.asStateFlow() + + override suspend fun saveUserProfile(userProfile: UserProfile) { + _userProfile.update { userProfile } + } + + override fun clearCache() { + _userProfile.update { null } + } +} diff --git a/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserRemoteDataSourceImpl.kt similarity index 65% rename from data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserDataSourceImpl.kt rename to data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserRemoteDataSourceImpl.kt index 9b7f9190..550725c8 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserDataSourceImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/user/datasourceImpl/UserRemoteDataSourceImpl.kt @@ -1,16 +1,14 @@ package com.threegap.bitnagil.data.user.datasourceImpl import com.threegap.bitnagil.data.common.safeApiCall -import com.threegap.bitnagil.data.user.datasource.UserDataSource +import com.threegap.bitnagil.data.user.datasource.UserRemoteDataSource import com.threegap.bitnagil.data.user.model.response.UserProfileResponse import com.threegap.bitnagil.data.user.service.UserService import javax.inject.Inject -class UserDataSourceImpl @Inject constructor( +class UserRemoteDataSourceImpl @Inject constructor( private val userService: UserService, -) : UserDataSource { +) : UserRemoteDataSource { override suspend fun fetchUserProfile(): Result = - safeApiCall { - userService.fetchUserProfile() - } + safeApiCall { userService.fetchUserProfile() } } diff --git a/data/src/main/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImpl.kt index e0506f24..19be4a5f 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImpl.kt @@ -1,14 +1,59 @@ package com.threegap.bitnagil.data.user.repositoryImpl -import com.threegap.bitnagil.data.user.datasource.UserDataSource +import com.threegap.bitnagil.data.user.datasource.UserLocalDataSource +import com.threegap.bitnagil.data.user.datasource.UserRemoteDataSource import com.threegap.bitnagil.data.user.model.response.toDomain import com.threegap.bitnagil.domain.user.model.UserProfile import com.threegap.bitnagil.domain.user.repository.UserRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import javax.inject.Inject +import javax.inject.Singleton +@Singleton class UserRepositoryImpl @Inject constructor( - private val userDataSource: UserDataSource, + private val userLocalDataSource: UserLocalDataSource, + private val userRemoteDataSource: UserRemoteDataSource, ) : UserRepository { - override suspend fun fetchUserProfile(): Result = - userDataSource.fetchUserProfile().map { it.toDomain() } + private val fetchMutex = Mutex() + + override fun observeUserProfile(): Flow> = flow { + fetchAndCacheIfNeeded().onFailure { + emit(Result.failure(it)) + return@flow + } + + emitAll( + userLocalDataSource.userProfile + .filterNotNull() + .map { Result.success(it) }, + ) + } + + override suspend fun getUserProfile(): Result { + return fetchAndCacheIfNeeded() + } + + override fun clearCache() { + userLocalDataSource.clearCache() + } + + private suspend fun fetchAndCacheIfNeeded(): Result { + userLocalDataSource.userProfile.value?.let { return Result.success(it) } + + return fetchMutex.withLock { + userLocalDataSource.userProfile.value?.let { return@withLock Result.success(it) } + + userRemoteDataSource.fetchUserProfile() + .onSuccess { response -> + userLocalDataSource.saveUserProfile(response.toDomain()) + } + .map { it.toDomain() } + } + } } diff --git a/data/src/test/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImplTest.kt b/data/src/test/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImplTest.kt new file mode 100644 index 00000000..64289259 --- /dev/null +++ b/data/src/test/java/com/threegap/bitnagil/data/user/repositoryImpl/UserRepositoryImplTest.kt @@ -0,0 +1,126 @@ +package com.threegap.bitnagil.data.user.repositoryImpl + +import com.threegap.bitnagil.data.user.datasource.UserLocalDataSource +import com.threegap.bitnagil.data.user.datasource.UserRemoteDataSource +import com.threegap.bitnagil.data.user.model.response.UserProfileResponse +import com.threegap.bitnagil.domain.user.model.UserProfile +import com.threegap.bitnagil.domain.user.repository.UserRepository +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import java.util.concurrent.atomic.AtomicInteger + +class UserRepositoryImplTest { + + private lateinit var localDataSource: FakeUserLocalDataSource + private lateinit var remoteDataSource: FakeUserRemoteDataSource + private lateinit var userRepository: UserRepository + + @Before + fun setup() { + localDataSource = FakeUserLocalDataSource() + remoteDataSource = FakeUserRemoteDataSource() + userRepository = UserRepositoryImpl(localDataSource, remoteDataSource) + } + + @Test + fun `캐시가 비어있을 때 observeUserProfile을 구독하면 Remote에서 데이터를 가져와 캐시를 업데이트해야 한다`() = + runTest { + // given + val expectedProfile = UserProfile(nickname = "TestUser") + remoteDataSource.profileResponse = UserProfileResponse(nickname = "TestUser") + + // when + // 구독(first)이 시작되는 순간 Fetch가 발생함 + val result = userRepository.observeUserProfile().first() + + // then + assertEquals(expectedProfile, result.getOrNull()) + assertEquals(1, remoteDataSource.fetchCount.get()) + assertEquals(expectedProfile, localDataSource.userProfile.value) + } + + @Test + fun `캐시가 이미 존재할 때 observeUserProfile을 구독하면 Remote를 호출하지 않고 캐시를 반환해야 한다`() = + runTest { + // given + val cachedProfile = UserProfile(nickname = "CachedUser") + localDataSource.saveUserProfile(cachedProfile) + + // when + val result = userRepository.observeUserProfile().first() + + // then + assertEquals(cachedProfile, result.getOrNull()) + assertEquals(0, remoteDataSource.fetchCount.get()) + } + + @Test + fun `여러 코루틴이 동시에 observeUserProfile을 구독해도 Remote API는 1회만 호출되어야 한다 (Race Condition 방지)`() = + runTest { + // given + remoteDataSource.profileResponse = UserProfileResponse(nickname = "RaceUser") + remoteDataSource.delayMillis = 100L // 네트워크 지연 시뮬레이션 + + // when + // 10개의 코루틴이 동시에 구독 시작 + val jobs = List(10) { + async { userRepository.observeUserProfile().first() } + } + jobs.awaitAll() + + // then + assertEquals(1, remoteDataSource.fetchCount.get()) + assertEquals("RaceUser", localDataSource.userProfile.value?.nickname) + } + + @Test + fun `clearCache를 호출하면 로컬 캐시가 초기화되어야 한다`() = + runTest { + // given + localDataSource.saveUserProfile(UserProfile(nickname = "ToDelete")) + + // when + userRepository.clearCache() + + // then + assertEquals(null, localDataSource.userProfile.value) + } + + // --- Fake Objects --- + + private class FakeUserLocalDataSource : UserLocalDataSource { + private val _userProfile = MutableStateFlow(null) + override val userProfile: StateFlow = _userProfile.asStateFlow() + + override suspend fun saveUserProfile(userProfile: UserProfile) { + _userProfile.update { userProfile } + } + + override fun clearCache() { + _userProfile.update { null } + } + } + + private class FakeUserRemoteDataSource : UserRemoteDataSource { + var profileResponse: UserProfileResponse? = null + val fetchCount = AtomicInteger(0) + var delayMillis = 0L + + override suspend fun fetchUserProfile(): Result { + if (delayMillis > 0) delay(delayMillis) + fetchCount.incrementAndGet() + return profileResponse?.let { Result.success(it) } + ?: Result.failure(Exception("No profile set in fake")) + } + } +} diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt index f8893314..b7418429 100644 --- a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt +++ b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt @@ -1,10 +1,15 @@ package com.threegap.bitnagil.domain.auth.usecase import com.threegap.bitnagil.domain.auth.repository.AuthRepository +import com.threegap.bitnagil.domain.user.repository.UserRepository import javax.inject.Inject class LogoutUseCase @Inject constructor( private val authRepository: AuthRepository, + private val userRepository: UserRepository, ) { - suspend operator fun invoke(): Result = authRepository.logout() + suspend operator fun invoke(): Result = + authRepository.logout().onSuccess { + userRepository.clearCache() + } } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt index 956a80ed..12c578a7 100644 --- a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt +++ b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt @@ -1,10 +1,15 @@ package com.threegap.bitnagil.domain.auth.usecase import com.threegap.bitnagil.domain.auth.repository.AuthRepository +import com.threegap.bitnagil.domain.user.repository.UserRepository import javax.inject.Inject class WithdrawalUseCase @Inject constructor( private val authRepository: AuthRepository, + private val userRepository: UserRepository, ) { - suspend operator fun invoke(reason: String): Result = authRepository.withdrawal(reason) + suspend operator fun invoke(reason: String): Result = + authRepository.withdrawal(reason).onSuccess { + userRepository.clearCache() + } } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/user/repository/UserRepository.kt b/domain/src/main/java/com/threegap/bitnagil/domain/user/repository/UserRepository.kt index de352843..3bc25503 100644 --- a/domain/src/main/java/com/threegap/bitnagil/domain/user/repository/UserRepository.kt +++ b/domain/src/main/java/com/threegap/bitnagil/domain/user/repository/UserRepository.kt @@ -1,7 +1,10 @@ package com.threegap.bitnagil.domain.user.repository import com.threegap.bitnagil.domain.user.model.UserProfile +import kotlinx.coroutines.flow.Flow interface UserRepository { - suspend fun fetchUserProfile(): Result + fun observeUserProfile(): Flow> + suspend fun getUserProfile(): Result + fun clearCache() } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/FetchUserProfileUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/GetUserProfileUseCase.kt similarity index 63% rename from domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/FetchUserProfileUseCase.kt rename to domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/GetUserProfileUseCase.kt index baee4a20..b07b6822 100644 --- a/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/FetchUserProfileUseCase.kt +++ b/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/GetUserProfileUseCase.kt @@ -4,9 +4,8 @@ import com.threegap.bitnagil.domain.user.model.UserProfile import com.threegap.bitnagil.domain.user.repository.UserRepository import javax.inject.Inject -class FetchUserProfileUseCase @Inject constructor( +class GetUserProfileUseCase @Inject constructor( private val userRepository: UserRepository, ) { - suspend operator fun invoke(): Result = - userRepository.fetchUserProfile() + suspend operator fun invoke(): Result = userRepository.getUserProfile() } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/ObserveUserProfileUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/ObserveUserProfileUseCase.kt new file mode 100644 index 00000000..ed371c28 --- /dev/null +++ b/domain/src/main/java/com/threegap/bitnagil/domain/user/usecase/ObserveUserProfileUseCase.kt @@ -0,0 +1,12 @@ +package com.threegap.bitnagil.domain.user.usecase + +import com.threegap.bitnagil.domain.user.model.UserProfile +import com.threegap.bitnagil.domain.user.repository.UserRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class ObserveUserProfileUseCase @Inject constructor( + private val userRepository: UserRepository, +) { + operator fun invoke(): Flow> = userRepository.observeUserProfile() +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/home/HomeViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/home/HomeViewModel.kt index 810c9a1f..3f6ded78 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/home/HomeViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/home/HomeViewModel.kt @@ -11,7 +11,7 @@ import com.threegap.bitnagil.domain.routine.usecase.FetchWeeklyRoutinesUseCase import com.threegap.bitnagil.domain.routine.usecase.GetWriteRoutineEventFlowUseCase import com.threegap.bitnagil.domain.routine.usecase.RoutineCompletionUseCase import com.threegap.bitnagil.domain.routine.usecase.ToggleRoutineUseCase -import com.threegap.bitnagil.domain.user.usecase.FetchUserProfileUseCase +import com.threegap.bitnagil.domain.user.usecase.ObserveUserProfileUseCase import com.threegap.bitnagil.presentation.screen.home.contract.HomeSideEffect import com.threegap.bitnagil.presentation.screen.home.contract.HomeState import com.threegap.bitnagil.presentation.screen.home.model.ToggleStrategy @@ -35,7 +35,7 @@ import javax.inject.Inject @HiltViewModel class HomeViewModel @Inject constructor( private val fetchWeeklyRoutinesUseCase: FetchWeeklyRoutinesUseCase, - private val fetchUserProfileUseCase: FetchUserProfileUseCase, + private val observeUserProfileUseCase: ObserveUserProfileUseCase, private val fetchDailyEmotionUseCase: FetchDailyEmotionUseCase, private val routineCompletionUseCase: RoutineCompletionUseCase, private val getWriteRoutineEventFlowUseCase: GetWriteRoutineEventFlowUseCase, @@ -185,7 +185,7 @@ class HomeViewModel @Inject constructor( private fun initialize() { intent { coroutineScope { - launch { fetchUserProfile() } + launch { observeUserProfile() } launch { fetchDailyEmotion() } launch { fetchWeeklyRoutines(state.currentWeeks) } launch { observeWriteRoutineEvent() } @@ -246,18 +246,22 @@ class HomeViewModel @Inject constructor( } } - private suspend fun fetchUserProfile() { - subIntent { - reduce { state.copy(loadingCount = state.loadingCount + 1) } - fetchUserProfileUseCase().fold( - onSuccess = { - reduce { state.copy(userNickname = it.nickname, loadingCount = state.loadingCount - 1) } - }, - onFailure = { - Log.e("HomeViewModel", "유저 정보 가져오기 실패: ${it.message}") - reduce { state.copy(loadingCount = state.loadingCount - 1) } - }, - ) + private fun observeUserProfile() { + intent { + repeatOnSubscription { + reduce { state.copy(loadingCount = state.loadingCount + 1) } + observeUserProfileUseCase().collect { result -> + result.fold( + onSuccess = { + reduce { state.copy(userNickname = it.nickname, loadingCount = state.loadingCount - 1) } + }, + onFailure = { + Log.e("HomeViewModel", "유저 정보 가져오기 실패: ${it.message}") + reduce { state.copy(loadingCount = state.loadingCount - 1) } + }, + ) + } + } } } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/mypage/MyPageViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/mypage/MyPageViewModel.kt index 1e417234..5b40610d 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/mypage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/mypage/MyPageViewModel.kt @@ -1,7 +1,7 @@ package com.threegap.bitnagil.presentation.screen.mypage import androidx.lifecycle.ViewModel -import com.threegap.bitnagil.domain.user.usecase.FetchUserProfileUseCase +import com.threegap.bitnagil.domain.user.usecase.ObserveUserProfileUseCase import com.threegap.bitnagil.presentation.screen.mypage.contract.MyPageSideEffect import com.threegap.bitnagil.presentation.screen.mypage.contract.MyPageState import dagger.hilt.android.lifecycle.HiltViewModel @@ -12,26 +12,24 @@ import javax.inject.Inject @HiltViewModel class MyPageViewModel @Inject constructor( - private val fetchUserProfileUseCase: FetchUserProfileUseCase, + private val observeUserProfileUseCase: ObserveUserProfileUseCase, ) : ContainerHost, ViewModel() { - override val container: Container = container(initialState = MyPageState.INIT) - init { - loadMyPageInfo() - } - - private fun loadMyPageInfo() = intent { - fetchUserProfileUseCase().fold( - onSuccess = { - reduce { - state.copy( - name = it.nickname, - profileUrl = "profileUrl", - ) + override val container: Container = + container( + initialState = MyPageState.INIT, + buildSettings = { repeatOnSubscribedStopTimeout = 5_000L }, + onCreate = { + repeatOnSubscription { + observeUserProfileUseCase().collect { result -> + result.fold( + onSuccess = { + reduce { state.copy(name = it.nickname, profileUrl = "profileUrl") } + }, + onFailure = {}, + ) + } } }, - onFailure = { - }, ) - } } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/onboarding/OnBoardingViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/onboarding/OnBoardingViewModel.kt index c9e6a6ca..03f54a07 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/onboarding/OnBoardingViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/screen/onboarding/OnBoardingViewModel.kt @@ -8,7 +8,7 @@ import com.threegap.bitnagil.domain.onboarding.usecase.GetOnBoardingsUseCase import com.threegap.bitnagil.domain.onboarding.usecase.GetRecommendOnBoardingRoutinesUseCase import com.threegap.bitnagil.domain.onboarding.usecase.GetUserOnBoardingUseCase import com.threegap.bitnagil.domain.onboarding.usecase.RegisterRecommendOnBoardingRoutinesUseCase -import com.threegap.bitnagil.domain.user.usecase.FetchUserProfileUseCase +import com.threegap.bitnagil.domain.user.usecase.GetUserProfileUseCase import com.threegap.bitnagil.presentation.screen.onboarding.contract.OnBoardingSideEffect import com.threegap.bitnagil.presentation.screen.onboarding.contract.OnBoardingState import com.threegap.bitnagil.presentation.screen.onboarding.model.OnBoardingItemUiModel @@ -34,7 +34,7 @@ class OnBoardingViewModel @AssistedInject constructor( private val getRecommendOnBoardingRoutinesUseCase: GetRecommendOnBoardingRoutinesUseCase, private val getOnBoardingAbstractUseCase: GetOnBoardingAbstractUseCase, private val registerRecommendOnBoardingRoutinesUseCase: RegisterRecommendOnBoardingRoutinesUseCase, - private val fetchUserProfileUseCase: FetchUserProfileUseCase, + private val getUserProfileUseCase: GetUserProfileUseCase, private val getUserOnBoardingUseCase: GetUserOnBoardingUseCase, @Assisted private val onBoardingArg: OnBoardingScreenArg, ) : ContainerHost, ViewModel() { @@ -71,7 +71,7 @@ class OnBoardingViewModel @AssistedInject constructor( } private fun loadIntro() = intent { - val userName = fetchUserProfileUseCase().getOrNull()?.nickname ?: "-" + val userName = getUserProfileUseCase().getOrNull()?.nickname ?: "-" reduce { OnBoardingState.Idle( @@ -86,7 +86,7 @@ class OnBoardingViewModel @AssistedInject constructor( } private fun loadUserOnBoarding() = intent { - val userName = fetchUserProfileUseCase().getOrNull()?.nickname ?: "-" + val userName = getUserProfileUseCase().getOrNull()?.nickname ?: "-" val userOnBoarding = getUserOnBoardingUseCase().fold( onSuccess = { it }, onFailure = {