PM-17404: Set app delegate on theme change (#4605)

This commit is contained in:
David Perez
2025-01-22 14:02:18 -06:00
committed by GitHub
parent 2787edbf45
commit bf60f8f9e3
13 changed files with 173 additions and 69 deletions

View File

@@ -50,6 +50,7 @@ import com.x8bit.bitwarden.data.vault.manager.model.VaultStateEvent
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppLanguage
import com.x8bit.bitwarden.ui.platform.feature.settings.appearance.model.AppTheme
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.util.isAccountSecurityShortcut
@@ -85,10 +86,12 @@ class MainViewModelTest : BaseViewModelTest() {
private val addTotpItemAuthenticatorManager = AddTotpItemFromAuthenticatorManagerImpl()
private val mutableUserStateFlow = MutableStateFlow<UserState?>(null)
private val mutableAppThemeFlow = MutableStateFlow(AppTheme.DEFAULT)
private val mutableAppLanguageFlow = MutableStateFlow(AppLanguage.DEFAULT)
private val mutableScreenCaptureAllowedFlow = MutableStateFlow(true)
private val settingsRepository = mockk<SettingsRepository> {
every { appTheme } returns AppTheme.DEFAULT
every { appThemeStateFlow } returns mutableAppThemeFlow
every { appLanguageStateFlow } returns mutableAppLanguageFlow
every { isScreenCaptureAllowed } returns true
every { isScreenCaptureAllowedStateFlow } returns mutableScreenCaptureAllowedFlow
every { storeUserHasLoggedInValue(any()) } just runs
@@ -190,6 +193,10 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
mutableUserStateFlow.value = UserState(
activeUserId = userId1,
accounts = listOf(
@@ -237,6 +244,10 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
mutableVaultStateEventFlow.tryEmit(VaultStateEvent.Unlocked(userId = "userId"))
expectNoEvents()
@@ -254,6 +265,10 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val cipherView = mockk<CipherView>()
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
accessibilitySelectionManager.emitAccessibilitySelection(cipherView = cipherView)
assertEquals(
MainEvent.CompleteAccessibilityAutofill(cipherView = cipherView),
@@ -267,6 +282,10 @@ class MainViewModelTest : BaseViewModelTest() {
val viewModel = createViewModel()
val cipherView = mockk<CipherView>()
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
autofillSelectionManager.emitAutofillSelection(cipherView = cipherView)
assertEquals(
MainEvent.CompleteAutofill(cipherView = cipherView),
@@ -291,28 +310,44 @@ class MainViewModelTest : BaseViewModelTest() {
}
@Test
fun `on AppThemeChanged should update state`() {
fun `on AppThemeChanged should update state and send event`() = runTest {
val theme = AppTheme.DARK
val viewModel = createViewModel()
assertEquals(
DEFAULT_STATE,
viewModel.stateFlow.value,
)
viewModel.trySendAction(
MainAction.Internal.ThemeUpdate(
theme = AppTheme.DARK,
),
)
assertEquals(
DEFAULT_STATE.copy(
theme = AppTheme.DARK,
),
viewModel.stateFlow.value,
)
viewModel.stateEventFlow(backgroundScope) { stateFlow, eventFlow ->
// We skip the first 2 events because they are the default appTheme and appLanguage
eventFlow.awaitItem()
eventFlow.awaitItem()
assertEquals(DEFAULT_STATE, stateFlow.awaitItem())
mutableAppThemeFlow.value = theme
assertEquals(DEFAULT_STATE.copy(theme = theme), stateFlow.awaitItem())
assertEquals(MainEvent.UpdateAppTheme(osTheme = theme.osValue), eventFlow.awaitItem())
}
verify {
settingsRepository.appTheme
settingsRepository.appThemeStateFlow
settingsRepository.appLanguageStateFlow
}
}
@Test
fun `on AppLanguageChanged should send UpdateAppLocale event`() = runTest {
val language = AppLanguage.ENGLISH_BRITISH
val viewModel = createViewModel()
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
mutableAppLanguageFlow.value = language
assertEquals(MainEvent.UpdateAppLocale(localeName = language.localeName), awaitItem())
}
verify(exactly = 1) {
settingsRepository.appLanguageStateFlow
}
}
@@ -511,12 +546,12 @@ class MainViewModelTest : BaseViewModelTest() {
)
} returns EmailTokenResult.Error(message = null)
viewModel.trySendAction(
MainAction.ReceiveFirstIntent(
intent = mockIntent,
),
)
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
viewModel.trySendAction(MainAction.ReceiveFirstIntent(intent = mockIntent))
assertEquals(
MainEvent.ShowToast(R.string.there_was_an_issue_validating_the_registration_token.asText()),
awaitItem(),
@@ -548,12 +583,12 @@ class MainViewModelTest : BaseViewModelTest() {
)
} returns EmailTokenResult.Error(message = expectedMessage)
viewModel.trySendAction(
MainAction.ReceiveFirstIntent(
intent = mockIntent,
),
)
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
viewModel.trySendAction(MainAction.ReceiveFirstIntent(intent = mockIntent))
assertEquals(
MainEvent.ShowToast(expectedMessage.asText()),
awaitItem(),
@@ -957,9 +992,12 @@ class MainViewModelTest : BaseViewModelTest() {
@Test
fun `send NavigateToDebugMenu action when OpenDebugMenu action is sent`() = runTest {
val viewModel = createViewModel()
viewModel.trySendAction(MainAction.OpenDebugMenu)
viewModel.eventFlow.test {
// We skip the first 2 events because they are the default appTheme and appLanguage
awaitItem()
awaitItem()
viewModel.trySendAction(MainAction.OpenDebugMenu)
assertEquals(MainEvent.NavigateToDebugMenu, awaitItem())
}
}