From 2b54dc471599a6195540bb1943b76b8cdda451d5 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 2 Jun 2026 11:59:39 -0400 Subject: [PATCH] Ensure we uppercase AEP entry, add tests. --- .../restore/BackupKeyVisualTransformation.kt | 6 ++--- .../BackupKeyVisualTransformationTest.kt | 9 +++++++ .../screens/aepentry/EnterAepScreen.kt | 6 ++--- .../aepentry/AepVisualTransformationTest.kt | 23 ++++++++++++++++++ .../EnterAepScreenEventHandlerTest.kt | 24 +++++++++++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 feature/registration/src/test/java/org/signal/registration/screens/aepentry/AepVisualTransformationTest.kt create mode 100644 feature/registration/src/test/java/org/signal/registration/screens/aepentry/EnterAepScreenEventHandlerTest.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformation.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformation.kt index 5f6b4eef66..d0f00f5fe8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformation.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformation.kt @@ -11,8 +11,8 @@ import androidx.compose.ui.text.input.TransformedText import androidx.compose.ui.text.input.VisualTransformation /** - * Visual formatter for backup keys. Preserves whatever the user typed verbatim (no character - * swapping) and just groups characters with spaces. + * Visual formatter for backup keys. Uppercases and groups characters with spaces without swapping + * display-equivalent characters. * * @param chunkSize character count per group */ @@ -26,7 +26,7 @@ class BackupKeyVisualTransformation(private val chunkSize: Int) : VisualTransfor } } - val transformed = output.trimEnd() + val transformed = output.trimEnd().uppercase() return TransformedText( text = AnnotatedString(transformed), diff --git a/app/src/test/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformationTest.kt b/app/src/test/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformationTest.kt index 43603eb8e8..06c56b8fbf 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformationTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/registration/ui/restore/BackupKeyVisualTransformationTest.kt @@ -47,6 +47,15 @@ class BackupKeyVisualTransformationTest { assertThat(result).isEqualTo(expected) } + @Test + fun `Given display-equivalent characters, ensure characters are not swapped`() { + val testSubject = BackupKeyVisualTransformation(chunkSize = 4) + + val result = testSubject.filter(AnnotatedString("a0O#=b")).text + + assertThat(result).isEqualTo(AnnotatedString("A0O# =B")) + } + @Test fun `Given output length, when I originalToTransformed, then I expect proper output`() { val testSubject = BackupKeyVisualTransformation(chunkSize = 4) diff --git a/feature/registration/src/main/java/org/signal/registration/screens/aepentry/EnterAepScreen.kt b/feature/registration/src/main/java/org/signal/registration/screens/aepentry/EnterAepScreen.kt index 29e6159c7c..8309b262ed 100644 --- a/feature/registration/src/main/java/org/signal/registration/screens/aepentry/EnterAepScreen.kt +++ b/feature/registration/src/main/java/org/signal/registration/screens/aepentry/EnterAepScreen.kt @@ -279,10 +279,10 @@ private fun NextButton(state: EnterAepState, onEvent: (EnterAepEvents) -> Unit, } /** - * Visual formatter for backup keys — groups characters with spaces. Preserves whatever the user - * typed verbatim (no character swapping). + * Visual formatter for backup keys. Uppercases and groups characters with spaces without swapping + * display-equivalent characters. */ -private class AepVisualTransformation(private val chunkSize: Int) : VisualTransformation { +internal class AepVisualTransformation(private val chunkSize: Int) : VisualTransformation { override fun filter(text: AnnotatedString): TransformedText { var output = "" for ((i, c) in text.text.withIndex()) { diff --git a/feature/registration/src/test/java/org/signal/registration/screens/aepentry/AepVisualTransformationTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/aepentry/AepVisualTransformationTest.kt new file mode 100644 index 0000000000..dd17a7f65b --- /dev/null +++ b/feature/registration/src/test/java/org/signal/registration/screens/aepentry/AepVisualTransformationTest.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2026 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.signal.registration.screens.aepentry + +import androidx.compose.ui.text.AnnotatedString +import assertk.assertThat +import assertk.assertions.isEqualTo +import org.junit.Test + +class AepVisualTransformationTest { + + @Test + fun `filter - uppercases and groups characters without swapping display equivalents`() { + val transformation = AepVisualTransformation(chunkSize = 4) + + val transformed = transformation.filter(AnnotatedString("a0O#=b")) + + assertThat(transformed.text).isEqualTo(AnnotatedString("A0O# =B")) + } +} diff --git a/feature/registration/src/test/java/org/signal/registration/screens/aepentry/EnterAepScreenEventHandlerTest.kt b/feature/registration/src/test/java/org/signal/registration/screens/aepentry/EnterAepScreenEventHandlerTest.kt new file mode 100644 index 0000000000..1f67f27391 --- /dev/null +++ b/feature/registration/src/test/java/org/signal/registration/screens/aepentry/EnterAepScreenEventHandlerTest.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2026 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.signal.registration.screens.aepentry + +import assertk.assertThat +import assertk.assertions.isEqualTo +import org.junit.Test + +class EnterAepScreenEventHandlerTest { + + @Test + fun `BackupKeyChanged - preserves entered display-equivalent characters while normalizing backup key`() { + val updated = EnterAepScreenEventHandler.applyEvent( + EnterAepState(), + EnterAepEvents.BackupKeyChanged("a0O#=b") + ) + + assertThat(updated.enteredText).isEqualTo("a0O#=b") + assertThat(updated.backupKey).isEqualTo("a0oo0b") + } +}