This source file includes following definitions.
- AuthenticateAutofillAndFillForm
- ACTION_P
- ACTION_P
- OnPasswordFormSubmitted
- SetUp
- TearDown
- MakeSimpleForm
- MakeTwitterLoginForm
- MakeTwitterFailedLoginForm
- FormsAreEqual
- manager
- OnPasswordFormSubmitted
- SubmissionCallback
- FormSubmitted
- MATCHER_P
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include <vector>
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/testing_pref_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/password_manager/core/browser/mock_password_store.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
class PasswordGenerationManager;
using autofill::PasswordForm;
using base::ASCIIToUTF16;
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
using testing::Exactly;
using testing::Return;
using testing::WithArg;
namespace autofill {
class AutofillManager;
}
namespace {
class MockPasswordManagerClient : public PasswordManagerClient {
public:
MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*));
MOCK_METHOD0(GetPasswordStore, PasswordStore*());
MOCK_METHOD0(GetPrefs, PrefService*());
MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
MOCK_METHOD1(GetProbabilityForExperiment,
base::FieldTrial::Probability(const std::string&));
MOCK_METHOD1(AuthenticateAutofillAndFillFormPtr,
void(autofill::PasswordFormFillData* fill_data));
virtual void AuthenticateAutofillAndFillForm(
scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
return AuthenticateAutofillAndFillFormPtr(fill_data.release());
}
};
class MockPasswordManagerDriver : public PasswordManagerDriver {
public:
MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
MOCK_METHOD0(IsOffTheRecord, bool());
MOCK_METHOD0(GetPasswordGenerationManager, PasswordGenerationManager*());
MOCK_METHOD0(GetPasswordManager, PasswordManager*());
MOCK_METHOD0(GetAutofillManager, autofill::AutofillManager*());
MOCK_METHOD1(AllowPasswordGenerationForForm, void(autofill::PasswordForm*));
MOCK_METHOD1(AccountCreationFormsFound,
void(const std::vector<autofill::FormData>&));
};
ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
class TestPasswordManager : public PasswordManager {
public:
explicit TestPasswordManager(PasswordManagerClient* client)
: PasswordManager(client) {}
virtual ~TestPasswordManager() {}
virtual void OnPasswordFormSubmitted(const PasswordForm& form) OVERRIDE {
PasswordManager::OnPasswordFormSubmitted(form);
}
private:
DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
};
}
class PasswordManagerTest : public testing::Test {
protected:
virtual void SetUp() {
prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
true);
store_ = new MockPasswordStore;
CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
manager_.reset(new TestPasswordManager(&client_));
EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
.WillRepeatedly(Return(false));
EXPECT_CALL(driver_, IsOffTheRecord()).WillRepeatedly(Return(false));
EXPECT_CALL(driver_, GetPasswordGenerationManager())
.WillRepeatedly(Return(static_cast<PasswordGenerationManager*>(NULL)));
EXPECT_CALL(driver_, GetPasswordManager())
.WillRepeatedly(Return(manager_.get()));
EXPECT_CALL(driver_, AllowPasswordGenerationForForm(_)).Times(AnyNumber());
EXPECT_CALL(*store_, ReportMetricsImpl()).Times(AnyNumber());
}
virtual void TearDown() {
store_->Shutdown();
store_ = NULL;
}
PasswordForm MakeSimpleForm() {
PasswordForm form;
form.origin = GURL("http://www.google.com/a/LoginAuth");
form.action = GURL("http://www.google.com/a/Login");
form.username_element = ASCIIToUTF16("Email");
form.password_element = ASCIIToUTF16("Passwd");
form.username_value = ASCIIToUTF16("google");
form.password_value = ASCIIToUTF16("password");
form.password_autocomplete_set = true;
form.submit_element = ASCIIToUTF16("signIn");
form.signon_realm = "http://www.google.com";
return form;
}
PasswordForm MakeTwitterLoginForm() {
PasswordForm form;
form.origin = GURL("https://twitter.com/");
form.action = GURL("https://twitter.com/sessions");
form.username_element = ASCIIToUTF16("Email");
form.password_element = ASCIIToUTF16("Passwd");
form.username_value = ASCIIToUTF16("twitter");
form.password_value = ASCIIToUTF16("password");
form.password_autocomplete_set = true;
form.submit_element = ASCIIToUTF16("signIn");
form.signon_realm = "https://twitter.com";
return form;
}
PasswordForm MakeTwitterFailedLoginForm() {
PasswordForm form;
form.origin = GURL("https://twitter.com/login/error?redirect_after_login");
form.action = GURL("https://twitter.com/sessions");
form.username_element = ASCIIToUTF16("EmailField");
form.password_element = ASCIIToUTF16("PasswdField");
form.username_value = ASCIIToUTF16("twitter");
form.password_value = ASCIIToUTF16("password");
form.password_autocomplete_set = true;
form.submit_element = ASCIIToUTF16("signIn");
form.signon_realm = "https://twitter.com";
return form;
}
bool FormsAreEqual(const autofill::PasswordForm& lhs,
const autofill::PasswordForm& rhs) {
if (lhs.origin != rhs.origin)
return false;
if (lhs.action != rhs.action)
return false;
if (lhs.username_element != rhs.username_element)
return false;
if (lhs.password_element != rhs.password_element)
return false;
if (lhs.username_value != rhs.username_value)
return false;
if (lhs.password_value != rhs.password_value)
return false;
if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
return false;
if (lhs.submit_element != rhs.submit_element)
return false;
if (lhs.signon_realm != rhs.signon_realm)
return false;
return true;
}
TestPasswordManager* manager() { return manager_.get(); }
void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
manager()->OnPasswordFormSubmitted(form);
}
PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
return base::Bind(&PasswordManagerTest::FormSubmitted,
base::Unretained(this));
}
void FormSubmitted(const autofill::PasswordForm& form) {
submitted_form_ = form;
}
TestingPrefServiceSimple prefs_;
scoped_refptr<MockPasswordStore> store_;
MockPasswordManagerClient client_;
MockPasswordManagerDriver driver_;
scoped_ptr<TestPasswordManager> manager_;
PasswordForm submitted_form_;
};
MATCHER_P(FormMatches, form, "") {
return form.signon_realm == arg.signon_realm && form.origin == arg.origin &&
form.action == arg.action &&
form.username_element == arg.username_element &&
form.password_element == arg.password_element &&
form.password_autocomplete_set == arg.password_autocomplete_set &&
form.submit_element == arg.submit_element;
}
TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_))
.WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
ASSERT_TRUE(form_to_save.get());
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
form_to_save->Save();
}
TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->SetFormHasGeneratedPassword(form);
manager()->ProvisionallySavePassword(form);
EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}
TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
std::vector<PasswordForm*> result;
PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
existing_different->username_value = ASCIIToUTF16("google2");
result.push_back(existing_different);
EXPECT_CALL(driver_, FillPasswordForm(_));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_))
.WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
ASSERT_TRUE(form_to_save.get());
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
form_to_save->Save();
}
TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}
TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->DidNavigateMainFrame(true);
OnPasswordFormSubmitted(form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_))
.WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
ASSERT_FALSE(NULL == form_to_save.get());
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
form_to_save->Save();
}
TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
PasswordForm first_form(MakeSimpleForm());
first_form.origin = GURL("http://www.nytimes.com/");
first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
first_form.signon_realm = "http://www.nytimes.com/";
PasswordForm second_form(MakeSimpleForm());
second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
second_form.signon_realm = "https://myaccount.nytimes.com/";
std::vector<PasswordForm> observed;
observed.push_back(first_form);
manager()->OnPasswordFormsParsed(observed);
observed.clear();
manager()->OnPasswordFormsRendered(observed);
manager()->DidNavigateMainFrame(false);
observed.push_back(second_form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
OnPasswordFormSubmitted(second_form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_))
.WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
ASSERT_TRUE(form_to_save.get());
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form)));
form_to_save->Save();
}
TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}
TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_))
.WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
manager()->OnPasswordFormsParsed(observed);
observed.clear();
manager()->OnPasswordFormsRendered(observed);
ASSERT_TRUE(form_to_save.get());
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
form_to_save->Save();
}
TEST_F(PasswordManagerTest, InitiallyInvisibleForm) {
std::vector<PasswordForm*> result;
PasswordForm* existing = new PasswordForm(MakeSimpleForm());
result.push_back(existing);
EXPECT_CALL(driver_, FillPasswordForm(_));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
observed.clear();
manager()->OnPasswordFormsRendered(observed);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}
TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
base::Value::CreateBooleanValue(true));
EXPECT_TRUE(manager()->IsSavingEnabled());
prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
base::Value::CreateBooleanValue(false));
EXPECT_FALSE(manager()->IsSavingEnabled());
}
TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
std::vector<PasswordForm*> result;
PasswordForm* existing = new PasswordForm(MakeSimpleForm());
result.push_back(existing);
prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
base::Value::CreateBooleanValue(false));
EXPECT_CALL(driver_, FillPasswordForm(_));
EXPECT_CALL(*store_.get(),
GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
}
TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
form.password_autocomplete_set = false;
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(form);
scoped_ptr<PasswordFormManager> form_to_save;
EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(1)).WillOnce(
WithArg<0>(SaveToScopedPtr(&form_to_save)));
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
ASSERT_TRUE(form_to_save.get());
}
TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm form(MakeSimpleForm());
form.password_autocomplete_set = false;
observed.push_back(form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->SetFormHasGeneratedPassword(form);
manager()->ProvisionallySavePassword(form);
EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
observed.clear();
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}
TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
manager()->AddSubmissionCallback(SubmissionCallback());
PasswordForm form = MakeSimpleForm();
OnPasswordFormSubmitted(form);
EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
}
TEST_F(PasswordManagerTest, PasswordFormReappearance) {
std::vector<PasswordForm*> result;
EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
.WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
std::vector<PasswordForm> observed;
PasswordForm login_form(MakeTwitterLoginForm());
observed.push_back(login_form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
manager()->ProvisionallySavePassword(login_form);
PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
observed.clear();
observed.push_back(failed_login_form);
manager()->OnPasswordFormsParsed(observed);
manager()->OnPasswordFormsRendered(observed);
}