From c9eb7d4d55f758df8cc6bb510e61f8f72566adb7 Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:45:50 +0200 Subject: [PATCH 1/4] Update back button assertion in StartActivityTest --- .../java/app/notesr/activity/StartActivityTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/app/notesr/activity/StartActivityTest.java b/app/src/androidTest/java/app/notesr/activity/StartActivityTest.java index b7551be2..cda8db81 100644 --- a/app/src/androidTest/java/app/notesr/activity/StartActivityTest.java +++ b/app/src/androidTest/java/app/notesr/activity/StartActivityTest.java @@ -7,6 +7,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import android.app.Activity; import android.app.Instrumentation; @@ -79,8 +80,9 @@ public void testGetStartedButtonHasClickListener() { @Test public void testOnCreateDisablesBackButton() { try (ActivityScenario scenario = createScenario()) { - scenario.onActivity(activity -> - assertNotNull("Activity should be created successfully", activity)); + scenario.onActivity(activity -> assertTrue( + "Back button should be disabled", + activity.getOnBackPressedDispatcher().hasEnabledCallbacks())); } } From 2163328834d9df644e522106389299cbd3986ce4 Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:46:20 +0200 Subject: [PATCH 2/4] Update back navigation tests in AuthActivityTest to verify behavior across modes --- .../activity/security/AuthActivityTest.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/app/src/androidTest/java/app/notesr/activity/security/AuthActivityTest.java b/app/src/androidTest/java/app/notesr/activity/security/AuthActivityTest.java index 128849d5..a5103a2c 100644 --- a/app/src/androidTest/java/app/notesr/activity/security/AuthActivityTest.java +++ b/app/src/androidTest/java/app/notesr/activity/security/AuthActivityTest.java @@ -506,24 +506,39 @@ public void testBackspaceRemovesLastCharacterAcrossCapsAndSymbolInput() { } @Test - public void testAuthenticationModeDisablesBackNavigation() { + public void testAuthenticationModeBackNavigationFinishesAffinity() { Intent authIntent = new Intent(context, AuthActivity.class) .putExtra(AuthActivity.EXTRA_MODE, AuthActivity.Mode.AUTHENTICATION.getModeName()); try (ActivityScenario scenario = ActivityScenario.launch(authIntent)) { - scenario.onActivity(activity -> - assertTrue("Authentication mode should install a back callback", - activity.getOnBackPressedDispatcher().hasEnabledCallbacks())); + scenario.onActivity(activity -> { + assertTrue("Authentication mode should install a back callback", + activity.getOnBackPressedDispatcher().hasEnabledCallbacks()); + + activity.getOnBackPressedDispatcher().onBackPressed(); + + assertTrue("Authentication mode should finish the activity" + + " when back is pressed", + activity.isFinishing()); + }); } + } - Intent createIntent = new Intent(context, AuthActivity.class) - .putExtra(AuthActivity.EXTRA_MODE, AuthActivity.Mode.CREATE_PASSWORD.getModeName()); + @Test + public void testNonAuthenticationModesAllowStandardBackNavigation() { + for (AuthActivity.Mode mode : new AuthActivity.Mode[] { + AuthActivity.Mode.CREATE_PASSWORD, + AuthActivity.Mode.CHANGE_PASSWORD, + AuthActivity.Mode.KEY_RECOVERY}) { + Intent intent = new Intent(context, AuthActivity.class) + .putExtra(AuthActivity.EXTRA_MODE, mode.getModeName()); - try (ActivityScenario createScenario = - ActivityScenario.launch(createIntent)) { - createScenario.onActivity(activity -> - assertFalse("Create-password mode should not disable back navigation", - activity.getOnBackPressedDispatcher().hasEnabledCallbacks())); + try (ActivityScenario scenario = ActivityScenario.launch(intent)) { + scenario.onActivity(activity -> + assertFalse("Non-authentication modes should keep" + + " the default back behavior", + activity.getOnBackPressedDispatcher().hasEnabledCallbacks())); + } } } From 5d21884bb4354b1229a1c7fd5b96c1722b5f5657 Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:46:58 +0200 Subject: [PATCH 3/4] Verify toast messages in KeyRecoveryActivityTest --- .../security/KeyRecoveryActivityTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/src/androidTest/java/app/notesr/activity/security/KeyRecoveryActivityTest.java b/app/src/androidTest/java/app/notesr/activity/security/KeyRecoveryActivityTest.java index a475634c..4a29ecd0 100644 --- a/app/src/androidTest/java/app/notesr/activity/security/KeyRecoveryActivityTest.java +++ b/app/src/androidTest/java/app/notesr/activity/security/KeyRecoveryActivityTest.java @@ -15,11 +15,13 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import android.app.Activity; import android.app.Instrumentation; import android.widget.Button; import android.widget.EditText; +import android.widget.Toast; import androidx.appcompat.app.ActionBar; import androidx.test.core.app.ActivityScenario; @@ -40,6 +42,7 @@ import app.notesr.core.util.KeyUtils; import app.notesr.service.security.AppSecurityException; import app.notesr.service.security.AppSecurityService; +import app.notesr.util.ActivityUtils; import io.bloco.faker.Faker; @RunWith(AndroidJUnit4.class) @@ -180,6 +183,9 @@ public void testWrongRecoveryKeyDoesNotFinishActivity() { doReturn(false).when(spyAppSecurityService) .isKeyMatchingWithStored(any(byte[].class)); + ActivityUtils activityUtils = spy(activity.getActivityUtils()); + activity.setActivityUtils(activityUtils); + EditText recoveryKeyField = activity.findViewById(R.id.importRecoveryKeyField); Button applyButton = activity.findViewById(R.id.applyRecoveryKeyButton); @@ -197,6 +203,10 @@ public void testWrongRecoveryKeyDoesNotFinishActivity() { recoveryKeyField.getText().toString()); assertFalse("Wrong recovery keys should not finish the current activity", activity.isFinishing()); + + verify(activityUtils).showToastMessage( + "Wrong key!", + Toast.LENGTH_SHORT); }); } } @@ -210,6 +220,9 @@ public void testInvalidRecoveryKeyDoesNotFinishActivity() { activity.setAppSecurityService(spyAppSecurityService); spyAppSecurityService.setSecrets(getTestCryptoSecrets()); + ActivityUtils activityUtils = spy(activity.getActivityUtils()); + activity.setActivityUtils(activityUtils); + EditText recoveryKeyField = activity.findViewById(R.id.importRecoveryKeyField); Button applyButton = activity.findViewById(R.id.applyRecoveryKeyButton); String invalidKey = "inv4lidkey"; @@ -226,6 +239,10 @@ public void testInvalidRecoveryKeyDoesNotFinishActivity() { recoveryKeyField.getText().toString()); assertFalse("Invalid recovery key input should not finish the activity", activity.isFinishing()); + + verify(activityUtils).showToastMessage( + "Invalid key!", + Toast.LENGTH_SHORT); }); } } From 5a2e404aa32a5065eb25b766eab617df5cc72145 Mon Sep 17 00:00:00 2001 From: zHd4 <38856321+zHd4@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:51:53 +0200 Subject: [PATCH 4/4] Refactor AuthHandler by removing showToastMessage helpers --- .../notesr/activity/security/AuthHandler.java | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/app/notesr/activity/security/AuthHandler.java b/app/src/main/java/app/notesr/activity/security/AuthHandler.java index 98da44e4..b029560a 100644 --- a/app/src/main/java/app/notesr/activity/security/AuthHandler.java +++ b/app/src/main/java/app/notesr/activity/security/AuthHandler.java @@ -64,7 +64,8 @@ public void authenticate() { var password = passwordBuilder.toCharArray(); if (password.length == 0) { - showToastMessage(R.string.enter_the_code); + activityUtils.showToastMessage(activity.getString(R.string.enter_the_code), + Toast.LENGTH_SHORT); return; } @@ -137,7 +138,8 @@ public void changePassword() { try { secretsRotationService.updatePassword(password); - showToastMessage(R.string.updated); + activityUtils.showToastMessage(activity.getString(R.string.updated), + Toast.LENGTH_SHORT); activity.startActivity(getNewIntent(NotesListActivity.class)); activity.finish(); } catch (Exception e) { @@ -154,16 +156,17 @@ protected char[] proceedPasswordSetting() { createdPassword = password; topLabel.setText(activity.getString(R.string.repeat_access_code)); } else { - showToastMessage(String.format( + activityUtils.showToastMessage(String.format( activity.getString(R.string.minimum_password_length_is_n), - CryptoSecrets.PASSWORD_MIN_LENGTH)); + CryptoSecrets.PASSWORD_MIN_LENGTH), Toast.LENGTH_SHORT); } } else { if (Arrays.equals(password, createdPassword)) { resetPassword(); return password; } else { - showToastMessage(R.string.code_not_match); + activityUtils.showToastMessage(activity.getString(R.string.code_not_match), + Toast.LENGTH_SHORT); } } @@ -196,7 +199,8 @@ protected void onAuthenticationFailed() { throw new RuntimeException(e); } - showToastMessage(R.string.blocked); + activityUtils.showToastMessage(activity.getString(R.string.blocked), + Toast.LENGTH_SHORT); activity.startActivity(getNewIntent(KeyRecoveryActivity.class)); activity.finish(); } else { @@ -206,9 +210,9 @@ protected void onAuthenticationFailed() { throw new RuntimeException(e); } - showToastMessage(String.format( + activityUtils.showToastMessage(String.format( activity.getString(R.string.wrong_code_you_have_n_attempts), - authAttempts)); + authAttempts), Toast.LENGTH_SHORT); } resetPassword(); @@ -243,12 +247,4 @@ protected void resetPassword() { protected void sleepBeforeRetry() throws InterruptedException { Thread.sleep(DELAY_AFTER_AUTH_FAILED); } - - protected void showToastMessage(int stringResId) { - showToastMessage(activity.getString(stringResId)); - } - - protected void showToastMessage(String text) { - activityUtils.showToastMessage(text, Toast.LENGTH_SHORT); - } }