| Index: chrome/browser/password_manager/password_manager_unittest.cc
|
| diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc
|
| deleted file mode 100644
|
| index a6ba43bc053e5afb43f642e4f2eecf23e6ded57d..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/password_manager/password_manager_unittest.cc
|
| +++ /dev/null
|
| @@ -1,628 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <vector>
|
| -
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/common/url_constants.h"
|
| -#include "chrome/test/base/chrome_render_view_host_test_harness.h"
|
| -#include "chrome/test/base/testing_pref_service_syncable.h"
|
| -#include "chrome/test/base/testing_profile.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(GetProfile, Profile*());
|
| - MOCK_METHOD0(GetPasswordStore, PasswordStore*());
|
| - MOCK_METHOD0(GetPrefs, PrefService*());
|
| - MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
|
| - MOCK_METHOD1(GetProbabilityForExperiment,
|
| - base::FieldTrial::Probability(const std::string&));
|
| -
|
| - // The following is required because GMock does not support move-only
|
| - // parameters.
|
| - 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);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -class PasswordManagerTest : public ChromeRenderViewHostTestHarness {
|
| - protected:
|
| - virtual void SetUp() {
|
| - ChromeRenderViewHostTestHarness::SetUp();
|
| - store_ = new MockPasswordStore;
|
| - CHECK(store_->Init());
|
| -
|
| - EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
|
| - EXPECT_CALL(client_, GetPrefs())
|
| - .WillRepeatedly(Return(profile()->GetTestingPrefService()));
|
| - 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;
|
| -
|
| - // Destroy the PasswordManager before tearing down the Profile to avoid
|
| - // crashes due to prefs accesses.
|
| - manager_.reset();
|
| - ChromeRenderViewHostTestHarness::TearDown();
|
| - }
|
| -
|
| - 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");
|
| - // Default to true so we only need to add tests in autocomplete=off cases.
|
| - form.password_autocomplete_set = true;
|
| - form.submit_element = ASCIIToUTF16("signIn");
|
| - form.signon_realm = "http://www.google.com";
|
| - return form;
|
| - }
|
| -
|
| - // Reproduction of the form present on twitter's login page.
|
| - 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;
|
| - }
|
| -
|
| - // Reproduction of the form present on twitter's failed login page.
|
| - 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;
|
| - }
|
| -
|
| - 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) {
|
| - // Test that observing a newly submitted form shows the save password bar.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // And the form submit contract is to call ProvisionallySavePassword.
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - scoped_ptr<PasswordFormManager> form_to_save;
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_))
|
| - .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -
|
| - ASSERT_TRUE(form_to_save.get());
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Simulate saving the form, as if the info bar was accepted.
|
| - form_to_save->Save();
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
|
| - // This test is the same FormSubmitEmptyStore, except that it simulates the
|
| - // user generating the password through the browser.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // Simulate the user generating the password and submitting the form.
|
| - manager()->SetFormHasGeneratedPassword(form);
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // The user should not be presented with an infobar as they have already given
|
| - // consent by using the generated password. The form should be saved once
|
| - // navigation occurs.
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
|
| - // Same as above, except with an existing form for the same signon realm,
|
| - // but different origin. Detailed cases like this are covered by
|
| - // PasswordFormManagerTest.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // We still expect an add, since we didn't have a good match.
|
| - scoped_ptr<PasswordFormManager> form_to_save;
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_))
|
| - .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -
|
| - ASSERT_TRUE(form_to_save.get());
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Simulate saving the form.
|
| - form_to_save->Save();
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // No message from the renderer that a password was submitted. No
|
| - // expected calls.
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
|
| - // Test that navigating in the page does not prevent us from showing the save
|
| - // password infobar.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // Simulate navigating in the page.
|
| - manager()->DidNavigateMainFrame(true);
|
| -
|
| - // Simulate submitting the password.
|
| - OnPasswordFormSubmitted(form);
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - scoped_ptr<PasswordFormManager> form_to_save;
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_))
|
| - .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
|
| -
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -
|
| - ASSERT_FALSE(NULL == form_to_save.get());
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Simulate saving the form, as if the info bar was accepted.
|
| - form_to_save->Save();
|
| -}
|
| -
|
| -// This test verifies a fix for http://crbug.com/236673
|
| -TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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/";
|
| -
|
| - // Pretend that the form is hidden on the first page.
|
| - std::vector<PasswordForm> observed;
|
| - observed.push_back(first_form);
|
| - manager()->OnPasswordFormsParsed(observed);
|
| - observed.clear();
|
| - manager()->OnPasswordFormsRendered(observed);
|
| -
|
| - // Now navigate to a second page.
|
| - manager()->DidNavigateMainFrame(false);
|
| -
|
| - // This page contains a form with the same markup, but on a different
|
| - // URL.
|
| - observed.push_back(second_form);
|
| - manager()->OnPasswordFormsParsed(observed);
|
| - manager()->OnPasswordFormsRendered(observed);
|
| -
|
| - // Now submit this form
|
| - OnPasswordFormSubmitted(second_form);
|
| -
|
| - // Navigation after form submit.
|
| - 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);
|
| -
|
| - // Make sure that the saved form matches the second form, not the first.
|
| - ASSERT_TRUE(form_to_save.get());
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form)));
|
| -
|
| - // Simulate saving the form, as if the info bar was accepted.
|
| - form_to_save->Save();
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // The form reappears, and is visible in the layout:
|
| - // No expected calls to the PasswordStore...
|
| - manager()->OnPasswordFormsParsed(observed);
|
| - manager()->OnPasswordFormsRendered(observed);
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) {
|
| - // Tests fix of issue 28911: if the login form reappears on the subsequent
|
| - // page, but is invisible, it shouldn't count as a failed login.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // Expect info bar to appear:
|
| - scoped_ptr<PasswordFormManager> form_to_save;
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_))
|
| - .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
|
| -
|
| - // The form reappears, but is not visible in the layout:
|
| - manager()->OnPasswordFormsParsed(observed);
|
| - observed.clear();
|
| - manager()->OnPasswordFormsRendered(observed);
|
| -
|
| - ASSERT_TRUE(form_to_save.get());
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Simulate saving the form.
|
| - form_to_save->Save();
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, InitiallyInvisibleForm) {
|
| - // Make sure an invisible login form still gets autofilled.
|
| - 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); // The initial load.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
|
| - // Test that saving passwords depends on the password manager enabled
|
| - // preference.
|
| - TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
|
| - prefService->SetUserPref(prefs::kPasswordManagerEnabled,
|
| - base::Value::CreateBooleanValue(true));
|
| - EXPECT_TRUE(manager()->IsSavingEnabled());
|
| - prefService->SetUserPref(prefs::kPasswordManagerEnabled,
|
| - base::Value::CreateBooleanValue(false));
|
| - EXPECT_FALSE(manager()->IsSavingEnabled());
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
|
| - // Test fix for issue 158296: Passwords must be filled even if the password
|
| - // manager is disabled.
|
| - std::vector<PasswordForm*> result;
|
| - PasswordForm* existing = new PasswordForm(MakeSimpleForm());
|
| - result.push_back(existing);
|
| - TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
|
| - prefService->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) {
|
| - // Test password form with non-generated password will be saved even if
|
| - // autocomplete=off.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // And the form submit contract is to call ProvisionallySavePassword.
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // Password form should be saved.
|
| - 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));
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -
|
| - ASSERT_TRUE(form_to_save.get());
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
|
| - // Test password form with generated password will still be saved if
|
| - // autocomplete=off.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - // Simulate the user generating the password and submitting the form.
|
| - manager()->SetFormHasGeneratedPassword(form);
|
| - manager()->ProvisionallySavePassword(form);
|
| -
|
| - // The user should not be presented with an infobar as they have already given
|
| - // consent by using the generated password. The form should be saved once
|
| - // navigation occurs.
|
| - EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
|
| - EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
|
| -
|
| - // Now the password manager waits for the navigation to complete.
|
| - observed.clear();
|
| - manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
|
| - manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
|
| - manager()->AddSubmissionCallback(SubmissionCallback());
|
| - PasswordForm form = MakeSimpleForm();
|
| - OnPasswordFormSubmitted(form);
|
| - EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
|
| -}
|
| -
|
| -TEST_F(PasswordManagerTest, PasswordFormReappearance) {
|
| - // Test the heuristic to know if a password form reappears.
|
| - // We assume that if we send our credentials and there
|
| - // is at least one visible password form in the next page that
|
| - // means that our previous login attempt failed.
|
| - std::vector<PasswordForm*> result; // Empty password store.
|
| - 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); // The initial load.
|
| - manager()->OnPasswordFormsRendered(observed); // The initial layout.
|
| -
|
| - manager()->ProvisionallySavePassword(login_form);
|
| -
|
| - PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
|
| - observed.clear();
|
| - observed.push_back(failed_login_form);
|
| - // A PasswordForm appears, and is visible in the layout:
|
| - // No expected calls to the PasswordStore...
|
| - manager()->OnPasswordFormsParsed(observed);
|
| - manager()->OnPasswordFormsRendered(observed);
|
| -}
|
|
|