Skip to content

Commit

Permalink
Merge pull request #25 from andrewafanasenko/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
andrewafanasenko authored Dec 29, 2023
2 parents 0c4573d + c9a359f commit bb68a7d
Show file tree
Hide file tree
Showing 7 changed files with 590 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import kotlinx.coroutines.test.setMain
import org.junit.rules.TestWatcher
import org.junit.runner.Description

class MainDispatcherRule @OptIn(ExperimentalCoroutinesApi::class) constructor(
val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(),
@OptIn(ExperimentalCoroutinesApi::class)
class MainDispatcherRule constructor(
private val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(),
) : TestWatcher() {
@OptIn(ExperimentalCoroutinesApi::class)

override fun starting(description: Description) {
Dispatchers.setMain(testDispatcher)
}

@OptIn(ExperimentalCoroutinesApi::class)
override fun finished(description: Description) {
Dispatchers.resetMain()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.example.tvschedule.data.show_details.repository

import com.example.tvschedule.data.search.mapper.ShowMapper
import com.example.tvschedule.data.show_details.api.ShowDetailsApi
import com.example.tvschedule.data.util.ModelUtil
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.mockito.Mockito
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever


class ShowDetailsRepositoryTest {

private val api = mock<ShowDetailsApi>()

private val showMapper = mock<ShowMapper>()

private val showDetailsRepository = ShowDetailsRepositoryImpl(
api = api,
showMapper = showMapper
)

@Test
fun `get show details success`() = runTest {
whenever(api.getShowDetails(ModelUtil.showId)).thenReturn(ModelUtil.showResponse)
whenever(showMapper.map(ModelUtil.showResponse)).thenReturn(ModelUtil.show)
val result = showDetailsRepository.getShowDetails(ModelUtil.showId)
verify(api, Mockito.times(1)).getShowDetails(ModelUtil.showId)
verify(showMapper, Mockito.times(1)).map(ModelUtil.showResponse)
assertThat(result).isEqualTo(ModelUtil.show)
}

@Test
fun `get show details failed`() = runTest {
val exception = IllegalStateException("Failed to get show details")
whenever(api.getShowDetails(ModelUtil.showId)).thenThrow(exception)
runCatching {
showDetailsRepository.getShowDetails(ModelUtil.showId)
}.onFailure { e ->
verify(api, Mockito.times(1)).getShowDetails(ModelUtil.showId)
assertThat(e).isEqualTo(exception)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -30,6 +31,8 @@ object ModelUtil {
const val showAverageRuntime = 30
val showGenres = listOf("Comedy", "Drama", "Thriller")

const val searchQuery = "query"

const val castId = 43L
const val castFullName = "John Gold"
const val castCharacterName = "Peter"
Expand Down Expand Up @@ -204,6 +207,11 @@ object ModelUtil {
seasons = seasons
)

val showDetails = ShowDetails(
show = show,
isFavorite = true
)

val showFromEntity = Show(
id = showId,
showName = showName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.example.tvschedule.presentation.favorite

import com.example.tvschedule.MainDispatcherRule
import com.example.tvschedule.data.util.ModelUtil
import com.example.tvschedule.domain.favorite.use_case.GetFavoritesUseCase
import com.example.tvschedule.domain.favorite.use_case.RemoveFromFavoritesUseCase
import com.example.tvschedule.presentation.favorite.model.FavoriteUiEvent
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.Mockito.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever


class FavoriteViewModelTest {

private val getFavoritesUseCase = mock<GetFavoritesUseCase>()

private val removeFromFavoritesUseCase = mock<RemoveFromFavoritesUseCase>()

private lateinit var viewModel : FavoriteViewModel

@get:Rule
val mainCoroutineRule = MainDispatcherRule()

@Test
fun `get favorite shows success`() = runTest {
val flow = flow { emit(listOf(ModelUtil.show)) }
whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow))
viewModel = FavoriteViewModel(
getFavoritesUseCase = getFavoritesUseCase,
removeFromFavoritesUseCase = removeFromFavoritesUseCase
)
verify(getFavoritesUseCase, times(1)).invoke()
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.searchQuery).isEmpty()
assertThat(state.shows).isNotEmpty()
}

@Test
fun `get favorite shows failed`() = runTest {
whenever(getFavoritesUseCase.invoke())
.thenReturn(Result.failure(IllegalStateException("Failed to get favorites")))
viewModel = FavoriteViewModel(
getFavoritesUseCase = getFavoritesUseCase,
removeFromFavoritesUseCase = removeFromFavoritesUseCase
)
verify(getFavoritesUseCase, times(1)).invoke()
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isTrue()
assertThat(state.searchQuery).isEmpty()
assertThat(state.shows).isEmpty()
}

@Test
fun `remove from favorite shows success`() = runTest {
val flow = flow { emit(listOf(ModelUtil.show)) }
whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow))
whenever(removeFromFavoritesUseCase.invoke(ModelUtil.showId))
.thenReturn(Result.success(Unit))
viewModel = FavoriteViewModel(
getFavoritesUseCase = getFavoritesUseCase,
removeFromFavoritesUseCase = removeFromFavoritesUseCase
)
viewModel.setEvent(FavoriteUiEvent.OnFavoriteClick(ModelUtil.showId))
verify(removeFromFavoritesUseCase, times(1)).invoke(ModelUtil.showId)
verify(getFavoritesUseCase, times(1)).invoke()
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.searchQuery).isEmpty()
assertThat(state.shows).isNotEmpty()
}

@Test
fun `handle retry event success`() = runTest {
val flow = flow { emit(listOf(ModelUtil.show)) }
whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow))
viewModel = FavoriteViewModel(
getFavoritesUseCase = getFavoritesUseCase,
removeFromFavoritesUseCase = removeFromFavoritesUseCase
)
whenever(viewModel.setEvent(FavoriteUiEvent.Retry)).thenReturn(Unit)
verify(getFavoritesUseCase, times(1)).invoke()
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.searchQuery).isEmpty()
assertThat(state.shows).isNotEmpty()
}

@Test
fun `handle query change event success`() = runTest {
val flow = flow { emit(listOf(ModelUtil.show)) }
whenever(getFavoritesUseCase.invoke()).thenReturn(Result.success(flow))
viewModel = FavoriteViewModel(
getFavoritesUseCase = getFavoritesUseCase,
removeFromFavoritesUseCase = removeFromFavoritesUseCase
)
whenever(viewModel.setEvent(FavoriteUiEvent.OnQueryChange(ModelUtil.searchQuery)))
.thenReturn(Unit)
verify(getFavoritesUseCase, times(0)).invoke()
val state = viewModel.viewState.value
assertThat(state.isError).isFalse()
assertThat(state.searchQuery).isNotEmpty()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.example.tvschedule.presentation.schedule

import com.example.tvschedule.MainDispatcherRule
import com.example.tvschedule.data.util.ModelUtil
import com.example.tvschedule.domain.schedule.use_case.GetScheduleUseCase
import com.example.tvschedule.presentation.schedule.model.ScheduleUiEvent
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever


class ScheduleViewModelTest {

private val getScheduleUseCase = mock<GetScheduleUseCase>()

private lateinit var viewModel: ScheduleViewModel

@get:Rule
val mainCoroutineRule = MainDispatcherRule()

@Test
fun `load schedule success`() = runTest {
whenever(getScheduleUseCase.invoke(any()))
.thenReturn(Result.success(ModelUtil.schedules))
viewModel = ScheduleViewModel(getScheduleUseCase)
verify(getScheduleUseCase, times(1)).invoke(any())
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.schedule).isNotEmpty()
}

@Test
fun `load schedule failed`() = runTest {
whenever(getScheduleUseCase.invoke(any()))
.thenReturn(Result.failure(IllegalStateException("Failed to load schedule")))
viewModel = ScheduleViewModel(getScheduleUseCase)
verify(getScheduleUseCase, times(1)).invoke(any())
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isTrue()
assertThat(state.schedule).isEmpty()
}

@Test
fun `handle select date event success`() = runTest {
whenever(getScheduleUseCase.invoke(any()))
.thenReturn(Result.success(ModelUtil.schedules))
viewModel = ScheduleViewModel(getScheduleUseCase)
whenever(viewModel.setEvent(ScheduleUiEvent.SelectDate(ModelUtil.scheduleDate)))
.thenReturn(Unit)
verify(getScheduleUseCase, times(1)).invoke(any())
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.schedule).isNotEmpty()
assertThat(state.selectedDate).isEqualTo(ModelUtil.scheduleDate)
}

@Test
fun `handle retry event success`() = runTest {
whenever(getScheduleUseCase.invoke(any()))
.thenReturn(Result.success(ModelUtil.schedules))
viewModel = ScheduleViewModel(getScheduleUseCase)
whenever(viewModel.setEvent(ScheduleUiEvent.Retry)).thenReturn(Unit)
verify(getScheduleUseCase, times(1)).invoke(any())
val state = viewModel.viewState.value
assertThat(state.isLoading).isFalse()
assertThat(state.isError).isFalse()
assertThat(state.schedule).isNotEmpty()
}
}
Loading

0 comments on commit bb68a7d

Please sign in to comment.