Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Unified Diff: components/password_manager/core/browser/password_form_manager_unittest.cc

Issue 2263933002: Make FormFetcher a PasswordStoreConsumer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@621355_form_fetcher
Patch Set: Also operator= is now default Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/password_manager/core/browser/password_form_manager_unittest.cc
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 6699623c9c0ab361825a8592ad9dd28fd909cb4a..0957eab4b9ccde17b3e174b9d261082f2e77d618 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -6,17 +6,17 @@
#include <map>
#include <memory>
+#include <set>
#include <utility>
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "base/run_loop.h"
+#include "base/message_loop/message_loop.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 "build/build_config.h"
#include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/proto/server.pb.h"
#include "components/autofill/core/browser/test_autofill_client.h"
@@ -24,12 +24,11 @@
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/mock_password_store.h"
+#include "components/password_manager/core/browser/fake_form_fetcher.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
-#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/statistics_table.h"
#include "components/password_manager/core/browser/stub_credentials_filter.h"
#include "components/password_manager/core/browser/stub_form_saver.h"
@@ -50,7 +49,6 @@ using autofill::FieldPropertiesMask;
using autofill::PasswordForm;
using base::ASCIIToUTF16;
using ::testing::_;
-using ::testing::ElementsAre;
using ::testing::IsEmpty;
using ::testing::Mock;
using ::testing::NiceMock;
@@ -97,16 +95,6 @@ class MockFormSaver : public StubFormSaver {
DISALLOW_COPY_AND_ASSIGN(MockFormSaver);
};
-// Invokes the password store consumer with a copy of all forms.
-ACTION_P4(InvokeConsumer, form1, form2, form3, form4) {
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(form1));
- result.push_back(base::MakeUnique<PasswordForm>(form2));
- result.push_back(base::MakeUnique<PasswordForm>(form3));
- result.push_back(base::MakeUnique<PasswordForm>(form4));
- arg0->OnGetPasswordStoreResults(std::move(result));
-}
-
MATCHER_P(CheckUsername, username_value, "Username incorrect") {
return arg.username_value == username_value;
}
@@ -224,10 +212,6 @@ MATCHER_P(CheckFieldPropertiesMasksUpload,
return true;
}
-void ClearVector(std::vector<std::unique_ptr<PasswordForm>>* results) {
- results->clear();
-}
-
class MockAutofillDownloadManager : public autofill::AutofillDownloadManager {
public:
MockAutofillDownloadManager(
@@ -303,41 +287,15 @@ class MockPasswordManagerDriver : public StubPasswordManagerDriver {
NiceMock<MockAutofillManager> mock_autofill_manager_;
};
-class MockStoreResultFilter : public StubCredentialsFilter {
- public:
- // This method is called by StubCredentialsFilter::FilterResults.
- MOCK_CONST_METHOD1(FilterResultsPtr,
- void(std::vector<std::unique_ptr<PasswordForm>>* results));
-};
-
class TestPasswordManagerClient : public StubPasswordManagerClient {
public:
- explicit TestPasswordManagerClient(PasswordStore* password_store)
- : password_store_(password_store),
- driver_(new NiceMock<MockPasswordManagerDriver>),
- filter_all_results_(false) {
+ TestPasswordManagerClient()
+ : driver_(new NiceMock<MockPasswordManagerDriver>) {
prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
true);
}
- // After this method is called, the filter returned by GetStoreResultFilter()
- // will filter out all forms.
- void FilterAllResults() {
- filter_all_results_ = true;
-
- // EXPECT_CALL rather than ON_CALL, because if the test needs the
- // filtering, then it needs it called.
- EXPECT_CALL(all_filter_, FilterResultsPtr(_))
- .Times(testing::AtLeast(1))
- .WillRepeatedly(testing::Invoke(ClearVector));
- }
-
- const CredentialsFilter* GetStoreResultFilter() const override {
- return filter_all_results_ ? &all_filter_ : &none_filter_;
- }
-
PrefService* GetPrefs() override { return &prefs_; }
- PasswordStore* GetPasswordStore() const override { return password_store_; }
MockPasswordManagerDriver* mock_driver() { return driver_.get(); }
@@ -351,29 +309,14 @@ class TestPasswordManagerClient : public StubPasswordManagerClient {
private:
TestingPrefServiceSimple prefs_;
- PasswordStore* password_store_;
std::unique_ptr<MockPasswordManagerDriver> driver_;
-
- // Filters to remove all and no results, respectively, in FilterResults.
- NiceMock<MockStoreResultFilter> all_filter_;
- NiceMock<MockStoreResultFilter> none_filter_;
- bool filter_all_results_;
};
} // namespace
class PasswordFormManagerTest : public testing::Test {
public:
- PasswordFormManagerTest() {}
-
- // Types of possible outcomes of simulated matching, see
- // SimulateMatchingPhase.
- enum ResultOfSimulatedMatching {
- RESULT_NO_MATCH,
- RESULT_SAVED_MATCH = 1 << 0, // Include saved_match_ in store results.
- RESULT_PSL_MATCH = 1 << 1, // Include psl_saved_match_ in store results.
- };
- typedef int ResultOfSimulatedMatchingMask;
+ PasswordFormManagerTest() { fake_form_fetcher_.Fetch(); }
void SetUp() override {
observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
@@ -415,42 +358,10 @@ class PasswordFormManagerTest : public testing::Test {
field.form_control_type = "password";
saved_match_.form_data.fields.push_back(field);
- mock_store_ = new NiceMock<MockPasswordStore>();
- ON_CALL(*mock_store_, GetSiteStatsMock(_))
- .WillByDefault(Return(std::vector<InteractionsStats*>()));
- client_.reset(new TestPasswordManagerClient(mock_store_.get()));
- password_manager_.reset(new PasswordManager(client_.get()));
- EXPECT_CALL(*mock_store_,
- GetLogins(PasswordStore::FormDigest(observed_form_), _));
+ password_manager_.reset(new PasswordManager(&client_));
form_manager_.reset(new PasswordFormManager(
- password_manager_.get(), client_.get(), client_.get()->driver(),
- observed_form_, base::MakeUnique<NiceMock<MockFormSaver>>()));
- Mock::VerifyAndClearExpectations(mock_store_.get());
- }
-
- void TearDown() override {
- if (mock_store_.get())
- mock_store_->ShutdownOnUIThread();
- }
-
- MockPasswordStore* mock_store() const { return mock_store_.get(); }
-
- void SimulateMatchingPhase(PasswordFormManager* p,
- ResultOfSimulatedMatchingMask result) {
- if (result == RESULT_NO_MATCH) {
- p->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
- return;
- }
-
- std::vector<std::unique_ptr<PasswordForm>> result_form;
- if (result & RESULT_SAVED_MATCH) {
- result_form.push_back(base::MakeUnique<PasswordForm>(saved_match_));
- }
- if (result & RESULT_PSL_MATCH) {
- result_form.push_back(base::MakeUnique<PasswordForm>(psl_saved_match_));
- }
- p->OnGetPasswordStoreResults(std::move(result_form));
+ password_manager_.get(), &client_, client_.driver(), observed_form_,
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fake_form_fetcher_));
}
// Save saved_match() for observed_form() where |observed_form_data|,
@@ -465,28 +376,29 @@ class PasswordFormManagerTest : public testing::Test {
form.form_data = observed_form_data;
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(
password_manager(), client(), client()->driver(), form,
- base::MakeUnique<NiceMock<MockFormSaver>>());
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(CreateSavedMatch(false));
- result[0]->generation_upload_status = status;
- result[0]->times_used = times_used;
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ PasswordForm match = CreateSavedMatch(false);
+ match.generation_upload_status = status;
+ match.times_used = times_used;
PasswordForm form_to_save(form);
form_to_save.preferred = true;
form_to_save.username_element = ASCIIToUTF16("observed-username-field");
- form_to_save.username_value = result[0]->username_value;
- form_to_save.password_value = result[0]->password_value;
+ form_to_save.username_value = match.username_value;
+ form_to_save.password_value = match.password_value;
// When we're voting for an account creation form, we should also vote
// for its username field.
base::string16 username_vote =
(field_type && *field_type == autofill::ACCOUNT_CREATION_PASSWORD)
- ? result[0]->username_element
+ ? match.username_element
: base::string16();
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ fetcher.SetNonFederated({&match}, 0u);
std::string expected_login_signature;
autofill::FormStructure observed_structure(observed_form_data);
autofill::FormStructure pending_structure(saved_match()->form_data);
@@ -541,11 +453,12 @@ class PasswordFormManagerTest : public testing::Test {
field.form_control_type = "password";
observed_form()->form_data.fields.push_back(field);
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(
password_manager(), client(), client()->driver(), *observed_form(),
- base::MakeUnique<NiceMock<MockFormSaver>>());
-
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ fetcher.SetNonFederated({saved_match()}, 0u);
// User submits current and new credentials to the observed form.
PasswordForm submitted_form(*observed_form());
@@ -671,12 +584,13 @@ class PasswordFormManagerTest : public testing::Test {
saved_match()->password_value + ASCIIToUTF16("1");
}
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(
password_manager(), client(), client()->driver(), form,
- base::MakeUnique<NiceMock<MockFormSaver>>());
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
- std::vector<std::unique_ptr<PasswordForm>> result;
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
autofill::ServerFieldTypeSet expected_available_field_types;
expected_available_field_types.insert(autofill::USERNAME);
@@ -717,19 +631,20 @@ class PasswordFormManagerTest : public testing::Test {
PasswordForm* observed_form() { return &observed_form_; }
PasswordForm* saved_match() { return &saved_match_; }
PasswordForm* psl_saved_match() { return &psl_saved_match_; }
- std::unique_ptr<PasswordForm> CreateSavedMatch(bool blacklisted) {
- // Owned by the caller of this method.
- auto match = base::MakeUnique<PasswordForm>(saved_match_);
- match->blacklisted_by_user = blacklisted;
+ PasswordForm CreateSavedMatch(bool blacklisted) {
+ PasswordForm match = saved_match_;
+ match.blacklisted_by_user = blacklisted;
return match;
}
- TestPasswordManagerClient* client() { return client_.get(); }
+ TestPasswordManagerClient* client() { return &client_; }
PasswordManager* password_manager() { return password_manager_.get(); }
PasswordFormManager* form_manager() { return form_manager_.get(); }
+ FakeFormFetcher* fake_form_fetcher() { return &fake_form_fetcher_; }
+
// To spare typing for PasswordFormManager instances which need no driver.
const base::WeakPtr<PasswordManagerDriver> kNoDriver;
@@ -740,10 +655,10 @@ class PasswordFormManagerTest : public testing::Test {
PasswordForm observed_form_;
PasswordForm saved_match_;
PasswordForm psl_saved_match_;
- scoped_refptr<NiceMock<MockPasswordStore>> mock_store_;
- std::unique_ptr<TestPasswordManagerClient> client_;
+ TestPasswordManagerClient client_;
std::unique_ptr<PasswordManager> password_manager_;
std::unique_ptr<PasswordFormManager> form_manager_;
+ FakeFormFetcher fake_form_fetcher_;
};
class PasswordFormManagerFillOnAccountSelectTest
@@ -756,8 +671,9 @@ class PasswordFormManagerFillOnAccountSelectTest
base::test::ScopedFeatureList scoped_feature_list_;
};
+// Test provisionally saving a new login.
TEST_F(PasswordFormManagerTest, TestNewLogin) {
- SimulateMatchingPhase(form_manager(), RESULT_NO_MATCH);
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
// User submits credentials for the observed form.
PasswordForm credentials = *observed_form();
@@ -788,26 +704,25 @@ TEST_F(PasswordFormManagerTest, TestNewLogin) {
EXPECT_TRUE(form_manager()->pending_credentials().new_password_value.empty());
}
+// Test provisionally saving a new login in presence of other saved logins.
TEST_F(PasswordFormManagerTest, TestAdditionalLogin) {
- // Now, suppose the user re-visits the site and wants to save an additional
- // login for the site with a new username. In this case, the matching phase
- // will yield the previously saved login.
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
- // Set up the new login.
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
+
base::string16 new_user = ASCIIToUTF16("newuser");
base::string16 new_pass = ASCIIToUTF16("newpass");
+ ASSERT_NE(new_user, saved_match()->username_value);
- PasswordForm credentials = *observed_form();
- credentials.username_value = new_user;
- credentials.password_value = new_pass;
- credentials.preferred = true;
+ PasswordForm new_login = *observed_form();
+ new_login.username_value = new_user;
+ new_login.password_value = new_pass;
+ new_login.preferred = true;
form_manager()->ProvisionallySave(
- credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+ new_login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
- // Again, the PasswordFormManager should know this is still a new login.
+ // The username value differs from the saved match, so this is a new login.
EXPECT_TRUE(form_manager()->IsNewLogin());
- // And make sure everything squares up again.
+
EXPECT_EQ(observed_form()->origin.spec(),
form_manager()->pending_credentials().origin.spec());
EXPECT_EQ(observed_form()->signon_realm,
@@ -820,16 +735,18 @@ TEST_F(PasswordFormManagerTest, TestAdditionalLogin) {
EXPECT_TRUE(form_manager()->pending_credentials().new_password_value.empty());
}
+// Test blacklisting in the presence of saved results.
TEST_F(PasswordFormManagerTest, TestBlacklist) {
saved_match()->origin = observed_form()->origin;
saved_match()->action = observed_form()->action;
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
- // Set up the new login.
- PasswordForm credentials = *observed_form();
- credentials.username_value = ASCIIToUTF16("newuser");
- credentials.password_value = ASCIIToUTF16("newpass");
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
+
+ PasswordForm new_login = *observed_form();
+ new_login.username_value = ASCIIToUTF16("newuser");
+ new_login.password_value = ASCIIToUTF16("newpass");
+ // Pretend Chrome detected a form submission with |new_login|.
form_manager()->ProvisionallySave(
- credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+ new_login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
EXPECT_TRUE(form_manager()->IsNewLogin());
EXPECT_EQ(observed_form()->origin.spec(),
@@ -839,64 +756,72 @@ TEST_F(PasswordFormManagerTest, TestBlacklist) {
const PasswordForm pending_form = form_manager()->pending_credentials();
PasswordForm actual_add_form;
+ // Now pretend the user wants to never save passwords on this origin. Chrome
+ // is supposed to only request blacklisting of a single form.
EXPECT_CALL(MockFormSaver::Get(form_manager()), PermanentlyBlacklist(_))
.WillOnce(SaveArgPointee<0>(&actual_add_form));
form_manager()->PermanentlyBlacklist();
EXPECT_EQ(pending_form, form_manager()->pending_credentials());
+ // The PasswordFormManager should have updated its knowledge of blacklisting
+ // without waiting for PasswordStore updates.
EXPECT_TRUE(form_manager()->IsBlacklisted());
EXPECT_THAT(form_manager()->blacklisted_matches(),
- ElementsAre(Pointee(actual_add_form)));
+ UnorderedElementsAre(Pointee(actual_add_form)));
}
+// Test that stored blacklisted forms are correctly evaluated for whether they
+// apply to the observed form.
TEST_F(PasswordFormManagerTest, TestBlacklistMatching) {
observed_form()->origin = GURL("http://accounts.google.com/a/LoginAuth");
observed_form()->action = GURL("http://accounts.google.com/a/Login");
observed_form()->signon_realm = "http://accounts.google.com";
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
- // Doesn't match because of PSL.
+ // Doesn't apply because it is just a PSL match of the observed form.
PasswordForm blacklisted_psl = *observed_form();
blacklisted_psl.signon_realm = "http://m.accounts.google.com";
blacklisted_psl.is_public_suffix_match = true;
blacklisted_psl.blacklisted_by_user = true;
- // Doesn't match because of different origin.
+ // Doesn't apply because of different origin.
PasswordForm blacklisted_not_match = *observed_form();
blacklisted_not_match.origin = GURL("http://google.com/a/LoginAuth");
blacklisted_not_match.blacklisted_by_user = true;
- // Doesn't match because of different username element and different page.
+ // Doesn't apply because of different username element and different page.
PasswordForm blacklisted_not_match2 = *observed_form();
blacklisted_not_match2.origin = GURL("http://accounts.google.com/a/Login123");
blacklisted_not_match2.username_element = ASCIIToUTF16("Element");
blacklisted_not_match2.blacklisted_by_user = true;
- // Doesn't match because of different PasswordForm::Scheme.
+ // Doesn't apply because of different PasswordForm::Scheme.
PasswordForm blacklisted_not_match3 = *observed_form();
blacklisted_not_match3.scheme = PasswordForm::SCHEME_BASIC;
- // Matches because of same element names, despite different page
+ // Applies because of same element names, despite different page
PasswordForm blacklisted_match = *observed_form();
blacklisted_match.origin = GURL("http://accounts.google.com/a/LoginAuth1234");
blacklisted_match.blacklisted_by_user = true;
- // Matches because of same page, despite different element names
+ // Applies because of same page, despite different element names
PasswordForm blacklisted_match2 = *observed_form();
blacklisted_match2.origin = GURL("http://accounts.google.com/a/LoginAuth");
blacklisted_match2.username_element = ASCIIToUTF16("Element");
blacklisted_match2.blacklisted_by_user = true;
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_psl));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_not_match));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_not_match2));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_not_match3));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_match));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted_match2));
- result.push_back(base::MakeUnique<PasswordForm>(*saved_match()));
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ std::vector<const PasswordForm*> matches = {&blacklisted_psl,
+ &blacklisted_not_match,
+ &blacklisted_not_match2,
+ &blacklisted_not_match3,
+ &blacklisted_match,
+ &blacklisted_match2,
+ saved_match()};
+ fetcher.SetNonFederated(matches, 0u);
+
EXPECT_TRUE(form_manager.IsBlacklisted());
EXPECT_THAT(form_manager.blacklisted_matches(),
UnorderedElementsAre(Pointee(blacklisted_match),
@@ -905,9 +830,9 @@ TEST_F(PasswordFormManagerTest, TestBlacklistMatching) {
EXPECT_EQ(*saved_match(), *form_manager.preferred_match());
}
+// Test that even in the presence of blacklisted matches, the non-blacklisted
+// ones are still autofilled.
TEST_F(PasswordFormManagerTest, AutofillBlacklisted) {
- // Blacklisted best matches credentials should not be autofilled, but the
- // non-blacklisted should.
PasswordForm saved_form = *observed_form();
saved_form.username_value = ASCIIToUTF16("user");
saved_form.password_value = ASCIIToUTF16("pass");
@@ -916,15 +841,11 @@ TEST_F(PasswordFormManagerTest, AutofillBlacklisted) {
blacklisted.blacklisted_by_user = true;
blacklisted.username_value.clear();
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(saved_form));
- result.push_back(base::MakeUnique<PasswordForm>(blacklisted));
-
autofill::PasswordFormFillData fill_data;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- form_manager()->OnGetPasswordStoreResults(std::move(result));
+ fake_form_fetcher()->SetNonFederated({&saved_form, &blacklisted}, 0u);
EXPECT_EQ(1u, form_manager()->blacklisted_matches().size());
EXPECT_TRUE(form_manager()->IsBlacklisted());
EXPECT_EQ(1u, form_manager()->best_matches().size());
@@ -938,7 +859,7 @@ TEST_F(PasswordFormManagerTest, AutofillBlacklisted) {
TEST_F(PasswordFormManagerTest,
OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
// The suggestion needs to be PSL-matched.
- SimulateMatchingPhase(form_manager(), RESULT_PSL_MATCH);
+ fake_form_fetcher()->SetNonFederated({psl_saved_match()}, 0u);
// User modifies the suggested password and submits the form.
PasswordForm credentials(*observed_form());
@@ -952,10 +873,12 @@ TEST_F(PasswordFormManagerTest,
EXPECT_FALSE(form_manager()->IsPendingCredentialsPublicSuffixMatch());
}
+// Test that if a PSL-matched suggestion is saved on a new origin, its metadata
+// are correctly updated.
TEST_F(PasswordFormManagerTest, PSLMatchedCredentialsMetadataUpdated) {
- // The suggestion needs to be PSL-matched.
- saved_match()->is_public_suffix_match = true;
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ PasswordForm psl_suggestion = *saved_match();
+ psl_suggestion.is_public_suffix_match = true;
+ fake_form_fetcher()->SetNonFederated({&psl_suggestion}, 0u);
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
@@ -987,21 +910,23 @@ TEST_F(PasswordFormManagerTest, PSLMatchedCredentialsMetadataUpdated) {
EXPECT_EQ(expected_saved_form, actual_saved_form);
}
+// Test that when the submitted form contains a "new-password" field, then the
+// password value is taken from there.
TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
- // Add a new password field to the test form. The PasswordFormManager should
- // save the password from this field, instead of the current password field.
observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
observed_form()->username_marked_by_site = true;
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
- SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
// User enters current and new credentials to the observed form.
PasswordForm credentials(*observed_form());
credentials.username_value = saved_match()->username_value;
- credentials.password_value = saved_match()->password_value;
+ credentials.password_value = ASCIIToUTF16("oldpassword");
credentials.new_password_value = ASCIIToUTF16("newpassword");
credentials.preferred = true;
form_manager.ProvisionallySave(
@@ -1029,7 +954,7 @@ TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
}
TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
// User submits credentials for the observed form using a username previously
// stored, but a new password. Note that the observed form may have different
@@ -1074,10 +999,12 @@ TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
// verify in the end that this did not happen.
saved_match()->submit_element.clear();
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated({saved_match()}, 0u);
// User submits current and new credentials to the observed form.
PasswordForm credentials(*observed_form());
@@ -1107,7 +1034,6 @@ TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
.WillOnce(testing::SaveArg<0>(&new_credentials));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
// No meta-information should be updated, only the password.
EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
@@ -1116,50 +1042,35 @@ TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
}
+// Test that saved results are not ignored if they differ in paths for action or
+// origin.
TEST_F(PasswordFormManagerTest, TestIgnoreResult_Paths) {
PasswordForm observed(*observed_form());
observed.origin = GURL("https://accounts.google.com/a/LoginAuth");
observed.action = GURL("https://accounts.google.com/a/Login");
observed.signon_realm = "https://accounts.google.com";
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), observed,
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
PasswordForm saved_form = observed;
saved_form.origin = GURL("https://accounts.google.com/a/OtherLoginAuth");
saved_form.action = GURL("https://accounts.google.com/a/OtherLogin");
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(saved_form));
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ fetcher.SetNonFederated({&saved_form}, 0u);
// Different paths for action / origin are okay.
- EXPECT_FALSE(form_manager.best_matches().empty());
-}
-
-TEST_F(PasswordFormManagerTest, TestIgnoreResult_IgnoredCredentials) {
- PasswordForm observed(*observed_form());
- observed.origin = GURL("https://accounts.google.com/a/LoginAuth");
- observed.action = GURL("https://accounts.google.com/a/Login");
- observed.signon_realm = "https://accounts.google.com";
-
- PasswordFormManager form_manager(password_manager(), client(),
- client()->driver(), observed,
- base::MakeUnique<MockFormSaver>());
- client()->FilterAllResults();
-
- PasswordForm saved_form = observed;
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(saved_form));
- form_manager.OnGetPasswordStoreResults(std::move(result));
-
- // Results should be ignored if the client requests it.
- EXPECT_TRUE(form_manager.best_matches().empty());
+ EXPECT_EQ(1u, form_manager.best_matches().size());
+ EXPECT_EQ(*form_manager.best_matches().begin()->second, saved_form);
}
+// Test that saved empty action URL is updated with the submitted action URL.
TEST_F(PasswordFormManagerTest, TestEmptyAction) {
saved_match()->action = GURL();
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
+
// User logs in with the autofilled username / password from saved_match.
PasswordForm login = *observed_form();
login.username_value = saved_match()->username_value;
@@ -1167,15 +1078,18 @@ TEST_F(PasswordFormManagerTest, TestEmptyAction) {
form_manager()->ProvisionallySave(
login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
EXPECT_FALSE(form_manager()->IsNewLogin());
- // We bless our saved PasswordForm entry with the action URL of the
+ // Chrome updates the saved PasswordForm entry with the action URL of the
// observed form.
EXPECT_EQ(observed_form()->action,
form_manager()->pending_credentials().action);
}
TEST_F(PasswordFormManagerTest, TestUpdateAction) {
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ saved_match()->action = GURL("http://accounts.google.com/a/ServiceLogin");
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
+
// User logs in with the autofilled username / password from saved_match.
+ observed_form()->action = GURL("http://accounts.google.com/a/Login");
PasswordForm login = *observed_form();
login.username_value = saved_match()->username_value;
login.password_value = saved_match()->password_value;
@@ -1183,37 +1097,40 @@ TEST_F(PasswordFormManagerTest, TestUpdateAction) {
form_manager()->ProvisionallySave(
login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
EXPECT_FALSE(form_manager()->IsNewLogin());
- // The observed action URL is different from the previously saved one, and
- // is the same as the one that would be submitted on successful login.
- EXPECT_NE(observed_form()->action, saved_match()->action);
+ // The observed action URL is different from the previously saved one. Chrome
+ // should update the store by setting the pending credential's action URL to
+ // be that of the currently observed form.
EXPECT_EQ(observed_form()->action,
form_manager()->pending_credentials().action);
}
TEST_F(PasswordFormManagerTest, TestDynamicAction) {
- SimulateMatchingPhase(form_manager(), RESULT_NO_MATCH);
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
+
+ observed_form()->action = GURL("http://accounts.google.com/a/Login");
PasswordForm login(*observed_form());
// The submitted action URL is different from the one observed on page load.
- GURL new_action = GURL("http://www.google.com/new_action");
- login.action = new_action;
+ login.action = GURL("http://www.google.com/new_action");
form_manager()->ProvisionallySave(
login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
EXPECT_TRUE(form_manager()->IsNewLogin());
// Check that the provisionally saved action URL is the same as the submitted
// action URL, not the one observed on page load.
- EXPECT_EQ(new_action, form_manager()->pending_credentials().action);
+ EXPECT_EQ(login.action, form_manager()->pending_credentials().action);
}
+// Test that if the saved match has other possible usernames stored, and the
+// user chooses the main one, then the other possible usernames are dropped on
+// update.
TEST_F(PasswordFormManagerTest, TestAlternateUsername_NoChange) {
EXPECT_CALL(*client()->mock_driver(), AllowPasswordGenerationForForm(_));
PasswordForm saved_form = *saved_match();
- ASSERT_FALSE(saved_form.other_possible_usernames.empty());
+ saved_form.other_possible_usernames.push_back(
+ ASCIIToUTF16("other_possible@gmail.com"));
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(saved_form));
- form_manager()->OnGetPasswordStoreResults(std::move(result));
+ fake_form_fetcher()->SetNonFederated({&saved_form}, 0u);
// The saved match has the right username already.
PasswordForm login(*observed_form());
@@ -1239,22 +1156,24 @@ TEST_F(PasswordFormManagerTest, TestAlternateUsername_NoChange) {
EXPECT_TRUE(saved_result.other_possible_usernames.empty());
}
+// Test that if the saved match has other possible usernames stored, and the
+// user chooses an alternative one, then the other possible usernames are
+// dropped on update, but the main username is changed to the one chosen by the
+// user.
TEST_F(PasswordFormManagerTest, TestAlternateUsername_OtherUsername) {
- // This time use an alternate username.
-
EXPECT_CALL(*client()->mock_driver(), AllowPasswordGenerationForForm(_));
+ const base::string16 kOtherUsername =
+ ASCIIToUTF16("other_possible@gmail.com");
PasswordForm saved_form = *saved_match();
- ASSERT_FALSE(saved_form.other_possible_usernames.empty());
+ saved_form.other_possible_usernames.push_back(kOtherUsername);
- std::vector<std::unique_ptr<autofill::PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(saved_form));
- form_manager()->OnGetPasswordStoreResults(std::move(result));
+ fake_form_fetcher()->SetNonFederated({&saved_form}, 0u);
- // The saved match has the right username already.
+ // The user chooses an alternative username.
PasswordForm login(*observed_form());
login.preferred = true;
- login.username_value = saved_match()->other_possible_usernames[0];
+ login.username_value = kOtherUsername;
login.password_value = saved_match()->password_value;
form_manager()->ProvisionallySave(
@@ -1272,8 +1191,7 @@ TEST_F(PasswordFormManagerTest, TestAlternateUsername_OtherUsername) {
// |other_possible_usernames| should also be empty, but username_value should
// be changed to match |new_username|.
- EXPECT_EQ(saved_match()->other_possible_usernames[0],
- saved_result.username_value);
+ EXPECT_EQ(kOtherUsername, saved_result.username_value);
EXPECT_TRUE(saved_result.other_possible_usernames.empty());
}
@@ -1281,39 +1199,35 @@ TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage_NoCredentials) {
// First time sign-up attempt. Password store does not contain matching
// credentials. AllowPasswordGenerationForForm should be called to send the
// "not blacklisted" message.
- EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
- .Times(1);
- form_manager()->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
+ EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
}
TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage_Credentials) {
// Signing up on a previously visited site. Credentials are found in the
// password store, and are not blacklisted. AllowPasswordGenerationForForm
// should be called to send the "not blacklisted" message.
- EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
- .Times(1);
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(false));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
+ PasswordForm simulated_result = CreateSavedMatch(false);
+ fake_form_fetcher()->SetNonFederated({&simulated_result}, 0u);
}
TEST_F(PasswordFormManagerTest,
TestSendNotBlacklistedMessage_DroppedCredentials) {
- // There are cases, such as when a form is explicitly for creating a new
+ // There are cases, such as when a form is made explicitly for creating a new
// password, where we may ignore saved credentials. Make sure that we still
// allow generation in that case.
PasswordForm signup_form(*observed_form());
signup_form.new_password_element = base::ASCIIToUTF16("new_password_field");
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), signup_form,
- base::MakeUnique<MockFormSaver>());
- EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
- .Times(1);
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(false));
- form_manager.OnGetPasswordStoreResults(std::move(simulated_results));
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
+ PasswordForm simulated_result = CreateSavedMatch(false);
+ fetcher.SetNonFederated({&simulated_result}, 0u);
}
TEST_F(PasswordFormManagerTest,
@@ -1322,44 +1236,48 @@ TEST_F(PasswordFormManagerTest,
// password store, but they are blacklisted. AllowPasswordGenerationForForm
// is still called.
EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(true));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ PasswordForm simulated_result = CreateSavedMatch(true);
+ fake_form_fetcher()->SetNonFederated({&simulated_result}, 0u);
}
-TEST_F(PasswordFormManagerTest, TestBestCredentialsByEachUsernameAreIncluded) {
- // Simulate having several matches, with 3 different usernames. Some of the
- // matches are PSL matches. One match for each username should be chosen.
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
+// Test that exactly one match for each username is chosen as a best match, even
+// though it is a PSL match.
+TEST_F(PasswordFormManagerTest, TestBestCredentialsForEachUsernameAreIncluded) {
// Add a best scoring match. It should be in |best_matches| and chosen as a
// prefferred match.
- simulated_results.push_back(base::MakeUnique<PasswordForm>(*saved_match()));
+ PasswordForm best_scoring = *saved_match();
+
// Add a match saved on another form, it has lower score. It should not be in
// |best_matches|.
- simulated_results.push_back(base::MakeUnique<PasswordForm>(*saved_match()));
- simulated_results[1]->password_element = ASCIIToUTF16("signup_password");
- simulated_results[1]->username_element = ASCIIToUTF16("signup_username");
+ PasswordForm other_form = *saved_match();
+ other_form.password_element = ASCIIToUTF16("signup_password");
+ other_form.username_element = ASCIIToUTF16("signup_username");
+
// Add a match saved on another form with a different username. It should be
// in |best_matches|.
- simulated_results.push_back(base::MakeUnique<PasswordForm>(*saved_match()));
- auto username1 = simulated_results[0]->username_value + ASCIIToUTF16("1");
- simulated_results[2]->username_value = username1;
- simulated_results[2]->password_element = ASCIIToUTF16("signup_password");
- simulated_results[2]->username_element = ASCIIToUTF16("signup_username");
+ PasswordForm other_username = other_form;
+ const base::string16 kUsername1 =
+ other_username.username_value + ASCIIToUTF16("1");
+ other_username.username_value = kUsername1;
+
// Add a PSL match, it should not be in |best_matches|.
- simulated_results.push_back(
- base::MakeUnique<PasswordForm>(*psl_saved_match()));
+ PasswordForm psl_match = *psl_saved_match();
+
// Add a PSL match with a different username. It should be in |best_matches|.
- simulated_results.push_back(
- base::MakeUnique<PasswordForm>(*psl_saved_match()));
- auto username2 = simulated_results[0]->username_value + ASCIIToUTF16("2");
- simulated_results[4]->username_value = username2;
+ PasswordForm psl_match_other = psl_match;
+ const base::string16 kUsername2 =
+ psl_match_other.username_value + ASCIIToUTF16("2");
+ psl_match_other.username_value = kUsername2;
autofill::PasswordFormFillData fill_data;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated(
+ {&best_scoring, &other_form, &other_username, &psl_match,
+ &psl_match_other},
+ 0u);
+
const std::map<base::string16, const PasswordForm*>& best_matches =
form_manager()->best_matches();
EXPECT_EQ(3u, best_matches.size());
@@ -1367,8 +1285,8 @@ TEST_F(PasswordFormManagerTest, TestBestCredentialsByEachUsernameAreIncluded) {
best_matches.find(saved_match()->username_value));
EXPECT_EQ(*saved_match(),
*best_matches.find(saved_match()->username_value)->second);
- EXPECT_NE(best_matches.end(), best_matches.find(username1));
- EXPECT_NE(best_matches.end(), best_matches.find(username2));
+ EXPECT_NE(best_matches.end(), best_matches.find(kUsername1));
+ EXPECT_NE(best_matches.end(), best_matches.find(kUsername2));
EXPECT_EQ(*saved_match(), *form_manager()->preferred_match());
EXPECT_EQ(2u, fill_data.additional_logins.size());
@@ -1377,8 +1295,7 @@ TEST_F(PasswordFormManagerTest, TestBestCredentialsByEachUsernameAreIncluded) {
TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
const base::string16 kUsernameOther = ASCIIToUTF16("other username");
- form_manager()->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
PasswordForm credentials(*observed_form());
credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
@@ -1408,8 +1325,7 @@ TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernamesDuplicates) {
const base::string16 kUsernameDuplicate = ASCIIToUTF16("duplicate");
const base::string16 kUsernameRandom = ASCIIToUTF16("random");
- form_manager()->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
PasswordForm credentials(*observed_form());
credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
@@ -1436,8 +1352,9 @@ TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernamesDuplicates) {
UnorderedElementsAre(kUsernameDuplicate, kUsernameRandom));
}
+// Test that if metadata stored with a form in PasswordStore are incomplete,
+// they are updated upon the next encounter.
TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
- // We've found this form on a website:
PasswordForm encountered_form;
encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
encountered_form.signon_realm = "http://accounts.google.com/";
@@ -1448,36 +1365,35 @@ TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), encountered_form,
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
- // Password store only has these incomplete credentials.
- std::unique_ptr<PasswordForm> incomplete_form(new PasswordForm());
- incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
- incomplete_form->signon_realm = "http://accounts.google.com/";
- incomplete_form->password_value = ASCIIToUTF16("my_password");
- incomplete_form->username_value = ASCIIToUTF16("my_username");
- incomplete_form->preferred = true;
- incomplete_form->scheme = PasswordForm::SCHEME_HTML;
+ PasswordForm incomplete_form;
+ incomplete_form.origin = GURL("http://accounts.google.com/LoginAuth");
+ incomplete_form.signon_realm = "http://accounts.google.com/";
+ incomplete_form.password_value = ASCIIToUTF16("my_password");
+ incomplete_form.username_value = ASCIIToUTF16("my_username");
+ incomplete_form.preferred = true;
+ incomplete_form.scheme = PasswordForm::SCHEME_HTML;
// We expect to see this form eventually sent to the Password store. It
// has password/username values from the store and 'username_element',
// 'password_element', 'submit_element' and 'action' fields copied from
// the encountered form.
- PasswordForm complete_form(*incomplete_form);
+ PasswordForm complete_form(incomplete_form);
complete_form.action = encountered_form.action;
complete_form.password_element = encountered_form.password_element;
complete_form.username_element = encountered_form.username_element;
complete_form.submit_element = encountered_form.submit_element;
- PasswordForm obsolete_form(*incomplete_form);
+ PasswordForm obsolete_form(incomplete_form);
obsolete_form.action = encountered_form.action;
// Feed the incomplete credentials to the manager.
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(std::move(incomplete_form));
- form_manager.OnGetPasswordStoreResults(std::move(simulated_results));
+ fetcher.SetNonFederated({&incomplete_form}, 0u);
form_manager.ProvisionallySave(
complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
@@ -1491,32 +1407,32 @@ TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
form_manager.Save();
}
+// Test that public-suffix-matched credentials score lower than same-origin
+// ones.
TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
- // Simulate having two matches for this form, first comes from different
- // signon realm, but reports the same origin and action as matched form.
- // Second candidate has the same signon realm as the form, but has a different
- // origin and action. Public suffix match is the most important criterion so
- // the second candidate should be selected.
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(false));
- simulated_results.push_back(CreateSavedMatch(false));
- simulated_results[0]->is_public_suffix_match = true;
- simulated_results[1]->origin =
- GURL("http://accounts.google.com/a/ServiceLoginAuth2");
- simulated_results[1]->action =
- GURL("http://accounts.google.com/a/ServiceLogin2");
+ PasswordForm base_match = CreateSavedMatch(false);
+ base_match.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
+ base_match.action = GURL("http://accounts.google.com/a/ServiceLogin");
+
+ PasswordForm psl_match = base_match;
+ psl_match.is_public_suffix_match = true;
+
+ // Change origin and action URLs to decrease the score.
+ PasswordForm same_origin_match = base_match;
+ psl_match.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
+ psl_match.action = GURL("http://accounts.google.com/a/ServiceLogin2");
autofill::PasswordFormFillData fill_data;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated({&psl_match, &same_origin_match}, 0u);
EXPECT_TRUE(fill_data.additional_logins.empty());
EXPECT_EQ(1u, form_manager()->best_matches().size());
- EXPECT_TRUE(
- !form_manager()->best_matches().begin()->second->is_public_suffix_match);
+ EXPECT_FALSE(
+ form_manager()->best_matches().begin()->second->is_public_suffix_match);
}
TEST_F(PasswordFormManagerTest, AndroidCredentialsAreAutofilled) {
@@ -1538,9 +1454,7 @@ TEST_F(PasswordFormManagerTest, AndroidCredentialsAreAutofilled) {
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(base::MakeUnique<PasswordForm>(android_login));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated({&android_login}, 0u);
EXPECT_TRUE(fill_data.additional_logins.empty());
EXPECT_FALSE(fill_data.wait_for_username);
EXPECT_EQ(1u, form_manager()->best_matches().size());
@@ -1560,7 +1474,6 @@ TEST_F(PasswordFormManagerTest, AndroidCredentialsAreAutofilled) {
EXPECT_CALL(MockFormSaver::Get(form_manager()), Update(_, _, _, nullptr))
.WillOnce(testing::SaveArg<0>(&updated_credential));
form_manager()->Save();
- Mock::VerifyAndClearExpectations(mock_store());
EXPECT_EQ(android_login.username_value, updated_credential.username_value);
EXPECT_EQ(android_login.password_value, updated_credential.password_value);
@@ -1587,30 +1500,29 @@ TEST_F(PasswordFormManagerTest, AndroidCredentialsAreProtected) {
// from Android: the first has the same username as the web-based credential,
// so it should be suppressed, but the second has a different username, so it
// should be shown.
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(false));
- simulated_results[0]->username_value = ASCIIToUTF16(kTestUsername1);
- simulated_results[0]->password_value = ASCIIToUTF16(kTestWebPassword);
- simulated_results.push_back(base::MakeUnique<PasswordForm>());
- simulated_results[1]->signon_realm = "android://hash@com.google.android";
- simulated_results[1]->origin = GURL("android://hash@com.google.android/");
- simulated_results[1]->username_value = ASCIIToUTF16(kTestUsername1);
- simulated_results[1]->password_value = ASCIIToUTF16(kTestAndroidPassword1);
- simulated_results.push_back(
- base::MakeUnique<PasswordForm>(*simulated_results[1]));
- simulated_results[2]->username_value = ASCIIToUTF16(kTestUsername2);
- simulated_results[2]->password_value = ASCIIToUTF16(kTestAndroidPassword2);
+ PasswordForm website_login = CreateSavedMatch(false);
+ website_login.username_value = ASCIIToUTF16(kTestUsername1);
+ website_login.password_value = ASCIIToUTF16(kTestWebPassword);
+
+ PasswordForm android_same;
+ android_same.signon_realm = "android://hash@com.google.android";
+ android_same.origin = GURL("android://hash@com.google.android/");
+ android_same.username_value = ASCIIToUTF16(kTestUsername1);
+ android_same.password_value = ASCIIToUTF16(kTestAndroidPassword1);
+
+ PasswordForm android_other = android_same;
+ android_other.username_value = ASCIIToUTF16(kTestUsername2);
+ android_other.password_value = ASCIIToUTF16(kTestAndroidPassword2);
std::vector<std::unique_ptr<PasswordForm>> expected_matches;
- expected_matches.push_back(
- base::MakeUnique<PasswordForm>(*simulated_results[0]));
- expected_matches.push_back(
- base::MakeUnique<PasswordForm>(*simulated_results[2]));
+ expected_matches.push_back(base::MakeUnique<PasswordForm>(website_login));
+ expected_matches.push_back(base::MakeUnique<PasswordForm>(android_other));
autofill::PasswordFormFillData fill_data;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated(
+ {&website_login, &android_same, &android_other}, 0u);
EXPECT_FALSE(fill_data.wait_for_username);
EXPECT_EQ(1u, fill_data.additional_logins.size());
@@ -1634,9 +1546,9 @@ TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
PasswordFormManager::RESULT_ACTION_MATCH);
// Then when the observed form has an invalid URL:
PasswordForm valid_action_form(*observed_form());
- PasswordFormManager invalid_manager(password_manager(), client(),
- client()->driver(), invalid_action_form,
- base::MakeUnique<MockFormSaver>());
+ PasswordFormManager invalid_manager(
+ password_manager(), client(), client()->driver(), invalid_action_form,
+ base::MakeUnique<MockFormSaver>(), fake_form_fetcher());
EXPECT_EQ(0,
invalid_manager.DoesManage(valid_action_form) &
PasswordFormManager::RESULT_ACTION_MATCH);
@@ -1654,7 +1566,7 @@ TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
PasswordForm valid_action_form(*observed_form());
PasswordFormManager empty_action_manager(
password_manager(), client(), client()->driver(), empty_action_form,
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), fake_form_fetcher());
EXPECT_EQ(0,
empty_action_manager.DoesManage(valid_action_form) &
PasswordFormManager::RESULT_ACTION_MATCH);
@@ -1669,9 +1581,9 @@ TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
// The other way round: observing a non-HTML form, don't match a HTML form.
PasswordForm html_form(*observed_form());
- PasswordFormManager non_html_manager(password_manager(), client(), kNoDriver,
- non_html_form,
- base::MakeUnique<MockFormSaver>());
+ PasswordFormManager non_html_manager(
+ password_manager(), client(), kNoDriver, non_html_form,
+ base::MakeUnique<MockFormSaver>(), fake_form_fetcher());
EXPECT_EQ(0, non_html_manager.DoesManage(html_form) &
PasswordFormManager::RESULT_HTML_ATTRIBUTES_MATCH);
}
@@ -1706,9 +1618,9 @@ TEST_F(PasswordFormManagerTest,
PasswordForm secure_observed_form(*observed_form());
secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
- PasswordFormManager secure_manager(password_manager(), client(),
- client()->driver(), secure_observed_form,
- base::MakeUnique<MockFormSaver>());
+ PasswordFormManager secure_manager(
+ password_manager(), client(), client()->driver(), secure_observed_form,
+ base::MakeUnique<MockFormSaver>(), fake_form_fetcher());
// Also for HTTPS in the observed form, and HTTP in the compared form, an
// exact path match is expected.
EXPECT_EQ(0, secure_manager.DoesManage(form_longer_path) &
@@ -1761,11 +1673,7 @@ TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
third.password_value = ASCIIToUTF16("second");
third.preferred = false;
- std::vector<std::unique_ptr<PasswordForm>> result;
- result.push_back(base::MakeUnique<PasswordForm>(first));
- result.push_back(base::MakeUnique<PasswordForm>(second));
- result.push_back(base::MakeUnique<PasswordForm>(third));
- form_manager()->OnGetPasswordStoreResults(std::move(result));
+ fake_form_fetcher()->SetNonFederated({&first, &second, &third}, 0u);
// |first| scored slightly higher.
EXPECT_EQ(ASCIIToUTF16("first"),
@@ -1805,10 +1713,12 @@ TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
// For newly saved passwords, upload a password vote for autofill::PASSWORD.
// Don't vote for the username field yet.
- PasswordFormManager form_manager(password_manager(), client(),
- client()->driver(), *saved_match(),
- base::MakeUnique<NiceMock<MockFormSaver>>());
- SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
+ PasswordFormManager form_manager(
+ password_manager(), client(), client()->driver(), *saved_match(),
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
PasswordForm form_to_save(*saved_match());
form_to_save.preferred = true;
@@ -1824,22 +1734,24 @@ TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
form_manager.ProvisionallySave(
form_to_save, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
- Mock::VerifyAndClearExpectations(&form_manager);
+}
+TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword_Blacklist) {
// Do not upload a vote if the user is blacklisting the form.
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager blacklist_form_manager(
password_manager(), client(), client()->driver(), *saved_match(),
- base::MakeUnique<NiceMock<MockFormSaver>>());
- SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
- expected_available_field_types.clear();
+ autofill::ServerFieldTypeSet expected_available_field_types;
expected_available_field_types.insert(autofill::USERNAME);
expected_available_field_types.insert(autofill::PASSWORD);
EXPECT_CALL(*client()->mock_driver()->mock_autofill_download_manager(),
StartUploadRequest(_, _, expected_available_field_types, _, true))
.Times(0);
blacklist_form_manager.PermanentlyBlacklist();
- Mock::VerifyAndClearExpectations(&blacklist_form_manager);
}
TEST_F(PasswordFormManagerTest, UploadPasswordForm) {
@@ -1883,8 +1795,7 @@ TEST_F(PasswordFormManagerTest, UploadPasswordForm) {
TEST_F(PasswordFormManagerTest, CorrectlySavePasswordWithoutUsernameFields) {
EXPECT_CALL(*client()->mock_driver(), AllowPasswordGenerationForForm(_));
- form_manager()->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
PasswordForm login(*observed_form());
login.username_element.clear();
@@ -1915,43 +1826,40 @@ TEST_F(PasswordFormManagerTest, DriverDeletedBeforeStoreDone) {
// This test checks implicitly that after step 4 the PFM does not attempt
// use-after-free of the deleted driver.
std::string example_url("http://example.com");
- std::unique_ptr<PasswordForm> form(new PasswordForm);
- form->origin = GURL(example_url);
- form->signon_realm = example_url;
- form->action = GURL(example_url);
- form->username_element = ASCIIToUTF16("u");
- form->password_element = ASCIIToUTF16("p");
- form->submit_element = ASCIIToUTF16("s");
-
+ PasswordForm form;
+ form.origin = GURL(example_url);
+ form.signon_realm = example_url;
+ form.action = GURL(example_url);
+ form.username_element = ASCIIToUTF16("u");
+ form.password_element = ASCIIToUTF16("p");
+ form.submit_element = ASCIIToUTF16("s");
+
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
- client()->driver(), *form,
- base::MakeUnique<MockFormSaver>());
+ client()->driver(), form,
+ base::MakeUnique<MockFormSaver>(), &fetcher);
// Suddenly, the frame and its driver disappear.
client()->KillDriver();
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(std::move(form));
- form_manager.OnGetPasswordStoreResults(std::move(simulated_results));
+ fetcher.SetNonFederated({&form}, 0u);
}
TEST_F(PasswordFormManagerTest, PreferredMatchIsUpToDate) {
// Check that preferred_match() is always a member of best_matches().
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- std::unique_ptr<PasswordForm> form(new PasswordForm(*observed_form()));
- form->username_value = ASCIIToUTF16("username");
- form->password_value = ASCIIToUTF16("password1");
- form->preferred = false;
+ PasswordForm form = *observed_form();
+ form.username_value = ASCIIToUTF16("username");
+ form.password_value = ASCIIToUTF16("password1");
+ form.preferred = false;
- std::unique_ptr<PasswordForm> generated_form(new PasswordForm(*form));
- generated_form->type = PasswordForm::TYPE_GENERATED;
- generated_form->password_value = ASCIIToUTF16("password2");
- generated_form->preferred = true;
+ PasswordForm generated_form = form;
+ generated_form.type = PasswordForm::TYPE_GENERATED;
+ generated_form.password_value = ASCIIToUTF16("password2");
+ generated_form.preferred = true;
- simulated_results.push_back(std::move(generated_form));
- simulated_results.push_back(std::move(form));
+ fake_form_fetcher()->SetNonFederated({&form, &generated_form}, 0u);
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
EXPECT_EQ(1u, form_manager()->best_matches().size());
EXPECT_EQ(form_manager()->preferred_match(),
form_manager()->best_matches().begin()->second);
@@ -2006,17 +1914,19 @@ TEST_F(PasswordFormManagerTest, TestSuggestingPasswordChangeForms) {
PasswordForm observed_change_password_form = *observed_form();
observed_change_password_form.new_password_element =
base::ASCIIToUTF16("new_pwd");
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager manager_creds(
password_manager(), client(), client()->driver(),
- observed_change_password_form, base::MakeUnique<MockFormSaver>());
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(CreateSavedMatch(false));
+ observed_change_password_form, base::MakeUnique<MockFormSaver>(),
+ &fetcher);
autofill::PasswordFormFillData fill_data;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_))
.WillOnce(SaveArg<0>(&fill_data));
- manager_creds.OnGetPasswordStoreResults(std::move(simulated_results));
+ PasswordForm result = CreateSavedMatch(false);
+ fetcher.SetNonFederated({&result}, 0u);
EXPECT_EQ(1u, manager_creds.best_matches().size());
EXPECT_EQ(0u, fill_data.additional_logins.size());
EXPECT_TRUE(fill_data.wait_for_username);
@@ -2041,11 +1951,14 @@ TEST_F(PasswordFormManagerTest, TestUpdateMethod) {
// verify in the end that this did not happen.
saved_match()->submit_element.clear();
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+
+ fetcher.SetNonFederated({saved_match()}, 0u);
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
// User submits current and new credentials to the observed form.
PasswordForm credentials(*observed_form());
credentials.username_element.clear();
@@ -2075,7 +1988,6 @@ TEST_F(PasswordFormManagerTest, TestUpdateMethod) {
.WillOnce(SaveArg<0>(&new_credentials));
form_manager.Update(*saved_match());
- Mock::VerifyAndClearExpectations(mock_store());
// No meta-information should be updated, only the password.
EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
@@ -2085,8 +1997,9 @@ TEST_F(PasswordFormManagerTest, TestUpdateMethod) {
}
TEST_F(PasswordFormManagerTest, TestUpdateNoUsernameTextfieldPresent) {
- // Add a new password field to the test form. The PasswordFormManager should
- // save the password from this field, instead of the current password field.
+ // Add a new password field to the test form and insert a |username_value|
+ // unlikely to be a real username. The PasswordFormManager should still save
+ // the password from this field, instead of the current password field.
observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
autofill::FormFieldData field;
field.label = ASCIIToUTF16("NewPasswd");
@@ -2103,11 +2016,14 @@ TEST_F(PasswordFormManagerTest, TestUpdateNoUsernameTextfieldPresent) {
// will verify in the end that this did not happen.
saved_match()->submit_element.clear();
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+
+ fetcher.SetNonFederated({saved_match()}, 0u);
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
// User submits current and new credentials to the observed form.
PasswordForm credentials(*observed_form());
// The |username_value| contains a text that's unlikely to be real username.
@@ -2139,9 +2055,9 @@ TEST_F(PasswordFormManagerTest, TestUpdateNoUsernameTextfieldPresent) {
.WillOnce(SaveArg<0>(&new_credentials));
form_manager.Update(form_manager.pending_credentials());
- Mock::VerifyAndClearExpectations(mock_store());
- // No meta-information should be updated, only the password.
+ // No other information than password value should be updated. In particular
+ // not the username.
EXPECT_EQ(saved_match()->username_value, new_credentials.username_value);
EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
@@ -2149,15 +2065,19 @@ TEST_F(PasswordFormManagerTest, TestUpdateNoUsernameTextfieldPresent) {
EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
}
+// Test that if WipeStoreCopyIfOutdated is called before password store
+// callback, the UMA is signalled accordingly.
TEST_F(PasswordFormManagerTest, WipeStoreCopyIfOutdated_BeforeStoreCallback) {
PasswordForm form(*saved_match());
- ASSERT_FALSE(form.password_value.empty());
+ form.password_value = ASCIIToUTF16("nonempty-password");
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), form,
- base::MakeUnique<MockFormSaver>());
- // The creation of |form_manager| caused a GetLogins call. This test does not
- // provide the callback for that call back to |form_manager| on purpose.
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ // The creation of |fetcher| keeps it waiting for store results. This test
+ // keeps the fetcher waiting on purpose.
PasswordForm submitted_form(form);
submitted_form.password_value += ASCIIToUTF16("add stuff, make it different");
@@ -2173,19 +2093,16 @@ TEST_F(PasswordFormManagerTest, WipeStoreCopyIfOutdated_BeforeStoreCallback) {
}
TEST_F(PasswordFormManagerTest, GenerationStatusChangedWithPassword) {
- std::unique_ptr<PasswordForm> generated_form(
- new PasswordForm(*observed_form()));
- generated_form->type = PasswordForm::TYPE_GENERATED;
- generated_form->username_value = ASCIIToUTF16("username");
- generated_form->password_value = ASCIIToUTF16("password2");
- generated_form->preferred = true;
-
- PasswordForm submitted_form(*generated_form);
+ PasswordForm generated_form = *observed_form();
+ generated_form.type = PasswordForm::TYPE_GENERATED;
+ generated_form.username_value = ASCIIToUTF16("username");
+ generated_form.password_value = ASCIIToUTF16("password2");
+ generated_form.preferred = true;
+
+ PasswordForm submitted_form(generated_form);
submitted_form.password_value = ASCIIToUTF16("password3");
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(std::move(generated_form));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated({&generated_form}, 0u);
form_manager()->ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
@@ -2201,18 +2118,15 @@ TEST_F(PasswordFormManagerTest, GenerationStatusChangedWithPassword) {
TEST_F(PasswordFormManagerTest, GenerationStatusNotUpdatedIfPasswordUnchanged) {
base::HistogramTester histogram_tester;
- std::unique_ptr<PasswordForm> generated_form(
- new PasswordForm(*observed_form()));
- generated_form->type = PasswordForm::TYPE_GENERATED;
- generated_form->username_value = ASCIIToUTF16("username");
- generated_form->password_value = ASCIIToUTF16("password2");
- generated_form->preferred = true;
+ PasswordForm generated_form = *observed_form();
+ generated_form.type = PasswordForm::TYPE_GENERATED;
+ generated_form.username_value = ASCIIToUTF16("username");
+ generated_form.password_value = ASCIIToUTF16("password2");
+ generated_form.preferred = true;
- PasswordForm submitted_form(*generated_form);
+ PasswordForm submitted_form(generated_form);
- std::vector<std::unique_ptr<PasswordForm>> simulated_results;
- simulated_results.push_back(std::move(generated_form));
- form_manager()->OnGetPasswordStoreResults(std::move(simulated_results));
+ fake_form_fetcher()->SetNonFederated({&generated_form}, 0u);
form_manager()->ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
@@ -2227,105 +2141,56 @@ TEST_F(PasswordFormManagerTest, GenerationStatusNotUpdatedIfPasswordUnchanged) {
metrics_util::PASSWORD_USED, 1);
}
-TEST_F(PasswordFormManagerTest,
- FetchMatchingLoginsFromPasswordStore_Reentrance) {
- form_manager()->FetchDataFromPasswordStore();
- form_manager()->FetchDataFromPasswordStore();
-
- // First response from the store, should be ignored.
- std::unique_ptr<PasswordForm> saved_form(new PasswordForm(*saved_match()));
- saved_form->username_value = ASCIIToUTF16("a@gmail.com");
- std::vector<std::unique_ptr<PasswordForm>> results;
- results.push_back(std::move(saved_form));
- // Expect the additional call for GetLogins after the first response arrives.
- EXPECT_CALL(
- *mock_store(),
- GetLogins(PasswordStore::FormDigest(form_manager()->observed_form()),
- form_manager()));
- form_manager()->OnGetPasswordStoreResults(std::move(results));
- EXPECT_TRUE(form_manager()->best_matches().empty());
-
- // Second response from the store should not be ignored.
- saved_form.reset(new PasswordForm(*saved_match()));
- saved_form->username_value = ASCIIToUTF16("b@gmail.com");
- results.push_back(std::move(saved_form));
- saved_form.reset(new PasswordForm(*saved_match()));
- saved_form->username_value = ASCIIToUTF16("c@gmail.com");
- results.push_back(std::move(saved_form));
- form_manager()->OnGetPasswordStoreResults(std::move(results));
- EXPECT_EQ(2U, form_manager()->best_matches().size());
-}
-
+// Test that ProcessFrame is called on receiving matches from the fetcher,
+// resulting in a FillPasswordForm call.
TEST_F(PasswordFormManagerTest, ProcessFrame) {
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_));
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
}
+// Test that ProcessFrame can also be called directly, resulting in an
+// additional FillPasswordForm call.
TEST_F(PasswordFormManagerTest, ProcessFrame_MoreProcessFrameMoreFill) {
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)).Times(2);
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
form_manager()->ProcessFrame(client()->mock_driver()->AsWeakPtr());
}
+// Test that when ProcessFrame is called on a driver added after receiving
+// matches, such driver is still told to call FillPasswordForm.
TEST_F(PasswordFormManagerTest, ProcessFrame_TwoDrivers) {
NiceMock<MockPasswordManagerDriver> second_driver;
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_));
EXPECT_CALL(second_driver, FillPasswordForm(_));
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
form_manager()->ProcessFrame(second_driver.AsWeakPtr());
}
+// Test that a second driver is added before receiving matches, such driver is
+// also told to call FillPasswordForm once the matches arrive.
TEST_F(PasswordFormManagerTest, ProcessFrame_DriverBeforeMatching) {
- NiceMock<MockPasswordManagerDriver> extra_driver;
-
- EXPECT_CALL(extra_driver, FillPasswordForm(_));
-
- // The PasswordStore was asked store for logins when |form_manager()| was
- // created, but should not respond yet.
-
- // Now add the extra driver.
- form_manager()->ProcessFrame(extra_driver.AsWeakPtr());
+ NiceMock<MockPasswordManagerDriver> second_driver;
+ form_manager()->ProcessFrame(second_driver.AsWeakPtr());
- // Password store responds.
- std::unique_ptr<PasswordForm> match(new PasswordForm(*saved_match()));
- std::vector<std::unique_ptr<PasswordForm>> result_form;
- result_form.push_back(std::move(match));
- form_manager()->OnGetPasswordStoreResults(std::move(result_form));
+ EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_));
+ EXPECT_CALL(second_driver, FillPasswordForm(_));
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
}
+// Test that if the fetcher updates the information about stored matches,
+// autofill is re-triggered.
TEST_F(PasswordFormManagerTest, ProcessFrame_StoreUpdatesCausesAutofill) {
EXPECT_CALL(*client()->mock_driver(), FillPasswordForm(_)).Times(2);
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
- form_manager()->FetchDataFromPasswordStore();
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ std::vector<const PasswordForm*> matches = {saved_match()};
+ fake_form_fetcher()->SetNonFederated(matches, 0u);
+ fake_form_fetcher()->Fetch();
+ fake_form_fetcher()->SetNonFederated(matches, 0u);
}
-TEST_F(PasswordFormManagerTest, UpdateFormManagers_IsCalled) {
- // Let |password_manager()| create one additional PasswordFormManager.
- PasswordStoreConsumer* consumer = nullptr; // Will point to the new PFM.
- EXPECT_CALL(*mock_store(), GetLogins(_, _)).WillOnce(SaveArg<1>(&consumer));
- PasswordForm form;
- std::vector<PasswordForm> observed;
- observed.push_back(form);
- password_manager()->OnPasswordFormsParsed(client()->mock_driver(), observed);
- // Make sure that the additional PFM is in POST_MATCHING phase.
- ASSERT_TRUE(consumer);
- consumer->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
-
- // Now prepare |form_manager()| for saving.
- SimulateMatchingPhase(form_manager(), RESULT_NO_MATCH);
- PasswordForm saved_form(*observed_form());
- saved_form.preferred = true;
- form_manager()->ProvisionallySave(
- saved_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
-
- // Firing Save() should cause PasswordManager::UpdateFormManagers to make the
- // additional PFM to call the password store again.
- EXPECT_CALL(*mock_store(), GetLogins(_, _));
- form_manager()->Save();
-}
+// TODO(crbug.com/639786): Restore the following test:
+// when PasswordFormManager::Save is called, then PasswordFormManager also
+// calls PasswordManager::UpdateFormManagers.
TEST_F(PasswordFormManagerTest, UploadChangePasswordForm_NEW_PASSWORD) {
ChangePasswordUploadTest(autofill::NEW_PASSWORD);
@@ -2341,10 +2206,12 @@ TEST_F(PasswordFormManagerTest, UploadChangePasswordForm_NOT_NEW_PASSWORD) {
}
TEST_F(PasswordFormManagerTest, TestUpdatePSLMatchedCredentials) {
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH | RESULT_PSL_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated({saved_match(), psl_saved_match()}, 0u);
// User submits a credentials with an old username and a new password.
PasswordForm credentials(*observed_form());
@@ -2369,7 +2236,6 @@ TEST_F(PasswordFormManagerTest, TestUpdatePSLMatchedCredentials) {
StartUploadRequest(_, false, _, _, true));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
// No meta-information should be updated, only the password.
EXPECT_EQ(credentials.password_value, new_credentials.password_value);
@@ -2392,11 +2258,13 @@ TEST_F(PasswordFormManagerTest, TestUpdatePSLMatchedCredentials) {
TEST_F(PasswordFormManagerTest,
TestNotUpdatePSLMatchedCredentialsWithAnotherUsername) {
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
psl_saved_match()->username_value += ASCIIToUTF16("1");
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH | RESULT_PSL_MATCH);
+ fetcher.SetNonFederated({saved_match(), psl_saved_match()}, 0u);
// User submits a credentials with an old username and a new password.
PasswordForm credentials(*observed_form());
@@ -2420,7 +2288,6 @@ TEST_F(PasswordFormManagerTest,
StartUploadRequest(_, false, _, _, true));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
// No meta-information should be updated, only the password.
EXPECT_EQ(credentials.password_value, new_credentials.password_value);
@@ -2432,11 +2299,13 @@ TEST_F(PasswordFormManagerTest,
TEST_F(PasswordFormManagerTest,
TestNotUpdatePSLMatchedCredentialsWithAnotherPassword) {
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
+ base::MakeUnique<MockFormSaver>(), &fetcher);
psl_saved_match()->password_value += ASCIIToUTF16("1");
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH | RESULT_PSL_MATCH);
+ fetcher.SetNonFederated({saved_match(), psl_saved_match()}, 0u);
// User submits a credentials with an old username and a new password.
PasswordForm credentials(*observed_form());
@@ -2460,7 +2329,6 @@ TEST_F(PasswordFormManagerTest,
StartUploadRequest(_, false, _, _, true));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
// No meta-information should be updated, only the password.
EXPECT_EQ(credentials.password_value, new_credentials.password_value);
@@ -2471,10 +2339,12 @@ TEST_F(PasswordFormManagerTest,
}
TEST_F(PasswordFormManagerTest, TestNotUpdateWhenOnlyPSLMatched) {
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
- SimulateMatchingPhase(&form_manager, RESULT_PSL_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated({psl_saved_match()}, 0u);
// User submits a credentials with an old username and a new password.
PasswordForm credentials(*observed_form());
@@ -2493,7 +2363,6 @@ TEST_F(PasswordFormManagerTest, TestNotUpdateWhenOnlyPSLMatched) {
.WillOnce(testing::SaveArg<0>(&new_credentials));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
EXPECT_EQ(credentials.password_value, new_credentials.password_value);
EXPECT_EQ(credentials.username_value, new_credentials.username_value);
@@ -2502,41 +2371,9 @@ TEST_F(PasswordFormManagerTest, TestNotUpdateWhenOnlyPSLMatched) {
EXPECT_EQ(credentials.origin, new_credentials.origin);
}
-#if !defined(OS_IOS) && !defined(OS_ANDROID)
-TEST_F(PasswordFormManagerTest, FetchStatistics) {
- InteractionsStats stats;
- stats.origin_domain = observed_form()->origin.GetOrigin();
- stats.username_value = saved_match()->username_value;
- stats.dismissal_count = 5;
- std::vector<InteractionsStats*> db_stats;
- db_stats.push_back(new InteractionsStats(stats));
- EXPECT_CALL(*mock_store(), GetSiteStatsMock(stats.origin_domain))
- .WillOnce(Return(db_stats));
- form_manager()->FetchDataFromPasswordStore();
- base::RunLoop().RunUntilIdle();
-
- EXPECT_THAT(form_manager()->form_fetcher()->GetInteractionsStats(),
- ElementsAre(Pointee(stats)));
-}
-#else
-TEST_F(PasswordFormManagerTest, DontFetchStatistics) {
- // Because |form_manager()| is currently waiting for a PasswordStore response,
- // the response needs to be faked in order to be able to re-request another
- // one below.
- form_manager()->OnGetPasswordStoreResults(
- std::vector<std::unique_ptr<PasswordForm>>());
- EXPECT_CALL(
- *mock_store(),
- GetLogins(PasswordStore::FormDigest(*observed_form()), form_manager()));
- EXPECT_CALL(*mock_store(), GetSiteStatsMock(_)).Times(0);
- form_manager()->FetchDataFromPasswordStore();
- base::RunLoop().RunUntilIdle();
-}
-#endif
-
TEST_F(PasswordFormManagerTest,
TestSavingOnChangePasswordFormGenerationNoStoredForms) {
- SimulateMatchingPhase(form_manager(), RESULT_NO_MATCH);
+ fake_form_fetcher()->SetNonFederated(std::vector<const PasswordForm*>(), 0u);
form_manager()->set_has_generated_password(true);
// User submits change password form and there is no stored credentials.
@@ -2571,7 +2408,7 @@ TEST_F(PasswordFormManagerTest,
}
TEST_F(PasswordFormManagerTest, TestUpdatingOnChangePasswordFormGeneration) {
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
form_manager()->set_has_generated_password(true);
// User submits credentials for the change password form, and old password is
@@ -2607,7 +2444,7 @@ TEST_F(PasswordFormManagerTest, TestUpdatingOnChangePasswordFormGeneration) {
TEST_F(PasswordFormManagerTest,
TestSavingOnChangePasswordFormGenerationNoMatchedForms) {
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
form_manager()->set_has_generated_password(true);
// User submits credentials for the change password form, and old password is
@@ -2658,11 +2495,12 @@ TEST_F(PasswordFormManagerTest,
field.name = ASCIIToUTF16("NewPasswd");
observed_form()->form_data.fields.push_back(field);
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
-
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated({saved_match()}, 0u);
// User submits current and new credentials to the observed form.
PasswordForm submitted_form(*observed_form());
@@ -2735,17 +2573,18 @@ TEST_F(PasswordFormManagerTest, FormClassifierVoteUpload) {
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_match()->password_value;
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(
password_manager(), client(), client()->driver(), form,
- base::MakeUnique<NiceMock<MockFormSaver>>());
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
base::string16 generation_element = form.password_element;
if (found_generation_element)
form_manager.SaveGenerationFieldDetectedByClassifier(generation_element);
else
form_manager.SaveGenerationFieldDetectedByClassifier(base::string16());
- std::vector<std::unique_ptr<PasswordForm>> result;
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
autofill::FormStructure form_structure(submitted_form.form_data);
@@ -2771,11 +2610,12 @@ TEST_F(PasswordFormManagerTest, FieldPropertiesMasksUpload) {
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_match()->password_value;
- PasswordFormManager form_manager(password_manager(), client(),
- client()->driver(), form,
- base::MakeUnique<NiceMock<MockFormSaver>>());
- std::vector<std::unique_ptr<PasswordForm>> result;
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
+ PasswordFormManager form_manager(
+ password_manager(), client(), client()->driver(), form,
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
DCHECK_EQ(3U, form.form_data.fields.size());
submitted_form.form_data.fields[1].properties_mask =
@@ -2805,10 +2645,12 @@ TEST_F(PasswordFormManagerTest, TestSavingAPIFormsWithSamePassword) {
saved_match()->username_element.clear();
saved_match()->type = autofill::PasswordForm::TYPE_API;
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(password_manager(), client(),
client()->driver(), *observed_form(),
- base::MakeUnique<MockFormSaver>());
- SimulateMatchingPhase(&form_manager, RESULT_SAVED_MATCH);
+ base::MakeUnique<MockFormSaver>(), &fetcher);
+ fetcher.SetNonFederated({saved_match()}, 0u);
// User submits new credentials with the same password as in already saved
// one.
@@ -2828,7 +2670,6 @@ TEST_F(PasswordFormManagerTest, TestSavingAPIFormsWithSamePassword) {
.WillOnce(SaveArg<0>(&new_credentials));
form_manager.Save();
- Mock::VerifyAndClearExpectations(mock_store());
EXPECT_EQ(saved_match()->username_value + ASCIIToUTF16("1"),
new_credentials.username_value);
@@ -2840,7 +2681,7 @@ TEST_F(PasswordFormManagerTest, TestSavingAPIFormsWithSamePassword) {
TEST_F(PasswordFormManagerTest, SkipZeroClickIntact) {
saved_match()->skip_zero_click = true;
psl_saved_match()->skip_zero_click = true;
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH | RESULT_PSL_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match(), psl_saved_match()}, 0u);
EXPECT_EQ(1u, form_manager()->best_matches().size());
// User submits a credentials with an old username and a new password.
@@ -2866,31 +2707,15 @@ TEST_F(PasswordFormManagerTest, SkipZeroClickIntact) {
EXPECT_TRUE(credentials_to_update[0].skip_zero_click);
}
-TEST_F(PasswordFormManagerTest, FederatedCredentialsFiltered) {
- PasswordForm federated(*saved_match());
- federated.password_value.clear();
- federated.federation_origin =
- url::Origin(GURL("https://accounts.google.com"));
-
- std::vector<std::unique_ptr<PasswordForm>> results;
- results.push_back(base::MakeUnique<PasswordForm>(federated));
- results.push_back(base::MakeUnique<PasswordForm>(*saved_match()));
- form_manager()->OnGetPasswordStoreResults(std::move(results));
-
- EXPECT_EQ(1u, form_manager()->form_fetcher()->GetFederatedMatches().size());
- EXPECT_EQ(*form_manager()->form_fetcher()->GetFederatedMatches()[0],
- federated);
- EXPECT_EQ(1u, form_manager()->best_matches().size());
- EXPECT_EQ(*(form_manager()->best_matches().begin()->second), *saved_match());
-}
-
TEST_F(PasswordFormManagerTest, ProbablyAccountCreationUpload) {
PasswordForm form(*observed_form());
form.form_data = saved_match()->form_data;
- PasswordFormManager form_manager(password_manager(), client(),
- client()->driver(), form,
- base::MakeUnique<NiceMock<MockFormSaver>>());
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
+ PasswordFormManager form_manager(
+ password_manager(), client(), client()->driver(), form,
+ base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
PasswordForm form_to_save(form);
form_to_save.preferred = true;
@@ -2899,8 +2724,7 @@ TEST_F(PasswordFormManagerTest, ProbablyAccountCreationUpload) {
form_to_save.password_value = saved_match()->password_value;
form_to_save.does_look_like_signup_form = true;
- std::vector<std::unique_ptr<PasswordForm>> result;
- form_manager.OnGetPasswordStoreResults(std::move(result));
+ fetcher.SetNonFederated(std::vector<const PasswordForm*>(), 0u);
autofill::FormStructure pending_structure(form_to_save.form_data);
autofill::ServerFieldTypeSet expected_available_field_types;
@@ -2927,14 +2751,14 @@ TEST_F(PasswordFormManagerTest, ProbablyAccountCreationUpload) {
TEST_F(PasswordFormManagerFillOnAccountSelectTest, ProcessFrame) {
EXPECT_CALL(*client()->mock_driver(),
ShowInitialPasswordAccountSuggestions(_));
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
}
// Check that PasswordFormManager records
// PasswordManager_LoginFollowingAutofill as part of processing a credential
// update.
TEST_F(PasswordFormManagerTest, ReportProcessingUpdate) {
- SimulateMatchingPhase(form_manager(), RESULT_SAVED_MATCH);
+ fake_form_fetcher()->SetNonFederated({saved_match()}, 0u);
PasswordForm pending = *observed_form();
pending.username_value = saved_match()->username_value;
pending.password_value = saved_match()->password_value;
@@ -2973,11 +2797,13 @@ TEST_F(PasswordFormManagerTest, RemoveResultsWithWrongScheme_ObservingHTML) {
PasswordForm observed = *observed_form();
observed.scheme = kCorrectScheme;
+ FakeFormFetcher fetcher;
+ fetcher.Fetch();
PasswordFormManager form_manager(
password_manager(), client(),
(kCorrectScheme == PasswordForm::SCHEME_HTML ? client()->driver()
: nullptr),
- observed, base::MakeUnique<NiceMock<MockFormSaver>>());
+ observed, base::MakeUnique<NiceMock<MockFormSaver>>(), &fetcher);
PasswordForm match = *saved_match();
match.scheme = kCorrectScheme;
@@ -2986,18 +2812,16 @@ TEST_F(PasswordFormManagerTest, RemoveResultsWithWrongScheme_ObservingHTML) {
non_match.scheme = kWrongScheme;
// First try putting the correct scheme first in returned matches.
- std::vector<const PasswordForm*> all_matches = {&match, &non_match};
static_cast<FormFetcher::Consumer*>(&form_manager)
- ->ProcessMatches(all_matches, 0u);
+ ->ProcessMatches({&match, &non_match}, 0u);
EXPECT_EQ(1u, form_manager.best_matches().size());
EXPECT_EQ(kCorrectScheme,
form_manager.best_matches().begin()->second->scheme);
// Now try putting the correct scheme last in returned matches.
- all_matches = {&non_match, &match};
static_cast<FormFetcher::Consumer*>(&form_manager)
- ->ProcessMatches(all_matches, 0u);
+ ->ProcessMatches({&non_match, &match}, 0u);
EXPECT_EQ(1u, form_manager.best_matches().size());
EXPECT_EQ(kCorrectScheme,

Powered by Google App Engine
This is Rietveld 408576698