From 5897a655bfefc78cacb4930cc0e8e6c2e4e6c295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolf-Martell=20Montw=C3=A9?= Date: Wed, 26 Jul 2023 18:04:38 +0200 Subject: [PATCH] Add ValidateServerSettings use case --- .../account/setup/domain/DomainContract.kt | 4 + .../domain/usecase/ValidateServerSettings.kt | 28 ++++ .../usecase/ValidateServerSettingsTest.kt | 131 ++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettings.kt create mode 100644 feature/account/setup/src/test/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettingsTest.kt diff --git a/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/DomainContract.kt b/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/DomainContract.kt index c0170a857ee..72317dc492e 100644 --- a/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/DomainContract.kt +++ b/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/DomainContract.kt @@ -14,6 +14,10 @@ interface DomainContract { suspend fun execute(emailAddress: String): AutoDiscoveryResult } + fun interface ValidateServerSettings { + suspend fun execute(settings: ServerSettings): ServerSettingsValidationResult + } + fun interface CheckIncomingServerConfig { suspend fun execute( protocolType: IncomingProtocolType, diff --git a/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettings.kt b/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettings.kt new file mode 100644 index 00000000000..1bcf7ef7f40 --- /dev/null +++ b/feature/account/setup/src/main/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettings.kt @@ -0,0 +1,28 @@ +package app.k9mail.feature.account.setup.domain.usecase + +import app.k9mail.feature.account.setup.domain.DomainContract.UseCase +import com.fsck.k9.mail.ServerSettings +import com.fsck.k9.mail.server.ServerSettingsValidationResult +import com.fsck.k9.mail.server.ServerSettingsValidator +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +internal class ValidateServerSettings( + private val imapValidator: ServerSettingsValidator, + private val pop3Validator: ServerSettingsValidator, + private val smtpValidator: ServerSettingsValidator, + private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO, +) : UseCase.ValidateServerSettings { + override suspend fun execute(settings: ServerSettings): ServerSettingsValidationResult = + withContext(coroutineDispatcher) { + return@withContext when (settings.type) { + "imap" -> imapValidator.checkServerSettings(settings) + "pop3" -> pop3Validator.checkServerSettings(settings) + "smtp" -> smtpValidator.checkServerSettings(settings) + else -> { + throw IllegalArgumentException("Unsupported server type: ${settings.type}") + } + } + } +} diff --git a/feature/account/setup/src/test/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettingsTest.kt b/feature/account/setup/src/test/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettingsTest.kt new file mode 100644 index 00000000000..c5b888eb52b --- /dev/null +++ b/feature/account/setup/src/test/kotlin/app/k9mail/feature/account/setup/domain/usecase/ValidateServerSettingsTest.kt @@ -0,0 +1,131 @@ +package app.k9mail.feature.account.setup.domain.usecase + +import assertk.assertThat +import assertk.assertions.isEqualTo +import com.fsck.k9.mail.AuthType +import com.fsck.k9.mail.ConnectionSecurity +import com.fsck.k9.mail.ServerSettings +import com.fsck.k9.mail.server.ServerSettingsValidationResult +import java.io.IOException +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class ValidateServerSettingsTest { + + @Test + fun `should check with imap validator when protocol is imap`() = runTest { + val testSubject = ValidateServerSettings( + imapValidator = { ServerSettingsValidationResult.Success }, + pop3Validator = { ServerSettingsValidationResult.NetworkError(IOException("Failed POP3")) }, + smtpValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed SMTP")) }, + ) + + val result = testSubject.execute(IMAP_SERVER_SETTINGS) + + assertThat(result).isEqualTo(ServerSettingsValidationResult.Success) + } + + @Test + fun `should check with imap validator when protocol is imap and return failure`() = runTest { + val failure = ServerSettingsValidationResult.ServerError("Failed") + val testSubject = ValidateServerSettings( + imapValidator = { failure }, + pop3Validator = { ServerSettingsValidationResult.NetworkError(IOException("Failed POP3")) }, + smtpValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed SMTP")) }, + ) + + val result = testSubject.execute(IMAP_SERVER_SETTINGS) + + assertThat(result).isEqualTo(failure) + } + + @Test + fun `should check with pop3 validator when protocol is pop3`() = runTest { + val testSubject = ValidateServerSettings( + imapValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed IMAP")) }, + pop3Validator = { ServerSettingsValidationResult.Success }, + smtpValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed SMTP")) }, + ) + + val result = testSubject.execute(POP3_SERVER_SETTINGS) + + assertThat(result).isEqualTo(ServerSettingsValidationResult.Success) + } + + @Test + fun `should check with pop3 validator when protocol is pop3 and return failure`() = runTest { + val failure = ServerSettingsValidationResult.ServerError("Failed POP3") + val testSubject = ValidateServerSettings( + imapValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed IMAP")) }, + pop3Validator = { failure }, + smtpValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed SMTP")) }, + ) + + val result = testSubject.execute(POP3_SERVER_SETTINGS) + + assertThat(result).isEqualTo(failure) + } + + @Test + fun `should check with smtp validator when protocol is smtp`() = runTest { + val testSubject = ValidateServerSettings( + imapValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed IMAP")) }, + pop3Validator = { ServerSettingsValidationResult.NetworkError(IOException("Failed POP3")) }, + smtpValidator = { ServerSettingsValidationResult.Success }, + ) + + val result = testSubject.execute(SMTP_SERVER_SETTINGS) + + assertThat(result).isEqualTo(ServerSettingsValidationResult.Success) + } + + @Test + fun `should check with smtp validator when protocol is smtp and return failure`() = runTest { + val failure = ServerSettingsValidationResult.ServerError("Failed SMTP") + val testSubject = ValidateServerSettings( + imapValidator = { ServerSettingsValidationResult.NetworkError(IOException("Failed IMAP")) }, + pop3Validator = { ServerSettingsValidationResult.NetworkError(IOException("Failed POP3")) }, + smtpValidator = { failure }, + ) + + val result = testSubject.execute(SMTP_SERVER_SETTINGS) + + assertThat(result).isEqualTo(failure) + } + + private companion object { + + val IMAP_SERVER_SETTINGS = ServerSettings( + type = "imap", + host = "imap.example.org", + port = 993, + connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED, + authenticationType = AuthType.PLAIN, + username = "user", + password = "password", + clientCertificateAlias = null, + ) + + val POP3_SERVER_SETTINGS = ServerSettings( + type = "pop3", + host = "pop3.example.org", + port = 993, + connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED, + authenticationType = AuthType.PLAIN, + username = "user", + password = "password", + clientCertificateAlias = null, + ) + + val SMTP_SERVER_SETTINGS = ServerSettings( + type = "smtp", + host = "smtp.example.org", + port = 993, + connectionSecurity = ConnectionSecurity.SSL_TLS_REQUIRED, + authenticationType = AuthType.PLAIN, + username = "user", + password = "password", + clientCertificateAlias = null, + ) + } +}