Skip to content

Commit 6d3cfbc

Browse files
frettclaude
andcommitted
Migrate ToolsLayout Paparazzi tests into DashboardLayoutPaparazziTest
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 73b73e0 commit 6d3cfbc

2 files changed

Lines changed: 185 additions & 145 deletions

File tree

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package org.cru.godtools.ui.dashboard
2+
3+
import androidx.activity.compose.LocalActivityResultRegistryOwner
4+
import androidx.compose.runtime.CompositionLocalProvider
5+
import androidx.compose.runtime.mutableStateOf
6+
import app.cash.paparazzi.DeviceConfig
7+
import coil.Coil
8+
import coil.ImageLoader
9+
import coil.annotation.ExperimentalCoilApi
10+
import coil.test.FakeImageLoaderEngine
11+
import com.android.resources.NightMode
12+
import com.google.testing.junit.testparameterinjector.TestParameter
13+
import com.google.testing.junit.testparameterinjector.TestParameterInjector
14+
import com.slack.circuit.foundation.Circuit
15+
import com.slack.circuit.foundation.CircuitCompositionLocals
16+
import com.slack.circuit.runtime.presenter.presenterOf
17+
import io.mockk.mockk
18+
import java.util.Locale
19+
import kotlin.test.AfterTest
20+
import kotlin.test.BeforeTest
21+
import kotlin.test.Ignore
22+
import kotlin.test.Test
23+
import kotlinx.collections.immutable.persistentListOf
24+
import kotlinx.coroutines.Dispatchers
25+
import kotlinx.coroutines.ExperimentalCoroutinesApi
26+
import kotlinx.coroutines.test.UnconfinedTestDispatcher
27+
import kotlinx.coroutines.test.resetMain
28+
import kotlinx.coroutines.test.setMain
29+
import org.cru.godtools.base.ui.BasePaparazziTest
30+
import org.cru.godtools.base.ui.circuit.screen.dashboard.page.ToolsScreen
31+
import org.cru.godtools.model.Language
32+
import org.cru.godtools.model.Tool
33+
import org.cru.godtools.model.randomTool
34+
import org.cru.godtools.ui.dashboard.DashboardPresenter.UiState
35+
import org.cru.godtools.ui.dashboard.filters.FilterMenu
36+
import org.cru.godtools.ui.dashboard.tools.ToolFiltersStateProducer.Filters
37+
import org.cru.godtools.ui.dashboard.tools.ToolsLayout
38+
import org.cru.godtools.ui.dashboard.tools.ToolsPresenter
39+
import org.cru.godtools.ui.tools.ToolCardStateTestData
40+
import org.junit.Assume.assumeTrue
41+
import org.junit.runner.RunWith
42+
43+
@RunWith(TestParameterInjector::class)
44+
class DashboardLayoutPaparazziTest(
45+
@TestParameter(valuesProvider = DeviceConfigProvider::class) deviceConfig: DeviceConfig,
46+
@TestParameter nightMode: NightMode,
47+
@TestParameter accessibilityMode: AccessibilityMode,
48+
) : BasePaparazziTest(deviceConfig = deviceConfig, nightMode = nightMode, accessibilityMode = accessibilityMode) {
49+
private val state = UiState()
50+
51+
@BeforeTest
52+
@OptIn(ExperimentalCoilApi::class, ExperimentalCoroutinesApi::class)
53+
fun setup() {
54+
Dispatchers.setMain(UnconfinedTestDispatcher())
55+
Coil.setImageLoader(
56+
ImageLoader.Builder(paparazzi.context)
57+
.components {
58+
add(
59+
FakeImageLoaderEngine.Builder()
60+
.intercept(ToolCardStateTestData.banner, ToolCardStateTestData.bannerDrawable)
61+
.build()
62+
)
63+
}
64+
.build()
65+
)
66+
}
67+
68+
@AfterTest
69+
@OptIn(ExperimentalCoroutinesApi::class)
70+
fun cleanup() {
71+
Coil.reset()
72+
Dispatchers.resetMain()
73+
}
74+
75+
// region ToolsLayout
76+
private var toolsState = ToolsPresenter.UiState(
77+
isPersonalizationEnabled = true,
78+
dataLoaded = true,
79+
spotlightTools = listOf(
80+
ToolCardStateTestData.tool.copy(toolCode = "spotlight1", tool = randomTool("spotlight1", isFavorite = false)),
81+
ToolCardStateTestData.tool.copy(toolCode = "spotlight2", tool = randomTool("spotlight2", isFavorite = true)),
82+
ToolCardStateTestData.tool.copy(toolCode = "spotlight3", tool = randomTool("spotlight3", isFavorite = false)),
83+
),
84+
tools = listOf(
85+
ToolCardStateTestData.tool.copy(toolCode = "tool1"),
86+
ToolCardStateTestData.tool.copy(toolCode = "tool2"),
87+
ToolCardStateTestData.tool.copy(toolCode = "tool3"),
88+
),
89+
)
90+
91+
@Test
92+
fun `ToolsLayout() - Data Not Loaded`() {
93+
assumeTrue(
94+
"Disable Accessibility screenshots since this doesn't have any addition",
95+
accessibilityMode == AccessibilityMode.NO_ACCESSIBILITY
96+
)
97+
toolsState = toolsState.copy(dataLoaded = false, tools = emptyList())
98+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
99+
}
100+
101+
@Test
102+
fun `ToolsLayout() - Personalization`() {
103+
toolsState = toolsState.copy(mode = ToolsPresenter.UiState.Mode.PERSONALIZATION)
104+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
105+
}
106+
107+
@Test
108+
fun `ToolsLayout() - Personalization - No Tools`() {
109+
toolsState = toolsState.copy(
110+
mode = ToolsPresenter.UiState.Mode.PERSONALIZATION,
111+
tools = emptyList()
112+
)
113+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
114+
}
115+
116+
@Test
117+
fun `ToolsLayout() - All Tools`() {
118+
toolsState = toolsState.copy(
119+
mode = ToolsPresenter.UiState.Mode.ALL_TOOLS,
120+
spotlightTools = emptyList(),
121+
)
122+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
123+
}
124+
125+
@Test
126+
fun `ToolsLayout() - All Tools - Filters Selected`() {
127+
toolsState = toolsState.copy(
128+
mode = ToolsPresenter.UiState.Mode.ALL_TOOLS,
129+
filters = Filters(
130+
categoryFilter = FilterMenu.UiState(selectedItem = Tool.CATEGORY_GOSPEL),
131+
languageFilter = FilterMenu.UiState(
132+
selectedItem = Language(Locale.ENGLISH),
133+
menuExpanded = mutableStateOf(false),
134+
),
135+
),
136+
spotlightTools = emptyList(),
137+
)
138+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
139+
}
140+
141+
@Test
142+
@Ignore("LayoutLib does not correctly support Popups/Windows currently")
143+
fun `ToolsLayout() - All Tools - Language Filter Expanded`() {
144+
toolsState = toolsState.copy(
145+
filters = Filters(
146+
languageFilter = FilterMenu.UiState(
147+
selectedItem = Language(Locale.ENGLISH),
148+
menuExpanded = mutableStateOf(true),
149+
items = persistentListOf(
150+
FilterMenu.UiState.Item(null, 0),
151+
FilterMenu.UiState.Item(Language(Locale.ENGLISH), 12345),
152+
FilterMenu.UiState.Item(Language(Locale.FRENCH), 1),
153+
FilterMenu.UiState.Item(Language(Locale("es")), 3),
154+
),
155+
)
156+
)
157+
)
158+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
159+
}
160+
161+
@Test
162+
fun `ToolsLayout() - No Personalization`() {
163+
toolsState = toolsState.copy(isPersonalizationEnabled = false)
164+
snapshotDashboardLayout(state.copy(initialPage = ToolsScreen))
165+
}
166+
// endregion ToolsLayout
167+
168+
private val circuit = Circuit.Builder()
169+
.addPresenter<ToolsScreen, ToolsPresenter.UiState> { _, _, _ -> presenterOf { toolsState } }
170+
.addUi<ToolsScreen, ToolsPresenter.UiState> { state, modifier -> ToolsLayout(state, modifier) }
171+
.build()
172+
173+
private fun snapshotDashboardLayout(state: UiState = this.state) = snapshot {
174+
CircuitCompositionLocals(circuit) {
175+
CompositionLocalProvider(
176+
// mock required for AppUpdateSnackbar
177+
LocalActivityResultRegistryOwner provides mockk(relaxed = true),
178+
// mock required for AppUpdateSnackbar
179+
LocalAppUpdateManager provides mockk(relaxed = true)
180+
) {
181+
DashboardLayout(state)
182+
}
183+
}
184+
}
185+
}

app/src/testDebug/kotlin/org/cru/godtools/ui/dashboard/tools/ToolsLayoutPaparazziTest.kt

Lines changed: 0 additions & 145 deletions
This file was deleted.

0 commit comments

Comments
 (0)