BIT-725: Replace "region" concept with Environment (#152)

This commit is contained in:
Brian Yencho
2023-10-24 11:17:10 -05:00
committed by GitHub
parent 689cc2be27
commit 4d93147186
10 changed files with 120 additions and 75 deletions

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.ui.auth.feature.landing
import android.app.Application
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsEnabled
@@ -15,6 +16,8 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performTextInput
import androidx.test.core.app.ApplicationProvider
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
@@ -29,6 +32,9 @@ import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
class LandingScreenTest : BaseComposeTest() {
private val resources
get() = ApplicationProvider.getApplicationContext<Application>().resources
@Test
fun `continue button should be enabled or disabled according to the state`() {
val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
@@ -218,8 +224,8 @@ class LandingScreenTest : BaseComposeTest() {
}
@Test
fun `selecting region should send RegionOptionSelect action`() {
val selectedRegion = LandingState.RegionOption.BITWARDEN_EU
fun `selecting environment should send EnvironmentOptionSelect action`() {
val selectedEnvironment = Environment.Eu
val viewModel = mockk<LandingViewModel>(relaxed = true) {
every { eventFlow } returns emptyFlow()
every { stateFlow } returns MutableStateFlow(DEFAULT_STATE)
@@ -234,13 +240,17 @@ class LandingScreenTest : BaseComposeTest() {
}
// Clicking to open dropdown
composeTestRule.onNodeWithText(LandingState.RegionOption.BITWARDEN_US.label).performClick()
composeTestRule
.onNodeWithText(Environment.Us.label.toString(resources))
.performClick()
// Clicking item from the dropdown menu
composeTestRule.onNodeWithText(selectedRegion.label).performClick()
composeTestRule
.onNodeWithText(selectedEnvironment.label.toString(resources))
.performClick()
verify {
viewModel.trySendAction(LandingAction.RegionOptionSelect(selectedRegion))
viewModel.trySendAction(LandingAction.EnvironmentTypeSelect(selectedEnvironment.type))
}
}
@@ -319,7 +329,7 @@ class LandingScreenTest : BaseComposeTest() {
emailInput = "",
isContinueButtonEnabled = true,
isRememberMeEnabled = false,
selectedRegion = LandingState.RegionOption.BITWARDEN_US,
selectedEnvironment = Environment.Us,
errorDialogState = BasicDialogState.Hidden,
)
}

View File

@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.auth.feature.landing
import androidx.lifecycle.SavedStateHandle
import app.cash.turbine.test
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
@@ -145,14 +146,14 @@ class LandingViewModelTest : BaseViewModelTest() {
}
@Test
fun `RegionOptionSelect should update value of selected region`() = runTest {
val inputRegion = LandingState.RegionOption.BITWARDEN_EU
fun `EnvironmentTypeSelect should update value of selected region`() = runTest {
val inputEnvironment = Environment.Eu
val viewModel = createViewModel()
viewModel.stateFlow.test {
awaitItem()
viewModel.trySendAction(LandingAction.RegionOptionSelect(inputRegion))
viewModel.trySendAction(LandingAction.EnvironmentTypeSelect(inputEnvironment.type))
assertEquals(
DEFAULT_STATE.copy(selectedRegion = LandingState.RegionOption.BITWARDEN_EU),
DEFAULT_STATE.copy(selectedEnvironment = Environment.Eu),
awaitItem(),
)
}
@@ -162,11 +163,15 @@ class LandingViewModelTest : BaseViewModelTest() {
private fun createViewModel(
rememberedEmail: String? = null,
environment: Environment = Environment.Us,
savedStateHandle: SavedStateHandle = SavedStateHandle(),
): LandingViewModel = LandingViewModel(
authRepository = mockk(relaxed = true) {
every { rememberedEmailAddress } returns rememberedEmail
},
environmentRepository = mockk(relaxed = true) {
every { this@mockk.environment } returns environment
},
savedStateHandle = savedStateHandle,
)
@@ -177,7 +182,7 @@ class LandingViewModelTest : BaseViewModelTest() {
emailInput = "",
isContinueButtonEnabled = false,
isRememberMeEnabled = false,
selectedRegion = LandingState.RegionOption.BITWARDEN_US,
selectedEnvironment = Environment.Us,
errorDialogState = BasicDialogState.Hidden,
)
}

View File

@@ -14,6 +14,7 @@ import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performTextInput
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
import io.mockk.every
@@ -37,7 +38,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -65,7 +66,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -93,7 +94,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -121,7 +122,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -161,7 +162,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -190,7 +191,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),
@@ -219,7 +220,7 @@ class LoginScreenTest : BaseComposeTest() {
captchaToken = null,
isLoginButtonEnabled = false,
passwordInput = "",
region = "",
environmentLabel = "".asText(),
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
),

View File

@@ -8,6 +8,8 @@ import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.model.LoginResult
import com.x8bit.bitwarden.data.auth.repository.util.CaptchaCallbackTokenResult
import com.x8bit.bitwarden.data.auth.repository.util.generateUriForCaptcha
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
@@ -29,7 +31,6 @@ class LoginViewModelTest : BaseViewModelTest() {
private val savedStateHandle = SavedStateHandle().also {
it["email_address"] = "test@gmail.com"
it["region_label"] = ""
}
@BeforeEach
@@ -47,7 +48,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -72,6 +75,9 @@ class LoginViewModelTest : BaseViewModelTest() {
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = handle,
)
viewModel.stateFlow.test {
@@ -84,7 +90,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -108,10 +116,13 @@ class LoginViewModelTest : BaseViewModelTest() {
)
} returns LoginResult.Error(errorMessage = "mock_error")
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
}
val environmentRepository = mockk<EnvironmentRepository> {
every { environment } returns Environment.Us
}
val viewModel = LoginViewModel(
authRepository = authRepository,
environmentRepository = environmentRepository,
savedStateHandle = savedStateHandle,
)
viewModel.stateFlow.test {
@@ -148,10 +159,12 @@ class LoginViewModelTest : BaseViewModelTest() {
login("test@gmail.com", "", captchaToken = null)
} returns LoginResult.Success
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
}
val viewModel = LoginViewModel(
authRepository = authRepository,
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
viewModel.stateFlow.test {
@@ -186,10 +199,12 @@ class LoginViewModelTest : BaseViewModelTest() {
coEvery { login("test@gmail.com", "", captchaToken = null) } returns
LoginResult.CaptchaRequired(captchaId = "mock_captcha_id")
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
}
val viewModel = LoginViewModel(
authRepository = authRepository,
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
viewModel.eventFlow.test {
@@ -207,7 +222,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -226,7 +243,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -245,7 +264,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -264,7 +285,9 @@ class LoginViewModelTest : BaseViewModelTest() {
val viewModel = LoginViewModel(
authRepository = mockk {
every { captchaTokenResultFlow } returns flowOf()
every { selectedRegionLabel } returns "bitwarden.us"
},
environmentRepository = mockk {
every { environment } returns Environment.Us
},
savedStateHandle = savedStateHandle,
)
@@ -283,7 +306,6 @@ class LoginViewModelTest : BaseViewModelTest() {
every { captchaTokenResultFlow } returns flowOf(
CaptchaCallbackTokenResult.Success("token"),
)
every { selectedRegionLabel } returns "bitwarden.us"
coEvery {
login(
"test@gmail.com",
@@ -292,8 +314,12 @@ class LoginViewModelTest : BaseViewModelTest() {
)
} returns LoginResult.Success
}
val environmentRepository = mockk<EnvironmentRepository> {
every { environment } returns Environment.Us
}
LoginViewModel(
authRepository = authRepository,
environmentRepository = environmentRepository,
savedStateHandle = savedStateHandle,
)
coVerify {
@@ -306,7 +332,7 @@ class LoginViewModelTest : BaseViewModelTest() {
emailAddress = "test@gmail.com",
passwordInput = "",
isLoginButtonEnabled = true,
region = "bitwarden.us",
environmentLabel = Environment.Us.type.label,
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
captchaToken = null,