Add AccountAutoConfig contract and view model
This commit is contained in:
parent
a644d37742
commit
fd3dfb3235
11 changed files with 365 additions and 4 deletions
|
@ -1,6 +1,7 @@
|
|||
package app.k9mail.feature.account.setup
|
||||
|
||||
import app.k9mail.feature.account.setup.ui.AccountSetupViewModel
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigViewModel
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigContract
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigValidator
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigViewModel
|
||||
|
@ -20,6 +21,7 @@ val featureAccountSetupModule: Module = module {
|
|||
factory<AccountOptionsContract.Validator> { AccountOptionsValidator() }
|
||||
|
||||
viewModel { AccountSetupViewModel() }
|
||||
viewModel { AccountAutoConfigViewModel() }
|
||||
viewModel {
|
||||
AccountIncomingConfigViewModel(
|
||||
validator = get(),
|
||||
|
|
|
@ -7,7 +7,9 @@ import app.k9mail.feature.account.setup.ui.AccountSetupContract.Effect
|
|||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.SetupStep
|
||||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.ViewModel
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigScreen
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigViewModel
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigContract
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigScreen
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigViewModel
|
||||
|
@ -24,6 +26,7 @@ fun AccountSetupScreen(
|
|||
onFinish: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
viewModel: ViewModel = koinViewModel<AccountSetupViewModel>(),
|
||||
autoConfigViewModel: AccountAutoConfigContract.ViewModel = koinViewModel<AccountAutoConfigViewModel>(),
|
||||
incomingViewModel: AccountIncomingConfigContract.ViewModel = koinViewModel<AccountIncomingConfigViewModel>(),
|
||||
outgoingViewModel: AccountOutgoingConfigContract.ViewModel = koinViewModel<AccountOutgoingConfigViewModel>(),
|
||||
optionsViewModel: AccountOptionsContract.ViewModel = koinViewModel<AccountOptionsViewModel>(),
|
||||
|
@ -40,6 +43,7 @@ fun AccountSetupScreen(
|
|||
AccountAutoConfigScreen(
|
||||
onNext = { dispatch(Event.OnNext) },
|
||||
onBack = { dispatch(Event.OnBack) },
|
||||
viewModel = autoConfigViewModel,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,13 @@ import app.k9mail.core.ui.compose.designsystem.template.ResponsiveWidthContainer
|
|||
import app.k9mail.core.ui.compose.theme.K9Theme
|
||||
import app.k9mail.core.ui.compose.theme.MainTheme
|
||||
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
|
||||
@Composable
|
||||
internal fun AccountAutoConfigContent(
|
||||
state: State,
|
||||
onEvent: (Event) -> Unit,
|
||||
contentPadding: PaddingValues,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
@ -39,6 +43,8 @@ internal fun AccountAutoConfigContent(
|
|||
) {
|
||||
item {
|
||||
AccountSetupEmailForm(
|
||||
state = state,
|
||||
onEvent = onEvent,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
|
@ -48,6 +54,8 @@ internal fun AccountAutoConfigContent(
|
|||
|
||||
@Composable
|
||||
private fun AccountSetupEmailForm(
|
||||
state: State,
|
||||
onEvent: (Event) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
|
@ -55,8 +63,8 @@ private fun AccountSetupEmailForm(
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
TextFieldOutlined(
|
||||
value = "",
|
||||
onValueChange = { /*TODO*/ },
|
||||
value = state.emailAddress.value,
|
||||
onValueChange = { onEvent(Event.EmailAddressChanged(it)) },
|
||||
label = "Email address",
|
||||
)
|
||||
}
|
||||
|
@ -67,6 +75,8 @@ private fun AccountSetupEmailForm(
|
|||
internal fun AccountAutoConfigContentK9Preview() {
|
||||
K9Theme {
|
||||
AccountAutoConfigContent(
|
||||
state = State(),
|
||||
onEvent = {},
|
||||
contentPadding = PaddingValues(),
|
||||
)
|
||||
}
|
||||
|
@ -77,6 +87,8 @@ internal fun AccountAutoConfigContentK9Preview() {
|
|||
internal fun AccountAutoConfigContentThunderbirdPreview() {
|
||||
ThunderbirdTheme {
|
||||
AccountAutoConfigContent(
|
||||
state = State(),
|
||||
onEvent = {},
|
||||
contentPadding = PaddingValues(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.UnidirectionalViewModel
|
||||
import app.k9mail.feature.account.setup.domain.entity.AutoConfig
|
||||
import app.k9mail.feature.account.setup.domain.input.StringInputField
|
||||
|
||||
interface AccountAutoConfigContract {
|
||||
|
||||
enum class ConfigStep {
|
||||
EMAIL_ADDRESS,
|
||||
OAUTH,
|
||||
PASSWORD,
|
||||
}
|
||||
|
||||
interface ViewModel : UnidirectionalViewModel<State, Event, Effect> {
|
||||
fun initState(state: State)
|
||||
}
|
||||
|
||||
data class State(
|
||||
val configStep: ConfigStep = ConfigStep.EMAIL_ADDRESS,
|
||||
val emailAddress: StringInputField = StringInputField(),
|
||||
val password: StringInputField = StringInputField(),
|
||||
val autoConfig: AutoConfig? = null,
|
||||
val errorMessage: String? = null,
|
||||
val isLoading: Boolean = false,
|
||||
)
|
||||
|
||||
sealed class Event {
|
||||
data class EmailAddressChanged(val emailAddress: String) : Event()
|
||||
data class PasswordChanged(val password: String) : Event()
|
||||
|
||||
object OnRetryClicked : Event()
|
||||
object OnNextClicked : Event()
|
||||
object OnBackClicked : Event()
|
||||
}
|
||||
|
||||
sealed class Effect {
|
||||
object NavigateNext : Effect()
|
||||
object NavigateBack : Effect()
|
||||
}
|
||||
}
|
|
@ -4,10 +4,14 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.k9mail.core.ui.compose.common.DevicePreviews
|
||||
import app.k9mail.core.ui.compose.common.mvi.observe
|
||||
import app.k9mail.core.ui.compose.designsystem.template.Scaffold
|
||||
import app.k9mail.core.ui.compose.theme.K9Theme
|
||||
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
|
||||
import app.k9mail.feature.account.setup.R
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ViewModel
|
||||
import app.k9mail.feature.account.setup.ui.common.AccountSetupBottomBar
|
||||
import app.k9mail.feature.account.setup.ui.common.AccountSetupTopHeader
|
||||
|
||||
|
@ -15,8 +19,16 @@ import app.k9mail.feature.account.setup.ui.common.AccountSetupTopHeader
|
|||
fun AccountAutoConfigScreen(
|
||||
onNext: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
viewModel: ViewModel,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val (state, dispatch) = viewModel.observe { effect ->
|
||||
when (effect) {
|
||||
Effect.NavigateBack -> onBack()
|
||||
Effect.NavigateNext -> onNext()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AccountSetupTopHeader()
|
||||
|
@ -25,13 +37,15 @@ fun AccountAutoConfigScreen(
|
|||
AccountSetupBottomBar(
|
||||
nextButtonText = stringResource(id = R.string.account_setup_button_next),
|
||||
backButtonText = stringResource(id = R.string.account_setup_button_back),
|
||||
onNextClick = onNext,
|
||||
onBackClick = onBack,
|
||||
onNextClick = { dispatch(Event.OnNextClicked) },
|
||||
onBackClick = { dispatch(Event.OnBackClicked) },
|
||||
)
|
||||
},
|
||||
modifier = modifier,
|
||||
) { innerPadding ->
|
||||
AccountAutoConfigContent(
|
||||
state = state.value,
|
||||
onEvent = { dispatch(it) },
|
||||
contentPadding = innerPadding,
|
||||
)
|
||||
}
|
||||
|
@ -44,6 +58,7 @@ internal fun AccountAutoConfigScreenK9Preview() {
|
|||
AccountAutoConfigScreen(
|
||||
onNext = {},
|
||||
onBack = {},
|
||||
viewModel = AccountAutoConfigViewModel(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +70,7 @@ internal fun AccountAutoConfigScreenThunderbirdPreview() {
|
|||
AccountAutoConfigScreen(
|
||||
onNext = {},
|
||||
onBack = {},
|
||||
viewModel = AccountAutoConfigViewModel(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.BaseViewModel
|
||||
import app.k9mail.feature.account.setup.domain.input.StringInputField
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ConfigStep.EMAIL_ADDRESS
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ConfigStep.OAUTH
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ConfigStep.PASSWORD
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ViewModel
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class AccountAutoConfigViewModel(
|
||||
initialState: State = State(),
|
||||
) : BaseViewModel<State, Event, Effect>(initialState), ViewModel {
|
||||
|
||||
override fun initState(state: State) {
|
||||
updateState {
|
||||
state.copy()
|
||||
}
|
||||
}
|
||||
|
||||
override fun event(event: Event) {
|
||||
when (event) {
|
||||
is Event.EmailAddressChanged -> changeEmailAddress(event.emailAddress)
|
||||
is Event.PasswordChanged -> changePassword(event.password)
|
||||
Event.OnNextClicked -> submit()
|
||||
Event.OnBackClicked -> navigateBack()
|
||||
Event.OnRetryClicked -> retry()
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeEmailAddress(emailAddress: String) {
|
||||
updateState {
|
||||
State(
|
||||
emailAddress = StringInputField(value = emailAddress),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changePassword(password: String) {
|
||||
updateState {
|
||||
it.copy(
|
||||
password = it.password.updateValue(password),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun submit() {
|
||||
when (state.value.configStep) {
|
||||
EMAIL_ADDRESS -> submitEmail()
|
||||
PASSWORD -> submitPassword()
|
||||
OAUTH -> TODO()
|
||||
}
|
||||
}
|
||||
|
||||
private fun retry() {
|
||||
TODO()
|
||||
}
|
||||
|
||||
private fun submitEmail() {
|
||||
navigateNext()
|
||||
}
|
||||
|
||||
private fun submitPassword() {
|
||||
navigateNext()
|
||||
}
|
||||
|
||||
private fun navigateBack() = emitEffect(Effect.NavigateBack)
|
||||
|
||||
private fun navigateNext() = emitEffect(Effect.NavigateNext)
|
||||
}
|
|
@ -7,6 +7,7 @@ import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
|
|||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.SetupStep
|
||||
import app.k9mail.feature.account.setup.ui.AccountSetupContract.State
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.FakeAccountAutoConfigViewModel
|
||||
import app.k9mail.feature.account.setup.ui.incoming.FakeAccountIncomingConfigViewModel
|
||||
import app.k9mail.feature.account.setup.ui.options.FakeAccountOptionsViewModel
|
||||
import app.k9mail.feature.account.setup.ui.outgoing.FakeAccountOutgoingConfigViewModel
|
||||
|
@ -22,6 +23,7 @@ class AccountSetupScreenKtTest : ComposeTest() {
|
|||
@Test
|
||||
fun `should display correct screen for every setup step`() = runTest {
|
||||
val viewModel = FakeAccountSetupViewModel()
|
||||
val autoConfigViewModel = FakeAccountAutoConfigViewModel()
|
||||
val incomingViewModel = FakeAccountIncomingConfigViewModel()
|
||||
val outgoingViewModel = FakeAccountOutgoingConfigViewModel()
|
||||
val optionsViewModel = FakeAccountOptionsViewModel()
|
||||
|
@ -32,6 +34,7 @@ class AccountSetupScreenKtTest : ComposeTest() {
|
|||
onFinish = { },
|
||||
onBack = { },
|
||||
viewModel = viewModel,
|
||||
autoConfigViewModel = autoConfigViewModel,
|
||||
incomingViewModel = incomingViewModel,
|
||||
outgoingViewModel = outgoingViewModel,
|
||||
optionsViewModel = optionsViewModel,
|
||||
|
@ -49,6 +52,7 @@ class AccountSetupScreenKtTest : ComposeTest() {
|
|||
fun `should delegate navigation effects`() = runTest {
|
||||
val initialState = State()
|
||||
val viewModel = FakeAccountSetupViewModel(initialState)
|
||||
val autoConfigViewModel = FakeAccountAutoConfigViewModel()
|
||||
val incomingViewModel = FakeAccountIncomingConfigViewModel()
|
||||
val outgoingViewModel = FakeAccountOutgoingConfigViewModel()
|
||||
val optionsViewModel = FakeAccountOptionsViewModel()
|
||||
|
@ -61,6 +65,7 @@ class AccountSetupScreenKtTest : ComposeTest() {
|
|||
onFinish = { onFinishCounter++ },
|
||||
onBack = { onBackCounter++ },
|
||||
viewModel = viewModel,
|
||||
autoConfigViewModel = autoConfigViewModel,
|
||||
incomingViewModel = incomingViewModel,
|
||||
outgoingViewModel = outgoingViewModel,
|
||||
optionsViewModel = optionsViewModel,
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.k9mail.core.ui.compose.testing.ComposeTest
|
||||
import app.k9mail.core.ui.compose.testing.setContent
|
||||
import app.k9mail.core.ui.compose.theme.ThunderbirdTheme
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AccountAutoConfigScreenKtTest : ComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `should delegate navigation effects`() = runTest {
|
||||
val initialState = State()
|
||||
val viewModel = FakeAccountAutoConfigViewModel(initialState)
|
||||
var onNextCounter = 0
|
||||
var onBackCounter = 0
|
||||
|
||||
setContent {
|
||||
ThunderbirdTheme {
|
||||
AccountAutoConfigScreen(
|
||||
onNext = { onNextCounter++ },
|
||||
onBack = { onBackCounter++ },
|
||||
viewModel = viewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(onNextCounter).isEqualTo(0)
|
||||
assertThat(onBackCounter).isEqualTo(0)
|
||||
|
||||
viewModel.effect(Effect.NavigateNext)
|
||||
|
||||
assertThat(onNextCounter).isEqualTo(1)
|
||||
assertThat(onBackCounter).isEqualTo(0)
|
||||
|
||||
viewModel.effect(Effect.NavigateBack)
|
||||
|
||||
assertThat(onNextCounter).isEqualTo(1)
|
||||
assertThat(onBackCounter).isEqualTo(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.k9mail.feature.account.setup.domain.input.StringInputField
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ConfigStep
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
import assertk.all
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.prop
|
||||
import org.junit.Test
|
||||
|
||||
class AccountAutoConfigStateTest {
|
||||
|
||||
@Test
|
||||
fun `should set default values`() {
|
||||
val state = State()
|
||||
|
||||
assertThat(state).all {
|
||||
prop(State::configStep).isEqualTo(ConfigStep.EMAIL_ADDRESS)
|
||||
prop(State::emailAddress).isEqualTo(StringInputField())
|
||||
prop(State::password).isEqualTo(StringInputField())
|
||||
prop(State::autoConfig).isEqualTo(null)
|
||||
prop(State::errorMessage).isEqualTo(null)
|
||||
prop(State::isLoading).isEqualTo(false)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.cash.turbine.testIn
|
||||
import app.k9mail.core.ui.compose.testing.MainDispatcherRule
|
||||
import app.k9mail.feature.account.setup.domain.input.StringInputField
|
||||
import app.k9mail.feature.account.setup.testing.eventStateTest
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ConfigStep
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
import assertk.assertions.assertThatAndTurbinesConsumed
|
||||
import assertk.assertions.isEqualTo
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AccountAutoConfigViewModelTest {
|
||||
|
||||
@get:Rule
|
||||
val mainDispatcherRule = MainDispatcherRule()
|
||||
|
||||
private val testSubject = AccountAutoConfigViewModel()
|
||||
|
||||
@Test
|
||||
fun `should reset state when EmailAddressChanged event is received`() = runTest {
|
||||
val initialState = State(
|
||||
configStep = ConfigStep.PASSWORD,
|
||||
emailAddress = StringInputField(value = "email"),
|
||||
password = StringInputField(value = "password"),
|
||||
)
|
||||
testSubject.initState(initialState)
|
||||
|
||||
eventStateTest(
|
||||
viewModel = testSubject,
|
||||
initialState = initialState,
|
||||
event = Event.EmailAddressChanged("email"),
|
||||
expectedState = State(
|
||||
configStep = ConfigStep.EMAIL_ADDRESS,
|
||||
emailAddress = StringInputField(value = "email"),
|
||||
password = StringInputField(),
|
||||
),
|
||||
coroutineScope = backgroundScope,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change state when PasswordChanged event is received`() = runTest {
|
||||
eventStateTest(
|
||||
viewModel = testSubject,
|
||||
initialState = State(),
|
||||
event = Event.PasswordChanged("password"),
|
||||
expectedState = State(
|
||||
password = StringInputField(value = "password"),
|
||||
),
|
||||
coroutineScope = backgroundScope,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit NavigateNext effect when NextClicked event is received`() = runTest {
|
||||
val viewModel = testSubject
|
||||
val stateTurbine = viewModel.state.testIn(backgroundScope)
|
||||
val effectTurbine = viewModel.effect.testIn(backgroundScope)
|
||||
val turbines = listOf(stateTurbine, effectTurbine)
|
||||
|
||||
assertThatAndTurbinesConsumed(
|
||||
actual = stateTurbine.awaitItem(),
|
||||
turbines = turbines,
|
||||
) {
|
||||
isEqualTo(State())
|
||||
}
|
||||
|
||||
viewModel.event(Event.OnNextClicked)
|
||||
|
||||
assertThatAndTurbinesConsumed(
|
||||
actual = effectTurbine.awaitItem(),
|
||||
turbines = turbines,
|
||||
) {
|
||||
isEqualTo(Effect.NavigateNext)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit NavigateBack effect when BackClicked event is received`() = runTest {
|
||||
val viewModel = testSubject
|
||||
val stateTurbine = viewModel.state.testIn(backgroundScope)
|
||||
val effectTurbine = viewModel.effect.testIn(backgroundScope)
|
||||
val turbines = listOf(stateTurbine, effectTurbine)
|
||||
|
||||
assertThatAndTurbinesConsumed(
|
||||
actual = stateTurbine.awaitItem(),
|
||||
turbines = turbines,
|
||||
) {
|
||||
isEqualTo(State())
|
||||
}
|
||||
|
||||
viewModel.event(Event.OnBackClicked)
|
||||
|
||||
assertThatAndTurbinesConsumed(
|
||||
actual = effectTurbine.awaitItem(),
|
||||
turbines = turbines,
|
||||
) {
|
||||
isEqualTo(Effect.NavigateBack)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package app.k9mail.feature.account.setup.ui.autoconfig
|
||||
|
||||
import app.k9mail.core.ui.compose.common.mvi.BaseViewModel
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Effect
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.State
|
||||
import app.k9mail.feature.account.setup.ui.autoconfig.AccountAutoConfigContract.ViewModel
|
||||
|
||||
class FakeAccountAutoConfigViewModel(
|
||||
initialState: State = State(),
|
||||
) : BaseViewModel<State, Event, Effect>(initialState), ViewModel {
|
||||
|
||||
val events = mutableListOf<Event>()
|
||||
|
||||
override fun initState(state: State) {
|
||||
updateState { state }
|
||||
}
|
||||
|
||||
override fun event(event: Event) {
|
||||
events.add(event)
|
||||
}
|
||||
|
||||
fun effect(effect: Effect) {
|
||||
emitEffect(effect)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue