SecureBackupEnterRecoveryKeyEvents -> SecureBackupEnterRecoveryKeyEvent

This commit is contained in:
Benoit Marty
2026-08-25 10:20:48 +02:00
parent c8c579ed7e
commit 2d611475da
7 changed files with 29 additions and 29 deletions
@@ -8,9 +8,9 @@
package io.element.android.features.securebackup.impl.enter
sealed interface SecureBackupEnterRecoveryKeyEvents {
data class OnRecoveryKeyChange(val recoveryKey: String) : SecureBackupEnterRecoveryKeyEvents
data class ChangeRecoveryKeyFieldContentsVisibility(val visible: Boolean) : SecureBackupEnterRecoveryKeyEvents
data object Submit : SecureBackupEnterRecoveryKeyEvents
data object ClearDialog : SecureBackupEnterRecoveryKeyEvents
sealed interface SecureBackupEnterRecoveryKeyEvent {
data class OnRecoveryKeyChange(val recoveryKey: String) : SecureBackupEnterRecoveryKeyEvent
data class ChangeRecoveryKeyFieldContentsVisibility(val visible: Boolean) : SecureBackupEnterRecoveryKeyEvent
data object Submit : SecureBackupEnterRecoveryKeyEvent
data object ClearDialog : SecureBackupEnterRecoveryKeyEvent
}
@@ -45,12 +45,12 @@ class SecureBackupEnterRecoveryKeyPresenter(
mutableStateOf(AsyncAction.Uninitialized)
}
fun handleEvent(event: SecureBackupEnterRecoveryKeyEvents) {
fun handleEvent(event: SecureBackupEnterRecoveryKeyEvent) {
when (event) {
SecureBackupEnterRecoveryKeyEvents.ClearDialog -> {
SecureBackupEnterRecoveryKeyEvent.ClearDialog -> {
submitAction.value = AsyncAction.Uninitialized
}
is SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange -> {
is SecureBackupEnterRecoveryKeyEvent.OnRecoveryKeyChange -> {
val previousRecoveryKey = recoveryKey
recoveryKey = if (previousRecoveryKey.isEmpty() && recoveryKeyTools.isRecoveryKeyFormatValid(event.recoveryKey)) {
// A Recovery key has been entered, remove the spaces for a better rendering
@@ -60,11 +60,11 @@ class SecureBackupEnterRecoveryKeyPresenter(
event.recoveryKey
}
}
SecureBackupEnterRecoveryKeyEvents.Submit -> {
SecureBackupEnterRecoveryKeyEvent.Submit -> {
// No need to remove the spaces, the SDK will do it.
coroutineScope.submitRecoveryKey(recoveryKey, submitAction)
}
is SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility -> {
is SecureBackupEnterRecoveryKeyEvent.ChangeRecoveryKeyFieldContentsVisibility -> {
displayRecoveryKeyFieldContents = event.visible
}
}
@@ -15,5 +15,5 @@ data class SecureBackupEnterRecoveryKeyState(
val recoveryKeyViewState: RecoveryKeyViewState,
val isSubmitEnabled: Boolean,
val submitAction: AsyncAction<Unit>,
val eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit
val eventSink: (SecureBackupEnterRecoveryKeyEvent) -> Unit
)
@@ -30,7 +30,7 @@ fun aSecureBackupEnterRecoveryKeyState(
isSubmitEnabled: Boolean = recoveryKey.isNotEmpty(),
displayTextFieldContents: Boolean = true,
submitAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit = {},
eventSink: (SecureBackupEnterRecoveryKeyEvent) -> Unit = {},
) = SecureBackupEnterRecoveryKeyState(
recoveryKeyViewState = RecoveryKeyViewState(
recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
@@ -41,7 +41,7 @@ fun SecureBackupEnterRecoveryKeyView(
progressDialog = { },
errorTitle = { stringResource(id = R.string.screen_recovery_key_confirm_error_title) },
errorMessage = { stringResource(id = R.string.screen_recovery_key_confirm_error_content) },
onErrorDismiss = { state.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) },
onErrorDismiss = { state.eventSink(SecureBackupEnterRecoveryKeyEvent.ClearDialog) },
)
FlowStepPage(
@@ -68,13 +68,13 @@ private fun Content(
state = state.recoveryKeyViewState,
onClick = null,
onChange = {
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange(it))
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvent.OnRecoveryKeyChange(it))
},
onSubmit = {
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.Submit)
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvent.Submit)
},
toggleRecoveryKeyVisibility = {
state.eventSink(SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility(it))
state.eventSink(SecureBackupEnterRecoveryKeyEvent.ChangeRecoveryKeyFieldContentsVisibility(it))
}
)
}
@@ -89,7 +89,7 @@ private fun ColumnScope.Buttons(
showProgress = state.submitAction.isLoading(),
modifier = Modifier.fillMaxWidth(),
onClick = {
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvents.Submit)
state.eventSink.invoke(SecureBackupEnterRecoveryKeyEvent.Submit)
}
)
}
@@ -56,7 +56,7 @@ class SecureBackupEnterRecoveryKeyPresenterTest {
presenter.present()
}.test {
val initialState = awaitItem()
initialState.eventSink(SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("1234"))
initialState.eventSink(SecureBackupEnterRecoveryKeyEvent.OnRecoveryKeyChange("1234"))
val withRecoveryKeyState = awaitItem()
assertThat(withRecoveryKeyState.isSubmitEnabled).isTrue()
assertThat(withRecoveryKeyState.recoveryKeyViewState).isEqualTo(
@@ -68,19 +68,19 @@ class SecureBackupEnterRecoveryKeyPresenterTest {
)
)
encryptionService.givenRecoverFailure(AN_EXCEPTION)
withRecoveryKeyState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
withRecoveryKeyState.eventSink(SecureBackupEnterRecoveryKeyEvent.Submit)
val loadingState = awaitItem()
assertThat(loadingState.submitAction).isEqualTo(AsyncAction.Loading)
assertThat(loadingState.isSubmitEnabled).isFalse()
val errorState = awaitItem()
assertThat(errorState.submitAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
assertThat(errorState.isSubmitEnabled).isFalse()
errorState.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog)
errorState.eventSink(SecureBackupEnterRecoveryKeyEvent.ClearDialog)
val clearedState = awaitItem()
assertThat(clearedState.submitAction).isEqualTo(AsyncAction.Uninitialized)
assertThat(clearedState.isSubmitEnabled).isTrue()
encryptionService.givenRecoverFailure(null)
clearedState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
clearedState.eventSink(SecureBackupEnterRecoveryKeyEvent.Submit)
val loadingState2 = awaitItem()
assertThat(loadingState2.submitAction).isEqualTo(AsyncAction.Loading)
assertThat(loadingState2.isSubmitEnabled).isFalse()
@@ -58,32 +58,32 @@ class SecureBackupEnterRecoveryKeyViewTest : RobolectricTest() {
@Test
@Config(qualifiers = "h1024dp")
fun `tapping on Continue when key is valid - calls expected action`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvent>()
setSecureBackupEnterRecoveryKeyView(
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
)
clickOn(CommonStrings.action_continue)
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvent.Submit)
}
@Test
fun `entering a char emits the expected event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvent>()
val keyValue = aFormattedRecoveryKey()
setSecureBackupEnterRecoveryKeyView(
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
)
onNodeWithText(keyValue).performTextInput("X")
recorder.assertSingle(
SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("X$keyValue")
SecureBackupEnterRecoveryKeyEvent.OnRecoveryKeyChange("X$keyValue")
)
}
@Test
@Config(qualifiers = "h1024dp")
fun `toggling the visibility of the textfield changes it`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvent>()
val keyValue = aFormattedRecoveryKey()
setSecureBackupEnterRecoveryKeyView(aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder))
@@ -94,18 +94,18 @@ class SecureBackupEnterRecoveryKeyViewTest : RobolectricTest() {
waitForIdle()
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.ChangeRecoveryKeyFieldContentsVisibility(false))
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvent.ChangeRecoveryKeyFieldContentsVisibility(false))
}
@Test
fun `validating from keyboard emits the expected event`() = runAndroidComposeUiTest {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvent>()
val keyValue = aFormattedRecoveryKey()
setSecureBackupEnterRecoveryKeyView(
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
)
onNodeWithText(keyValue).performImeAction()
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvent.Submit)
}
@Test