diff options
Diffstat (limited to 'chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc')
-rw-r--r-- | chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc | 527 |
1 files changed, 171 insertions, 356 deletions
diff --git a/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 90bdfefc7fc..f5a3ba67027 100644 --- a/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/chromium/components/password_manager/core/browser/password_autofill_manager_unittest.cc @@ -11,9 +11,8 @@ #include "base/message_loop/message_loop.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/test/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "base/test/user_action_tester.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/metrics/user_action_tester.h" #include "build/build_config.h" #include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/suggestion_test_helpers.h" @@ -23,6 +22,7 @@ #include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/password_form_fill_data.h" +#include "components/favicon/core/test/mock_favicon_service.h" #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/stub_password_manager_client.h" @@ -37,6 +37,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/geometry/rect_f.h" +#include "ui/gfx/image/image_unittest_util.h" #if defined(OS_ANDROID) #include "base/android/build_info.h" @@ -51,10 +52,13 @@ const char kAliceUsername[] = "alice"; const char kAlicePassword[] = "password"; using autofill::Suggestion; +using autofill::SuggestionVectorIconsAre; using autofill::SuggestionVectorIdsAre; using autofill::SuggestionVectorValuesAre; using autofill::SuggestionVectorLabelsAre; using testing::_; +using testing::ElementsAreArray; +using testing::Return; using UkmEntry = ukm::builders::PageWithPassword; @@ -85,6 +89,9 @@ class TestPasswordManagerClient : public StubPasswordManagerClient { MockPasswordManagerDriver* mock_driver() { return &driver_; } const GURL& GetMainFrameURL() const override { return main_frame_url_; } + MOCK_METHOD0(GeneratePassword, void()); + MOCK_METHOD0(GetFaviconService, favicon::FaviconService*()); + private: MockPasswordManagerDriver driver_; GURL main_frame_url_; @@ -107,10 +114,11 @@ class MockAutofillClient : public autofill::TestAutofillClient { : sync_service_(sync_service) { LOG(ERROR) << "init mpck client"; } - MOCK_METHOD4(ShowAutofillPopup, + MOCK_METHOD5(ShowAutofillPopup, void(const gfx::RectF& element_bounds, base::i18n::TextDirection text_direction, const std::vector<Suggestion>& suggestions, + bool autoselect_first_suggestion, base::WeakPtr<autofill::AutofillPopupDelegate> delegate)); MOCK_METHOD0(HideAutofillPopup, void()); MOCK_METHOD1(ExecuteCommand, void(int)); @@ -130,6 +138,24 @@ bool IsPreLollipopAndroid() { #endif } +std::vector<base::string16> GetSuggestionList( + std::vector<base::string16> credentials) { + if (!IsPreLollipopAndroid()) { + credentials.push_back( + l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS)); + } + return credentials; +} + +std::vector<base::string16> GetIconsList(std::vector<std::string> icons) { + std::vector<base::string16> ret(icons.size()); + std::transform(icons.begin(), icons.end(), ret.begin(), &base::ASCIIToUTF16); + // On older Android versions the item "Manage passwords" is absent. + if (!IsPreLollipopAndroid()) + ret.push_back(base::string16()); + return ret; +} + } // namespace class PasswordAutofillManagerTest : public testing::Test { @@ -157,113 +183,22 @@ class PasswordAutofillManagerTest : public testing::Test { autofill::AutofillClient* autofill_client) { password_autofill_manager_.reset(new PasswordAutofillManager( client->mock_driver(), autofill_client, client)); + favicon::MockFaviconService favicon_service; + EXPECT_CALL(*client, GetFaviconService()) + .WillOnce(Return(&favicon_service)); + EXPECT_CALL(favicon_service, + GetFaviconImageForPageURL(fill_data_.origin, _, _)); password_autofill_manager_->OnAddPasswordFormMapping(fill_data_id_, fill_data_); + testing::Mock::VerifyAndClearExpectations(client); + // Suppress the warnings in the tests. + EXPECT_CALL(*client, GetFaviconService()).WillRepeatedly(Return(nullptr)); } protected: int fill_data_id() { return fill_data_id_; } autofill::PasswordFormFillData& fill_data() { return fill_data_; } - void SetManualFallbacksForFilling(bool enabled) { - if (enabled) { - scoped_feature_list_.InitAndEnableFeature( - password_manager::features::kManualFallbacksFilling); - } else { - scoped_feature_list_.InitAndDisableFeature( - password_manager::features::kManualFallbacksFilling); - } - } - - void SetManualFallbacksForFillingStandalone(bool enabled) { - if (enabled) { - scoped_feature_list_.InitAndEnableFeature( - password_manager::features::kEnableManualFallbacksFillingStandalone); - } else { - scoped_feature_list_.InitAndDisableFeature( - password_manager::features::kEnableManualFallbacksFillingStandalone); - } - } - - static bool IsManualFallbackForFillingEnabled() { - return base::FeatureList::IsEnabled( - password_manager::features::kManualFallbacksFilling) && - !IsPreLollipopAndroid(); - } - - void SetManualFallbacks(bool enabled) { - std::vector<std::string> features = { - password_manager::features::kManualFallbacksFilling.name, - password_manager::features::kEnableManualFallbacksFillingStandalone - .name, - password_manager::features::kEnableManualFallbacksGeneration.name}; - if (enabled) { - scoped_feature_list_.InitFromCommandLine(base::JoinString(features, ","), - std::string()); - } else { - scoped_feature_list_.InitFromCommandLine(std::string(), - base::JoinString(features, ",")); - } - } - - void TestGenerationFallback(bool custom_passphrase_enabled) { - MockSyncService mock_sync_service; - EXPECT_CALL(mock_sync_service, IsFirstSetupComplete()) - .WillRepeatedly(::testing::Return(true)); - EXPECT_CALL(mock_sync_service, IsSyncActive()) - .WillRepeatedly(::testing::Return(true)); - EXPECT_CALL(mock_sync_service, GetActiveDataTypes()) - .Times(::testing::AnyNumber()) - .WillRepeatedly( - ::testing::Return(syncer::ModelTypeSet(syncer::PASSWORDS))); - EXPECT_CALL(mock_sync_service, IsUsingSecondaryPassphrase()) - .WillRepeatedly(::testing::Return(custom_passphrase_enabled)); - std::unique_ptr<TestPasswordManagerClient> client( - new TestPasswordManagerClient); - std::unique_ptr<MockAutofillClient> autofill_client( - new MockAutofillClient(&mock_sync_service)); - InitializePasswordAutofillManager(client.get(), autofill_client.get()); - - gfx::RectF element_bounds; - autofill::PasswordFormFillData data; - data.username_field.value = test_username_; - data.password_field.value = test_password_; - data.origin = GURL("https://foo.test"); - - int dummy_key = 0; - password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - SetManualFallbacks(true); - - std::vector<base::string16> elements = { - l10n_util::GetStringUTF16( - IDS_AUTOFILL_PASSWORD_FIELD_SUGGESTIONS_TITLE), - test_username_}; - if (!IsPreLollipopAndroid() || !custom_passphrase_enabled) { -#if !defined(OS_ANDROID) - elements.push_back(base::string16()); -#endif - elements.push_back( - l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ALL_SAVED_FALLBACK)); - if (!custom_passphrase_enabled) { -#if !defined(OS_ANDROID) - elements.push_back(base::string16()); -#endif - elements.push_back( - l10n_util::GetStringUTF16(IDS_AUTOFILL_GENERATE_PASSWORD_FALLBACK)); - } - } - - EXPECT_CALL( - *autofill_client, - ShowAutofillPopup( - element_bounds, _, - SuggestionVectorValuesAre(testing::ElementsAreArray(elements)), _)); - - password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, - autofill::IS_PASSWORD_FIELD, element_bounds); - } - std::unique_ptr<PasswordAutofillManager> password_autofill_manager_; base::string16 test_username_; @@ -272,7 +207,6 @@ class PasswordAutofillManagerTest : public testing::Test { private: autofill::PasswordFormFillData fill_data_; const int fill_data_id_; - base::test::ScopedFeatureList scoped_feature_list_; // The TestAutofillDriver uses a SequencedWorkerPool which expects the // existence of a MessageLoop. @@ -329,10 +263,12 @@ TEST_F(PasswordAutofillManagerTest, PreviewSuggestion) { fill_data_id(), test_username_)); } -// Test that the popup is marked as visible after recieving password +// Test that the popup is marked as visible after receiving password // suggestions. TEST_F(PasswordAutofillManagerTest, ExternalDelegatePasswordSuggestions) { for (bool is_suggestion_on_password_field : {false, true}) { + SCOPED_TRACE(testing::Message() << "is_suggestion_on_password_field = " + << is_suggestion_on_password_field); std::unique_ptr<TestPasswordManagerClient> client( new TestPasswordManagerClient); std::unique_ptr<MockAutofillClient> autofill_client(new MockAutofillClient); @@ -344,34 +280,45 @@ TEST_F(PasswordAutofillManagerTest, ExternalDelegatePasswordSuggestions) { data.password_field.value = test_password_; data.preferred_realm = "http://foo.com/"; int dummy_key = 0; + favicon::MockFaviconService favicon_service; + EXPECT_CALL(*client, GetFaviconService()) + .WillOnce(Return(&favicon_service)); + favicon_base::FaviconImageCallback callback; + EXPECT_CALL(favicon_service, GetFaviconImageForPageURL(data.origin, _, _)) + .WillOnce(DoAll(testing::SaveArg<1>(&callback), Return(1))); password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - EXPECT_CALL(*client->mock_driver(), - FillSuggestion(test_username_, test_password_)); + // Resolve the favicon. + favicon_base::FaviconImageResult image_result; + image_result.image = gfx::test::CreateImage(16, 16); + callback.Run(image_result); std::vector<autofill::PopupItemId> ids = { - autofill::POPUP_ITEM_ID_USERNAME_ENTRY}; - if (is_suggestion_on_password_field) { - ids = {autofill::POPUP_ITEM_ID_TITLE, - autofill::POPUP_ITEM_ID_PASSWORD_ENTRY}; - if (IsManualFallbackForFillingEnabled()) { -#if !defined(OS_ANDROID) - ids.push_back(autofill::POPUP_ITEM_ID_SEPARATOR); -#endif - ids.push_back(autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY); - } + is_suggestion_on_password_field + ? autofill::POPUP_ITEM_ID_PASSWORD_ENTRY + : autofill::POPUP_ITEM_ID_USERNAME_ENTRY}; + if (!IsPreLollipopAndroid()) { + ids.push_back(autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY); } + std::vector<Suggestion> suggestions; EXPECT_CALL( *autofill_client, ShowAutofillPopup( - _, _, SuggestionVectorIdsAre(testing::ElementsAreArray(ids)), _)); + _, _, SuggestionVectorIdsAre(testing::ElementsAreArray(ids)), false, + _)) + .WillOnce(testing::SaveArg<2>(&suggestions)); int show_suggestion_options = is_suggestion_on_password_field ? autofill::IS_PASSWORD_FIELD : 0; password_autofill_manager_->OnShowPasswordSuggestions( dummy_key, base::i18n::RIGHT_TO_LEFT, base::string16(), show_suggestion_options, element_bounds); + ASSERT_GE(suggestions.size(), 1u); + EXPECT_TRUE(gfx::test::AreImagesEqual(suggestions[0].custom_icon, + image_result.image)); + EXPECT_CALL(*client->mock_driver(), + FillSuggestion(test_username_, test_password_)); // Accepting a suggestion should trigger a call to hide the popup. EXPECT_CALL(*autofill_client, HideAutofillPopup()); password_autofill_manager_->DidAcceptSuggestion( @@ -407,41 +354,43 @@ TEST_F(PasswordAutofillManagerTest, ExtractSuggestions) { // First, simulate displaying suggestions matching an empty prefix. Also // verify that both the values and labels are filled correctly. The 'value' // should be the user name; the 'label' should be the realm. - EXPECT_CALL(*autofill_client, - ShowAutofillPopup( - element_bounds, _, - testing::AllOf( - SuggestionVectorValuesAre(testing::UnorderedElementsAre( - test_username_, additional_username)), - SuggestionVectorLabelsAre(testing::UnorderedElementsAre( - base::UTF8ToUTF16(data.preferred_realm), - base::UTF8ToUTF16(additional.realm)))), - _)); + EXPECT_CALL( + *autofill_client, + ShowAutofillPopup( + element_bounds, _, + testing::AllOf( + SuggestionVectorValuesAre(testing::UnorderedElementsAreArray( + GetSuggestionList({test_username_, additional_username}))), + SuggestionVectorLabelsAre(testing::AllOf( + testing::Contains(base::UTF8ToUTF16(data.preferred_realm)), + testing::Contains(base::UTF8ToUTF16(additional.realm))))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::string16(), false, + dummy_key, base::i18n::RIGHT_TO_LEFT, base::string16(), 0, element_bounds); // Now simulate displaying suggestions matching "John". EXPECT_CALL( *autofill_client, ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre( - testing::UnorderedElementsAre(additional_username)), - _)); + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({additional_username}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("John"), false, + dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("John"), 0, element_bounds); // Finally, simulate displaying all suggestions, without any prefix matching. EXPECT_CALL( *autofill_client, - ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre(testing::UnorderedElementsAre( - test_username_, additional_username)), - _)); + ShowAutofillPopup( + element_bounds, _, + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({test_username_, additional_username}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("xyz"), true, - element_bounds); + dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("xyz"), + autofill::SHOW_ALL, element_bounds); } // Verify that, for Android application credentials, the prettified realms of @@ -466,15 +415,15 @@ TEST_F(PasswordAutofillManagerTest, PrettifiedAndroidRealmsAreShownAsLabels) { password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); EXPECT_CALL(*autofill_client, - ShowAutofillPopup( - _, _, - SuggestionVectorLabelsAre(testing::UnorderedElementsAre( - base::ASCIIToUTF16("android://com.example1.android/"), - base::ASCIIToUTF16("android://com.example2.android/"))), - _)); + ShowAutofillPopup(_, _, + SuggestionVectorLabelsAre(testing::AllOf( + testing::Contains(base::ASCIIToUTF16( + "android://com.example1.android/")), + testing::Contains(base::ASCIIToUTF16( + "android://com.example2.android/")))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::string16(), false, - gfx::RectF()); + dummy_key, base::i18n::RIGHT_TO_LEFT, base::string16(), 0, gfx::RectF()); } TEST_F(PasswordAutofillManagerTest, FillSuggestionPasswordField) { @@ -500,27 +449,12 @@ TEST_F(PasswordAutofillManagerTest, FillSuggestionPasswordField) { int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - // Simulate displaying suggestions matching a username and specifying that the - // field is a password field. - base::string16 title = l10n_util::GetStringUTF16( - IDS_AUTOFILL_PASSWORD_FIELD_SUGGESTIONS_TITLE); - std::vector<base::string16> elements = {title, test_username_}; - if (IsManualFallbackForFillingEnabled()) { - elements = { - title, - test_username_, -#if !defined(OS_ANDROID) - base::string16(), -#endif - l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ALL_SAVED_FALLBACK) - }; - } - EXPECT_CALL( *autofill_client, - ShowAutofillPopup( - element_bounds, _, - SuggestionVectorValuesAre(testing::ElementsAreArray(elements)), _)); + ShowAutofillPopup(element_bounds, _, + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({test_username_}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, autofill::IS_PASSWORD_FIELD, element_bounds); @@ -556,14 +490,14 @@ TEST_F(PasswordAutofillManagerTest, DisplaySuggestionsWithMatchingTokens) { int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - EXPECT_CALL( - *autofill_client, - ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre(testing::UnorderedElementsAre( - username, additional_username)), - _)); + EXPECT_CALL(*autofill_client, + ShowAutofillPopup( + element_bounds, _, + SuggestionVectorValuesAre(testing::UnorderedElementsAreArray( + GetSuggestionList({username, additional_username}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("foo"), false, + dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("foo"), 0, element_bounds); } @@ -597,10 +531,10 @@ TEST_F(PasswordAutofillManagerTest, NoSuggestionForNonPrefixTokenMatch) { int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - EXPECT_CALL(*autofill_client, ShowAutofillPopup(_, _, _, _)).Times(0); + EXPECT_CALL(*autofill_client, ShowAutofillPopup(_, _, _, _, _)).Times(0); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("oo"), false, + dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("oo"), 0, element_bounds); } @@ -639,12 +573,12 @@ TEST_F(PasswordAutofillManagerTest, EXPECT_CALL( *autofill_client, ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre( - testing::UnorderedElementsAre(additional_username)), - _)); + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({additional_username}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("foo@exam"), - false, element_bounds); + dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("foo@exam"), 0, + element_bounds); } // Verify that typing "example" into the username field will match and order @@ -679,12 +613,12 @@ TEST_F(PasswordAutofillManagerTest, int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - EXPECT_CALL( - *autofill_client, - ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre(testing::UnorderedElementsAre( - username, additional_username)), - _)); + EXPECT_CALL(*autofill_client, + ShowAutofillPopup( + element_bounds, _, + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({username, additional_username}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( dummy_key, base::i18n::RIGHT_TO_LEFT, base::ASCIIToUTF16("foo"), false, element_bounds); @@ -702,7 +636,7 @@ TEST_F(PasswordAutofillManagerTest, PreviewAndFillEmptyUsernameSuggestion) { l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN); // Simulate that the user clicks on a username field. - EXPECT_CALL(*autofill_client, ShowAutofillPopup(_, _, _, _)); + EXPECT_CALL(*autofill_client, ShowAutofillPopup(_, _, _, _, _)); gfx::RectF element_bounds; password_autofill_manager_->OnShowPasswordSuggestions( fill_data_id(), base::i18n::RIGHT_TO_LEFT, base::string16(), false, @@ -724,60 +658,8 @@ TEST_F(PasswordAutofillManagerTest, PreviewAndFillEmptyUsernameSuggestion) { testing::Mock::VerifyAndClearExpectations(client->mock_driver()); } -// Tests that the "Show all passwords" suggestion isn't shown along with -// "Use password for" in the popup when the feature which controls its -// appearance is disabled. -TEST_F(PasswordAutofillManagerTest, - NotShowAllPasswordsOptionOnPasswordFieldWhenFeatureDisabled) { - auto client = std::make_unique<TestPasswordManagerClient>(); - auto autofill_client = std::make_unique<MockAutofillClient>(); - InitializePasswordAutofillManager(client.get(), autofill_client.get()); - - gfx::RectF element_bounds; - autofill::PasswordFormFillData data; - data.username_field.value = test_username_; - data.password_field.value = test_password_; - data.origin = GURL("https://foo.test"); - - int dummy_key = 0; - password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - - // String "Use password for:" shown when displaying suggestions matching a - // username and specifying that the field is a password field. - base::string16 title = - l10n_util::GetStringUTF16(IDS_AUTOFILL_PASSWORD_FIELD_SUGGESTIONS_TITLE); - - SetManualFallbacksForFilling(false); - - // No "Show all passwords row" when feature is disabled. - EXPECT_CALL(*autofill_client, - ShowAutofillPopup(element_bounds, _, - SuggestionVectorValuesAre(testing::ElementsAre( - title, test_username_)), - _)); - password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, - autofill::IS_PASSWORD_FIELD, element_bounds); -} - -// Tests that the "Generate Password Suggestion" suggestion isn't shown in the -// Suggestion popup when the user is sync user with custom passphrase and manual -// fallbacks experiment is enabled. -TEST_F(PasswordAutofillManagerTest, - NotShowGeneratePasswordOptionOnPasswordFieldWhenCustomPassphraseUser) { - TestGenerationFallback(true /* custom_passphrase_enabled */); -} - -// Tests that the "Generate Password Suggestion" suggestion is shown along -// with "Use password for" and "Show all passwords" in the popup for the user -// with custom passphrase. -TEST_F(PasswordAutofillManagerTest, ShowGeneratePasswordOptionOnPasswordField) { - TestGenerationFallback(false /* custom_passphrase_enabled */); -} - -// Tests that the "Show all passwords" suggestion is shown along with -// "Use password for" in the popup when the feature which controls its -// appearance is enabled. +// Tests that the "Manage passwords" suggestion is shown along with the password +// popup. TEST_F(PasswordAutofillManagerTest, ShowAllPasswordsOptionOnPasswordField) { const char kShownContextHistogram[] = "PasswordManager.ShowAllSavedPasswordsShownContext"; @@ -804,30 +686,12 @@ TEST_F(PasswordAutofillManagerTest, ShowAllPasswordsOptionOnPasswordField) { int dummy_key = 0; password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - // String "Use password for:" shown when displaying suggestions matching a - // username and specifying that the field is a password field. - base::string16 title = - l10n_util::GetStringUTF16(IDS_AUTOFILL_PASSWORD_FIELD_SUGGESTIONS_TITLE); - - SetManualFallbacksForFilling(true); - - std::vector<base::string16> elements = {title, test_username_}; - if (!IsPreLollipopAndroid()) { - elements = { - title, - test_username_, -#if !defined(OS_ANDROID) - base::string16(), -#endif - l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ALL_SAVED_FALLBACK) - }; - } - EXPECT_CALL( *autofill_client, - ShowAutofillPopup( - element_bounds, _, - SuggestionVectorValuesAre(testing::ElementsAreArray(elements)), _)); + ShowAutofillPopup(element_bounds, _, + SuggestionVectorValuesAre(testing::ElementsAreArray( + GetSuggestionList({test_username_}))), + false, _)); password_autofill_manager_->OnShowPasswordSuggestions( dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, @@ -878,100 +742,48 @@ TEST_F(PasswordAutofillManagerTest, ShowAllPasswordsOptionOnPasswordField) { } } -TEST_F(PasswordAutofillManagerTest, ShowStandaloneShowAllPasswords) { - const char kShownContextHistogram[] = - "PasswordManager.ShowAllSavedPasswordsShownContext"; - const char kAcceptedContextHistogram[] = - "PasswordManager.ShowAllSavedPasswordsAcceptedContext"; - base::HistogramTester histograms; - ukm::TestAutoSetUkmRecorder test_ukm_recorder; - +// Tests that the "Manage passwords" fallback shows up in non-password +// fields of login forms. +TEST_F(PasswordAutofillManagerTest, ShowAllPasswordsOptionOnNonPasswordField) { auto client = std::make_unique<TestPasswordManagerClient>(); auto autofill_client = std::make_unique<MockAutofillClient>(); - auto manager = - std::make_unique<password_manager::PasswordManager>(client.get()); InitializePasswordAutofillManager(client.get(), autofill_client.get()); - ON_CALL(*(client->mock_driver()), GetPasswordManager()) - .WillByDefault(testing::Return(manager.get())); - gfx::RectF element_bounds; autofill::PasswordFormFillData data; data.username_field.value = test_username_; data.password_field.value = test_password_; - data.origin = GURL("http://foo.test"); - - // String for the "Show all passwords" fallback. - base::string16 show_all_saved_row_text = - l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ALL_SAVED_FALLBACK); + data.origin = GURL("https://foo.test"); - SetManualFallbacksForFillingStandalone(true); + int dummy_key = 0; + password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); EXPECT_CALL( *autofill_client, ShowAutofillPopup(element_bounds, _, SuggestionVectorValuesAre(testing::ElementsAreArray( - {show_all_saved_row_text})), - _)) - .Times(IsPreLollipopAndroid() ? 0 : 1); - password_autofill_manager_->OnShowManualFallbackSuggestion( - base::i18n::RIGHT_TO_LEFT, element_bounds); - - if (IsPreLollipopAndroid()) { - EXPECT_THAT(histograms.GetAllSamples(kShownContextHistogram), - testing::IsEmpty()); - } else { - // Expect a sample only in the shown histogram. - histograms.ExpectUniqueSample( - kShownContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_MANUAL_FALLBACK, 1); - } + GetSuggestionList({test_username_}))), + false, _)); + password_autofill_manager_->OnShowPasswordSuggestions( + dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, 0, element_bounds); +} - if (!IsPreLollipopAndroid()) { - // Clicking at the "Show all passwords row" should trigger a call to open - // the Password Manager settings page and hide the popup. - EXPECT_CALL( - *autofill_client, - ExecuteCommand(autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY)); - EXPECT_CALL(*autofill_client, HideAutofillPopup()); - password_autofill_manager_->DidAcceptSuggestion( - base::string16(), autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY, 0); - // Expect a sample in both the shown and accepted histogram. - histograms.ExpectUniqueSample( - kShownContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_MANUAL_FALLBACK, 1); - histograms.ExpectUniqueSample( - kAcceptedContextHistogram, - metrics_util::SHOW_ALL_SAVED_PASSWORDS_CONTEXT_MANUAL_FALLBACK, 1); - // Trigger UKM reporting, which happens at destruction time. - ukm::SourceId expected_source_id = client->GetUkmSourceId(); - manager.reset(); - autofill_client.reset(); - client.reset(); +TEST_F(PasswordAutofillManagerTest, + MaybeShowPasswordSuggestionsWithGenerationNoCredentials) { + auto client = std::make_unique<TestPasswordManagerClient>(); + auto autofill_client = std::make_unique<MockAutofillClient>(); + password_autofill_manager_.reset(new PasswordAutofillManager( + client->mock_driver(), autofill_client.get(), client.get())); - const auto& entries = - test_ukm_recorder.GetEntriesByName("PageWithPassword"); - EXPECT_EQ(1u, entries.size()); - for (const auto* entry : entries) { - EXPECT_EQ(expected_source_id, entry->source_id); - test_ukm_recorder.ExpectEntryMetric( - entry, UkmEntry::kPageLevelUserActionName, - static_cast<int64_t>( - password_manager::PasswordManagerMetricsRecorder:: - PageLevelUserAction::kShowAllPasswordsWhileNoneAreSuggested)); - } - } else { - EXPECT_THAT(histograms.GetAllSamples(kShownContextHistogram), - testing::IsEmpty()); - EXPECT_THAT(histograms.GetAllSamples(kAcceptedContextHistogram), - testing::IsEmpty()); - } + EXPECT_CALL(*autofill_client, ShowAutofillPopup(_, _, _, _, _)).Times(0); + gfx::RectF element_bounds; + EXPECT_FALSE( + password_autofill_manager_->MaybeShowPasswordSuggestionsWithGeneration( + element_bounds, base::i18n::RIGHT_TO_LEFT)); } -// Tests that the "Show all passwords" fallback doesn't shows up in non-password -// fields of login forms. TEST_F(PasswordAutofillManagerTest, - NotShowAllPasswordsOptionOnNonPasswordField) { + MaybeShowPasswordSuggestionsWithGenerationSomeCredentials) { auto client = std::make_unique<TestPasswordManagerClient>(); auto autofill_client = std::make_unique<MockAutofillClient>(); InitializePasswordAutofillManager(client.get(), autofill_client.get()); @@ -983,29 +795,32 @@ TEST_F(PasswordAutofillManagerTest, data.origin = GURL("https://foo.test"); int dummy_key = 0; + favicon::MockFaviconService favicon_service; + EXPECT_CALL(*client, GetFaviconService()).WillOnce(Return(&favicon_service)); + EXPECT_CALL(favicon_service, GetFaviconImageForPageURL(data.origin, _, _)); password_autofill_manager_->OnAddPasswordFormMapping(dummy_key, data); - SetManualFallbacksForFilling(true); - + // Bring up the drop-down with the generaion option. + base::string16 generation_string = + l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_GENERATE_PASSWORD); EXPECT_CALL( *autofill_client, ShowAutofillPopup( - element_bounds, _, - SuggestionVectorValuesAre(testing::ElementsAre(test_username_)), _)); - password_autofill_manager_->OnShowPasswordSuggestions( - dummy_key, base::i18n::RIGHT_TO_LEFT, test_username_, 0, element_bounds); -} - -// SimpleWebviewDialog doesn't have an autofill client. Nothing should crash if -// the filling fallback is invoked. -TEST_F(PasswordAutofillManagerTest, ShowAllPasswordsWithoutAutofillClient) { - auto client = std::make_unique<TestPasswordManagerClient>(); - InitializePasswordAutofillManager(client.get(), nullptr); - - SetManualFallbacksForFillingStandalone(true); - - password_autofill_manager_->OnShowManualFallbackSuggestion( - base::i18n::RIGHT_TO_LEFT, gfx::RectF()); + element_bounds, base::i18n::RIGHT_TO_LEFT, + AllOf(SuggestionVectorValuesAre(ElementsAreArray( + GetSuggestionList({test_username_, generation_string}))), + SuggestionVectorIconsAre( + ElementsAreArray(GetIconsList({"globeIcon", "keyIcon"})))), + false, _)); + EXPECT_TRUE( + password_autofill_manager_->MaybeShowPasswordSuggestionsWithGeneration( + element_bounds, base::i18n::RIGHT_TO_LEFT)); + + // Click "Generate password". + EXPECT_CALL(*client, GeneratePassword()); + EXPECT_CALL(*autofill_client, HideAutofillPopup()); + password_autofill_manager_->DidAcceptSuggestion( + base::string16(), autofill::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY, 1); } } // namespace password_manager |