Clean up generator minimum length implementation (#1244)

This commit is contained in:
Caleb Derosier 2024-04-09 14:51:05 -06:00 committed by Álison Fernandes
parent 2ae8a76103
commit 403cfc94f0
3 changed files with 22 additions and 34 deletions

View file

@ -300,7 +300,7 @@ class GeneratorViewModel @Inject constructor(
is Password -> { is Password -> {
val minLength = policy.minLength ?: Password.PASSWORD_LENGTH_SLIDER_MIN val minLength = policy.minLength ?: Password.PASSWORD_LENGTH_SLIDER_MIN
val password = Password( val password = Password(
rawLength = max(options.length, minLength), length = max(options.length, minLength),
minLength = minLength, minLength = minLength,
useCapitals = options.hasUppercase || policy.useUpper == true, useCapitals = options.hasUppercase || policy.useUpper == true,
capitalsEnabled = policy.useUpper != true, capitalsEnabled = policy.useUpper != true,
@ -764,14 +764,10 @@ class GeneratorViewModel @Inject constructor(
updatePasswordType { currentPasswordType -> updatePasswordType { currentPasswordType ->
currentPasswordType.copy( currentPasswordType.copy(
rawLength = adjustedLength.coerceIn( length = max(adjustedLength, currentPasswordType.minimumLength),
minimumValue = currentPasswordType.minLength,
maximumValue = currentPasswordType.maxLength,
),
isUserInteracting = action.isUserInteracting, isUserInteracting = action.isUserInteracting,
) )
} }
updatePasswordLength()
} }
private fun handleToggleCapitalLetters( private fun handleToggleCapitalLetters(
@ -1416,11 +1412,10 @@ class GeneratorViewModel @Inject constructor(
private fun updatePasswordLength() { private fun updatePasswordLength() {
updatePasswordType { currentPasswordType -> updatePasswordType { currentPasswordType ->
currentPasswordType.copy( currentPasswordType.copy(
rawLength = currentPasswordType.length, length = max(currentPasswordType.length, currentPasswordType.minimumLength),
) )
} }
} }
private inline fun updatePasswordType( private inline fun updatePasswordType(
crossinline block: (Password) -> Password, crossinline block: (Password) -> Password,
) { ) {
@ -1741,7 +1736,7 @@ data class GeneratorState(
* Represents a standard PASSWORD type, with configurable options for * Represents a standard PASSWORD type, with configurable options for
* length, character types, and requirements. * length, character types, and requirements.
* *
* @property rawLength The length of the generated password. * @property length The length of the generated password.
* @property minLength The number available on the low end of the slider. * @property minLength The number available on the low end of the slider.
* @property maxLength The number available on the high end of the slider. * @property maxLength The number available on the high end of the slider.
* @property useCapitals Whether to include capital letters. * @property useCapitals Whether to include capital letters.
@ -1766,7 +1761,7 @@ data class GeneratorState(
*/ */
@Parcelize @Parcelize
data class Password( data class Password(
private val rawLength: Int = DEFAULT_PASSWORD_LENGTH, val length: Int = DEFAULT_PASSWORD_LENGTH,
val minLength: Int = PASSWORD_LENGTH_SLIDER_MIN, val minLength: Int = PASSWORD_LENGTH_SLIDER_MIN,
val maxLength: Int = PASSWORD_LENGTH_SLIDER_MAX, val maxLength: Int = PASSWORD_LENGTH_SLIDER_MAX,
val useCapitals: Boolean = true, val useCapitals: Boolean = true,
@ -1790,13 +1785,6 @@ data class GeneratorState(
override val displayStringResId: Int override val displayStringResId: Int
get() = PasscodeTypeOption.PASSWORD.labelRes get() = PasscodeTypeOption.PASSWORD.labelRes
/**
* The larger of the user-set length and the minimum length this password can be
* (as determined by which characters are enabled, and how many).
*/
val length: Int
get() = max(rawLength, minimumLength)
companion object { companion object {
private const val DEFAULT_PASSWORD_LENGTH: Int = 14 private const val DEFAULT_PASSWORD_LENGTH: Int = 14
private const val MIN_NUMBERS: Int = 1 private const val MIN_NUMBERS: Int = 1

View file

@ -375,8 +375,8 @@ class GeneratorScreenTest : BaseComposeTest() {
} }
// This value would be 128 in a real scenario, because length passed here depends on the // This value would be 128 in a real scenario, because length passed here depends on the
// `sliderValue` which is indirectly updated via the call verified above. However, because // internal length which is indirectly updated via the call verified above. However, because
// the view model is a mock, the `length` value that `sliderValue` depends on will not // the view model is a mock, the length value that internal value depends on will not
// 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(

View file

@ -148,7 +148,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
initialPasscodeState.copy( initialPasscodeState.copy(
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
selectedType = GeneratorState.MainType.Passcode.PasscodeType.Password( selectedType = GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 14, length = 14,
minLength = 10, minLength = 10,
maxLength = 128, maxLength = 128,
useCapitals = true, useCapitals = true,
@ -182,7 +182,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
initialPasscodeState.copy( initialPasscodeState.copy(
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
selectedType = GeneratorState.MainType.Passcode.PasscodeType.Password( selectedType = GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 14, length = 14,
minLength = 5, minLength = 5,
maxLength = 128, maxLength = 128,
useCapitals = true, useCapitals = true,
@ -499,7 +499,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
initialPasscodeState.copy( initialPasscodeState.copy(
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 14, length = 14,
minLength = 10, minLength = 10,
useCapitals = true, useCapitals = true,
capitalsEnabled = false, capitalsEnabled = false,
@ -821,7 +821,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = newLength, length = newLength,
), ),
), ),
) )
@ -863,7 +863,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, length = 5,
useCapitals = false, useCapitals = false,
), ),
), ),
@ -882,7 +882,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, // 0 uppercase + 1 lowercase + 4 numbers + 0 special chars length = 5, // 0 uppercase + 1 lowercase + 4 numbers + 0 special chars
minNumbers = 4, minNumbers = 4,
useCapitals = false, useCapitals = false,
useNumbers = true, useNumbers = true,
@ -908,7 +908,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 6, // 1 uppercase + 1 lowercase + 4 numbers + 0 special chars length = 6, // 1 uppercase + 1 lowercase + 4 numbers + 0 special chars
minNumbers = 4, minNumbers = 4,
useCapitals = true, useCapitals = true,
), ),
@ -951,7 +951,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, length = 5,
useLowercase = false, useLowercase = false,
), ),
), ),
@ -970,7 +970,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, // 1 uppercase + 0 lowercase + 4 numbers + 0 special chars length = 5, // 1 uppercase + 0 lowercase + 4 numbers + 0 special chars
minNumbers = 4, minNumbers = 4,
useLowercase = false, useLowercase = false,
useNumbers = true, useNumbers = true,
@ -996,7 +996,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 6, // 1 uppercase + 1 lowercase + 4 numbers + 0 special chars length = 6, // 1 uppercase + 1 lowercase + 4 numbers + 0 special chars
minNumbers = 4, minNumbers = 4,
useLowercase = true, useLowercase = true,
), ),
@ -1105,7 +1105,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, // the current slider value, which the min doesn't exceed length = 5, // the current slider value, which the min doesn't exceed
minNumbers = minNumbers, minNumbers = minNumbers,
useNumbers = false, useNumbers = false,
), ),
@ -1129,7 +1129,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 7, // 1 uppercase + 1 lowercase + 5 numbers + 0 special length = 7, // 1 uppercase + 1 lowercase + 5 numbers + 0 special
minNumbers = minNumbers, minNumbers = minNumbers,
useNumbers = true, useNumbers = true,
), ),
@ -1173,7 +1173,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 5, length = 5,
minSpecial = minSpecial, minSpecial = minSpecial,
useSpecialChars = false, useSpecialChars = false,
), ),
@ -1197,7 +1197,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = updatedGeneratedPassword, generatedText = updatedGeneratedPassword,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = 8, // 1 uppercase + 1 lowercase + 1 number + 5 special chars length = 8, // 1 uppercase + 1 lowercase + 1 number + 5 special chars
minSpecial = minSpecial, minSpecial = minSpecial,
useSpecialChars = true, useSpecialChars = true,
), ),
@ -2098,7 +2098,7 @@ class GeneratorViewModelTest : BaseViewModelTest() {
generatedText = generatedText, generatedText = generatedText,
selectedType = GeneratorState.MainType.Passcode( selectedType = GeneratorState.MainType.Passcode(
GeneratorState.MainType.Passcode.PasscodeType.Password( GeneratorState.MainType.Passcode.PasscodeType.Password(
rawLength = length, length = length,
useCapitals = useCapitals, useCapitals = useCapitals,
useLowercase = useLowercase, useLowercase = useLowercase,
useNumbers = useNumbers, useNumbers = useNumbers,