1+ package com.adamdawi.popcornpicks.feature.user_profile.presentation.profile_screen
2+
3+ import androidx.compose.ui.graphics.toArgb
4+ import androidx.compose.ui.test.assertCountEquals
5+ import androidx.compose.ui.test.assertIsDisplayed
6+ import androidx.compose.ui.test.assertIsNotDisplayed
7+ import androidx.compose.ui.test.junit4.createComposeRule
8+ import androidx.compose.ui.test.onAllNodesWithTag
9+ import androidx.compose.ui.test.onNodeWithTag
10+ import androidx.compose.ui.test.onNodeWithText
11+ import androidx.compose.ui.test.performClick
12+ import com.adamdawi.popcornpicks.R
13+ import com.adamdawi.popcornpicks.core.KoinTestRule
14+ import com.adamdawi.popcornpicks.core.domain.local.GenresPreferences
15+ import com.adamdawi.popcornpicks.core.domain.local.LikedMoviesDbRepository
16+ import com.adamdawi.popcornpicks.core.domain.model.Genre
17+ import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.ICON_LABEL_CHIP
18+ import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.LOADING_SCREEN
19+ import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.PROFILE_IMAGE
20+ import com.adamdawi.popcornpicks.core.domain.util.Constants.Tests.PROFILE_IMAGE_EDIT_CONTENT
21+ import com.adamdawi.popcornpicks.core.domain.util.DataError
22+ import com.adamdawi.popcornpicks.core.domain.util.Result
23+ import com.adamdawi.popcornpicks.core.presentation.theme.ImageRed
24+ import com.adamdawi.popcornpicks.feature.user_profile.domain.ProfileImageStyle
25+ import com.adamdawi.popcornpicks.feature.user_profile.domain.local.UserProfilePreferences
26+ import io.mockk.coEvery
27+ import io.mockk.every
28+ import io.mockk.mockk
29+ import kotlinx.coroutines.Dispatchers
30+ import kotlinx.coroutines.delay
31+ import org.junit.Before
32+ import org.junit.Rule
33+ import org.junit.Test
34+ import org.koin.androidx.viewmodel.dsl.viewModel
35+ import org.koin.dsl.module
36+ import org.koin.java.KoinJavaComponent.inject
37+
38+ class ProfileScreenTest {
39+
40+ @get: Rule
41+ val composeTestRule = createComposeRule()
42+ private val genreList = listOf (
43+ Genre (id = 36 , name = " History" ),
44+ Genre (id = 27 , name = " Horror" ),
45+ Genre (id = 10402 , name = " Music" )
46+ )
47+
48+ private val genresPreferences: GenresPreferences = mockk(relaxed = true )
49+ private val userProfilePreferences: UserProfilePreferences = mockk(relaxed = true )
50+ private val likedMoviesDbRepository: LikedMoviesDbRepository = mockk(relaxed = true )
51+
52+ private val instrumentedTestModule = module {
53+ factory { genresPreferences }
54+ factory { userProfilePreferences }
55+ factory { likedMoviesDbRepository }
56+ factory { Dispatchers .IO }
57+ viewModel { ProfileViewModel (get(), get(), get(), get()) }
58+ }
59+
60+ @get:Rule
61+ val koinTestRule = KoinTestRule (
62+ modules = listOf (instrumentedTestModule)
63+ )
64+
65+ private val viewModel by inject<ProfileViewModel >(clazz = ProfileViewModel ::class .java)
66+
67+ @Before
68+ fun setup () {
69+ every { genresPreferences.getGenres() } answers { emptyList() }
70+ coEvery { likedMoviesDbRepository.getLikedMoviesCount() } answers { Result .Success (null ) }
71+ every { userProfilePreferences.getProfileImageStyle() } answers {
72+ ProfileImageStyle (
73+ imageId = R .drawable.happy_guard,
74+ ImageRed .toArgb()
75+ )
76+ }
77+ every { userProfilePreferences.saveProfileImageStyle(any()) } answers {}
78+ }
79+
80+ @Test
81+ fun profileScreen_emptyGenresList_correctTextIsDisplayed () {
82+ composeTestRule.setContent {
83+ ProfileScreen (
84+ viewModel = viewModel,
85+ onNavigateBack = {},
86+ onNavigateToLikedMoviesScreen = {}
87+ )
88+ }
89+
90+ composeTestRule.onNodeWithText(" No genres available" ).assertExists().assertIsDisplayed()
91+ }
92+ @Test
93+ fun profileScreen_notEmptyGenresList_correctGenresAreDisplayed () {
94+ val genreIdsList = genreList.map { it.id.toString() }
95+ every { genresPreferences.getGenres() } answers { genreIdsList }
96+ composeTestRule.setContent {
97+ ProfileScreen (
98+ viewModel = viewModel,
99+ onNavigateBack = {},
100+ onNavigateToLikedMoviesScreen = {}
101+ )
102+ }
103+
104+ genreList.forEach { genre ->
105+ composeTestRule.onNodeWithText(genre.name).assertExists().assertIsDisplayed()
106+ }
107+ }
108+
109+ @Test
110+ fun profileScreen_notEmptyGenresList_correctNumberOfGenresAreDisplayed () {
111+ val genreIdsList = genreList.map { it.id.toString() }
112+ every { genresPreferences.getGenres() } answers { genreIdsList }
113+ composeTestRule.setContent {
114+ ProfileScreen (
115+ viewModel = viewModel,
116+ onNavigateBack = {},
117+ onNavigateToLikedMoviesScreen = {}
118+ )
119+ }
120+
121+ composeTestRule.onAllNodesWithTag(ICON_LABEL_CHIP ).assertCountEquals(genreIdsList.size)
122+ }
123+
124+ @Test
125+ fun profileScreen_likedMoviesCountIsNull_correctTextIsDisplayed () {
126+ composeTestRule.setContent {
127+ ProfileScreen (
128+ viewModel = viewModel,
129+ onNavigateBack = {},
130+ onNavigateToLikedMoviesScreen = {}
131+ )
132+ }
133+
134+ composeTestRule.onNodeWithText(" No movies information available" ).assertExists().assertIsDisplayed()
135+ }
136+
137+ @Test
138+ fun profileScreen_likedMoviesCountIsNotNull_correctCountIsDisplayed () {
139+ coEvery { likedMoviesDbRepository.getLikedMoviesCount() } answers { Result .Success (28 ) }
140+ composeTestRule.setContent {
141+ ProfileScreen (
142+ viewModel = viewModel,
143+ onNavigateBack = {},
144+ onNavigateToLikedMoviesScreen = {}
145+ )
146+ }
147+
148+ composeTestRule.onNodeWithText(" 28" ).assertExists().assertIsDisplayed()
149+ }
150+
151+ @Test
152+ fun profileScreen_isLoading_loadingScreenDisplayed () {
153+ coEvery { likedMoviesDbRepository.getLikedMoviesCount() } coAnswers {
154+ delay(500 )
155+ Result .Error (DataError .Local .UNKNOWN )
156+ }
157+
158+ composeTestRule.setContent {
159+ ProfileScreen (
160+ viewModel = viewModel,
161+ onNavigateBack = {},
162+ onNavigateToLikedMoviesScreen = {}
163+ )
164+ }
165+
166+ composeTestRule.onNodeWithTag(LOADING_SCREEN ).assertExists().assertIsDisplayed()
167+ }
168+
169+ @Test
170+ fun profileScreen_notShowPopupDialog_popupDialogIsNotDisplayed (){
171+ composeTestRule.setContent {
172+ ProfileScreen (
173+ viewModel = viewModel,
174+ onNavigateBack = {},
175+ onNavigateToLikedMoviesScreen = {}
176+ )
177+ }
178+
179+ composeTestRule.onNodeWithTag(PROFILE_IMAGE_EDIT_CONTENT ).assertIsNotDisplayed().assertDoesNotExist()
180+ }
181+
182+ @Test
183+ fun profileScreen_showPopupDialog_popupDialogIsDisplayed (){
184+ composeTestRule.setContent {
185+ ProfileScreen (
186+ viewModel = viewModel,
187+ onNavigateBack = {},
188+ onNavigateToLikedMoviesScreen = {}
189+ )
190+ }
191+ composeTestRule.onNodeWithTag(PROFILE_IMAGE ).performClick()
192+
193+ composeTestRule.onNodeWithTag(PROFILE_IMAGE_EDIT_CONTENT ).assertExists().assertIsDisplayed()
194+ }
195+ }
0 commit comments