mirror of
https://github.com/bitwarden/android.git
synced 2026-04-28 20:08:27 -05:00
BIT-618: Auto-enable At Least One Toggle in Password Generation to Prevent Errors (#357)
This commit is contained in:
committed by
Álison Fernandes
parent
33a99ce68d
commit
9cbc73337e
@@ -666,7 +666,12 @@ class GeneratorViewModel @Inject constructor(
|
||||
if (currentPasswordType !is Password) {
|
||||
return@updateGeneratorMainTypePasscode currentSelectedType
|
||||
}
|
||||
currentSelectedType.copy(selectedType = block(currentPasswordType))
|
||||
|
||||
val updatedPasswordType = currentPasswordType
|
||||
.let(block)
|
||||
.enforceAtLeastOneToggleOn()
|
||||
|
||||
currentSelectedType.copy(selectedType = updatedPasswordType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1409,3 +1414,16 @@ sealed class GeneratorEvent {
|
||||
val message: Text,
|
||||
) : GeneratorEvent()
|
||||
}
|
||||
|
||||
@Suppress("ComplexCondition")
|
||||
private fun Password.enforceAtLeastOneToggleOn(): Password =
|
||||
// If all toggles are off, turn on useLowercase
|
||||
if (!this.useCapitals &&
|
||||
!this.useLowercase &&
|
||||
!this.useNumbers &&
|
||||
!this.useSpecialChars
|
||||
) {
|
||||
this.copy(useLowercase = true)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
@@ -649,6 +649,108 @@ class GeneratorViewModelTest : BaseViewModelTest() {
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Turning off all toggles should automatically turn on useLowercase`() = runTest {
|
||||
val updatedGeneratedPassword = "updatedPassword"
|
||||
fakeGeneratorRepository.setMockGeneratePasswordResult(
|
||||
GeneratedPasswordResult.Success(updatedGeneratedPassword),
|
||||
)
|
||||
|
||||
// Initially turn on all toggles
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleCapitalLettersChange(
|
||||
useCapitals = true,
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction
|
||||
.MainType
|
||||
.Passcode
|
||||
.PasscodeType
|
||||
.Password
|
||||
.ToggleLowercaseLettersChange(
|
||||
useLowercase = true,
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleNumbersChange(
|
||||
useNumbers = true,
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction
|
||||
.MainType
|
||||
.Passcode
|
||||
.PasscodeType
|
||||
.Password
|
||||
.ToggleSpecialCharactersChange(
|
||||
useSpecialChars = true,
|
||||
),
|
||||
)
|
||||
|
||||
// Attempt to turn off all toggles
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleCapitalLettersChange(
|
||||
useCapitals = false,
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction
|
||||
.MainType
|
||||
.Passcode
|
||||
.PasscodeType
|
||||
.Password
|
||||
.ToggleLowercaseLettersChange(
|
||||
useLowercase = false,
|
||||
),
|
||||
)
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction.MainType.Passcode.PasscodeType.Password.ToggleNumbersChange(
|
||||
useNumbers = false,
|
||||
),
|
||||
)
|
||||
|
||||
// Check the state with only one toggle (useSpecialChars) left on
|
||||
val intermediatePasswordState = GeneratorState.MainType.Passcode.PasscodeType.Password(
|
||||
useCapitals = false,
|
||||
useLowercase = false,
|
||||
useNumbers = false,
|
||||
useSpecialChars = true,
|
||||
)
|
||||
|
||||
val intermediateState = defaultPasswordState.copy(
|
||||
generatedText = updatedGeneratedPassword,
|
||||
selectedType = GeneratorState.MainType.Passcode(
|
||||
selectedType = intermediatePasswordState,
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(intermediateState, viewModel.stateFlow.value)
|
||||
|
||||
viewModel.actionChannel.trySend(
|
||||
GeneratorAction
|
||||
.MainType
|
||||
.Passcode
|
||||
.PasscodeType
|
||||
.Password
|
||||
.ToggleSpecialCharactersChange(
|
||||
useSpecialChars = false,
|
||||
),
|
||||
)
|
||||
|
||||
// Check if useLowercase is turned on automatically
|
||||
val expectedState = intermediateState.copy(
|
||||
selectedType = GeneratorState.MainType.Passcode(
|
||||
selectedType = intermediatePasswordState.copy(
|
||||
useLowercase = true,
|
||||
useSpecialChars = false,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
Reference in New Issue
Block a user