diff --git a/core/data/src/main/java/com/youthtalk/repository/PolicyRepositoryImpl.kt b/core/data/src/main/java/com/youthtalk/repository/PolicyRepositoryImpl.kt index 9aedc322..2e77b3e6 100644 --- a/core/data/src/main/java/com/youthtalk/repository/PolicyRepositoryImpl.kt +++ b/core/data/src/main/java/com/youthtalk/repository/PolicyRepositoryImpl.kt @@ -3,49 +3,22 @@ package com.youthtalk.repository import com.core.dataapi.repository.PolicyRepository import com.core.exception.NoDataException import com.youthtalk.data.PolicyService -import com.youthtalk.dto.PolicyDetailResponse -import com.youthtalk.dto.policy.PolicyResponse import com.youthtalk.mapper.toData import com.youthtalk.mapper.toDomain import com.youthtalk.model.policy.Policy import com.youthtalk.model.policy.PolicyDetail -import com.youthtalk.utils.ErrorUtils.throwableError +import com.youthtalk.utils.ErrorUtils.createResult import javax.inject.Inject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import timber.log.Timber class PolicyRepositoryImpl @Inject constructor( private val policyService: PolicyService ) : PolicyRepository { - override fun getPolicyDetail(policyId: Long): Flow = flow { - runCatching { - policyService.getPolicyDetail(policyId) - } - .onSuccess { response -> - response.data?.let { - emit(it.toData()) - } ?: throw NoDataException("no Data") - } - .onFailure { - Timber.e("getPolicyDetail $it") - throwableError(it) - } + override suspend fun getPolicyDetail(policyId: Long): Result = createResult { + policyService.getPolicyDetail(policyId).data?.toData() ?: throw NoDataException() } - override fun getRecentlyViewPolicies(): Flow> = flow { - runCatching { - policyService.getRecentlyViewPolicies() - } - .onSuccess { response -> - response.data?.let { data -> - emit(data.map { it.toDomain() }) - } ?: throw NoDataException("no Data") - } - .onFailure { - Timber.e("PolicyRepositoryImpl getRecentlyViewPolicies error $it") - throwableError(it) - } + override suspend fun getRecentlyViewPolicies(): Result> = createResult { + policyService.getRecentlyViewPolicies().data?.map { it.toDomain() } ?: throw NoDataException() } } diff --git a/core/data/src/test/java/com/youthtalk/repository/PolicyRepositoryTest.kt b/core/data/src/test/java/com/youthtalk/repository/PolicyRepositoryTest.kt new file mode 100644 index 00000000..3f1bfa43 --- /dev/null +++ b/core/data/src/test/java/com/youthtalk/repository/PolicyRepositoryTest.kt @@ -0,0 +1,68 @@ +package com.youthtalk.repository + +import com.core.dataapi.repository.PolicyRepository +import com.youthtalk.data.PolicyService +import com.youthtalk.dto.CommonResponse +import com.youthtalk.dto.PolicyDetailResponse +import com.youthtalk.mapper.toData +import com.youthtalk.model.policy.Policy +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@RunWith(MockitoJUnitRunner::class) +class PolicyRepositoryTest { + + private lateinit var sut: PolicyRepository + + @Mock + private lateinit var policyService: PolicyService + + @Before + fun setUp() { + sut = PolicyRepositoryImpl(policyService) + } + + @Test + fun givenPolicyId_whenGetPolicyDetail_thenReturnsPolicy() { + runTest { + // given + val policyId = 3L + val policyDetailResponse = createPolicyDetailResponse() + + whenever(policyService.getPolicyDetail(policyId)).thenReturn(CommonResponse(200, "정책 조회에 성공하였습니다.", "S04", policyDetailResponse)) + + // when + val result = sut.getPolicyDetail(policyId).getOrThrow() + + // then + assertEquals(policyDetailResponse.toData(), result) + verify(policyService).getPolicyDetail(policyId) + } + } + + @Test + fun given_whenGetRecentViewPolicy_thenReturnsPolicy() { + runTest { + // given + whenever(policyService.getRecentlyViewPolicies()).thenReturn(CommonResponse(200, "요청에 성공하였습니다.", "S01", listOf())) + + // when + val result = sut.getRecentlyViewPolicies().getOrThrow() + + // then + assertEquals(listOf(), result) + verify(policyService).getRecentlyViewPolicies() + } + } + + private fun createPolicyDetailResponse(): PolicyDetailResponse { + return PolicyDetailResponse("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", true, "", "") + } +} diff --git a/core/dataApi/src/main/java/com/core/dataapi/repository/PolicyRepository.kt b/core/dataApi/src/main/java/com/core/dataapi/repository/PolicyRepository.kt index 1b434be3..209ea3f9 100644 --- a/core/dataApi/src/main/java/com/core/dataapi/repository/PolicyRepository.kt +++ b/core/dataApi/src/main/java/com/core/dataapi/repository/PolicyRepository.kt @@ -2,9 +2,8 @@ package com.core.dataapi.repository import com.youthtalk.model.policy.Policy import com.youthtalk.model.policy.PolicyDetail -import kotlinx.coroutines.flow.Flow interface PolicyRepository { - fun getPolicyDetail(policyId: Long): Flow - fun getRecentlyViewPolicies(): Flow> + suspend fun getPolicyDetail(policyId: Long): Result + suspend fun getRecentlyViewPolicies(): Result> } diff --git a/core/domain/src/main/java/com/core/domain/usercase/policy/GetRecentlyViewPolicesUseCase.kt b/core/domain/src/main/java/com/core/domain/usercase/policy/GetRecentlyViewPolicesUseCase.kt index 1d04cfc3..e1efba70 100644 --- a/core/domain/src/main/java/com/core/domain/usercase/policy/GetRecentlyViewPolicesUseCase.kt +++ b/core/domain/src/main/java/com/core/domain/usercase/policy/GetRecentlyViewPolicesUseCase.kt @@ -6,5 +6,5 @@ import javax.inject.Inject class GetRecentlyViewPolicesUseCase @Inject constructor( private val policyRepository: PolicyRepository ) { - operator fun invoke() = policyRepository.getRecentlyViewPolicies() + suspend operator fun invoke() = policyRepository.getRecentlyViewPolicies() } diff --git a/core/domain/src/main/java/com/core/domain/usercase/policydetail/GetPolicyDetailUseCase.kt b/core/domain/src/main/java/com/core/domain/usercase/policydetail/GetPolicyDetailUseCase.kt index e3796533..5e9392cc 100644 --- a/core/domain/src/main/java/com/core/domain/usercase/policydetail/GetPolicyDetailUseCase.kt +++ b/core/domain/src/main/java/com/core/domain/usercase/policydetail/GetPolicyDetailUseCase.kt @@ -3,10 +3,9 @@ package com.core.domain.usercase.policydetail import com.core.dataapi.repository.PolicyRepository import com.youthtalk.model.policy.PolicyDetail import javax.inject.Inject -import kotlinx.coroutines.flow.Flow class GetPolicyDetailUseCase @Inject constructor( private val policyRepository: PolicyRepository ) { - operator fun invoke(policyId: Long): Flow = policyRepository.getPolicyDetail(policyId) + suspend operator fun invoke(policyId: Long): Result = policyRepository.getPolicyDetail(policyId) } diff --git a/feature/home/src/main/java/com/core/home/viewmodel/NewPolicyViewModel.kt b/feature/home/src/main/java/com/core/home/viewmodel/NewPolicyViewModel.kt index 98d72093..81df4e28 100644 --- a/feature/home/src/main/java/com/core/home/viewmodel/NewPolicyViewModel.kt +++ b/feature/home/src/main/java/com/core/home/viewmodel/NewPolicyViewModel.kt @@ -62,10 +62,7 @@ class NewPolicyViewModel @Inject constructor( viewModelScope.launch { state.value.policyId?.let { policyId -> getPolicyDetailUseCase(policyId) - .catch { - Timber.e("NewPolicyViewModel refresh error $it") - } - .collectLatest { policyDetail -> + .onSuccess { policyDetail -> setState { copy( newPolicies = newPolicies.copy( diff --git a/feature/home/src/main/java/com/core/home/viewmodel/PopularPolicyViewModel.kt b/feature/home/src/main/java/com/core/home/viewmodel/PopularPolicyViewModel.kt index a5145410..334f64cb 100644 --- a/feature/home/src/main/java/com/core/home/viewmodel/PopularPolicyViewModel.kt +++ b/feature/home/src/main/java/com/core/home/viewmodel/PopularPolicyViewModel.kt @@ -50,10 +50,7 @@ class PopularPolicyViewModel @Inject constructor( viewModelScope.launch { state.value.policyId?.let { policyId -> getPolicyDetailUseCase(policyId) - .catch { - Timber.e("PopularPolicyViewModel refresh error $it") - } - .collectLatest { policyDetail -> + .onSuccess { policyDetail -> setState { copy( policies = policies.map { policy -> diff --git a/feature/policy/src/main/java/com/feature/policy/viewmodel/PolicyViewModel.kt b/feature/policy/src/main/java/com/feature/policy/viewmodel/PolicyViewModel.kt index ce1ec75f..685e654a 100644 --- a/feature/policy/src/main/java/com/feature/policy/viewmodel/PolicyViewModel.kt +++ b/feature/policy/src/main/java/com/feature/policy/viewmodel/PolicyViewModel.kt @@ -68,8 +68,7 @@ class PolicyViewModel @Inject constructor( setState { copy( recentlyPolicies = recentlyPolicies - .map { - policy -> + .map { policy -> if (policy.policyId == policyId) policy.copy(scrap = !scrap) else policy } ) @@ -81,13 +80,12 @@ class PolicyViewModel @Inject constructor( private fun refresh() { viewModelScope.launch { getRecentlyViewPolicesUseCase() - .catch { - Timber.e("PolicyViewModel refresh error $it") - } - .collectLatest { policies -> + .onSuccess { policies -> setState { copy(recentlyPolicies = policies) } + }.onFailure { + Timber.e("error $it") } } } @@ -164,8 +162,8 @@ class PolicyViewModel @Inject constructor( private fun initData() { val today = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(state.value.selectedDay) viewModelScope.launch { + val recentViewPolicies = getRecentlyViewPolicesUseCase() combine( - getRecentlyViewPolicesUseCase(), getUserUseCase(), combine( postSpecPoliciesUseCase(SearchFilter(applyDue = today), PolicyType.POLICY_TAB_DEADLINE), @@ -179,10 +177,10 @@ class PolicyViewModel @Inject constructor( ) { categoryPolicies, allCount -> Pair(categoryPolicies, allCount) } - ) { recentlyViewPolicies, user, deadlineInfo, categoryInfo -> + ) { user, deadlineInfo, categoryInfo -> PolicyUiState.initState.copy( user = user, - recentlyPolicies = recentlyViewPolicies, + recentlyPolicies = recentViewPolicies.getOrThrow(), deadlinePolicies = deadlineInfo.first.cachedIn(viewModelScope), deadlineCount = deadlineInfo.second, allCount = categoryInfo.second, diff --git a/feature/policy/src/main/java/com/feature/policy/viewmodel/RecentlyViewPolicyViewModel.kt b/feature/policy/src/main/java/com/feature/policy/viewmodel/RecentlyViewPolicyViewModel.kt index fcb55887..3f5de79c 100644 --- a/feature/policy/src/main/java/com/feature/policy/viewmodel/RecentlyViewPolicyViewModel.kt +++ b/feature/policy/src/main/java/com/feature/policy/viewmodel/RecentlyViewPolicyViewModel.kt @@ -59,8 +59,7 @@ class RecentlyViewPolicyViewModel @Inject constructor( setState { copy( policies = policies - .map { - policy -> + .map { policy -> if (policy.policyId == policyId) policy.copy(scrap = !scrap) else policy } ) @@ -72,11 +71,10 @@ class RecentlyViewPolicyViewModel @Inject constructor( private fun initData() { viewModelScope.launch { getRecentlyViewPolicesUseCase() - .catch { - Timber.e("RecentlyViewPolicyViewModel initData error $it") - } - .collectLatest { + .onSuccess { setState { copy(isLoading = false, policies = it) } + }.onFailure { + Timber.e("error : $it") } } } diff --git a/feature/policydetail/src/main/java/com/feature/policydetail/viewmode/PolicyDetailViewModel.kt b/feature/policydetail/src/main/java/com/feature/policydetail/viewmode/PolicyDetailViewModel.kt index 587c4ad3..ed1733ab 100644 --- a/feature/policydetail/src/main/java/com/feature/policydetail/viewmode/PolicyDetailViewModel.kt +++ b/feature/policydetail/src/main/java/com/feature/policydetail/viewmode/PolicyDetailViewModel.kt @@ -21,7 +21,6 @@ import java.time.LocalDateTime import javax.inject.Inject import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch import timber.log.Timber @@ -197,29 +196,19 @@ class PolicyDetailViewModel @Inject constructor( private fun initData(policyId: Long) { viewModelScope.launch { val commentInfo = getPolicyDetailCommentUseCase(policyId) + val policyDetail = getPolicyDetailUseCase(policyId) - if (commentInfo.isFailure) { - Timber.e("commentInfoError ${commentInfo.exceptionOrNull()?.message}") - return@launch - } - - combine( - getPolicyDetailUseCase(policyId), - getUserUseCase() - ) { policyDetail, user -> - PolicyDetailUiState( - isLoading = false, - user = user, - policyDetail = policyDetail, - commentInfo = commentInfo.getOrThrow(), - policyId = policyId - ) - } + getUserUseCase() .catch { - Timber.e("PolicyDetailViewModel initData error $it") - } - .collectLatest { - setState { it } + Timber.e("error $it") + }.collectLatest { user -> + PolicyDetailUiState( + isLoading = false, + user = user, + policyDetail = policyDetail.getOrThrow(), + commentInfo = commentInfo.getOrThrow(), + policyId = policyId + ) } } }