Skip to content

Commit b44e39d

Browse files
committed
NEW: MovieDetailsScreen instrumented tests
1 parent 00e3445 commit b44e39d

4 files changed

Lines changed: 222 additions & 6 deletions

File tree

.idea/androidTestResultsUserPreferences.xml

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/deploymentTargetSelector.xml

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package com.adamdawi.popcornpicks.feature.movie_details.presentation.movie_details_screen
2+
3+
import androidx.compose.ui.test.assertIsDisplayed
4+
import androidx.compose.ui.test.junit4.createComposeRule
5+
import androidx.compose.ui.test.onNodeWithTag
6+
import androidx.compose.ui.test.onNodeWithText
7+
import androidx.lifecycle.SavedStateHandle
8+
import com.adamdawi.popcornpicks.core.KoinTestRule
9+
import com.adamdawi.popcornpicks.core.data.dummy.dummyDetailedMovie
10+
import com.adamdawi.popcornpicks.core.domain.util.Constants.NavArguments.MOVIE_ID
11+
import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.ERROR_SCREEN
12+
import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.LOADING_SCREEN
13+
import com.adamdawi.popcornpicks.core.domain.util.DataError
14+
import com.adamdawi.popcornpicks.core.domain.util.Result
15+
import com.adamdawi.popcornpicks.core.presentation.ui.mapping.asUiText
16+
import com.adamdawi.popcornpicks.feature.movie_details.domain.remote.MovieDetailsRepository
17+
import io.mockk.coEvery
18+
import io.mockk.mockk
19+
import kotlinx.coroutines.Dispatchers
20+
import kotlinx.coroutines.delay
21+
import org.junit.Before
22+
import org.junit.Rule
23+
import org.junit.Test
24+
import org.koin.androidx.viewmodel.dsl.viewModel
25+
import org.koin.dsl.module
26+
import org.koin.java.KoinJavaComponent.inject
27+
28+
class MovieDetailsScreenTest {
29+
30+
@get:Rule
31+
val composeTestRule = createComposeRule()
32+
33+
private val savedStateHandle = SavedStateHandle(mapOf(MOVIE_ID to "1"))
34+
private val movieDetailsRepository: MovieDetailsRepository = mockk(relaxed = true)
35+
36+
private val instrumentedTestModule = module {
37+
factory { movieDetailsRepository }
38+
factory { savedStateHandle }
39+
factory { Dispatchers.IO }
40+
viewModel { MovieDetailsViewModel(get(), get(), get()) }
41+
}
42+
43+
@get:Rule
44+
val koinTestRule = KoinTestRule(
45+
modules = listOf(instrumentedTestModule)
46+
)
47+
private val viewModel by inject<MovieDetailsViewModel>(clazz = MovieDetailsViewModel::class.java)
48+
49+
@Before
50+
fun setup() {
51+
coEvery { movieDetailsRepository.getDetailedMovie(any()) } answers {
52+
Result.Success(
53+
dummyDetailedMovie
54+
)
55+
}
56+
}
57+
58+
@Test
59+
fun movieDetailsScreen_success_correctTitleIsDisplayed() {
60+
composeTestRule.setContent {
61+
MovieDetailsScreen(
62+
viewModel = viewModel,
63+
onNavigateBack = {}
64+
)
65+
}
66+
composeTestRule.onNodeWithText("Spider-Man: No Way Home").assertExists().assertIsDisplayed()
67+
}
68+
69+
70+
@Test
71+
fun movieDetailsScreen_success_correctReleaseDateIsDisplayed() {
72+
composeTestRule.setContent {
73+
MovieDetailsScreen(
74+
viewModel = viewModel,
75+
onNavigateBack = {}
76+
)
77+
}
78+
composeTestRule.onNodeWithText("2021-12").assertExists().assertIsDisplayed()
79+
}
80+
81+
@Test
82+
fun movieDetailsScreen_success_correctRatingIsDisplayed() {
83+
composeTestRule.setContent {
84+
MovieDetailsScreen(
85+
viewModel = viewModel,
86+
onNavigateBack = {}
87+
)
88+
}
89+
composeTestRule.onNodeWithText("7.60/10").assertExists().assertIsDisplayed()
90+
}
91+
92+
@Test
93+
fun movieDetailsScreen_success_correctGenreIsDisplayed() {
94+
composeTestRule.setContent {
95+
MovieDetailsScreen(
96+
viewModel = viewModel,
97+
onNavigateBack = {}
98+
)
99+
}
100+
composeTestRule.onNodeWithText("Action").assertExists().assertIsDisplayed()
101+
}
102+
103+
@Test
104+
fun movieDetailsScreen_success_correctRuntimeIsDisplayed() {
105+
composeTestRule.setContent {
106+
MovieDetailsScreen(
107+
viewModel = viewModel,
108+
onNavigateBack = {}
109+
)
110+
}
111+
composeTestRule.onNodeWithText("2h 28m").assertExists().assertIsDisplayed()
112+
}
113+
114+
@Test
115+
fun movieDetailsScreen_success_correctOverviewIsDisplayed() {
116+
composeTestRule.setContent {
117+
MovieDetailsScreen(
118+
viewModel = viewModel,
119+
onNavigateBack = {}
120+
)
121+
}
122+
composeTestRule.onNodeWithText("Peter Parker is unmasked and no longer able to separate his normal life from the high-stakes of being a super-hero. When he asks for help from Doctor Strange the stakes become even more dangerous, forcing him to discover what it truly means to be Spider-Man.")
123+
.assertExists()
124+
.assertIsDisplayed()
125+
}
126+
127+
@Test
128+
fun movieDetailsScreen_isLoading_loadingScreenDisplayed() {
129+
coEvery { movieDetailsRepository.getDetailedMovie(any()) } coAnswers {
130+
delay(500)
131+
Result.Error(DataError.Network.UNKNOWN)
132+
}
133+
134+
composeTestRule.setContent {
135+
MovieDetailsScreen(
136+
viewModel = viewModel,
137+
onNavigateBack = {}
138+
)
139+
}
140+
141+
composeTestRule.onNodeWithTag(LOADING_SCREEN).assertExists().assertIsDisplayed()
142+
}
143+
144+
@Test
145+
fun movieDetailsScreen_error_errorScreenIsDisplayed() {
146+
coEvery { movieDetailsRepository.getDetailedMovie(any()) } answers { Result.Error(DataError.Network.UNKNOWN) }
147+
composeTestRule.setContent {
148+
MovieDetailsScreen(
149+
viewModel = viewModel,
150+
onNavigateBack = {}
151+
)
152+
}
153+
composeTestRule.onNodeWithTag(ERROR_SCREEN).assertExists().assertIsDisplayed()
154+
}
155+
156+
@Test
157+
fun movieDetailsScreen_error_correctErrorInErrorScreenDisplayed() {
158+
coEvery { movieDetailsRepository.getDetailedMovie(any()) } answers { Result.Error(DataError.Network.UNKNOWN) }
159+
composeTestRule.setContent {
160+
MovieDetailsScreen(
161+
viewModel = viewModel,
162+
onNavigateBack = {}
163+
)
164+
}
165+
composeTestRule.onNodeWithText(DataError.Network.UNKNOWN.asUiText()).assertExists().assertIsDisplayed()
166+
}
167+
}

app/src/main/java/com/adamdawi/popcornpicks/feature/movie_details/presentation/movie_details_screen/MovieDetailsViewModel.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import androidx.lifecycle.viewModelScope
66
import com.adamdawi.popcornpicks.core.domain.util.Constants.NavArguments.MOVIE_ID
77
import com.adamdawi.popcornpicks.core.domain.util.Result
88
import com.adamdawi.popcornpicks.core.presentation.ui.mapping.asUiText
9-
import com.adamdawi.popcornpicks.feature.movie_details.data.remote.MovieDetailsRepositoryImpl
9+
import com.adamdawi.popcornpicks.feature.movie_details.domain.remote.MovieDetailsRepository
1010
import kotlinx.coroutines.CoroutineDispatcher
1111
import kotlinx.coroutines.flow.MutableStateFlow
1212
import kotlinx.coroutines.flow.SharingStarted
@@ -17,9 +17,10 @@ import kotlinx.coroutines.launch
1717

1818
class MovieDetailsViewModel(
1919
private val savedStateHandle: SavedStateHandle,
20-
private val movieDetailsRepositoryImpl: MovieDetailsRepositoryImpl,
20+
private val movieDetailsRepositoryImpl: MovieDetailsRepository,
2121
private val ioDispatcher: CoroutineDispatcher
2222
): ViewModel() {
23+
//TODO unit test this viewModel
2324
private val _state = MutableStateFlow(MovieDetailsState())
2425
val state = _state.onStart {
2526
getMovieDetails(getMovieId())

0 commit comments

Comments
 (0)