Add authentication type to incoming server settings screen
This commit is contained in:
parent
032fa95041
commit
d677c542ef
9 changed files with 63 additions and 1 deletions
|
@ -2,9 +2,10 @@ package app.k9mail.feature.account.setup.domain.entity
|
|||
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal enum class AuthenticationType {
|
||||
enum class AuthenticationType {
|
||||
PasswordCleartext,
|
||||
PasswordEncrypted,
|
||||
ClientCertificate,
|
||||
OAuth2,
|
||||
;
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package app.k9mail.feature.account.setup.ui.common.mapper
|
||||
|
||||
import android.content.res.Resources
|
||||
import app.k9mail.feature.account.setup.R
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
|
||||
internal fun AuthenticationType.toResourceString(resources: Resources): String {
|
||||
return when (this) {
|
||||
AuthenticationType.PasswordCleartext -> {
|
||||
resources.getString(R.string.account_setup_authentication_password_cleartext)
|
||||
}
|
||||
AuthenticationType.PasswordEncrypted -> {
|
||||
resources.getString(R.string.account_setup_authentication_password_encrypted)
|
||||
}
|
||||
AuthenticationType.ClientCertificate -> {
|
||||
resources.getString(R.string.account_setup_authentication_client_certificate)
|
||||
}
|
||||
AuthenticationType.OAuth2 -> {
|
||||
resources.getString(R.string.account_setup_authentication_client_oauth)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,12 +26,14 @@ 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.R
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
|
||||
import app.k9mail.feature.account.setup.domain.entity.IncomingProtocolType
|
||||
import app.k9mail.feature.account.setup.ui.common.item.ErrorItem
|
||||
import app.k9mail.feature.account.setup.ui.common.item.LoadingItem
|
||||
import app.k9mail.feature.account.setup.ui.common.item.SuccessItem
|
||||
import app.k9mail.feature.account.setup.ui.common.item.defaultItemPadding
|
||||
import app.k9mail.feature.account.setup.ui.common.mapper.toResourceString
|
||||
import app.k9mail.feature.account.setup.ui.common.toResourceString
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigContract.Event
|
||||
import app.k9mail.feature.account.setup.ui.incoming.AccountIncomingConfigContract.State
|
||||
|
@ -132,6 +134,17 @@ internal fun AccountIncomingConfigContent(
|
|||
)
|
||||
}
|
||||
|
||||
item {
|
||||
SelectInput(
|
||||
options = AuthenticationType.all(),
|
||||
optionToStringTransformation = { it.toResourceString(resources) },
|
||||
selectedOption = state.authenticationType,
|
||||
onOptionChange = { onEvent(Event.AuthenticationTypeChanged(it)) },
|
||||
label = stringResource(id = R.string.account_setup_incoming_config_authentication_label),
|
||||
contentPadding = defaultItemPadding(),
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
TextInput(
|
||||
text = state.username.value,
|
||||
|
|
|
@ -2,6 +2,7 @@ package app.k9mail.feature.account.setup.ui.incoming
|
|||
|
||||
import app.k9mail.core.common.domain.usecase.validation.ValidationResult
|
||||
import app.k9mail.core.ui.compose.common.mvi.UnidirectionalViewModel
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
|
||||
import app.k9mail.feature.account.setup.domain.entity.IncomingProtocolType
|
||||
import app.k9mail.feature.account.setup.domain.entity.toDefaultPort
|
||||
|
@ -23,6 +24,7 @@ interface AccountIncomingConfigContract {
|
|||
val port: NumberInputField = NumberInputField(
|
||||
IncomingProtocolType.DEFAULT.toDefaultPort(IncomingProtocolType.DEFAULT.defaultConnectionSecurity),
|
||||
),
|
||||
val authenticationType: AuthenticationType = AuthenticationType.PasswordCleartext,
|
||||
val username: StringInputField = StringInputField(),
|
||||
val password: StringInputField = StringInputField(),
|
||||
val clientCertificate: String = "",
|
||||
|
@ -40,6 +42,7 @@ interface AccountIncomingConfigContract {
|
|||
data class ServerChanged(val server: String) : Event()
|
||||
data class SecurityChanged(val security: ConnectionSecurity) : Event()
|
||||
data class PortChanged(val port: Long?) : Event()
|
||||
data class AuthenticationTypeChanged(val authenticationType: AuthenticationType) : Event()
|
||||
data class UsernameChanged(val username: String) : Event()
|
||||
data class PasswordChanged(val password: String) : Event()
|
||||
data class ClientCertificateChanged(val clientCertificate: String) : Event()
|
||||
|
|
|
@ -32,12 +32,14 @@ internal class AccountIncomingConfigViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
override fun event(event: Event) {
|
||||
when (event) {
|
||||
is Event.ProtocolTypeChanged -> updateProtocolType(event.protocolType)
|
||||
is Event.ServerChanged -> updateState { it.copy(server = it.server.updateValue(event.server)) }
|
||||
is Event.SecurityChanged -> updateSecurity(event.security)
|
||||
is Event.PortChanged -> updateState { it.copy(port = it.port.updateValue(event.port)) }
|
||||
is Event.AuthenticationTypeChanged -> updateState { it.copy(authenticationType = event.authenticationType) }
|
||||
is Event.UsernameChanged -> updateState { it.copy(username = it.username.updateValue(event.username)) }
|
||||
is Event.PasswordChanged -> updateState { it.copy(password = it.password.updateValue(event.password)) }
|
||||
is Event.ClientCertificateChanged -> updateState { it.copy(clientCertificate = event.clientCertificate) }
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
<string name="account_setup_connection_security_none">None</string>
|
||||
<string name="account_setup_connection_security_ssl">SSL/TLS</string>
|
||||
<string name="account_setup_connection_security_start_tls">StartTLS</string>
|
||||
<string name="account_setup_authentication_password_cleartext">Normal password</string>
|
||||
<string name="account_setup_authentication_password_encrypted">Encrypted password</string>
|
||||
<string name="account_setup_authentication_client_certificate">Client certificate</string>
|
||||
<string name="account_setup_authentication_client_oauth">OAuth 2.0</string>
|
||||
<string name="account_setup_client_certificate_none_available">None available</string>
|
||||
|
||||
<string name="account_setup_error_network">Network </string>
|
||||
|
@ -43,6 +47,7 @@
|
|||
<string name="account_setup_incoming_config_protocol_type_label">Protocol</string>
|
||||
<string name="account_setup_incoming_config_server_label">Server</string>
|
||||
<string name="account_setup_incoming_config_security_label">Security</string>
|
||||
<string name="account_setup_incoming_config_authentication_label">Authentication</string>
|
||||
<string name="account_setup_incoming_config_imap_namespace_label">Auto-detect IMAP namespace</string>
|
||||
<string name="account_setup_incoming_config_imap_prefix_label">IMAP path prefix</string>
|
||||
<string name="account_setup_incoming_config_imap_compression_label">Use compression</string>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package app.k9mail.feature.account.setup.ui.incoming
|
||||
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
|
||||
import app.k9mail.feature.account.setup.domain.entity.IncomingProtocolType
|
||||
import app.k9mail.feature.account.setup.domain.entity.MailConnectionSecurity
|
||||
|
@ -21,6 +22,7 @@ class AccountIncomingConfigStateMapperKtTest {
|
|||
server = StringInputField(value = "imap.example.org"),
|
||||
port = NumberInputField(value = 993),
|
||||
security = ConnectionSecurity.TLS,
|
||||
authenticationType = AuthenticationType.PasswordCleartext,
|
||||
username = StringInputField(value = "user"),
|
||||
password = StringInputField(value = "password"),
|
||||
clientCertificate = "",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package app.k9mail.feature.account.setup.ui.incoming
|
||||
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
|
||||
import app.k9mail.feature.account.setup.domain.entity.IncomingProtocolType
|
||||
import app.k9mail.feature.account.setup.domain.entity.toImapDefaultPort
|
||||
|
@ -22,6 +23,7 @@ class AccountIncomingConfigStateTest {
|
|||
server = StringInputField(),
|
||||
security = ConnectionSecurity.DEFAULT,
|
||||
port = NumberInputField(value = ConnectionSecurity.DEFAULT.toImapDefaultPort()),
|
||||
authenticationType = AuthenticationType.PasswordCleartext,
|
||||
username = StringInputField(),
|
||||
password = StringInputField(),
|
||||
clientCertificate = "",
|
||||
|
|
|
@ -4,6 +4,7 @@ import app.cash.turbine.testIn
|
|||
import app.k9mail.core.common.domain.usecase.validation.ValidationError
|
||||
import app.k9mail.core.common.domain.usecase.validation.ValidationResult
|
||||
import app.k9mail.core.ui.compose.testing.MainDispatcherRule
|
||||
import app.k9mail.feature.account.setup.domain.entity.AuthenticationType
|
||||
import app.k9mail.feature.account.setup.domain.entity.ConnectionSecurity
|
||||
import app.k9mail.feature.account.setup.domain.entity.IncomingProtocolType
|
||||
import app.k9mail.feature.account.setup.domain.entity.toImapDefaultPort
|
||||
|
@ -96,6 +97,17 @@ class AccountIncomingConfigViewModelTest {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change authentication type when AuthenticationTypeChanged event is received`() = runTest {
|
||||
eventStateTest(
|
||||
viewModel = testSubject,
|
||||
initialState = State(),
|
||||
event = Event.AuthenticationTypeChanged(AuthenticationType.PasswordEncrypted),
|
||||
expectedState = State(authenticationType = AuthenticationType.PasswordEncrypted),
|
||||
coroutineScope = backgroundScope,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change state when UsernameChanged event is received`() = runTest {
|
||||
eventStateTest(
|
||||
|
|
Loading…
Reference in a new issue