mirror of
https://github.com/bitwarden/android.git
synced 2024-11-28 06:04:16 +03:00
PM-11176: Update generator to use segmented control (#4075)
This commit is contained in:
parent
2b87cdac9e
commit
efbf84238d
6 changed files with 958 additions and 1505 deletions
|
@ -46,6 +46,7 @@ fun BitwardenSegmentedButton(
|
||||||
) {
|
) {
|
||||||
options.forEachIndexed { index, option ->
|
options.forEachIndexed { index, option ->
|
||||||
SegmentedButton(
|
SegmentedButton(
|
||||||
|
enabled = option.isEnabled,
|
||||||
selected = option.isChecked,
|
selected = option.isChecked,
|
||||||
onClick = option.onClick,
|
onClick = option.onClick,
|
||||||
colors = bitwardenSegmentedButtonColors(),
|
colors = bitwardenSegmentedButtonColors(),
|
||||||
|
@ -74,5 +75,6 @@ data class SegmentedButtonState(
|
||||||
val text: String,
|
val text: String,
|
||||||
val onClick: () -> Unit,
|
val onClick: () -> Unit,
|
||||||
val isChecked: Boolean,
|
val isChecked: Boolean,
|
||||||
|
val isEnabled: Boolean = true,
|
||||||
val testTag: String? = null,
|
val testTag: String? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,6 +20,6 @@ fun bitwardenSegmentedButtonColors(): SegmentedButtonColors = SegmentedButtonCol
|
||||||
disabledActiveContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
|
disabledActiveContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
|
||||||
disabledActiveBorderColor = Color.Transparent,
|
disabledActiveBorderColor = Color.Transparent,
|
||||||
disabledInactiveContainerColor = BitwardenTheme.colorScheme.background.primary,
|
disabledInactiveContainerColor = BitwardenTheme.colorScheme.background.primary,
|
||||||
disabledInactiveContentColor = BitwardenTheme.colorScheme.filledButton.foregroundDisabled,
|
disabledInactiveContentColor = BitwardenTheme.colorScheme.stroke.divider,
|
||||||
disabledInactiveBorderColor = Color.Transparent,
|
disabledInactiveBorderColor = Color.Transparent,
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,6 +36,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.x8bit.bitwarden.R
|
import com.x8bit.bitwarden.R
|
||||||
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
||||||
import com.x8bit.bitwarden.ui.platform.base.util.LivecycleEventEffect
|
import com.x8bit.bitwarden.ui.platform.base.util.LivecycleEventEffect
|
||||||
|
import com.x8bit.bitwarden.ui.platform.base.util.scrolledContainerBottomDivider
|
||||||
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenMediumTopAppBar
|
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenMediumTopAppBar
|
||||||
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
|
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
|
||||||
import com.x8bit.bitwarden.ui.platform.components.appbar.action.BitwardenOverflowActionItem
|
import com.x8bit.bitwarden.ui.platform.components.appbar.action.BitwardenOverflowActionItem
|
||||||
|
@ -49,7 +50,10 @@ import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextField
|
||||||
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
|
import com.x8bit.bitwarden.ui.platform.components.field.BitwardenTextFieldWithActions
|
||||||
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
|
import com.x8bit.bitwarden.ui.platform.components.header.BitwardenListHeaderText
|
||||||
import com.x8bit.bitwarden.ui.platform.components.model.TooltipData
|
import com.x8bit.bitwarden.ui.platform.components.model.TooltipData
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.model.TopAppBarDividerStyle
|
||||||
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.segment.BitwardenSegmentedButton
|
||||||
|
import com.x8bit.bitwarden.ui.platform.components.segment.SegmentedButtonState
|
||||||
import com.x8bit.bitwarden.ui.platform.components.slider.BitwardenSlider
|
import com.x8bit.bitwarden.ui.platform.components.slider.BitwardenSlider
|
||||||
import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarHost
|
import com.x8bit.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarHost
|
||||||
import com.x8bit.bitwarden.ui.platform.components.stepper.BitwardenStepper
|
import com.x8bit.bitwarden.ui.platform.components.stepper.BitwardenStepper
|
||||||
|
@ -59,8 +63,8 @@ import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||||
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
|
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
|
||||||
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Passcode.PasscodeType.Passphrase.Companion.PASSPHRASE_MAX_NUMBER_OF_WORDS
|
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Passphrase.Companion.PASSPHRASE_MAX_NUMBER_OF_WORDS
|
||||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Passcode.PasscodeType.Passphrase.Companion.PASSPHRASE_MIN_NUMBER_OF_WORDS
|
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Passphrase.Companion.PASSPHRASE_MIN_NUMBER_OF_WORDS
|
||||||
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.ServiceType
|
||||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceTypeOption
|
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 com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||||
|
@ -129,17 +133,6 @@ fun GeneratorScreen(
|
||||||
{ viewModel.trySendAction(GeneratorAction.MainTypeOptionSelect(it)) }
|
{ viewModel.trySendAction(GeneratorAction.MainTypeOptionSelect(it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val onPasscodeOptionClicked: (GeneratorState.MainType.Passcode.PasscodeTypeOption) -> Unit =
|
|
||||||
remember(viewModel) {
|
|
||||||
{
|
|
||||||
viewModel.trySendAction(
|
|
||||||
GeneratorAction.MainType.Passcode.PasscodeTypeOptionSelect(
|
|
||||||
it,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val onUsernameOptionClicked: (GeneratorState.MainType.Username.UsernameTypeOption) -> Unit =
|
val onUsernameOptionClicked: (GeneratorState.MainType.Username.UsernameTypeOption) -> Unit =
|
||||||
remember(viewModel) {
|
remember(viewModel) {
|
||||||
{
|
{
|
||||||
|
@ -183,9 +176,7 @@ fun GeneratorScreen(
|
||||||
BitwardenScaffold(
|
BitwardenScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
when (state.generatorMode) {
|
when (state.generatorMode) {
|
||||||
is GeneratorMode.Modal.Username,
|
is GeneratorMode.Modal -> {
|
||||||
GeneratorMode.Modal.Password,
|
|
||||||
-> {
|
|
||||||
ModalAppBar(
|
ModalAppBar(
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
onCloseClick = remember(viewModel) {
|
onCloseClick = remember(viewModel) {
|
||||||
|
@ -212,22 +203,31 @@ fun GeneratorScreen(
|
||||||
},
|
},
|
||||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
ScrollContent(
|
Column(modifier = Modifier.padding(innerPadding)) {
|
||||||
state = state,
|
if (state.generatorMode == GeneratorMode.Default) {
|
||||||
onRegenerateClick = onRegenerateClick,
|
MainStateOptionsItem(
|
||||||
onCopyClick = onCopyClick,
|
selectedType = state.selectedType,
|
||||||
onMainStateOptionClicked = onMainStateOptionClicked,
|
passcodePolicyOverride = state.passcodePolicyOverride,
|
||||||
onPasscodeSubStateOptionClicked = onPasscodeOptionClicked,
|
possibleMainStates = state.typeOptions.toImmutableList(),
|
||||||
onUsernameSubStateOptionClicked = onUsernameOptionClicked,
|
onMainStateOptionClicked = onMainStateOptionClicked,
|
||||||
passwordHandlers = passwordHandlers,
|
modifier = Modifier
|
||||||
passphraseHandlers = passphraseHandlers,
|
.scrolledContainerBottomDivider(topAppBarScrollBehavior = scrollBehavior),
|
||||||
usernameTypeHandlers = usernameTypeHandlers,
|
)
|
||||||
forwardedEmailAliasHandlers = forwardedEmailAliasHandlers,
|
}
|
||||||
plusAddressedEmailHandlers = plusAddressedEmailHandlers,
|
ScrollContent(
|
||||||
catchAllEmailHandlers = catchAllEmailHandlers,
|
state = state,
|
||||||
randomWordHandlers = randomWordHandlers,
|
onRegenerateClick = onRegenerateClick,
|
||||||
modifier = Modifier.padding(innerPadding),
|
onCopyClick = onCopyClick,
|
||||||
)
|
onUsernameSubStateOptionClicked = onUsernameOptionClicked,
|
||||||
|
passwordHandlers = passwordHandlers,
|
||||||
|
passphraseHandlers = passphraseHandlers,
|
||||||
|
usernameTypeHandlers = usernameTypeHandlers,
|
||||||
|
forwardedEmailAliasHandlers = forwardedEmailAliasHandlers,
|
||||||
|
plusAddressedEmailHandlers = plusAddressedEmailHandlers,
|
||||||
|
catchAllEmailHandlers = catchAllEmailHandlers,
|
||||||
|
randomWordHandlers = randomWordHandlers,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +242,7 @@ private fun DefaultAppBar(
|
||||||
BitwardenMediumTopAppBar(
|
BitwardenMediumTopAppBar(
|
||||||
title = stringResource(id = R.string.generator),
|
title = stringResource(id = R.string.generator),
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
dividerStyle = TopAppBarDividerStyle.NONE,
|
||||||
actions = {
|
actions = {
|
||||||
BitwardenOverflowActionItem(
|
BitwardenOverflowActionItem(
|
||||||
menuItemDataList = persistentListOf(
|
menuItemDataList = persistentListOf(
|
||||||
|
@ -288,8 +289,6 @@ private fun ScrollContent(
|
||||||
state: GeneratorState,
|
state: GeneratorState,
|
||||||
onRegenerateClick: () -> Unit,
|
onRegenerateClick: () -> Unit,
|
||||||
onCopyClick: () -> Unit,
|
onCopyClick: () -> Unit,
|
||||||
onMainStateOptionClicked: (GeneratorState.MainTypeOption) -> Unit,
|
|
||||||
onPasscodeSubStateOptionClicked: (GeneratorState.MainType.Passcode.PasscodeTypeOption) -> Unit,
|
|
||||||
onUsernameSubStateOptionClicked: (GeneratorState.MainType.Username.UsernameTypeOption) -> Unit,
|
onUsernameSubStateOptionClicked: (GeneratorState.MainType.Username.UsernameTypeOption) -> Unit,
|
||||||
passwordHandlers: PasswordHandlers,
|
passwordHandlers: PasswordHandlers,
|
||||||
passphraseHandlers: PassphraseHandlers,
|
passphraseHandlers: PassphraseHandlers,
|
||||||
|
@ -305,8 +304,8 @@ private fun ScrollContent(
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.verticalScroll(rememberScrollState()),
|
.verticalScroll(rememberScrollState()),
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (state.isUnderPolicy) {
|
if (state.isUnderPolicy) {
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
BitwardenInfoCalloutCard(
|
BitwardenInfoCalloutCard(
|
||||||
text = stringResource(id = R.string.password_generator_policy_in_effect),
|
text = stringResource(id = R.string.password_generator_policy_in_effect),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -324,15 +323,6 @@ private fun ScrollContent(
|
||||||
onRegenerateClick = onRegenerateClick,
|
onRegenerateClick = onRegenerateClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (state.generatorMode == GeneratorMode.Default) {
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
MainStateOptionsItem(
|
|
||||||
selectedType = state.selectedType,
|
|
||||||
possibleMainStates = state.typeOptions.toImmutableList(),
|
|
||||||
onMainStateOptionClicked = onMainStateOptionClicked,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
BitwardenListHeaderText(
|
BitwardenListHeaderText(
|
||||||
|
@ -345,13 +335,17 @@ private fun ScrollContent(
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
when (val selectedType = state.selectedType) {
|
when (val selectedType = state.selectedType) {
|
||||||
is GeneratorState.MainType.Passcode -> {
|
is GeneratorState.MainType.Passphrase -> {
|
||||||
PasscodeTypeItems(
|
PassphraseTypeContent(
|
||||||
passcodeState = selectedType,
|
passphraseTypeState = selectedType,
|
||||||
onSubStateOptionClicked = onPasscodeSubStateOptionClicked,
|
|
||||||
passwordHandlers = passwordHandlers,
|
|
||||||
passphraseHandlers = passphraseHandlers,
|
passphraseHandlers = passphraseHandlers,
|
||||||
overridePasswordPolicyRestriction = state.overridePassword,
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
is GeneratorState.MainType.Password -> {
|
||||||
|
PasswordTypeContent(
|
||||||
|
passwordTypeState = selectedType,
|
||||||
|
passwordHandlers = passwordHandlers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,92 +401,55 @@ private fun GeneratedStringItem(
|
||||||
@Composable
|
@Composable
|
||||||
private fun MainStateOptionsItem(
|
private fun MainStateOptionsItem(
|
||||||
selectedType: GeneratorState.MainType,
|
selectedType: GeneratorState.MainType,
|
||||||
|
passcodePolicyOverride: GeneratorState.PasscodePolicyOverride?,
|
||||||
possibleMainStates: ImmutableList<GeneratorState.MainTypeOption>,
|
possibleMainStates: ImmutableList<GeneratorState.MainTypeOption>,
|
||||||
onMainStateOptionClicked: (GeneratorState.MainTypeOption) -> Unit,
|
onMainStateOptionClicked: (GeneratorState.MainTypeOption) -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val optionsWithStrings = possibleMainStates.associateWith { stringResource(id = it.labelRes) }
|
BitwardenSegmentedButton(
|
||||||
|
options = possibleMainStates
|
||||||
|
.map { mainOptionType ->
|
||||||
|
SegmentedButtonState(
|
||||||
|
text = stringResource(id = mainOptionType.labelRes),
|
||||||
|
onClick = { onMainStateOptionClicked(mainOptionType) },
|
||||||
|
isChecked = selectedType.mainTypeOption == mainOptionType,
|
||||||
|
isEnabled = when (mainOptionType) {
|
||||||
|
GeneratorState.MainTypeOption.PASSWORD -> {
|
||||||
|
when (passcodePolicyOverride) {
|
||||||
|
GeneratorState.PasscodePolicyOverride.PASSWORD -> true
|
||||||
|
GeneratorState.PasscodePolicyOverride.PASSPHRASE -> false
|
||||||
|
null -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BitwardenMultiSelectButton(
|
GeneratorState.MainTypeOption.PASSPHRASE -> {
|
||||||
label = stringResource(id = R.string.what_would_you_like_to_generate),
|
when (passcodePolicyOverride) {
|
||||||
options = optionsWithStrings.values.toImmutableList(),
|
GeneratorState.PasscodePolicyOverride.PASSWORD -> false
|
||||||
selectedOption = stringResource(id = selectedType.displayStringResId),
|
GeneratorState.PasscodePolicyOverride.PASSPHRASE -> true
|
||||||
onOptionSelected = { selectedOption ->
|
null -> true
|
||||||
val selectedOptionId =
|
}
|
||||||
optionsWithStrings.entries.first { it.value == selectedOption }.key
|
}
|
||||||
onMainStateOptionClicked(selectedOptionId)
|
|
||||||
},
|
GeneratorState.MainTypeOption.USERNAME -> true
|
||||||
modifier = Modifier
|
},
|
||||||
.padding(horizontal = 16.dp)
|
testTag = mainOptionType.testTag,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.toImmutableList(),
|
||||||
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.testTag("GeneratorTypePicker"),
|
.testTag(tag = "GeneratorTypePicker"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion ScrollContent and Static Items
|
//endregion ScrollContent and Static Items
|
||||||
|
|
||||||
//region PasscodeType Composables
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun ColumnScope.PasscodeTypeItems(
|
|
||||||
passcodeState: GeneratorState.MainType.Passcode,
|
|
||||||
onSubStateOptionClicked: (GeneratorState.MainType.Passcode.PasscodeTypeOption) -> Unit,
|
|
||||||
passwordHandlers: PasswordHandlers,
|
|
||||||
passphraseHandlers: PassphraseHandlers,
|
|
||||||
overridePasswordPolicyRestriction: Boolean,
|
|
||||||
) {
|
|
||||||
PasscodeOptionsItem(passcodeState, onSubStateOptionClicked, overridePasswordPolicyRestriction)
|
|
||||||
|
|
||||||
when (val selectedType = passcodeState.selectedType) {
|
|
||||||
is GeneratorState.MainType.Passcode.PasscodeType.Password -> {
|
|
||||||
PasswordTypeContent(
|
|
||||||
passwordTypeState = selectedType,
|
|
||||||
passwordHandlers = passwordHandlers,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
is GeneratorState.MainType.Passcode.PasscodeType.Passphrase -> {
|
|
||||||
PassphraseTypeContent(
|
|
||||||
passphraseTypeState = selectedType,
|
|
||||||
passphraseHandlers = passphraseHandlers,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun PasscodeOptionsItem(
|
|
||||||
currentSubState: GeneratorState.MainType.Passcode,
|
|
||||||
onSubStateOptionClicked: (GeneratorState.MainType.Passcode.PasscodeTypeOption) -> Unit,
|
|
||||||
overridePasswordPolicyRestriction: Boolean,
|
|
||||||
) {
|
|
||||||
val possibleSubStates = GeneratorState.MainType.Passcode.PasscodeTypeOption.entries
|
|
||||||
val optionsWithStrings = possibleSubStates.associateWith { stringResource(id = it.labelRes) }
|
|
||||||
|
|
||||||
BitwardenMultiSelectButton(
|
|
||||||
label = stringResource(id = R.string.password_type),
|
|
||||||
options = optionsWithStrings.values.toImmutableList(),
|
|
||||||
selectedOption = stringResource(id = currentSubState.selectedType.displayStringResId),
|
|
||||||
onOptionSelected = { selectedOption ->
|
|
||||||
val selectedOptionId =
|
|
||||||
optionsWithStrings.entries.first { it.value == selectedOption }.key
|
|
||||||
onSubStateOptionClicked(selectedOptionId)
|
|
||||||
},
|
|
||||||
isEnabled = !overridePasswordPolicyRestriction,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.testTag("PasswordTypePicker"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//endregion PasscodeType Composables
|
|
||||||
|
|
||||||
//region PasswordType Composables
|
//region PasswordType Composables
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.PasswordTypeContent(
|
private fun ColumnScope.PasswordTypeContent(
|
||||||
passwordTypeState: GeneratorState.MainType.Passcode.PasscodeType.Password,
|
passwordTypeState: GeneratorState.MainType.Password,
|
||||||
passwordHandlers: PasswordHandlers,
|
passwordHandlers: PasswordHandlers,
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
@ -707,7 +664,7 @@ private fun PasswordAvoidAmbiguousCharsToggleItem(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ColumnScope.PassphraseTypeContent(
|
private fun ColumnScope.PassphraseTypeContent(
|
||||||
passphraseTypeState: GeneratorState.MainType.Passcode.PasscodeType.Passphrase,
|
passphraseTypeState: GeneratorState.MainType.Passphrase,
|
||||||
passphraseHandlers: PassphraseHandlers,
|
passphraseHandlers: PassphraseHandlers,
|
||||||
) {
|
) {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
@ -1232,67 +1189,59 @@ private data class PasswordHandlers(
|
||||||
return PasswordHandlers(
|
return PasswordHandlers(
|
||||||
onPasswordSliderLengthChange = { newLength, isUserInteracting ->
|
onPasswordSliderLengthChange = { newLength, isUserInteracting ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.SliderLengthChange(
|
||||||
.SliderLengthChange(
|
length = newLength,
|
||||||
length = newLength,
|
isUserInteracting = isUserInteracting,
|
||||||
isUserInteracting = isUserInteracting,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordToggleCapitalLettersChange = { shouldUseCapitals ->
|
onPasswordToggleCapitalLettersChange = { shouldUseCapitals ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.ToggleCapitalLettersChange(
|
||||||
.ToggleCapitalLettersChange(
|
useCapitals = shouldUseCapitals,
|
||||||
useCapitals = shouldUseCapitals,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordToggleLowercaseLettersChange = { shouldUseLowercase ->
|
onPasswordToggleLowercaseLettersChange = { shouldUseLowercase ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.ToggleLowercaseLettersChange(
|
||||||
.ToggleLowercaseLettersChange(
|
useLowercase = shouldUseLowercase,
|
||||||
useLowercase = shouldUseLowercase,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordToggleNumbersChange = { shouldUseNumbers ->
|
onPasswordToggleNumbersChange = { shouldUseNumbers ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.ToggleNumbersChange(
|
||||||
.ToggleNumbersChange(
|
useNumbers = shouldUseNumbers,
|
||||||
useNumbers = shouldUseNumbers,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordToggleSpecialCharactersChange = { shouldUseSpecialChars ->
|
onPasswordToggleSpecialCharactersChange = { shouldUseSpecialChars ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.ToggleSpecialCharactersChange(
|
||||||
.ToggleSpecialCharactersChange(
|
useSpecialChars = shouldUseSpecialChars,
|
||||||
useSpecialChars = shouldUseSpecialChars,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordMinNumbersCounterChange = { newMinNumbers ->
|
onPasswordMinNumbersCounterChange = { newMinNumbers ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.MinNumbersCounterChange(
|
||||||
.MinNumbersCounterChange(
|
minNumbers = newMinNumbers,
|
||||||
minNumbers = newMinNumbers,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordMinSpecialCharactersChange = { newMinSpecial ->
|
onPasswordMinSpecialCharactersChange = { newMinSpecial ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.MinSpecialCharactersChange(
|
||||||
.MinSpecialCharactersChange(
|
minSpecial = newMinSpecial,
|
||||||
minSpecial = newMinSpecial,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPasswordToggleAvoidAmbiguousCharsChange = { shouldAvoidAmbiguousChars ->
|
onPasswordToggleAvoidAmbiguousCharsChange = { shouldAvoidAmbiguousChars ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password
|
GeneratorAction.MainType.Password.ToggleAvoidAmbigousCharactersChange(
|
||||||
.ToggleAvoidAmbigousCharactersChange(
|
avoidAmbiguousChars = shouldAvoidAmbiguousChars,
|
||||||
avoidAmbiguousChars = shouldAvoidAmbiguousChars,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -1317,34 +1266,30 @@ private data class PassphraseHandlers(
|
||||||
return PassphraseHandlers(
|
return PassphraseHandlers(
|
||||||
onPassphraseNumWordsCounterChange = { changeInCounter ->
|
onPassphraseNumWordsCounterChange = { changeInCounter ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase
|
GeneratorAction.MainType.Passphrase.NumWordsCounterChange(
|
||||||
.NumWordsCounterChange(
|
numWords = changeInCounter,
|
||||||
numWords = changeInCounter,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPassphraseWordSeparatorChange = { newSeparator ->
|
onPassphraseWordSeparatorChange = { newSeparator ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase
|
GeneratorAction.MainType.Passphrase.WordSeparatorTextChange(
|
||||||
.WordSeparatorTextChange(
|
wordSeparator = newSeparator,
|
||||||
wordSeparator = newSeparator,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPassphraseCapitalizeToggleChange = { shouldCapitalize ->
|
onPassphraseCapitalizeToggleChange = { shouldCapitalize ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase
|
GeneratorAction.MainType.Passphrase.ToggleCapitalizeChange(
|
||||||
.ToggleCapitalizeChange(
|
capitalize = shouldCapitalize,
|
||||||
capitalize = shouldCapitalize,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onPassphraseIncludeNumberToggleChange = { shouldIncludeNumber ->
|
onPassphraseIncludeNumberToggleChange = { shouldIncludeNumber ->
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase
|
GeneratorAction.MainType.Passphrase.ToggleIncludeNumberChange(
|
||||||
.ToggleIncludeNumberChange(
|
includeNumber = shouldIncludeNumber,
|
||||||
includeNumber = shouldIncludeNumber,
|
),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -205,15 +205,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
fun `clicking a MainStateOption should send MainTypeOptionSelect action`() {
|
fun `clicking a MainStateOption should send MainTypeOptionSelect action`() {
|
||||||
// Opens the menu
|
// Opens the menu
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onNodeWithContentDescription(label = "Password. What would you like to generate?")
|
.onNodeWithText(text = "Password")
|
||||||
.performClick()
|
|
||||||
|
|
||||||
// Choose the option from the menu
|
|
||||||
composeTestRule
|
|
||||||
.onAllNodesWithText(text = "Password")
|
|
||||||
.onLast()
|
|
||||||
.performScrollTo()
|
|
||||||
.assert(hasAnyAncestor(isDialog()))
|
|
||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
|
@ -228,45 +220,13 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
.assertDoesNotExist()
|
.assertDoesNotExist()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `clicking a PasscodeOption should send PasscodeTypeOption action`() {
|
|
||||||
// Opens the menu
|
|
||||||
composeTestRule
|
|
||||||
.onNodeWithContentDescription(label = "Password. Password type")
|
|
||||||
.performClick()
|
|
||||||
|
|
||||||
// Choose the option from the menu
|
|
||||||
composeTestRule
|
|
||||||
.onAllNodesWithText(text = "Passphrase")
|
|
||||||
.onLast()
|
|
||||||
.assert(hasAnyAncestor(isDialog()))
|
|
||||||
.performClick()
|
|
||||||
|
|
||||||
verify {
|
|
||||||
viewModel.trySendAction(
|
|
||||||
GeneratorAction.MainType.Passcode.PasscodeTypeOptionSelect(
|
|
||||||
GeneratorState.MainType.Passcode.PasscodeTypeOption.PASSPHRASE,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure dialog is hidden:
|
|
||||||
composeTestRule
|
|
||||||
.onNode(isDialog())
|
|
||||||
.assertDoesNotExist()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `clicking a UsernameOption should send UsernameTypeOption action`() {
|
fun `clicking a UsernameOption should send UsernameTypeOption action`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Username(
|
selectedType = GeneratorState.MainType.Username(
|
||||||
GeneratorState
|
GeneratorState.MainType.Username.UsernameType.PlusAddressedEmail(),
|
||||||
.MainType
|
|
||||||
.Username
|
|
||||||
.UsernameType
|
|
||||||
.PlusAddressedEmail(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -302,15 +262,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
//region Passcode Password Tests
|
//region Passcode Password Tests
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, the ViewModel state should update the UI correctly`() {
|
fun `in Password state, the ViewModel state should update the UI correctly`() {
|
||||||
composeTestRule
|
|
||||||
.onNodeWithContentDescription(label = "Password. What would you like to generate?")
|
|
||||||
.assertIsDisplayed()
|
|
||||||
|
|
||||||
composeTestRule
|
|
||||||
.onNodeWithContentDescription(label = "Password. Password type")
|
|
||||||
.assertIsDisplayed()
|
|
||||||
|
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onNode(
|
.onNode(
|
||||||
expectValue(
|
expectValue(
|
||||||
|
@ -363,7 +315,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, adjusting the slider should send SliderLengthChange action with length not equal to default`() {
|
fun `in Password state, adjusting the slider should send SliderLengthChange action with length not equal to default`() {
|
||||||
composeTestRule
|
composeTestRule
|
||||||
.onNodeWithText("Length")
|
.onNodeWithText("Length")
|
||||||
.onSiblings()
|
.onSiblings()
|
||||||
|
@ -383,7 +335,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.SliderLengthChange(
|
GeneratorAction.MainType.Password.SliderLengthChange(
|
||||||
length = 128,
|
length = 128,
|
||||||
isUserInteracting = true,
|
isUserInteracting = true,
|
||||||
),
|
),
|
||||||
|
@ -396,7 +348,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
// actually get updated from its original value, and thus will be its original value of 14.
|
// actually get updated from its original value, and thus will be its original value of 14.
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.SliderLengthChange(
|
GeneratorAction.MainType.Password.SliderLengthChange(
|
||||||
length = 14,
|
length = 14,
|
||||||
isUserInteracting = false,
|
isUserInteracting = false,
|
||||||
),
|
),
|
||||||
|
@ -406,14 +358,14 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, toggling the capital letters toggle should send ToggleCapitalLettersChange action`() {
|
fun `in Password state, toggling the capital letters toggle should send ToggleCapitalLettersChange action`() {
|
||||||
composeTestRule.onNodeWithText("A—Z")
|
composeTestRule.onNodeWithText("A—Z")
|
||||||
.performScrollTo()
|
.performScrollTo()
|
||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleCapitalLettersChange(
|
GeneratorAction.MainType.Password.ToggleCapitalLettersChange(
|
||||||
useCapitals = false,
|
useCapitals = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -422,36 +374,15 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, toggling the use lowercase toggle should send ToggleLowercaseLettersChange action`() {
|
fun `in Password state, toggling the use lowercase toggle should send ToggleLowercaseLettersChange action`() {
|
||||||
composeTestRule.onNodeWithText("a—z")
|
composeTestRule.onNodeWithText("a—z")
|
||||||
.performScrollTo()
|
.performScrollTo()
|
||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleLowercaseLettersChange(
|
||||||
.MainType
|
useLowercase = false,
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleLowercaseLettersChange(
|
|
||||||
useLowercase = false,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
|
||||||
fun `in Passcode_Password state, toggling the use numbers toggle should send ToggleNumbersChange action`() {
|
|
||||||
composeTestRule.onNodeWithText("0-9")
|
|
||||||
.performScrollTo()
|
|
||||||
.performClick()
|
|
||||||
|
|
||||||
verify {
|
|
||||||
viewModel.trySendAction(
|
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleNumbersChange(
|
|
||||||
useNumbers = false,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -459,28 +390,37 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, toggling the use special characters toggle should send ToggleSpecialCharactersChange action`() {
|
fun `in Password state, toggling the use numbers toggle should send ToggleNumbersChange action`() {
|
||||||
composeTestRule.onNodeWithText("!@#$%^&*")
|
composeTestRule.onNodeWithText("0-9")
|
||||||
.performScrollTo()
|
.performScrollTo()
|
||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleNumbersChange(useNumbers = false),
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleSpecialCharactersChange(
|
|
||||||
useSpecialChars = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, decrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
fun `in Password state, toggling the use special characters toggle should send ToggleSpecialCharactersChange action`() {
|
||||||
|
composeTestRule.onNodeWithText("!@#$%^&*")
|
||||||
|
.performScrollTo()
|
||||||
|
.performClick()
|
||||||
|
|
||||||
|
verify {
|
||||||
|
viewModel.trySendAction(
|
||||||
|
GeneratorAction.MainType.Password.ToggleSpecialCharactersChange(
|
||||||
|
useSpecialChars = true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `in Password state, decrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
||||||
val initialMinNumbers = 1
|
val initialMinNumbers = 1
|
||||||
|
|
||||||
composeTestRule.onNodeWithText("Minimum numbers")
|
composeTestRule.onNodeWithText("Minimum numbers")
|
||||||
|
@ -492,7 +432,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinNumbersCounterChange(
|
GeneratorAction.MainType.Password.MinNumbersCounterChange(
|
||||||
minNumbers = initialMinNumbers - 1,
|
minNumbers = initialMinNumbers - 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -501,7 +441,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, incrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
fun `in Password state, incrementing the minimum numbers counter should send MinNumbersCounterChange action`() {
|
||||||
val initialMinNumbers = 1
|
val initialMinNumbers = 1
|
||||||
|
|
||||||
composeTestRule.onNodeWithText("Minimum numbers")
|
composeTestRule.onNodeWithText("Minimum numbers")
|
||||||
|
@ -513,28 +453,19 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinNumbersCounterChange(
|
GeneratorAction.MainType.Password.MinNumbersCounterChange(
|
||||||
minNumbers = initialMinNumbers + 1,
|
minNumbers = initialMinNumbers + 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, decrementing the minimum numbers counter below 0 should do nothing`() {
|
fun `in Password state, decrementing the minimum numbers counter below 0 should do nothing`() {
|
||||||
val initialMinNumbers = 0
|
val initialMinNumbers = 0
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(minNumbers = initialMinNumbers),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minNumbers = initialMinNumbers,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -549,21 +480,12 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
verify(exactly = 1) { viewModel.trySendAction(any()) }
|
verify(exactly = 1) { viewModel.trySendAction(any()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, incrementing the minimum numbers counter above 9 should do nothing`() {
|
fun `in Password state, incrementing the minimum numbers counter above 9 should do nothing`() {
|
||||||
val initialMinNumbers = 9
|
val initialMinNumbers = 9
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(minNumbers = initialMinNumbers),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minNumbers = initialMinNumbers,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -580,7 +502,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, decrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
fun `in Password state, decrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
||||||
val initialSpecialChars = 1
|
val initialSpecialChars = 1
|
||||||
|
|
||||||
composeTestRule.onNodeWithText("Minimum special")
|
composeTestRule.onNodeWithText("Minimum special")
|
||||||
|
@ -592,7 +514,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinSpecialCharactersChange(
|
GeneratorAction.MainType.Password.MinSpecialCharactersChange(
|
||||||
minSpecial = initialSpecialChars - 1,
|
minSpecial = initialSpecialChars - 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -601,7 +523,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, incrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
fun `in Password state, incrementing the minimum special characters counter should send MinSpecialCharactersChange action`() {
|
||||||
val initialSpecialChars = 1
|
val initialSpecialChars = 1
|
||||||
|
|
||||||
composeTestRule.onNodeWithText("Minimum special")
|
composeTestRule.onNodeWithText("Minimum special")
|
||||||
|
@ -613,7 +535,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinSpecialCharactersChange(
|
GeneratorAction.MainType.Password.MinSpecialCharactersChange(
|
||||||
minSpecial = initialSpecialChars + 1,
|
minSpecial = initialSpecialChars + 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -622,19 +544,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, decrementing the minimum special characters below 0 should do nothing`() {
|
fun `in Password state, decrementing the minimum special characters below 0 should do nothing`() {
|
||||||
val initialSpecialChars = 0
|
val initialSpecialChars = 0
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(minSpecial = initialSpecialChars),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minSpecial = initialSpecialChars,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -650,19 +564,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, decrementing the minimum special characters above 9 should do nothing`() {
|
fun `in Password state, decrementing the minimum special characters above 9 should do nothing`() {
|
||||||
val initialSpecialChars = 9
|
val initialSpecialChars = 9
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(minSpecial = initialSpecialChars),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minSpecial = initialSpecialChars,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -678,41 +584,30 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, toggling the use avoid ambiguous characters toggle should send ToggleSpecialCharactersChange action`() {
|
fun `in Password state, toggling the use avoid ambiguous characters toggle should send ToggleSpecialCharactersChange action`() {
|
||||||
composeTestRule.onNodeWithText("Avoid ambiguous characters")
|
composeTestRule.onNodeWithText("Avoid ambiguous characters")
|
||||||
.performScrollTo()
|
.performScrollTo()
|
||||||
.performClick()
|
.performClick()
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleAvoidAmbigousCharactersChange(
|
||||||
.MainType
|
avoidAmbiguousChars = true,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleAvoidAmbigousCharactersChange(
|
|
||||||
avoidAmbiguousChars = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, disabled elements should not send events`() {
|
fun `in Password state, disabled elements should not send events`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(
|
||||||
GeneratorState
|
capitalsEnabled = false,
|
||||||
.MainType
|
lowercaseEnabled = false,
|
||||||
.Passcode
|
numbersEnabled = false,
|
||||||
.PasscodeType
|
specialCharsEnabled = false,
|
||||||
.Password(
|
ambiguousCharsEnabled = false,
|
||||||
capitalsEnabled = false,
|
|
||||||
lowercaseEnabled = false,
|
|
||||||
numbersEnabled = false,
|
|
||||||
specialCharsEnabled = false,
|
|
||||||
ambiguousCharsEnabled = false,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -735,72 +630,37 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify(exactly = 0) {
|
verify(exactly = 0) {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleCapitalLettersChange(useCapitals = false),
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleCapitalLettersChange(
|
|
||||||
useCapitals = false,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleLowercaseLettersChange(
|
||||||
.MainType
|
useLowercase = false,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleLowercaseLettersChange(
|
|
||||||
useLowercase = false,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleNumbersChange(useNumbers = false),
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleNumbersChange(
|
|
||||||
useNumbers = false,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleSpecialCharactersChange(
|
||||||
.MainType
|
useSpecialChars = true,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleSpecialCharactersChange(
|
|
||||||
useSpecialChars = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Password.ToggleAvoidAmbigousCharactersChange(
|
||||||
.MainType
|
avoidAmbiguousChars = true,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Password
|
|
||||||
.ToggleAvoidAmbigousCharactersChange(
|
|
||||||
avoidAmbiguousChars = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, minimum numbers cannot go below minimum threshold`() {
|
fun `in Password state, minimum numbers cannot go below minimum threshold`() {
|
||||||
val initialMinNumbers = 5
|
val initialMinNumbers = 5
|
||||||
|
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(
|
||||||
GeneratorState
|
minNumbersAllowed = initialMinNumbers,
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minNumbersAllowed = initialMinNumbers,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -814,7 +674,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify(exactly = 0) {
|
verify(exactly = 0) {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinNumbersCounterChange(
|
GeneratorAction.MainType.Password.MinNumbersCounterChange(
|
||||||
minNumbers = 4,
|
minNumbers = 4,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -822,21 +682,15 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, maximum numbers should match minimum if lower`() {
|
fun `in Password state, maximum numbers should match minimum if lower`() {
|
||||||
val initialMinNumbers = 7
|
val initialMinNumbers = 7
|
||||||
val initialMaxNumbers = 5
|
val initialMaxNumbers = 5
|
||||||
|
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(
|
||||||
GeneratorState
|
minNumbersAllowed = initialMinNumbers,
|
||||||
.MainType
|
maxNumbersAllowed = initialMaxNumbers,
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minNumbersAllowed = initialMinNumbers,
|
|
||||||
maxNumbersAllowed = initialMaxNumbers,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -850,21 +704,14 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
.assertIsDisplayed()
|
.assertIsDisplayed()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, minimum special characters cannot go below minimum threshold`() {
|
fun `in Password state, minimum special characters cannot go below minimum threshold`() {
|
||||||
val initialMinSpecials = 5
|
val initialMinSpecials = 5
|
||||||
|
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(
|
||||||
GeneratorState
|
minSpecialAllowed = initialMinSpecials,
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minSpecialAllowed = initialMinSpecials,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -878,7 +725,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify(exactly = 0) {
|
verify(exactly = 0) {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.MinSpecialCharactersChange(
|
GeneratorAction.MainType.Password.MinSpecialCharactersChange(
|
||||||
minSpecial = 4,
|
minSpecial = 4,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -886,21 +733,15 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Password state, maximum special should match minimum if lower `() {
|
fun `in Password state, maximum special should match minimum if lower `() {
|
||||||
val initialMinSpecials = 7
|
val initialMinSpecials = 7
|
||||||
val initialMaxSpecials = 5
|
val initialMaxSpecials = 5
|
||||||
|
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(
|
||||||
GeneratorState
|
minSpecialAllowed = initialMinSpecials,
|
||||||
.MainType
|
maxSpecialAllowed = initialMaxSpecials,
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Password(
|
|
||||||
minSpecialAllowed = initialMinSpecials,
|
|
||||||
maxSpecialAllowed = initialMaxSpecials,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -914,18 +755,12 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, disabled elements should not send events`() {
|
fun `in Passphrase state, disabled elements should not send events`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(
|
||||||
GeneratorState
|
capitalizeEnabled = false,
|
||||||
.MainType
|
includeNumberEnabled = false,
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(
|
|
||||||
capitalizeEnabled = false,
|
|
||||||
includeNumberEnabled = false,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -939,44 +774,25 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify(exactly = 0) {
|
verify(exactly = 0) {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Passphrase.ToggleCapitalizeChange(
|
||||||
.MainType
|
capitalize = true,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Passphrase
|
|
||||||
.ToggleCapitalizeChange(
|
|
||||||
capitalize = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction
|
GeneratorAction.MainType.Passphrase.ToggleIncludeNumberChange(
|
||||||
.MainType
|
includeNumber = true,
|
||||||
.Passcode
|
),
|
||||||
.PasscodeType
|
|
||||||
.Passphrase
|
|
||||||
.ToggleIncludeNumberChange(
|
|
||||||
includeNumber = true,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_passphrase state, minimum number of words cannot go below minimum threshold`() {
|
fun `in Passphrase state, minimum number of words cannot go below minimum threshold`() {
|
||||||
val initialMinWords = 5
|
val initialMinWords = 5
|
||||||
|
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(minNumWords = initialMinWords),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(
|
|
||||||
minNumWords = initialMinWords,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -989,9 +805,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify(exactly = 0) {
|
verify(exactly = 0) {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.NumWordsCounterChange(
|
GeneratorAction.MainType.Passphrase.NumWordsCounterChange(numWords = 4),
|
||||||
numWords = 4,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1002,19 +816,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, decrementing number of words should send NumWordsCounterChange action with decremented value`() {
|
fun `in Passphrase state, decrementing number of words should send NumWordsCounterChange action with decremented value`() {
|
||||||
val initialNumWords = 4
|
val initialNumWords = 4
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(numWords = initialNumWords),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(
|
|
||||||
numWords = initialNumWords,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1029,7 +835,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.NumWordsCounterChange(
|
GeneratorAction.MainType.Passphrase.NumWordsCounterChange(
|
||||||
numWords = initialNumWords - 1,
|
numWords = initialNumWords - 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1037,19 +843,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, decrementing number of words under 3 should do nothing`() {
|
fun `in Passphrase state, decrementing number of words under 3 should do nothing`() {
|
||||||
val initialNumWords = 3
|
val initialNumWords = 3
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(numWords = initialNumWords),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(
|
|
||||||
numWords = initialNumWords,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1066,19 +864,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, incrementing number of words over 20 should do nothing`() {
|
fun `in Passphrase state, incrementing number of words over 20 should do nothing`() {
|
||||||
val initialNumWords = 20
|
val initialNumWords = 20
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(numWords = initialNumWords),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(
|
|
||||||
numWords = initialNumWords,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1096,17 +886,11 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, incrementing number of words should send NumWordsCounterChange action with incremented value`() {
|
fun `in Passphrase state, incrementing number of words should send NumWordsCounterChange action with incremented value`() {
|
||||||
val initialNumWords = 3
|
val initialNumWords = 3
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1120,25 +904,18 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.NumWordsCounterChange(
|
GeneratorAction.MainType.Passphrase.NumWordsCounterChange(
|
||||||
numWords = initialNumWords + 1,
|
numWords = initialNumWords + 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, toggling capitalize should send ToggleCapitalizeChange action`() {
|
fun `in Passphrase state, toggling capitalize should send ToggleCapitalizeChange action`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1149,7 +926,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.ToggleCapitalizeChange(
|
GeneratorAction.MainType.Passphrase.ToggleCapitalizeChange(
|
||||||
capitalize = true,
|
capitalize = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1158,16 +935,10 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, toggling the include number toggle should send ToggleIncludeNumberChange action`() {
|
fun `in Passphrase state, toggling the include number toggle should send ToggleIncludeNumberChange action`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1177,7 +948,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.ToggleIncludeNumberChange(
|
GeneratorAction.MainType.Passphrase.ToggleIncludeNumberChange(
|
||||||
includeNumber = true,
|
includeNumber = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1186,16 +957,10 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@Test
|
@Test
|
||||||
fun `in Passcode_Passphrase state, updating text in word separator should send WordSeparatorTextChange action`() {
|
fun `in Passphrase state, updating text in word separator should send WordSeparatorTextChange action`() {
|
||||||
updateState(
|
updateState(
|
||||||
DEFAULT_STATE.copy(
|
DEFAULT_STATE.copy(
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Passphrase(),
|
||||||
GeneratorState
|
|
||||||
.MainType
|
|
||||||
.Passcode
|
|
||||||
.PasscodeType
|
|
||||||
.Passphrase(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1206,7 +971,7 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
verify {
|
verify {
|
||||||
viewModel.trySendAction(
|
viewModel.trySendAction(
|
||||||
GeneratorAction.MainType.Passcode.PasscodeType.Passphrase.WordSeparatorTextChange(
|
GeneratorAction.MainType.Passphrase.WordSeparatorTextChange(
|
||||||
wordSeparator = 'a',
|
wordSeparator = 'a',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1765,8 +1530,6 @@ class GeneratorScreenTest : BaseComposeTest() {
|
||||||
|
|
||||||
private val DEFAULT_STATE = GeneratorState(
|
private val DEFAULT_STATE = GeneratorState(
|
||||||
generatedText = "",
|
generatedText = "",
|
||||||
selectedType = GeneratorState.MainType.Passcode(
|
selectedType = GeneratorState.MainType.Password(),
|
||||||
GeneratorState.MainType.Passcode.PasscodeType.Password(),
|
|
||||||
),
|
|
||||||
currentEmailAddress = "currentEmail",
|
currentEmailAddress = "currentEmail",
|
||||||
)
|
)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue