[PM-10883] Support deserializing Forward Email service type details (#3739)

This commit is contained in:
Patrick Honkonen 2024-08-19 09:02:57 -04:00 committed by GitHub
parent b18d9f53c6
commit 8c8db78da6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 205 additions and 144 deletions

View file

@ -113,6 +113,9 @@ data class UsernameGenerationOptions(
@SerialName("4")
FASTMAIL,
@SerialName("5")
FORWARD_EMAIL,
}
}

View file

@ -46,6 +46,7 @@ import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Us
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.PlusAddressedEmail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.RandomWord
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
import com.x8bit.bitwarden.ui.tools.feature.generator.util.toServiceType
import com.x8bit.bitwarden.ui.tools.feature.generator.util.toStrictestPolicy
import com.x8bit.bitwarden.ui.tools.feature.generator.util.toUsernameGeneratorRequest
import dagger.hilt.android.lifecycle.HiltViewModel
@ -472,6 +473,13 @@ class GeneratorViewModel @Inject constructor(
simpleLoginApiKey = forwardedEmailAlias.selectedServiceType.apiKey,
)
is ForwardEmail -> options.copy(
type = UsernameGenerationOptions.UsernameType.FORWARDED_EMAIL_ALIAS,
serviceType = UsernameGenerationOptions.ForwardedEmailServiceType.FORWARD_EMAIL,
forwardEmailApiAccessToken = forwardedEmailAlias.selectedServiceType.apiKey,
forwardEmailDomainName = forwardedEmailAlias.selectedServiceType.domainName,
)
else -> options.copy(
type = UsernameGenerationOptions.UsernameType.FORWARDED_EMAIL_ALIAS,
serviceType = UsernameGenerationOptions.ForwardedEmailServiceType.NONE,
@ -2595,37 +2603,6 @@ private val UsernameGenerationOptions?.usernameType: Username.UsernameType
else -> PlusAddressedEmail()
}
private fun UsernameGenerationOptions.ForwardedEmailServiceType?.toServiceType(
options: UsernameGenerationOptions,
): ForwardedEmailAlias.ServiceType? {
return when (this) {
UsernameGenerationOptions.ForwardedEmailServiceType.FIREFOX_RELAY -> {
FirefoxRelay(apiAccessToken = options.firefoxRelayApiAccessToken.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.SIMPLE_LOGIN -> {
SimpleLogin(apiKey = options.simpleLoginApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.DUCK_DUCK_GO -> {
DuckDuckGo(apiKey = options.duckDuckGoApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.FASTMAIL -> {
FastMail(apiKey = options.fastMailApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.ANON_ADDY -> {
AddyIo(
apiAccessToken = options.anonAddyApiAccessToken.orEmpty(),
domainName = options.anonAddyDomainName.orEmpty(),
)
}
else -> null
}
}
private fun String?.toSelectedType(): Passcode.PasscodeType =
when (this) {
PolicyInformation.PasswordGenerator.TYPE_PASSPHRASE -> Passphrase()

View file

@ -0,0 +1,53 @@
package com.x8bit.bitwarden.ui.tools.feature.generator.util
import com.x8bit.bitwarden.data.tools.generator.repository.model.UsernameGenerationOptions
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.AddyIo
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.DuckDuckGo
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.FastMail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.FirefoxRelay
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.ForwardEmail
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.SimpleLogin
/**
* Converts this [UsernameGenerationOptions.ForwardedEmailServiceType] into a corresponding
* [ForwardedEmailAlias.ServiceType] with the given [options], or `null`.
*/
fun UsernameGenerationOptions.ForwardedEmailServiceType?.toServiceType(
options: UsernameGenerationOptions,
): ForwardedEmailAlias.ServiceType? {
this ?: return null
return when (this) {
UsernameGenerationOptions.ForwardedEmailServiceType.FIREFOX_RELAY -> {
FirefoxRelay(apiAccessToken = options.firefoxRelayApiAccessToken.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.SIMPLE_LOGIN -> {
SimpleLogin(apiKey = options.simpleLoginApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.DUCK_DUCK_GO -> {
DuckDuckGo(apiKey = options.duckDuckGoApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.FASTMAIL -> {
FastMail(apiKey = options.fastMailApiKey.orEmpty())
}
UsernameGenerationOptions.ForwardedEmailServiceType.ANON_ADDY -> {
AddyIo(
apiAccessToken = options.anonAddyApiAccessToken.orEmpty(),
domainName = options.anonAddyDomainName.orEmpty(),
)
}
UsernameGenerationOptions.ForwardedEmailServiceType.FORWARD_EMAIL -> {
ForwardEmail(
apiKey = options.forwardEmailApiAccessToken.orEmpty(),
domainName = options.forwardEmailDomainName.orEmpty(),
)
}
UsernameGenerationOptions.ForwardedEmailServiceType.NONE -> null
}
}

View file

@ -26,6 +26,8 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockPolicy
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceTypeOption
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
import io.mockk.every
import io.mockk.just
@ -1564,49 +1566,70 @@ class GeneratorViewModelTest : BaseViewModelTest() {
@Test
fun `ServiceTypeOptionSelect should update service type correctly`() = runTest {
val action = GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceTypeOptionSelect(
serviceTypeOption = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceTypeOption
.ADDY_IO,
)
fakeGeneratorRepository.setMockGenerateForwardedServiceResult(
GeneratedForwardedServiceUsernameResult.Success(
generatedEmailAddress = "defaultForwardedEmailAlias",
),
)
viewModel.trySendAction(action)
val expectedState = defaultForwardedEmailAliasState.copy(
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
selectedType = GeneratorState
ServiceTypeOption
.entries
.forEach {
val action = GeneratorAction
.MainType
.Username
.UsernameType
.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.ForwardedEmailAlias
.ServiceTypeOptionSelect(serviceTypeOption = it)
viewModel.trySendAction(action)
val serviceType = createMockForwardedEmailAliasGeneratorState(it)
val expectedState = defaultForwardedEmailAliasState.copy(
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
selectedType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
.AddyIo(),
.ForwardedEmailAlias(
selectedServiceType = serviceType,
),
),
),
)
)
assertEquals(expectedState, viewModel.stateFlow.value)
assertEquals(expectedState, viewModel.stateFlow.value)
}
}
@Suppress("MaxLineLength")
private fun createMockForwardedEmailAliasGeneratorState(
serviceTypeOption: ServiceTypeOption,
): ServiceType = when (serviceTypeOption) {
ServiceTypeOption.ADDY_IO -> {
ServiceType.AddyIo()
}
ServiceTypeOption.DUCK_DUCK_GO -> {
ServiceType.DuckDuckGo()
}
ServiceTypeOption.FAST_MAIL -> {
ServiceType.FastMail()
}
ServiceTypeOption.FIREFOX_RELAY -> {
ServiceType.FirefoxRelay()
}
ServiceTypeOption.FORWARD_EMAIL -> {
ServiceType.ForwardEmail()
}
ServiceTypeOption.SIMPLE_LOGIN -> {
ServiceType.SimpleLogin()
}
}
}
@ -1645,12 +1668,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.AddyIo(
apiAccessToken = newAccessToken,
),
@ -1685,12 +1703,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.AddyIo(
domainName = newDomainName,
),
@ -1736,12 +1749,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.DuckDuckGo(
apiKey = newApiKey,
),
@ -1787,12 +1795,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.FastMail(
apiKey = newApiKey,
),
@ -1839,12 +1842,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.FirefoxRelay(
apiAccessToken = newAccessToken,
),
@ -1891,12 +1889,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.ForwardEmail(
apiKey = newApiKey,
),
@ -1932,12 +1925,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.ForwardEmail(
domainName = newDomainName,
),
@ -1984,12 +1972,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = "-",
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.SimpleLogin(
apiKey = newApiKey,
),
@ -2235,12 +2218,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.AddyIo(),
),
),
@ -2254,12 +2232,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.DuckDuckGo(),
),
),
@ -2273,12 +2246,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.FastMail(),
),
),
@ -2292,12 +2260,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.FirefoxRelay(),
),
),
@ -2311,12 +2274,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.ForwardEmail(),
),
),
@ -2330,12 +2288,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText,
selectedType = GeneratorState.MainType.Username(
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
selectedServiceType = GeneratorState
.MainType
.Username
.UsernameType
.ForwardedEmailAlias
.ServiceType
selectedServiceType = ServiceType
.SimpleLogin(),
),
),

View file

@ -0,0 +1,75 @@
package com.x8bit.bitwarden.ui.tools.feature.generator.util
import com.x8bit.bitwarden.data.tools.generator.repository.model.UsernameGenerationOptions
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType
import org.junit.Test
import org.junit.jupiter.api.Assertions.assertEquals
class ForwardedEmailServiceTypeExtensionsTest {
@Test
fun `toServiceType should map to correct service type`() {
val options = UsernameGenerationOptions(
type = UsernameGenerationOptions.UsernameType.RANDOM_WORD,
serviceType = UsernameGenerationOptions.ForwardedEmailServiceType.NONE,
capitalizeRandomWordUsername = true,
includeNumberRandomWordUsername = false,
plusAddressedEmail = "example+plus@gmail.com",
catchAllEmailDomain = "example.com",
firefoxRelayApiAccessToken = "access_token_firefox_relay",
simpleLoginApiKey = "api_key_simple_login",
duckDuckGoApiKey = "api_key_duck_duck_go",
fastMailApiKey = "api_key_fast_mail",
anonAddyApiAccessToken = "access_token_anon_addy",
anonAddyDomainName = "anonaddy.com",
forwardEmailApiAccessToken = "access_token_forward_email",
forwardEmailDomainName = "forwardemail.net",
emailWebsite = "email.example.com",
)
UsernameGenerationOptions.ForwardedEmailServiceType.entries
.forEach {
val expected = createMockForwardedEmailAliasServiceType(it)
assertEquals(
expected,
it.toServiceType(options),
)
}
}
@Suppress("MaxLineLength")
private fun createMockForwardedEmailAliasServiceType(
serviceTypeOption: UsernameGenerationOptions.ForwardedEmailServiceType,
): ServiceType? = when (serviceTypeOption) {
UsernameGenerationOptions.ForwardedEmailServiceType.NONE -> null
UsernameGenerationOptions.ForwardedEmailServiceType.ANON_ADDY -> {
ServiceType.AddyIo(
apiAccessToken = "access_token_anon_addy",
domainName = "anonaddy.com",
)
}
UsernameGenerationOptions.ForwardedEmailServiceType.FIREFOX_RELAY -> {
ServiceType.FirefoxRelay(apiAccessToken = "access_token_firefox_relay")
}
UsernameGenerationOptions.ForwardedEmailServiceType.SIMPLE_LOGIN -> {
ServiceType.SimpleLogin(apiKey = "api_key_simple_login")
}
UsernameGenerationOptions.ForwardedEmailServiceType.DUCK_DUCK_GO -> {
ServiceType.DuckDuckGo(apiKey = "api_key_duck_duck_go")
}
UsernameGenerationOptions.ForwardedEmailServiceType.FASTMAIL -> {
ServiceType.FastMail(apiKey = "api_key_fast_mail")
}
UsernameGenerationOptions.ForwardedEmailServiceType.FORWARD_EMAIL -> {
ServiceType.ForwardEmail(
apiKey = "access_token_forward_email",
domainName = "forwardemail.net",
)
}
}
}