From c9a359fd34afbc1fd4c074ed2a2aa8cc1e4e1a90 Mon Sep 17 00:00:00 2001 From: Andrii Afanasenko Date: Fri, 29 Dec 2023 18:12:05 +0200 Subject: [PATCH] Show details view model tests --- .../example/tvschedule/data/util/ModelUtil.kt | 6 + .../show_details/ShowDetailsViewModelTest.kt | 177 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 app/src/test/java/com/example/tvschedule/presentation/show_details/ShowDetailsViewModelTest.kt diff --git a/app/src/test/java/com/example/tvschedule/data/util/ModelUtil.kt b/app/src/test/java/com/example/tvschedule/data/util/ModelUtil.kt index 652f15e..dcc2d81 100644 --- a/app/src/test/java/com/example/tvschedule/data/util/ModelUtil.kt +++ b/app/src/test/java/com/example/tvschedule/data/util/ModelUtil.kt @@ -17,6 +17,7 @@ import com.example.tvschedule.domain.schedule.model.Schedule import com.example.tvschedule.domain.show_details.model.Cast import com.example.tvschedule.domain.show_details.model.Season import com.example.tvschedule.domain.show_details.model.Show +import com.example.tvschedule.domain.show_details.model.ShowDetails import java.time.LocalDate object ModelUtil { @@ -206,6 +207,11 @@ object ModelUtil { seasons = seasons ) + val showDetails = ShowDetails( + show = show, + isFavorite = true + ) + val showFromEntity = Show( id = showId, showName = showName, diff --git a/app/src/test/java/com/example/tvschedule/presentation/show_details/ShowDetailsViewModelTest.kt b/app/src/test/java/com/example/tvschedule/presentation/show_details/ShowDetailsViewModelTest.kt new file mode 100644 index 0000000..2ee3ef4 --- /dev/null +++ b/app/src/test/java/com/example/tvschedule/presentation/show_details/ShowDetailsViewModelTest.kt @@ -0,0 +1,177 @@ +package com.example.tvschedule.presentation.show_details + +import androidx.lifecycle.SavedStateHandle +import com.example.tvschedule.MainDispatcherRule +import com.example.tvschedule.data.util.ModelUtil +import com.example.tvschedule.domain.favorite.use_case.AddToFavoritesUseCase +import com.example.tvschedule.domain.favorite.use_case.GetFavoritesUseCase +import com.example.tvschedule.domain.favorite.use_case.RemoveFromFavoritesUseCase +import com.example.tvschedule.domain.show_details.model.Show +import com.example.tvschedule.domain.show_details.use_case.GetShowDetailsUseCase +import com.example.tvschedule.presentation.model.Screen +import com.example.tvschedule.presentation.show_details.model.ShowDetailsUiEvent +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.times +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + + +class ShowDetailsViewModelTest { + + private val savedStateHandle = mock() + private val getShowDetailsUseCase = mock() + private val getFavoritesUseCase = mock() + private val addToFavoritesUseCase = mock() + private val removeFromFavoritesUseCase = mock() + + private lateinit var viewModel: ShowDetailsViewModel + + @get:Rule + val mainCoroutineRule = MainDispatcherRule() + + @Test + fun `get favorite show success`() = runTest { + val flow = flow { emit(emptyList()) } + val detailsFlow = flow { emit(ModelUtil.showDetails) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)).thenReturn(detailsFlow) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + val state = viewModel.viewState.value + assertThat(state.isLoading).isFalse() + assertThat(state.isError).isFalse() + assertThat(state.isFavorite).isTrue() + } + + @Test + fun `get favorite show failed`() = runTest { + val flow = flow { emit(ModelUtil.shows) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)) + .thenReturn(flow { throw RuntimeException("Failed to get favorite show") }) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + val state = viewModel.viewState.value + assertThat(state.isLoading).isFalse() + assertThat(state.isError).isTrue() + assertThat(state.isFavorite).isTrue() + } + + @Test + fun `add to favorites success`() = runTest { + val flow = flow { emit(ModelUtil.shows) } + val detailsFlow = flow { emit(ModelUtil.showDetails.copy(isFavorite = false)) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)).thenReturn(detailsFlow) + whenever(addToFavoritesUseCase.invoke(ModelUtil.show)).thenReturn(Result.success(Unit)) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + viewModel.setEvent(ShowDetailsUiEvent.OnFavoriteClick) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + verify(addToFavoritesUseCase, times(1)).invoke(ModelUtil.show) + val state = viewModel.viewState.value + assertThat(state.isLoading).isFalse() + assertThat(state.isError).isFalse() + } + + @Test + fun `remove from favorites success`() = runTest { + val flow = flow { emit(ModelUtil.shows) } + val detailsFlow = flow { emit(ModelUtil.showDetails.copy()) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)).thenReturn(detailsFlow) + whenever(removeFromFavoritesUseCase.invoke(ModelUtil.showId)) + .thenReturn(Result.success(Unit)) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + viewModel.setEvent(ShowDetailsUiEvent.OnFavoriteClick) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + verify(removeFromFavoritesUseCase, times(1)).invoke(ModelUtil.showId) + val state = viewModel.viewState.value + assertThat(state.isLoading).isFalse() + assertThat(state.isError).isFalse() + } + + @Test + fun `show all casts success`() = runTest { + val flow = flow { emit(ModelUtil.shows) } + val detailsFlow = flow { emit(ModelUtil.showDetails) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)).thenReturn(detailsFlow) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + viewModel.setEvent(ShowDetailsUiEvent.OnShowAllCastClick) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + val state = viewModel.viewState.value + assertThat(state.isViewAllCastButtonVisible).isFalse() + } + + @Test + fun `show all seasons success`() = runTest { + val flow = flow { emit(ModelUtil.shows) } + val detailsFlow = flow { emit(ModelUtil.showDetails) } + whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow)) + whenever(getShowDetailsUseCase.invoke(ModelUtil.showId)).thenReturn(detailsFlow) + whenever(savedStateHandle.get(Screen.SHOW_ID) as? Long).thenReturn(ModelUtil.showId) + viewModel = ShowDetailsViewModel( + savedStateHandle = savedStateHandle, + getShowDetailsUseCase = getShowDetailsUseCase, + getFavoritesUseCase = getFavoritesUseCase, + addToFavoritesUseCase = addToFavoritesUseCase, + removeFromFavoritesUseCase = removeFromFavoritesUseCase + ) + viewModel.setEvent(ShowDetailsUiEvent.OnShowAllSeasonsClick) + verify(savedStateHandle, times(1)).get(Screen.SHOW_ID) as? Long + verify(getFavoritesUseCase, times(1)).invoke() + verify(getShowDetailsUseCase, times(1)).invoke(ModelUtil.showId) + val state = viewModel.viewState.value + assertThat(state.isViewAllSeasonsButtonVisible).isFalse() + } +}