Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions app/src/main/java/org/searchmob/ui/settings/SettingsViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,28 @@ class SettingsViewModel(
viewModelScope.launch { preferences.setDynamicColor(enabled) }
}

/** Set the named theme for the light slot (light-mode themes only). Persists immediately. */
/**
* Set the named theme for the light slot (light-mode themes only). Persists immediately.
* Picking a theme is an explicit choice to use it, so Material You (which overrides the named
* themes while it is on) is switched off in the same edit; otherwise the pick appears to do
* nothing until the user finds the toggle.
*/
fun setLightTheme(themeId: String) {
viewModelScope.launch { preferences.setLightTheme(themeId) }
viewModelScope.launch {
preferences.setDynamicColor(false)
preferences.setLightTheme(themeId)
}
}

/** Set the named theme for the dark slot (dark-mode themes only). Persists immediately. */
/**
* Set the named theme for the dark slot (dark-mode themes only). Persists immediately.
* Switches Material You off for the same reason as [setLightTheme].
*/
fun setDarkTheme(themeId: String) {
viewModelScope.launch { preferences.setDarkTheme(themeId) }
viewModelScope.launch {
preferences.setDynamicColor(false)
preferences.setDarkTheme(themeId)
}
}

/** Set the base UI font size in points; clamped to the supported range by the repository. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package org.searchmob.ui.settings

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.searchmob.data.history.InMemoryHistoryStore
import org.searchmob.ui.prefs.InMemoryPreferencesStore
import org.searchmob.ui.prefs.PreferencesRepository

@OptIn(ExperimentalCoroutinesApi::class)
class SettingsViewModelThemeTest {
private val dispatcher = StandardTestDispatcher()
private lateinit var preferences: PreferencesRepository
private lateinit var viewModel: SettingsViewModel

@Before
fun setUp() {
Dispatchers.setMain(dispatcher)
preferences = PreferencesRepository(InMemoryPreferencesStore())
viewModel =
SettingsViewModel(
preferences = preferences,
historyStore = InMemoryHistoryStore(),
engineCatalog = emptyList(),
engineEnabledSink = MutableStateFlow(emptyMap()),
apiKeysSink = MutableStateFlow(emptyMap()),
)
}

@After
fun tearDown() {
Dispatchers.resetMain()
}

@Test
fun `picking a light theme switches Material You off so the pick takes effect`() =
runTest(dispatcher) {
assertTrue(preferences.preferences.first().dynamicColor) // default on

viewModel.setLightTheme("github-light")
advanceUntilIdle()

val prefs = preferences.preferences.first()
assertEquals("github-light", prefs.lightThemeId)
assertFalse(prefs.dynamicColor)
}

@Test
fun `picking a dark theme switches Material You off so the pick takes effect`() =
runTest(dispatcher) {
viewModel.setDarkTheme("dracula")
advanceUntilIdle()

val prefs = preferences.preferences.first()
assertEquals("dracula", prefs.darkThemeId)
assertFalse(prefs.dynamicColor)
}

@Test
fun `re-enabling Material You after a pick is respected`() =
runTest(dispatcher) {
viewModel.setDarkTheme("dracula")
advanceUntilIdle()
viewModel.setDynamicColor(true)
advanceUntilIdle()

val prefs = preferences.preferences.first()
assertTrue(prefs.dynamicColor)
assertEquals("dracula", prefs.darkThemeId) // the slot choice is kept
}
}