Skip to content

Commit e99cdf5

Browse files
committed
Fix ResultsScreen test and clarify up confusing test setups
1 parent c6f7f82 commit e99cdf5

File tree

5 files changed

+126
-89
lines changed

5 files changed

+126
-89
lines changed

feature/results/src/androidTest/java/com/android/developers/androidify/results/ResultsScreenTest.kt

Lines changed: 86 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
*/
1616
package com.android.developers.androidify.results
1717

18+
import android.net.Uri
1819
import androidx.activity.ComponentActivity
19-
import androidx.compose.foundation.layout.PaddingValues
2020
import androidx.compose.runtime.CompositionLocalProvider
21-
import androidx.compose.runtime.mutableStateOf
2221
import androidx.compose.ui.platform.LocalInspectionMode
2322
import androidx.compose.ui.test.assertIsDisplayed
2423
import androidx.compose.ui.test.assertIsOff
@@ -27,8 +26,10 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule
2726
import androidx.compose.ui.test.onNodeWithContentDescription
2827
import androidx.compose.ui.test.onNodeWithText
2928
import androidx.compose.ui.test.performClick
30-
import androidx.compose.ui.unit.dp
3129
import androidx.test.ext.junit.runners.AndroidJUnit4
30+
import com.android.developers.androidify.data.ConfigProvider
31+
import com.android.developers.androidify.theme.SharedElementContextPreview
32+
import com.android.developers.testing.network.TestRemoteConfigDataSource
3233
import junit.framework.TestCase.assertTrue
3334
import org.junit.Rule
3435
import org.junit.Test
@@ -41,24 +42,27 @@ class ResultsScreenTest {
4142
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
4243

4344
// Create a test bitmap for testing
44-
val testUri = android.net.Uri.parse("placeholder://image")
45+
val testUri = Uri.parse("placeholder://image")
4546

4647
@Test
4748
fun resultsScreenContents_displaysActionButtons() {
4849
val shareButtonText = composeTestRule.activity.getString(R.string.customize_and_share)
4950
// Note: Download button is identified by icon, harder to test reliably without tags/desc
5051

51-
val initialState = ResultState(resultImageUri = testUri, promptText = "test")
52-
val state = mutableStateOf(initialState)
52+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
53+
val viewModel = ResultsViewModel(testUri, null, promptText = "test", configProvider)
5354

5455
composeTestRule.setContent {
55-
// Disable animation
56-
CompositionLocalProvider(LocalInspectionMode provides true) {
57-
ResultsScreenContents(
58-
contentPadding = PaddingValues(0.dp),
59-
state = state,
60-
onCustomizeShareClicked = {},
61-
)
56+
SharedElementContextPreview {
57+
// Disable animation
58+
CompositionLocalProvider(LocalInspectionMode provides true) {
59+
ResultsScreen(
60+
onBackPress = {},
61+
onAboutPress = {},
62+
onNextPress = { _, _ -> },
63+
viewModel = viewModel,
64+
)
65+
}
6266
}
6367
}
6468

@@ -77,17 +81,20 @@ class ResultsScreenTest {
7781
val frontCardDesc = composeTestRule.activity.getString(R.string.resultant_android_bot)
7882

7983
// Ensure promptText is non-null when bitmap is present
80-
val initialState = ResultState(resultImageUri = testUri, promptText = "test")
81-
val state = mutableStateOf(initialState)
84+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
85+
val viewModel = ResultsViewModel(testUri, null, promptText = "test", configProvider)
8286

8387
composeTestRule.setContent {
84-
// Disable animation
85-
CompositionLocalProvider(LocalInspectionMode provides true) {
86-
ResultsScreenContents(
87-
contentPadding = PaddingValues(0.dp),
88-
state = state,
89-
onCustomizeShareClicked = {},
90-
)
88+
SharedElementContextPreview {
89+
// Disable animation
90+
CompositionLocalProvider(LocalInspectionMode provides true) {
91+
ResultsScreen(
92+
onBackPress = {},
93+
onAboutPress = {},
94+
onNextPress = { _, _ -> },
95+
viewModel = viewModel,
96+
)
97+
}
9198
}
9299
}
93100

@@ -105,19 +112,22 @@ class ResultsScreenTest {
105112
val photoOptionText = composeTestRule.activity.getString(R.string.photo)
106113
val frontCardDesc = composeTestRule.activity.getString(R.string.resultant_android_bot)
107114
val backCardDesc = composeTestRule.activity.getString(R.string.original_image)
108-
val testUri = android.net.Uri.parse("placeholder://image")
115+
val testUri = Uri.parse("placeholder://image")
109116

110-
val initialState = ResultState(resultImageUri = testUri, originalImageUrl = testUri)
111-
val state = mutableStateOf(initialState)
117+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
118+
val viewModel = ResultsViewModel(testUri, testUri, null, configProvider)
112119

113120
composeTestRule.setContent {
114-
// Disable animation
115-
CompositionLocalProvider(LocalInspectionMode provides true) {
116-
ResultsScreenContents(
117-
contentPadding = PaddingValues(0.dp),
118-
state = state,
119-
onCustomizeShareClicked = {},
120-
)
121+
SharedElementContextPreview {
122+
// Disable animation
123+
CompositionLocalProvider(LocalInspectionMode provides true) {
124+
ResultsScreen(
125+
onBackPress = {},
126+
onAboutPress = {},
127+
onNextPress = { _, _ -> },
128+
viewModel = viewModel,
129+
)
130+
}
121131
}
122132
}
123133

@@ -137,54 +147,61 @@ class ResultsScreenTest {
137147
@Test
138148
fun toolbarOption_ClickPhoto_selectsPhoto_andShowsBackCard_Prompt() {
139149
val botOptionText = composeTestRule.activity.getString(R.string.bot)
140-
val photoOptionText = composeTestRule.activity.getString(R.string.prompt)
141-
val frontCardDesc = composeTestRule.activity.getString(R.string.resultant_android_bot)
150+
val promptOptionText = composeTestRule.activity.getString(R.string.prompt)
142151
val promptText = "test prompt"
143152
val promptPrefix = composeTestRule.activity.getString(R.string.my_bot_is_wearing)
144153

145-
val initialState = ResultState(resultImageUri = testUri, promptText = promptText) // No original image URI
146-
val state = mutableStateOf(initialState)
154+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
155+
val viewModel = ResultsViewModel(testUri, null, promptText, configProvider)
147156

148157
composeTestRule.setContent {
149-
// Disable animation
150-
CompositionLocalProvider(LocalInspectionMode provides true) {
151-
ResultsScreenContents(
152-
contentPadding = PaddingValues(0.dp),
153-
state = state,
154-
onCustomizeShareClicked = {},
155-
)
158+
SharedElementContextPreview {
159+
// Disable animation
160+
CompositionLocalProvider(LocalInspectionMode provides true) {
161+
ResultsScreen(
162+
onBackPress = {},
163+
onAboutPress = {},
164+
onNextPress = { _, _ -> },
165+
viewModel = viewModel,
166+
)
167+
}
156168
}
157169
}
158170

159171
// Click Photo option
160-
composeTestRule.onNodeWithText(photoOptionText).performClick()
172+
composeTestRule.onNodeWithText(promptOptionText).performClick()
161173

162174
// Check toolbar state
163175
composeTestRule.onNodeWithText(botOptionText).assertIsOff()
164-
composeTestRule.onNodeWithText(photoOptionText).assertIsOn()
176+
composeTestRule.onNodeWithText(promptOptionText).assertIsOn()
165177

166178
// Check back card (prompt) is visible by finding its text
167-
composeTestRule.onNodeWithText(promptPrefix + " " + promptText, substring = true).assertIsDisplayed()
179+
composeTestRule.onNodeWithText(promptPrefix + " " + promptText, substring = true)
180+
.assertIsDisplayed()
168181
}
169182

170183
@Test
171184
fun toolbarOption_ClickBot_selectsBot_andShowsFrontCard() {
172185
val botOptionText = composeTestRule.activity.getString(R.string.bot)
173186
val photoOptionText = composeTestRule.activity.getString(R.string.photo)
174187
val frontCardDesc = composeTestRule.activity.getString(R.string.resultant_android_bot)
175-
val testUri = android.net.Uri.parse("placeholder://image")
188+
val testUri = Uri.parse("placeholder://image")
189+
190+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
191+
val viewModel = ResultsViewModel(testUri, originalImageUrl = testUri, null, configProvider)
176192

177-
val initialState = ResultState(resultImageUri = testUri, originalImageUrl = testUri)
178-
val state = mutableStateOf(initialState)
179193

180194
composeTestRule.setContent {
181195
// Disable animation
182-
CompositionLocalProvider(LocalInspectionMode provides true) {
183-
ResultsScreenContents(
184-
contentPadding = PaddingValues(0.dp),
185-
state = state,
186-
onCustomizeShareClicked = {},
187-
)
196+
SharedElementContextPreview {
197+
CompositionLocalProvider(LocalInspectionMode provides true) {
198+
ResultsScreen(
199+
onBackPress = {},
200+
onAboutPress = {},
201+
onNextPress = { _, _ -> },
202+
viewModel = viewModel,
203+
)
204+
}
188205
}
189206
}
190207

@@ -209,19 +226,22 @@ class ResultsScreenTest {
209226
var shareClicked = false
210227

211228
// Ensure promptText is non-null when bitmap is present
212-
val initialState = ResultState(resultImageUri = testUri, promptText = "test")
213-
val state = mutableStateOf(initialState)
229+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
230+
val viewModel = ResultsViewModel(testUri, originalImageUrl = null, "test", configProvider)
214231

215232
composeTestRule.setContent {
216-
// Disable animation
217-
CompositionLocalProvider(LocalInspectionMode provides true) {
218-
ResultsScreenContents(
219-
contentPadding = PaddingValues(0.dp),
220-
state = state,
221-
onCustomizeShareClicked = {
222-
shareClicked = true // Callback to test
223-
},
224-
)
233+
SharedElementContextPreview {
234+
// Disable animation
235+
CompositionLocalProvider(LocalInspectionMode provides true) {
236+
ResultsScreen(
237+
onBackPress = {},
238+
onAboutPress = {},
239+
onNextPress = { _, _ ->
240+
shareClicked = true
241+
},
242+
viewModel = viewModel,
243+
)
244+
}
225245
}
226246
}
227247

feature/results/src/main/java/com/android/developers/androidify/results/ResultOption.kt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ fun ResultToolbarOption(
4141
)
4242
}
4343

44-
enum class ResultOption(val displayName: Int) {
45-
OriginalInput(R.string.photo),
46-
ResultImage(R.string.bot),
44+
enum class ResultOption {
45+
OriginalInput,
46+
ResultImage,
4747
;
4848

4949
fun toFlippableState(): FlippableState {
@@ -54,10 +54,9 @@ enum class ResultOption(val displayName: Int) {
5454
}
5555

5656
fun displayText(wasPromptUsed: Boolean): Int {
57-
return if (this == OriginalInput) {
58-
if (wasPromptUsed) return R.string.prompt else R.string.photo
59-
} else {
60-
this.displayName
57+
return when (this) {
58+
OriginalInput -> if (wasPromptUsed) R.string.prompt else R.string.photo
59+
ResultImage -> R.string.bot
6160
}
6261
}
6362
}

feature/results/src/main/java/com/android/developers/androidify/results/ResultsScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ fun ResultsScreen(
102102
}
103103

104104
@Composable
105-
private fun ResultsScreenContents(
105+
fun ResultsScreenContents(
106106
selectedResultOption: ResultOption,
107107
onResultOptionSelected: (ResultOption) -> Unit,
108108
wasPromptUsed: Boolean,

feature/results/src/screenshotTest/java/com/android/developers/androidify/results/ResultsScreenScreenshotTest.kt

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ import android.graphics.Color
2121
import android.graphics.LinearGradient
2222
import android.graphics.Paint
2323
import android.graphics.Shader
24-
import androidx.compose.foundation.layout.PaddingValues
24+
import androidx.compose.material3.SnackbarHostState
2525
import androidx.compose.runtime.Composable
2626
import androidx.compose.runtime.CompositionLocalProvider
2727
import androidx.compose.runtime.mutableStateOf
2828
import androidx.compose.runtime.remember
2929
import androidx.compose.ui.platform.LocalInspectionMode
3030
import androidx.compose.ui.tooling.preview.Preview
31-
import androidx.compose.ui.unit.dp
3231
import androidx.core.net.toUri
3332
import com.android.developers.androidify.theme.AndroidifyTheme
3433
import com.android.developers.androidify.util.AdaptivePreview
@@ -52,10 +51,15 @@ class ResultsScreenScreenshotTest {
5251
CompositionLocalProvider(value = LocalInspectionMode provides true) {
5352
AndroidifyTheme {
5453
ResultsScreenContents(
55-
contentPadding = PaddingValues(0.dp),
56-
state = state,
57-
verboseLayout = true, // Replicates ResultsScreenPreview
54+
state = state.value,
55+
snackbarHostState = SnackbarHostState(),
5856
onCustomizeShareClicked = {},
57+
selectedResultOption = ResultOption.ResultImage,
58+
onResultOptionSelected = {},
59+
wasPromptUsed = false,
60+
onBackPress = {},
61+
layoutType = ResultsLayoutType.Verbose, // Replicates ResultsScreenPreview
62+
onAboutPress = {},
5963
)
6064
}
6165
}
@@ -77,10 +81,15 @@ class ResultsScreenScreenshotTest {
7781
CompositionLocalProvider(value = LocalInspectionMode provides true) {
7882
AndroidifyTheme {
7983
ResultsScreenContents(
80-
contentPadding = PaddingValues(0.dp),
81-
state = state,
82-
verboseLayout = false, // Replicates ResultsScreenPreviewSmall
84+
state = state.value,
85+
snackbarHostState = SnackbarHostState(),
8386
onCustomizeShareClicked = {},
87+
selectedResultOption = ResultOption.ResultImage,
88+
onResultOptionSelected = {},
89+
wasPromptUsed = false,
90+
onBackPress = {},
91+
layoutType = ResultsLayoutType.Constrained, // Replicates ResultsScreenPreviewSmall
92+
onAboutPress = {},
8493
)
8594
}
8695
}
@@ -101,11 +110,15 @@ class ResultsScreenScreenshotTest {
101110
CompositionLocalProvider(value = LocalInspectionMode provides true) {
102111
AndroidifyTheme {
103112
ResultsScreenContents(
104-
contentPadding = PaddingValues(0.dp),
105-
state = state,
106-
verboseLayout = true,
113+
state = state.value,
114+
snackbarHostState = SnackbarHostState(),
107115
onCustomizeShareClicked = {},
108-
defaultSelectedResult = ResultOption.OriginalInput, // Set the non-default option
116+
selectedResultOption = ResultOption.OriginalInput, // Set the non-default option
117+
onResultOptionSelected = {},
118+
wasPromptUsed = false,
119+
onBackPress = {},
120+
layoutType = ResultsLayoutType.Verbose,
121+
onAboutPress = {},
109122
)
110123
}
111124
}

feature/results/src/test/kotlin/com/android/developers/androidify/results/ResultsViewModelTest.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package com.android.developers.androidify.results
1919

2020
import android.net.Uri
21+
import com.android.developers.androidify.data.ConfigProvider
22+
import com.android.developers.testing.network.TestRemoteConfigDataSource
2123
import com.android.developers.testing.util.MainDispatcherRule
2224
import kotlinx.coroutines.ExperimentalCoroutinesApi
2325
import kotlinx.coroutines.test.runTest
@@ -39,7 +41,8 @@ class ResultsViewModelTest {
3941

4042
@Test
4143
fun stateInitialEmpty() = runTest {
42-
val viewModel = ResultsViewModel(null, null, null)
44+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
45+
val viewModel = ResultsViewModel(null, null, null, configProvider)
4346
assertEquals(
4447
ResultState(),
4548
viewModel.state.value,
@@ -48,7 +51,8 @@ class ResultsViewModelTest {
4851

4952
@Test
5053
fun setArgumentsWithOriginalImage_isCorrect() = runTest {
51-
val viewModel = ResultsViewModel(fakeUri, originalFakeUri, null)
54+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
55+
val viewModel = ResultsViewModel(fakeUri, originalFakeUri, null, configProvider)
5256
assertEquals(
5357
ResultState(
5458
resultImageUri = fakeUri,
@@ -60,7 +64,8 @@ class ResultsViewModelTest {
6064

6165
@Test
6266
fun initialState_withPrompt_isCorrect() = runTest {
63-
val viewModel = ResultsViewModel(fakeUri, null, fakePromptText)
67+
val configProvider = ConfigProvider(TestRemoteConfigDataSource(false))
68+
val viewModel = ResultsViewModel(fakeUri, null, fakePromptText, configProvider)
6469
assertEquals(
6570
ResultState(
6671
resultImageUri = fakeUri,

0 commit comments

Comments
 (0)