mirror of
https://github.com/bitwarden/android.git
synced 2026-05-26 14:34:19 -05:00
[PM-14936] Add AnonAddy self-hosted server URL support (#4708)
This commit is contained in:
@@ -21,6 +21,7 @@ import kotlinx.serialization.Serializable
|
||||
* @property fastMailApiKey The API key for FastMail.
|
||||
* @property anonAddyApiAccessToken The API access token for AnonAddy.
|
||||
* @property anonAddyDomainName The domain name associated with AnonAddy.
|
||||
* @property anonAddySelfHostServerUrl The self-hosted server URL for AnonAddy.
|
||||
* @property forwardEmailApiAccessToken The API access token for Forward Email.
|
||||
* @property forwardEmailDomainName The domain name associated with Forward Email.
|
||||
* @property emailWebsite The website associated with the email service.
|
||||
@@ -63,6 +64,9 @@ data class UsernameGenerationOptions(
|
||||
@SerialName("anonAddyDomainName")
|
||||
val anonAddyDomainName: String? = null,
|
||||
|
||||
@SerialName("anonAddyBaseUrl")
|
||||
val anonAddySelfHostServerUrl: String? = null,
|
||||
|
||||
@SerialName("forwardEmailApiAccessToken")
|
||||
val forwardEmailApiAccessToken: String? = null,
|
||||
|
||||
|
||||
@@ -215,3 +215,10 @@ fun String.prefixHttpsIfNecessaryOrNull(): String? =
|
||||
"http://" in this || "https://" in this -> this
|
||||
else -> "https://$this"
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given [String] is a valid URI, "https://" will be appended if it is not already present.
|
||||
* Otherwise the original [String] will be returned.
|
||||
*/
|
||||
fun String.prefixHttpsIfNecessary(): String =
|
||||
prefixHttpsIfNecessaryOrNull() ?: this
|
||||
|
||||
@@ -528,6 +528,8 @@ private fun CoachMarkScope<ExploreGeneratorCoachMark>.ScrollContent(
|
||||
plusAddressedEmailHandlers = plusAddressedEmailHandlers,
|
||||
catchAllEmailHandlers = catchAllEmailHandlers,
|
||||
randomWordHandlers = randomWordHandlers,
|
||||
shouldShowSelfHostServerUrlField =
|
||||
state.shouldShowAnonAddySelfHostServerUrlField,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1101,6 +1103,7 @@ private fun UsernameTypeItems(
|
||||
plusAddressedEmailHandlers: PlusAddressedEmailHandlers,
|
||||
catchAllEmailHandlers: CatchAllEmailHandlers,
|
||||
randomWordHandlers: RandomWordHandlers,
|
||||
shouldShowSelfHostServerUrlField: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
@@ -1125,6 +1128,7 @@ private fun UsernameTypeItems(
|
||||
ForwardedEmailAliasTypeContent(
|
||||
usernameTypeState = selectedType,
|
||||
forwardedEmailAliasHandlers = forwardedEmailAliasHandlers,
|
||||
shouldShowSelfHostServerUrlField = shouldShowSelfHostServerUrlField,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1185,6 +1189,7 @@ private fun UsernameOptionsItem(
|
||||
private fun ForwardedEmailAliasTypeContent(
|
||||
usernameTypeState: GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias,
|
||||
forwardedEmailAliasHandlers: ForwardedEmailAliasHandlers,
|
||||
shouldShowSelfHostServerUrlField: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
@@ -1226,6 +1231,21 @@ private fun ForwardedEmailAliasTypeContent(
|
||||
.standardHorizontalMargin()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
if (shouldShowSelfHostServerUrlField) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.self_host_server_url),
|
||||
value = usernameTypeState.selectedServiceType.selfHostServerUrl,
|
||||
onValueChange = forwardedEmailAliasHandlers.onAddyIoSelfHostServerUrlChange,
|
||||
textFieldTestTag = "AnonAddySelfHostUrlEntry",
|
||||
cardStyle = CardStyle.Full,
|
||||
modifier = Modifier
|
||||
.standardHorizontalMargin()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is ServiceType.DuckDuckGo -> {
|
||||
|
||||
@@ -12,11 +12,13 @@ import com.bitwarden.generators.UsernameGeneratorRequest
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation
|
||||
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.ReviewPromptManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.CoachMarkTourType
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
|
||||
import com.x8bit.bitwarden.data.platform.manager.util.getActivePolicies
|
||||
import com.x8bit.bitwarden.data.platform.manager.util.getActivePoliciesFlow
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.GeneratorRepository
|
||||
@@ -80,6 +82,7 @@ class GeneratorViewModel @Inject constructor(
|
||||
private val policyManager: PolicyManager,
|
||||
private val reviewPromptManager: ReviewPromptManager,
|
||||
private val firstTimeActionManager: FirstTimeActionManager,
|
||||
private val featureFlagManager: FeatureFlagManager,
|
||||
) : BaseViewModel<GeneratorState, GeneratorEvent, GeneratorAction>(
|
||||
initialState = savedStateHandle[KEY_STATE] ?: run {
|
||||
val generatorMode = GeneratorArgs(savedStateHandle).type
|
||||
@@ -109,6 +112,9 @@ class GeneratorViewModel @Inject constructor(
|
||||
.any(),
|
||||
website = (generatorMode as? GeneratorMode.Modal.Username)?.website,
|
||||
shouldShowCoachMarkTour = false,
|
||||
shouldShowAnonAddySelfHostServerUrlField = featureFlagManager.getFeatureFlag(
|
||||
FlagKey.AnonAddySelfHostAlias,
|
||||
),
|
||||
)
|
||||
},
|
||||
) {
|
||||
@@ -135,6 +141,17 @@ class GeneratorViewModel @Inject constructor(
|
||||
}
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
featureFlagManager
|
||||
.getFeatureFlagFlow(FlagKey.AnonAddySelfHostAlias)
|
||||
.map { shouldShowAnonAddySelfHostServerUrlField ->
|
||||
GeneratorAction.Internal.ShouldShowAnonAddySelfHostValueChangeReceive(
|
||||
shouldShowAnonAddySelfHostServerUrlField =
|
||||
shouldShowAnonAddySelfHostServerUrlField,
|
||||
)
|
||||
}
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
override fun handleAction(action: GeneratorAction) {
|
||||
@@ -268,6 +285,10 @@ class GeneratorViewModel @Inject constructor(
|
||||
is GeneratorAction.Internal.ShouldShowGeneratorCoachMarkValueChangeReceive -> {
|
||||
handleShouldShowCoachMarkValueChange(action)
|
||||
}
|
||||
|
||||
is GeneratorAction.Internal.ShouldShowAnonAddySelfHostValueChangeReceive -> {
|
||||
handleShouldShowAnonAddySelfHostValueChange(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,6 +568,8 @@ class GeneratorViewModel @Inject constructor(
|
||||
serviceType = UsernameGenerationOptions.ForwardedEmailServiceType.ANON_ADDY,
|
||||
anonAddyApiAccessToken = forwardedEmailAlias.selectedServiceType.apiAccessToken,
|
||||
anonAddyDomainName = forwardedEmailAlias.selectedServiceType.domainName,
|
||||
anonAddySelfHostServerUrl =
|
||||
forwardedEmailAlias.selectedServiceType.selfHostServerUrl,
|
||||
)
|
||||
|
||||
is DuckDuckGo -> options.copy(
|
||||
@@ -624,6 +647,7 @@ class GeneratorViewModel @Inject constructor(
|
||||
fastMailApiKey = "",
|
||||
anonAddyApiAccessToken = "",
|
||||
anonAddyDomainName = "",
|
||||
anonAddySelfHostServerUrl = "",
|
||||
forwardEmailApiAccessToken = "",
|
||||
forwardEmailDomainName = "",
|
||||
emailWebsite = "",
|
||||
@@ -1079,6 +1103,7 @@ class GeneratorViewModel @Inject constructor(
|
||||
selectedServiceType = AddyIo(
|
||||
apiAccessToken = options.anonAddyApiAccessToken.orEmpty(),
|
||||
domainName = options.anonAddyDomainName.orEmpty(),
|
||||
selfHostServerUrl = options.anonAddySelfHostServerUrl.orEmpty(),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1155,6 +1180,17 @@ class GeneratorViewModel @Inject constructor(
|
||||
-> {
|
||||
handleAddyIoDomainNameTextChange(action)
|
||||
}
|
||||
|
||||
is GeneratorAction
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.AddyIo
|
||||
.SelfHostServerUrlChange,
|
||||
-> {
|
||||
handleAddyIoSelfHostServerUrlChange(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1188,6 +1224,31 @@ class GeneratorViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleShouldShowAnonAddySelfHostValueChange(
|
||||
action: GeneratorAction.Internal.ShouldShowAnonAddySelfHostValueChangeReceive,
|
||||
) {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
shouldShowAnonAddySelfHostServerUrlField =
|
||||
action.shouldShowAnonAddySelfHostServerUrlField,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleAddyIoSelfHostServerUrlChange(
|
||||
action: GeneratorAction
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.AddyIo
|
||||
.SelfHostServerUrlChange,
|
||||
) {
|
||||
updateAddyIoServiceType { addyIoServiceType ->
|
||||
addyIoServiceType.copy(selfHostServerUrl = action.url)
|
||||
}
|
||||
}
|
||||
|
||||
//endregion Addy.Io Service Specific Handlers
|
||||
|
||||
//region DuckDuckGo Service Specific Handlers
|
||||
@@ -1472,10 +1533,16 @@ class GeneratorViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private suspend fun generateForwardedEmailAlias(alias: ForwardedEmailAlias) {
|
||||
val request = alias.selectedServiceType?.toUsernameGeneratorRequest(state.website) ?: run {
|
||||
mutableStateFlow.update { it.copy(generatedText = NO_GENERATED_TEXT) }
|
||||
return
|
||||
}
|
||||
val request = alias
|
||||
.selectedServiceType
|
||||
?.toUsernameGeneratorRequest(
|
||||
website = state.website,
|
||||
allowAddyIoSelfHostUrl = state.shouldShowAnonAddySelfHostServerUrlField,
|
||||
)
|
||||
?: run {
|
||||
mutableStateFlow.update { it.copy(generatedText = NO_GENERATED_TEXT) }
|
||||
return
|
||||
}
|
||||
val result = generatorRepository.generateForwardedServiceUsername(request)
|
||||
sendAction(GeneratorAction.Internal.UpdateGeneratedForwardedServiceUsernameResult(result))
|
||||
}
|
||||
@@ -1772,6 +1839,7 @@ data class GeneratorState(
|
||||
val website: String? = null,
|
||||
var passcodePolicyOverride: PasscodePolicyOverride? = null,
|
||||
private val shouldShowCoachMarkTour: Boolean,
|
||||
val shouldShowAnonAddySelfHostServerUrlField: Boolean,
|
||||
) : Parcelable {
|
||||
|
||||
/**
|
||||
@@ -2097,10 +2165,15 @@ data class GeneratorState(
|
||||
data class AddyIo(
|
||||
val apiAccessToken: String = "",
|
||||
val domainName: String = "",
|
||||
val baseUrl: String = "https://app.addy.io",
|
||||
val selfHostServerUrl: String = "",
|
||||
) : ServiceType(), Parcelable {
|
||||
override val displayStringResId: Int
|
||||
get() = ServiceTypeOption.ADDY_IO.labelRes
|
||||
|
||||
@Suppress("UndocumentedPublicClass")
|
||||
companion object {
|
||||
const val DEFAULT_ADDY_IO_URL = "https://app.addy.io"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2434,6 +2507,13 @@ sealed class GeneratorAction {
|
||||
* @property domain The new domain text.
|
||||
*/
|
||||
data class DomainTextChange(val domain: String) : AddyIo()
|
||||
|
||||
/**
|
||||
* Fired when the self host server url input text is changed.
|
||||
*
|
||||
* @property url The new self host server url text.
|
||||
*/
|
||||
data class SelfHostServerUrlChange(val url: String) : AddyIo()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2617,6 +2697,13 @@ sealed class GeneratorAction {
|
||||
data class ShouldShowGeneratorCoachMarkValueChangeReceive(
|
||||
val shouldShowCoachMarkTour: Boolean,
|
||||
) : Internal()
|
||||
|
||||
/**
|
||||
* The value for the shouldShowAnonAddySelfHostServerUrlField feature flag has changed.
|
||||
*/
|
||||
data class ShouldShowAnonAddySelfHostValueChangeReceive(
|
||||
val shouldShowAnonAddySelfHostServerUrlField: Boolean,
|
||||
) : Internal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ data class ForwardedEmailAliasHandlers(
|
||||
val onServiceChange: (ForwardedEmailAlias.ServiceTypeOption) -> Unit,
|
||||
val onAddyIoAccessTokenTextChange: (String) -> Unit,
|
||||
val onAddyIoDomainNameTextChange: (String) -> Unit,
|
||||
val onAddyIoSelfHostServerUrlChange: (String) -> Unit,
|
||||
val onDuckDuckGoApiKeyTextChange: (String) -> Unit,
|
||||
val onFastMailApiKeyTextChange: (String) -> Unit,
|
||||
val onFirefoxRelayAccessTokenTextChange: (String) -> Unit,
|
||||
@@ -30,6 +31,7 @@ data class ForwardedEmailAliasHandlers(
|
||||
* Creates an instance of [ForwardedEmailAliasHandlers] by binding actions to the provided
|
||||
* [GeneratorViewModel].
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
fun create(
|
||||
viewModel: GeneratorViewModel,
|
||||
): ForwardedEmailAliasHandlers = ForwardedEmailAliasHandlers(
|
||||
@@ -52,6 +54,11 @@ data class ForwardedEmailAliasHandlers(
|
||||
ForwardedEmailAliasAction.AddyIo.DomainTextChange(domain = newDomainName),
|
||||
)
|
||||
},
|
||||
onAddyIoSelfHostServerUrlChange = { newServerUrl ->
|
||||
viewModel.trySendAction(
|
||||
ForwardedEmailAliasAction.AddyIo.SelfHostServerUrlChange(url = newServerUrl),
|
||||
)
|
||||
},
|
||||
onDuckDuckGoApiKeyTextChange = { newApiKey ->
|
||||
viewModel.trySendAction(
|
||||
ForwardedEmailAliasAction.DuckDuckGo.ApiKeyTextChange(apiKey = newApiKey),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.x8bit.bitwarden.ui.tools.feature.generator.util
|
||||
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.UsernameGenerationOptions
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.prefixHttpsIfNecessary
|
||||
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
|
||||
@@ -38,6 +39,9 @@ fun UsernameGenerationOptions.ForwardedEmailServiceType?.toServiceType(
|
||||
AddyIo(
|
||||
apiAccessToken = options.anonAddyApiAccessToken.orEmpty(),
|
||||
domainName = options.anonAddyDomainName.orEmpty(),
|
||||
selfHostServerUrl = options.anonAddySelfHostServerUrl
|
||||
?.prefixHttpsIfNecessary()
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,22 +3,31 @@ package com.x8bit.bitwarden.ui.tools.feature.generator.util
|
||||
import com.bitwarden.generators.ForwarderServiceType
|
||||
import com.bitwarden.generators.UsernameGeneratorRequest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.prefixHttpsIfNecessary
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType
|
||||
|
||||
/**
|
||||
* Converts a [ServiceType] to a [UsernameGeneratorRequest.Forwarded].
|
||||
*/
|
||||
@Suppress("LongMethod")
|
||||
fun ServiceType.toUsernameGeneratorRequest(website: String?): UsernameGeneratorRequest.Forwarded? {
|
||||
fun ServiceType.toUsernameGeneratorRequest(
|
||||
website: String?,
|
||||
allowAddyIoSelfHostUrl: Boolean,
|
||||
): UsernameGeneratorRequest.Forwarded? {
|
||||
return when (this) {
|
||||
is ServiceType.AddyIo -> {
|
||||
val accessToken = this.apiAccessToken.orNullIfBlank() ?: return null
|
||||
val domain = this.domainName.orNullIfBlank() ?: return null
|
||||
val baseUrl = if (allowAddyIoSelfHostUrl && selfHostServerUrl.isNotBlank()) {
|
||||
selfHostServerUrl.prefixHttpsIfNecessary()
|
||||
} else {
|
||||
ServiceType.AddyIo.DEFAULT_ADDY_IO_URL
|
||||
}
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
service = ForwarderServiceType.AddyIo(
|
||||
apiToken = accessToken,
|
||||
domain = domain,
|
||||
baseUrl = this.baseUrl,
|
||||
baseUrl = baseUrl,
|
||||
),
|
||||
website = website,
|
||||
)
|
||||
|
||||
@@ -1209,4 +1209,5 @@ Do you want to switch to this account?</string>
|
||||
<string name="passkey_operation_failed_because_the_request_is_invalid">Passkey operation failed because the request is invalid.</string>
|
||||
<string name="passkey_operation_failed_because_user_verification_attempts_exceeded">Passkey operation failed because user verification attempts exceeded.</string>
|
||||
<string name="passkey_operation_failed_because_no_item_was_selected">Passkey operation failed because no item was selected.</string>
|
||||
<string name="self_host_server_url">Self-host server URL</string>
|
||||
</resources>
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.ui.semantics.SemanticsProperties
|
||||
import androidx.compose.ui.test.SemanticsMatcher.Companion.expectValue
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.assertIsOff
|
||||
import androidx.compose.ui.test.assertIsOn
|
||||
import androidx.compose.ui.test.assertTextEquals
|
||||
@@ -1124,6 +1125,84 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in Username_ForwardedEmailAlias_AddyIo state, updating self host server url text input should send SelfHostServerUrlChange action`() {
|
||||
updateState(
|
||||
DEFAULT_STATE.copy(
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
|
||||
selectedServiceType = GeneratorState
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.ServiceType
|
||||
.AddyIo(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
val newServerUrl = "https://addyio.local"
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Self-host server URL")
|
||||
.performScrollTo()
|
||||
.performTextInput(newServerUrl)
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
GeneratorAction
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.AddyIo
|
||||
.SelfHostServerUrlChange(
|
||||
url = newServerUrl,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in Username_ForwardedEmailAlias_AddyIo state, self host server url field should show based on state`() {
|
||||
updateState(
|
||||
DEFAULT_STATE.copy(
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
|
||||
selectedServiceType = GeneratorState
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.ServiceType
|
||||
.AddyIo(),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Self-host server URL")
|
||||
.performScrollTo()
|
||||
.assertIsDisplayed()
|
||||
|
||||
// Simulate Disabling the feature flag
|
||||
updateState(
|
||||
DEFAULT_STATE.copy(
|
||||
shouldShowAnonAddySelfHostServerUrlField = false,
|
||||
),
|
||||
)
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Self-host server URL")
|
||||
.assertIsNotDisplayed()
|
||||
}
|
||||
|
||||
//endregion Addy.Io Service Type Tests
|
||||
|
||||
//region DuckDuckGo Service Type Tests
|
||||
@@ -1773,4 +1852,5 @@ private val DEFAULT_STATE = GeneratorState(
|
||||
selectedType = GeneratorState.MainType.Password(),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = false,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
@@ -8,12 +8,14 @@ import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.ReviewPromptManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.CoachMarkTourType
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
|
||||
import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedCatchAllUsernameResult
|
||||
@@ -119,6 +121,13 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
every { markCoachMarkTourCompleted(CoachMarkTourType.GENERATOR) } just runs
|
||||
every { shouldShowGeneratorCoachMarkFlow } returns mutableShouldShowGeneratorCoachMarkFlow
|
||||
}
|
||||
private val mutableAnonAddySelfHostAliasFlow = MutableStateFlow(true)
|
||||
private val featureFlagManager = mockk<FeatureFlagManager> {
|
||||
every { getFeatureFlag(FlagKey.AnonAddySelfHostAlias) } returns true
|
||||
every {
|
||||
getFeatureFlagFlow(FlagKey.AnonAddySelfHostAlias)
|
||||
} returns mutableAnonAddySelfHostAliasFlow
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state should be correct when there is no saved state`() {
|
||||
@@ -148,9 +157,9 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
generatorMode = GeneratorMode.Modal.Username(website = ""),
|
||||
currentEmailAddress = "currentEmail",
|
||||
isUnderPolicy = false,
|
||||
website = "",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
val viewModel = createViewModel(
|
||||
@@ -184,9 +193,8 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
selectedType = GeneratorState.MainType.Passphrase(),
|
||||
generatorMode = GeneratorMode.Modal.Password,
|
||||
currentEmailAddress = "currentEmail",
|
||||
isUnderPolicy = false,
|
||||
website = null,
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
val viewModel = createViewModel(
|
||||
@@ -1696,9 +1704,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
|
||||
selectedServiceType = ServiceType
|
||||
.AddyIo(
|
||||
apiAccessToken = newAccessToken,
|
||||
),
|
||||
.AddyIo(apiAccessToken = newAccessToken),
|
||||
),
|
||||
),
|
||||
)
|
||||
@@ -1726,13 +1732,47 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
|
||||
viewModel.trySendAction(action)
|
||||
|
||||
val expectedState = defaultAddyIoState.copy(
|
||||
generatedText = "-",
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
|
||||
selectedServiceType = ServiceType
|
||||
.AddyIo(domainName = newDomainName),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ServerUrlTextChange should update the server text correctly`() = runTest {
|
||||
val newSelfHostServerUrl = "https://selfhost.alias"
|
||||
val action = GeneratorAction
|
||||
.MainType
|
||||
.Username
|
||||
.UsernameType
|
||||
.ForwardedEmailAlias
|
||||
.AddyIo
|
||||
.SelfHostServerUrlChange(
|
||||
url = newSelfHostServerUrl,
|
||||
)
|
||||
|
||||
fakeGeneratorRepository.setMockGenerateForwardedServiceResult(
|
||||
GeneratedForwardedServiceUsernameResult.Success(
|
||||
generatedEmailAddress = "defaultAddyIo",
|
||||
),
|
||||
)
|
||||
|
||||
viewModel.trySendAction(action)
|
||||
|
||||
val expectedState = defaultAddyIoState.copy(
|
||||
generatedText = "-",
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias(
|
||||
selectedServiceType = ServiceType
|
||||
.AddyIo(
|
||||
domainName = newDomainName,
|
||||
selfHostServerUrl = newSelfHostServerUrl,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -2295,6 +2335,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createPassphraseState(
|
||||
@@ -2314,6 +2355,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createUsernameModeState(
|
||||
@@ -2322,14 +2364,15 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
): GeneratorState =
|
||||
GeneratorState(
|
||||
generatedText = generatedText,
|
||||
generatorMode = GeneratorMode.Modal.Username(website = null),
|
||||
selectedType = GeneratorState.MainType.Username(
|
||||
GeneratorState.MainType.Username.UsernameType.PlusAddressedEmail(
|
||||
email = email,
|
||||
),
|
||||
),
|
||||
generatorMode = GeneratorMode.Modal.Username(website = null),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createForwardedEmailAliasState(
|
||||
@@ -2346,6 +2389,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createAddyIoState(
|
||||
@@ -2361,6 +2405,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createDuckDuckGoState(
|
||||
@@ -2376,6 +2421,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createFastMailState(
|
||||
@@ -2391,6 +2437,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createFirefoxRelayState(
|
||||
@@ -2406,6 +2453,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createForwardEmailState(
|
||||
@@ -2421,6 +2469,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createSimpleLoginState(
|
||||
@@ -2436,6 +2485,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createPlusAddressedEmailState(
|
||||
@@ -2451,6 +2501,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createCatchAllEmailState(
|
||||
@@ -2466,6 +2517,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createRandomWordState(
|
||||
@@ -2483,6 +2535,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
),
|
||||
currentEmailAddress = "currentEmail",
|
||||
shouldShowCoachMarkTour = true,
|
||||
shouldShowAnonAddySelfHostServerUrlField = true,
|
||||
)
|
||||
|
||||
private fun createSavedStateHandleWithState(state: GeneratorState) =
|
||||
@@ -2500,6 +2553,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
policyManager = policyManager,
|
||||
reviewPromptManager = reviewPromptManager,
|
||||
firstTimeActionManager = firstTimeActionManager,
|
||||
featureFlagManager = featureFlagManager,
|
||||
)
|
||||
|
||||
private fun createViewModel(
|
||||
|
||||
@@ -22,13 +22,17 @@ class ForwardedEmailServiceTypeExtensionsTest {
|
||||
fastMailApiKey = "api_key_fast_mail",
|
||||
anonAddyApiAccessToken = "access_token_anon_addy",
|
||||
anonAddyDomainName = "anonaddy.com",
|
||||
anonAddySelfHostServerUrl = "https://anonaddy.local",
|
||||
forwardEmailApiAccessToken = "access_token_forward_email",
|
||||
forwardEmailDomainName = "forwardemail.net",
|
||||
emailWebsite = "email.example.com",
|
||||
)
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.entries
|
||||
.forEach {
|
||||
val expected = createMockForwardedEmailAliasServiceType(it)
|
||||
val expected = createMockForwardedEmailAliasServiceType(
|
||||
serviceTypeOption = it,
|
||||
useEmptyValues = false,
|
||||
)
|
||||
assertEquals(
|
||||
expected,
|
||||
it.toServiceType(options),
|
||||
@@ -36,39 +40,90 @@ class ForwardedEmailServiceTypeExtensionsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `toServiceType should map to correct service type with empty values`() {
|
||||
val options = UsernameGenerationOptions(
|
||||
type = UsernameGenerationOptions.UsernameType.RANDOM_WORD,
|
||||
serviceType = UsernameGenerationOptions.ForwardedEmailServiceType.NONE,
|
||||
capitalizeRandomWordUsername = true,
|
||||
includeNumberRandomWordUsername = false,
|
||||
plusAddressedEmail = null,
|
||||
catchAllEmailDomain = null,
|
||||
firefoxRelayApiAccessToken = null,
|
||||
simpleLoginApiKey = null,
|
||||
duckDuckGoApiKey = null,
|
||||
fastMailApiKey = null,
|
||||
anonAddyApiAccessToken = null,
|
||||
anonAddyDomainName = null,
|
||||
anonAddySelfHostServerUrl = null,
|
||||
forwardEmailApiAccessToken = null,
|
||||
forwardEmailDomainName = null,
|
||||
emailWebsite = null,
|
||||
)
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.entries
|
||||
.forEach {
|
||||
assertEquals(
|
||||
createMockForwardedEmailAliasServiceType(
|
||||
serviceTypeOption = it,
|
||||
useEmptyValues = true,
|
||||
),
|
||||
it.toServiceType(options),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMockForwardedEmailAliasServiceType(
|
||||
serviceTypeOption: UsernameGenerationOptions.ForwardedEmailServiceType,
|
||||
useEmptyValues: Boolean = false,
|
||||
): ServiceType? = when (serviceTypeOption) {
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.NONE -> null
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.ANON_ADDY -> {
|
||||
ServiceType.AddyIo(
|
||||
apiAccessToken = "access_token_anon_addy",
|
||||
domainName = "anonaddy.com",
|
||||
apiAccessToken = "access_token_anon_addy".takeUnless { useEmptyValues }.orEmpty(),
|
||||
domainName = "anonaddy.com".takeUnless { useEmptyValues }.orEmpty(),
|
||||
selfHostServerUrl = "https://anonaddy.local"
|
||||
.takeUnless { useEmptyValues }
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.FIREFOX_RELAY -> {
|
||||
ServiceType.FirefoxRelay(apiAccessToken = "access_token_firefox_relay")
|
||||
ServiceType.FirefoxRelay(
|
||||
apiAccessToken = "access_token_firefox_relay"
|
||||
.takeUnless { useEmptyValues }
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.SIMPLE_LOGIN -> {
|
||||
ServiceType.SimpleLogin(apiKey = "api_key_simple_login")
|
||||
ServiceType.SimpleLogin(
|
||||
apiKey = "api_key_simple_login"
|
||||
.takeUnless { useEmptyValues }
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.DUCK_DUCK_GO -> {
|
||||
ServiceType.DuckDuckGo(apiKey = "api_key_duck_duck_go")
|
||||
ServiceType.DuckDuckGo(
|
||||
apiKey = "api_key_duck_duck_go"
|
||||
.takeUnless { useEmptyValues }
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.FASTMAIL -> {
|
||||
ServiceType.FastMail(apiKey = "api_key_fast_mail")
|
||||
ServiceType.FastMail(
|
||||
apiKey = "api_key_fast_mail"
|
||||
.takeUnless { useEmptyValues }
|
||||
.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
||||
UsernameGenerationOptions.ForwardedEmailServiceType.FORWARD_EMAIL -> {
|
||||
ServiceType.ForwardEmail(
|
||||
apiKey = "access_token_forward_email",
|
||||
domainName = "forwardemail.net",
|
||||
apiKey = "access_token_forward_email".takeUnless { useEmptyValues }.orEmpty(),
|
||||
domainName = "forwardemail.net".takeUnless { useEmptyValues }.orEmpty(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,11 +12,13 @@ internal class ServiceTypeExtensionsTest {
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for AddyIo returns null when apiAccessToken is blank`() {
|
||||
val addyIoServiceType = ServiceType.AddyIo(
|
||||
apiAccessToken = "",
|
||||
domainName = "test.com",
|
||||
baseUrl = "http://test.com",
|
||||
selfHostServerUrl = "http://test.com",
|
||||
)
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(website = null)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -25,23 +27,24 @@ internal class ServiceTypeExtensionsTest {
|
||||
fun `toUsernameGeneratorRequest for AddyIo returns null when domainName is blank`() {
|
||||
val addyIoServiceType = ServiceType.AddyIo(
|
||||
apiAccessToken = "testToken",
|
||||
domainName = "",
|
||||
baseUrl = "http://test.com",
|
||||
selfHostServerUrl = "http://test.com",
|
||||
)
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(website = null)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for AddyIo returns correct request`() {
|
||||
fun `toUsernameGeneratorRequest for AddyIo with selfHostServerUrl returns correct request`() {
|
||||
val addyIoServiceType = ServiceType.AddyIo(
|
||||
apiAccessToken = "testToken",
|
||||
domainName = "test.com",
|
||||
baseUrl = "http://test.com",
|
||||
selfHostServerUrl = "http://test.com",
|
||||
)
|
||||
val website = "bitwarden.com"
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(website)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
@@ -52,6 +55,51 @@ internal class ServiceTypeExtensionsTest {
|
||||
),
|
||||
website = website,
|
||||
),
|
||||
addyIoServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
),
|
||||
)
|
||||
|
||||
// Verify the correct request is returned when allowAddyIoSelfHostUrl is false
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
service = ForwarderServiceType.AddyIo(
|
||||
apiToken = "testToken",
|
||||
domain = "test.com",
|
||||
baseUrl = ServiceType.AddyIo.DEFAULT_ADDY_IO_URL,
|
||||
),
|
||||
website = website,
|
||||
),
|
||||
addyIoServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for AddyIo without selfHostServerUrl returns correct request`() {
|
||||
val addyIoServiceType = ServiceType.AddyIo(
|
||||
apiAccessToken = "testToken",
|
||||
domainName = "test.com",
|
||||
)
|
||||
val website = "bitwarden.com"
|
||||
val request = addyIoServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
service = ForwarderServiceType.AddyIo(
|
||||
apiToken = "testToken",
|
||||
domain = "test.com",
|
||||
baseUrl = ServiceType.AddyIo.DEFAULT_ADDY_IO_URL,
|
||||
),
|
||||
website = website,
|
||||
),
|
||||
request,
|
||||
)
|
||||
}
|
||||
@@ -59,7 +107,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for DuckDuckGo returns null when apiKey is blank`() {
|
||||
val duckDuckGoServiceType = ServiceType.DuckDuckGo(apiKey = "")
|
||||
val request = duckDuckGoServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = duckDuckGoServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -68,7 +119,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
fun `toUsernameGeneratorRequest for DuckDuckGo returns correct request`() {
|
||||
val duckDuckGoServiceType = ServiceType.DuckDuckGo(apiKey = "testKey")
|
||||
val website = "bitwarden.com"
|
||||
val request = duckDuckGoServiceType.toUsernameGeneratorRequest(website)
|
||||
val request = duckDuckGoServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
@@ -82,7 +136,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for FirefoxRelay returns null when apiAccessToken is blank`() {
|
||||
val firefoxRelayServiceType = ServiceType.FirefoxRelay(apiAccessToken = "")
|
||||
val request = firefoxRelayServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = firefoxRelayServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -91,7 +148,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
fun `toUsernameGeneratorRequest for FirefoxRelay returns correct request`() {
|
||||
val firefoxRelayServiceType = ServiceType.FirefoxRelay(apiAccessToken = "testToken")
|
||||
val website = "bitwarden.com"
|
||||
val request = firefoxRelayServiceType.toUsernameGeneratorRequest(website)
|
||||
val request = firefoxRelayServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
@@ -105,7 +165,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for FastMail returns null when apiKey is blank`() {
|
||||
val fastMailServiceType = ServiceType.FastMail(apiKey = "")
|
||||
val request = fastMailServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = fastMailServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -116,7 +179,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
apiKey = "testKey",
|
||||
)
|
||||
val website = "bitwarden.com"
|
||||
val request = fastMailServiceType.toUsernameGeneratorRequest(website)
|
||||
val request = fastMailServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
@@ -133,7 +199,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
apiKey = "",
|
||||
domainName = "domainName",
|
||||
)
|
||||
val request = forwardMailServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = forwardMailServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -144,7 +213,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
apiKey = "apiKey",
|
||||
domainName = "",
|
||||
)
|
||||
val request = forwardMailServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = forwardMailServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -156,7 +228,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
domainName = "domainName",
|
||||
)
|
||||
val website = "bitwarden.com"
|
||||
val request = forwardEmailServiceType.toUsernameGeneratorRequest(website)
|
||||
val request = forwardEmailServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
@@ -173,7 +248,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
@Test
|
||||
fun `toUsernameGeneratorRequest for SimpleLogin returns null when apiKey is blank`() {
|
||||
val simpleLoginServiceType = ServiceType.SimpleLogin(apiKey = "")
|
||||
val request = simpleLoginServiceType.toUsernameGeneratorRequest(website = null)
|
||||
val request = simpleLoginServiceType.toUsernameGeneratorRequest(
|
||||
website = null,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertNull(request)
|
||||
}
|
||||
@@ -182,7 +260,10 @@ internal class ServiceTypeExtensionsTest {
|
||||
fun `toUsernameGeneratorRequest for SimpleLogin returns correct request`() {
|
||||
val simpleLoginServiceType = ServiceType.SimpleLogin(apiKey = "testKey")
|
||||
val website = "bitwarden.com"
|
||||
val request = simpleLoginServiceType.toUsernameGeneratorRequest(website)
|
||||
val request = simpleLoginServiceType.toUsernameGeneratorRequest(
|
||||
website = website,
|
||||
allowAddyIoSelfHostUrl = true,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UsernameGeneratorRequest.Forwarded(
|
||||
|
||||
Reference in New Issue
Block a user