Commit 4a5f9167 authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[PwdCheckAndroid] Disable save button for empty passwords

With this CL, the save button is disabled while the new password is
empty. Additionally, it displays a brief error text to inform the user
about the required field.

Screenshots in the bug.

Bug: 1114720, 1092444
Change-Id: I0abb9582bdde093a69279a6887b74c0ddea68436
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2359995Reviewed-by: default avatarJan Wilken Dörrie <jdoerrie@chromium.org>
Commit-Queue: Friedrich [CET] <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799047}
parent 24721f06
......@@ -125,6 +125,7 @@ android_library("test_java") {
"//third_party/android_deps:androidx_recyclerview_recyclerview_java",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_deps:espresso_java",
"//third_party/android_deps:material_design_java",
"//third_party/android_sdk:android_test_base_java",
"//third_party/hamcrest:hamcrest_java",
"//third_party/junit",
......@@ -155,6 +156,9 @@ android_resources("java_resources") {
"java/res/values-night/colors.xml",
"java/res/values/colors.xml",
]
deps = [ "//chrome/browser/ui/android/strings:ui_strings_grd" ]
deps = [
"//chrome/browser/ui/android/strings:ui_strings_grd",
"//components/strings:components_strings_grd",
]
create_srcjar = false
}
......@@ -21,6 +21,8 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.PreferenceFragmentCompat;
import com.google.android.material.textfield.TextInputLayout;
import org.chromium.base.supplier.Supplier;
/**
......@@ -38,6 +40,8 @@ public class PasswordCheckEditFragmentView extends PreferenceFragmentCompat {
private CompromisedCredential mCredential;
private EditText mPasswordText;
private MenuItem mSaveButton;
private TextInputLayout mPasswordLabel;
/**
* Initializes the password check factory that allows to retrieve a {@link PasswordCheck}
......@@ -71,6 +75,7 @@ public class PasswordCheckEditFragmentView extends PreferenceFragmentCompat {
EditText usernameText = (EditText) view.findViewById(R.id.username_edit);
usernameText.setText(mCredential.getDisplayUsername());
mPasswordLabel = (TextInputLayout) view.findViewById(R.id.password_label);
mPasswordText = (EditText) view.findViewById(R.id.password_edit);
mPasswordText.setText(mCredential.getPassword());
mPasswordText.addTextChangedListener(new TextWatcher() {
......@@ -83,17 +88,19 @@ public class PasswordCheckEditFragmentView extends PreferenceFragmentCompat {
@Override
public void afterTextChanged(Editable editable) {
mNewPassword = mPasswordText.getText().toString();
if (TextUtils.isEmpty(mNewPassword)) {
// TODO(crbug.com/1114720): setError on R.id.password_label.
}
checkSavingConditions(TextUtils.isEmpty(mNewPassword));
}
});
// Enforce that even the initial password (maybe from a saved instance) cannot be empty.
checkSavingConditions(TextUtils.isEmpty(mNewPassword));
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear(); // Remove help and feedback for this screen.
inflater.inflate(R.menu.password_check_editor_action_bar_menu, menu);
mSaveButton = menu.findItem(R.id.action_save_edited_password);
checkSavingConditions(mNewPassword.isEmpty()); // Enable the newly created save button.
// TODO(crbug.com/1092444): Make the back arrow an 'X'.
}
......@@ -108,7 +115,7 @@ public class PasswordCheckEditFragmentView extends PreferenceFragmentCompat {
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_save_edited_password) {
if (!TextUtils.isEmpty(mNewPassword)) saveChanges();
saveChanges();
return true;
}
return super.onOptionsItemSelected(item);
......@@ -144,4 +151,11 @@ public class PasswordCheckEditFragmentView extends PreferenceFragmentCompat {
}
return mCredential.getPassword();
}
private void checkSavingConditions(boolean emptyPassword) {
if (mSaveButton != null) mSaveButton.setEnabled(!emptyPassword);
mPasswordLabel.setError(emptyPassword ? getContext().getString(
R.string.pref_edit_dialog_field_required_validation_message)
: "");
}
}
......@@ -6,11 +6,14 @@ package org.chromium.chrome.browser.password_check;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.eq;
......@@ -25,8 +28,11 @@ import android.os.Bundle;
import android.text.InputType;
import android.widget.EditText;
import androidx.annotation.StringRes;
import androidx.test.filters.MediumTest;
import com.google.android.material.textfield.TextInputLayout;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
......@@ -130,10 +136,29 @@ public class PasswordCheckEditViewTest {
verify(mPasswordCheck).updateCredential(eq(ANA), eq(newPassword));
}
@Test
@MediumTest
public void testEmptyPasswordDisablesSaveButton() {
// Delete the password.
EditText password = mPasswordCheckEditView.getView().findViewById(R.id.password_edit);
runOnUiThreadBlocking(() -> password.setText(""));
onView(withId(R.id.action_save_edited_password)).check(matches(not(isEnabled())));
TextInputLayout passwordLabel =
mPasswordCheckEditView.getView().findViewById(R.id.password_label);
assertNotNull(passwordLabel.getError());
assertThat(passwordLabel.getError().toString(),
equalTo(getString(R.string.pref_edit_dialog_field_required_validation_message)));
}
private void setUpUiLaunchedFromSettings() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putParcelable(EXTRA_COMPROMISED_CREDENTIAL, ANA);
mTestRule.startSettingsActivity(fragmentArgs);
mPasswordCheckEditView = mTestRule.getFragment();
}
private String getString(@StringRes int stringId) {
return mPasswordCheckEditView.getContext().getString(stringId);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment