1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <vector> 6 7#include "base/prefs/pref_registry_simple.h" 8#include "base/prefs/pref_service.h" 9#include "base/prefs/testing_pref_service.h" 10#include "base/strings/utf_string_conversions.h" 11#include "components/autofill/core/browser/autofill_field.h" 12#include "components/autofill/core/browser/autofill_metrics.h" 13#include "components/autofill/core/browser/form_structure.h" 14#include "components/autofill/core/common/form_data.h" 15#include "components/autofill/core/common/form_field_data.h" 16#include "components/password_manager/core/browser/password_autofill_manager.h" 17#include "components/password_manager/core/browser/password_generation_manager.h" 18#include "components/password_manager/core/browser/password_manager.h" 19#include "components/password_manager/core/browser/stub_password_manager_client.h" 20#include "components/password_manager/core/browser/stub_password_manager_driver.h" 21#include "components/password_manager/core/common/password_manager_pref_names.h" 22#include "testing/gtest/include/gtest/gtest.h" 23#include "url/gurl.h" 24 25using base::ASCIIToUTF16; 26 27namespace password_manager { 28 29namespace { 30 31class TestPasswordManagerDriver : public StubPasswordManagerDriver { 32 public: 33 TestPasswordManagerDriver(PasswordManagerClient* client) 34 : password_manager_(client), 35 password_generation_manager_(client), 36 password_autofill_manager_(client, NULL), 37 is_off_the_record_(false) {} 38 virtual ~TestPasswordManagerDriver() {} 39 40 // PasswordManagerDriver implementation. 41 virtual bool IsOffTheRecord() OVERRIDE { return is_off_the_record_; } 42 virtual PasswordGenerationManager* GetPasswordGenerationManager() OVERRIDE { 43 return &password_generation_manager_; 44 } 45 virtual PasswordManager* GetPasswordManager() OVERRIDE { 46 return &password_manager_; 47 } 48 virtual PasswordAutofillManager* GetPasswordAutofillManager() OVERRIDE { 49 return &password_autofill_manager_; 50 } 51 virtual void AccountCreationFormsFound( 52 const std::vector<autofill::FormData>& forms) OVERRIDE { 53 found_account_creation_forms_.insert( 54 found_account_creation_forms_.begin(), forms.begin(), forms.end()); 55 } 56 57 const std::vector<autofill::FormData>& GetFoundAccountCreationForms() { 58 return found_account_creation_forms_; 59 } 60 void set_is_off_the_record(bool is_off_the_record) { 61 is_off_the_record_ = is_off_the_record; 62 } 63 64 private: 65 PasswordManager password_manager_; 66 PasswordGenerationManager password_generation_manager_; 67 PasswordAutofillManager password_autofill_manager_; 68 std::vector<autofill::FormData> found_account_creation_forms_; 69 bool is_off_the_record_; 70}; 71 72class TestPasswordManagerClient : public StubPasswordManagerClient { 73 public: 74 TestPasswordManagerClient(scoped_ptr<PrefService> prefs) 75 : prefs_(prefs.Pass()), driver_(this), is_sync_enabled_(false) {} 76 77 virtual PasswordStore* GetPasswordStore() OVERRIDE { return NULL; } 78 virtual PrefService* GetPrefs() OVERRIDE { return prefs_.get(); } 79 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; } 80 virtual void AuthenticateAutofillAndFillForm( 81 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {} 82 virtual bool IsPasswordSyncEnabled() OVERRIDE { return is_sync_enabled_; } 83 84 void set_is_password_sync_enabled(bool enabled) { 85 is_sync_enabled_ = enabled; 86 } 87 88 private: 89 scoped_ptr<PrefService> prefs_; 90 TestPasswordManagerDriver driver_; 91 bool is_sync_enabled_; 92}; 93 94// Unlike the base AutofillMetrics, exposes copy and assignment constructors, 95// which are handy for briefer test code. The AutofillMetrics class is 96// stateless, so this is safe. 97class TestAutofillMetrics : public autofill::AutofillMetrics { 98 public: 99 TestAutofillMetrics() {} 100 virtual ~TestAutofillMetrics() {} 101}; 102 103} // anonymous namespace 104 105class PasswordGenerationManagerTest : public testing::Test { 106 protected: 107 virtual void SetUp() OVERRIDE { 108 // Construct a PrefService and register all necessary prefs before handing 109 // it off to |client_|, as the initialization flow of |client_| will 110 // indirectly cause those prefs to be immediately accessed. 111 scoped_ptr<TestingPrefServiceSimple> prefs(new TestingPrefServiceSimple()); 112 prefs->registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled, 113 true); 114 client_.reset(new TestPasswordManagerClient(prefs.PassAs<PrefService>())); 115 } 116 117 virtual void TearDown() OVERRIDE { client_.reset(); } 118 119 PasswordGenerationManager* GetGenerationManager() { 120 return client_->GetDriver()->GetPasswordGenerationManager(); 121 } 122 123 TestPasswordManagerDriver* GetTestDriver() { 124 return static_cast<TestPasswordManagerDriver*>(client_->GetDriver()); 125 } 126 127 bool IsGenerationEnabled() { 128 return GetGenerationManager()->IsGenerationEnabled(); 129 } 130 131 void DetectAccountCreationForms( 132 const std::vector<autofill::FormStructure*>& forms) { 133 GetGenerationManager()->DetectAccountCreationForms(forms); 134 } 135 136 scoped_ptr<TestPasswordManagerClient> client_; 137}; 138 139TEST_F(PasswordGenerationManagerTest, IsGenerationEnabled) { 140 // Enabling the PasswordManager and password sync should cause generation to 141 // be enabled. 142 PrefService* prefs = client_->GetPrefs(); 143 prefs->SetBoolean(prefs::kPasswordManagerSavingEnabled, true); 144 client_->set_is_password_sync_enabled(true); 145 EXPECT_TRUE(IsGenerationEnabled()); 146 147 // Disabling password syncing should cause generation to be disabled. 148 client_->set_is_password_sync_enabled(false); 149 EXPECT_FALSE(IsGenerationEnabled()); 150 151 // Disabling the PasswordManager should cause generation to be disabled even 152 // if syncing is enabled. 153 prefs->SetBoolean(prefs::kPasswordManagerSavingEnabled, false); 154 client_->set_is_password_sync_enabled(true); 155 EXPECT_FALSE(IsGenerationEnabled()); 156} 157 158TEST_F(PasswordGenerationManagerTest, DetectAccountCreationForms) { 159 // Setup so that IsGenerationEnabled() returns true. 160 PrefService* prefs = client_->GetPrefs(); 161 prefs->SetBoolean(prefs::kPasswordManagerSavingEnabled, true); 162 client_->set_is_password_sync_enabled(true); 163 164 autofill::FormData login_form; 165 login_form.origin = GURL("http://www.yahoo.com/login/"); 166 autofill::FormFieldData username; 167 username.label = ASCIIToUTF16("username"); 168 username.name = ASCIIToUTF16("login"); 169 username.form_control_type = "text"; 170 login_form.fields.push_back(username); 171 autofill::FormFieldData password; 172 password.label = ASCIIToUTF16("password"); 173 password.name = ASCIIToUTF16("password"); 174 password.form_control_type = "password"; 175 login_form.fields.push_back(password); 176 autofill::FormStructure form1(login_form); 177 std::vector<autofill::FormStructure*> forms; 178 forms.push_back(&form1); 179 autofill::FormData account_creation_form; 180 account_creation_form.origin = GURL("http://accounts.yahoo.com/"); 181 account_creation_form.fields.push_back(username); 182 account_creation_form.fields.push_back(password); 183 autofill::FormFieldData confirm_password; 184 confirm_password.label = ASCIIToUTF16("confirm_password"); 185 confirm_password.name = ASCIIToUTF16("password"); 186 confirm_password.form_control_type = "password"; 187 account_creation_form.fields.push_back(confirm_password); 188 autofill::FormStructure form2(account_creation_form); 189 forms.push_back(&form2); 190 191 // Simulate the server response to set the field types. 192 const char* const kServerResponse = 193 "<autofillqueryresponse>" 194 "<field autofilltype=\"9\" />" 195 "<field autofilltype=\"75\" />" 196 "<field autofilltype=\"9\" />" 197 "<field autofilltype=\"76\" />" 198 "<field autofilltype=\"75\" />" 199 "</autofillqueryresponse>"; 200 autofill::FormStructure::ParseQueryResponse( 201 kServerResponse, forms, TestAutofillMetrics()); 202 203 DetectAccountCreationForms(forms); 204 EXPECT_EQ(1u, GetTestDriver()->GetFoundAccountCreationForms().size()); 205 EXPECT_EQ(GURL("http://accounts.yahoo.com/"), 206 GetTestDriver()->GetFoundAccountCreationForms()[0].origin); 207} 208 209TEST_F(PasswordGenerationManagerTest, UpdatePasswordSyncStateIncognito) { 210 // Disable password manager by going incognito. Even though password 211 // syncing is enabled, generation should still 212 // be disabled. 213 GetTestDriver()->set_is_off_the_record(true); 214 PrefService* prefs = client_->GetPrefs(); 215 prefs->SetBoolean(prefs::kPasswordManagerSavingEnabled, true); 216 client_->set_is_password_sync_enabled(true); 217 218 EXPECT_FALSE(IsGenerationEnabled()); 219} 220 221} // namespace password_manager 222