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
25 using base::ASCIIToUTF16;
26
27 namespace password_manager {
28
29 namespace {
30
31 class TestPasswordManagerDriver : public StubPasswordManagerDriver {
32 public:
TestPasswordManagerDriver(PasswordManagerClient * client)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) {}
~TestPasswordManagerDriver()38 virtual ~TestPasswordManagerDriver() {}
39
40 // PasswordManagerDriver implementation.
IsOffTheRecord()41 virtual bool IsOffTheRecord() OVERRIDE { return is_off_the_record_; }
GetPasswordGenerationManager()42 virtual PasswordGenerationManager* GetPasswordGenerationManager() OVERRIDE {
43 return &password_generation_manager_;
44 }
GetPasswordManager()45 virtual PasswordManager* GetPasswordManager() OVERRIDE {
46 return &password_manager_;
47 }
GetPasswordAutofillManager()48 virtual PasswordAutofillManager* GetPasswordAutofillManager() OVERRIDE {
49 return &password_autofill_manager_;
50 }
AccountCreationFormsFound(const std::vector<autofill::FormData> & forms)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
GetFoundAccountCreationForms()57 const std::vector<autofill::FormData>& GetFoundAccountCreationForms() {
58 return found_account_creation_forms_;
59 }
set_is_off_the_record(bool is_off_the_record)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
72 class TestPasswordManagerClient : public StubPasswordManagerClient {
73 public:
TestPasswordManagerClient(scoped_ptr<PrefService> prefs)74 TestPasswordManagerClient(scoped_ptr<PrefService> prefs)
75 : prefs_(prefs.Pass()), driver_(this), is_sync_enabled_(false) {}
76
PromptUserToSavePassword(PasswordFormManager * form_to_save)77 virtual void PromptUserToSavePassword(PasswordFormManager* form_to_save)
78 OVERRIDE {}
GetPasswordStore()79 virtual PasswordStore* GetPasswordStore() OVERRIDE { return NULL; }
GetPrefs()80 virtual PrefService* GetPrefs() OVERRIDE { return prefs_.get(); }
GetDriver()81 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
AuthenticateAutofillAndFillForm(scoped_ptr<autofill::PasswordFormFillData> fill_data)82 virtual void AuthenticateAutofillAndFillForm(
83 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {}
IsPasswordSyncEnabled()84 virtual bool IsPasswordSyncEnabled() OVERRIDE { return is_sync_enabled_; }
85
set_is_password_sync_enabled(bool enabled)86 void set_is_password_sync_enabled(bool enabled) {
87 is_sync_enabled_ = enabled;
88 }
89
90 private:
91 scoped_ptr<PrefService> prefs_;
92 TestPasswordManagerDriver driver_;
93 bool is_sync_enabled_;
94 };
95
96 // Unlike the base AutofillMetrics, exposes copy and assignment constructors,
97 // which are handy for briefer test code. The AutofillMetrics class is
98 // stateless, so this is safe.
99 class TestAutofillMetrics : public autofill::AutofillMetrics {
100 public:
TestAutofillMetrics()101 TestAutofillMetrics() {}
~TestAutofillMetrics()102 virtual ~TestAutofillMetrics() {}
103 };
104
105 } // anonymous namespace
106
107 class PasswordGenerationManagerTest : public testing::Test {
108 protected:
SetUp()109 virtual void SetUp() OVERRIDE {
110 // Construct a PrefService and register all necessary prefs before handing
111 // it off to |client_|, as the initialization flow of |client_| will
112 // indirectly cause those prefs to be immediately accessed.
113 scoped_ptr<TestingPrefServiceSimple> prefs(new TestingPrefServiceSimple());
114 prefs->registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
115 true);
116 client_.reset(new TestPasswordManagerClient(prefs.PassAs<PrefService>()));
117 }
118
TearDown()119 virtual void TearDown() OVERRIDE { client_.reset(); }
120
GetGenerationManager()121 PasswordGenerationManager* GetGenerationManager() {
122 return client_->GetDriver()->GetPasswordGenerationManager();
123 }
124
GetTestDriver()125 TestPasswordManagerDriver* GetTestDriver() {
126 return static_cast<TestPasswordManagerDriver*>(client_->GetDriver());
127 }
128
IsGenerationEnabled()129 bool IsGenerationEnabled() {
130 return GetGenerationManager()->IsGenerationEnabled();
131 }
132
DetectAccountCreationForms(const std::vector<autofill::FormStructure * > & forms)133 void DetectAccountCreationForms(
134 const std::vector<autofill::FormStructure*>& forms) {
135 GetGenerationManager()->DetectAccountCreationForms(forms);
136 }
137
138 scoped_ptr<TestPasswordManagerClient> client_;
139 };
140
TEST_F(PasswordGenerationManagerTest,IsGenerationEnabled)141 TEST_F(PasswordGenerationManagerTest, IsGenerationEnabled) {
142 // Enabling the PasswordManager and password sync should cause generation to
143 // be enabled.
144 PrefService* prefs = client_->GetPrefs();
145 prefs->SetBoolean(prefs::kPasswordManagerEnabled, true);
146 client_->set_is_password_sync_enabled(true);
147 EXPECT_TRUE(IsGenerationEnabled());
148
149 // Disabling password syncing should cause generation to be disabled.
150 client_->set_is_password_sync_enabled(false);
151 EXPECT_FALSE(IsGenerationEnabled());
152
153 // Disabling the PasswordManager should cause generation to be disabled even
154 // if syncing is enabled.
155 prefs->SetBoolean(prefs::kPasswordManagerEnabled, false);
156 client_->set_is_password_sync_enabled(true);
157 EXPECT_FALSE(IsGenerationEnabled());
158 }
159
TEST_F(PasswordGenerationManagerTest,DetectAccountCreationForms)160 TEST_F(PasswordGenerationManagerTest, DetectAccountCreationForms) {
161 // Setup so that IsGenerationEnabled() returns true.
162 PrefService* prefs = client_->GetPrefs();
163 prefs->SetBoolean(prefs::kPasswordManagerEnabled, true);
164 client_->set_is_password_sync_enabled(true);
165
166 autofill::FormData login_form;
167 login_form.origin = GURL("http://www.yahoo.com/login/");
168 autofill::FormFieldData username;
169 username.label = ASCIIToUTF16("username");
170 username.name = ASCIIToUTF16("login");
171 username.form_control_type = "text";
172 login_form.fields.push_back(username);
173 autofill::FormFieldData password;
174 password.label = ASCIIToUTF16("password");
175 password.name = ASCIIToUTF16("password");
176 password.form_control_type = "password";
177 login_form.fields.push_back(password);
178 autofill::FormStructure form1(login_form);
179 std::vector<autofill::FormStructure*> forms;
180 forms.push_back(&form1);
181 autofill::FormData account_creation_form;
182 account_creation_form.origin = GURL("http://accounts.yahoo.com/");
183 account_creation_form.fields.push_back(username);
184 account_creation_form.fields.push_back(password);
185 autofill::FormFieldData confirm_password;
186 confirm_password.label = ASCIIToUTF16("confirm_password");
187 confirm_password.name = ASCIIToUTF16("password");
188 confirm_password.form_control_type = "password";
189 account_creation_form.fields.push_back(confirm_password);
190 autofill::FormStructure form2(account_creation_form);
191 forms.push_back(&form2);
192
193 // Simulate the server response to set the field types.
194 const char* const kServerResponse =
195 "<autofillqueryresponse>"
196 "<field autofilltype=\"9\" />"
197 "<field autofilltype=\"75\" />"
198 "<field autofilltype=\"9\" />"
199 "<field autofilltype=\"76\" />"
200 "<field autofilltype=\"75\" />"
201 "</autofillqueryresponse>";
202 autofill::FormStructure::ParseQueryResponse(
203 kServerResponse, forms, TestAutofillMetrics());
204
205 DetectAccountCreationForms(forms);
206 EXPECT_EQ(1u, GetTestDriver()->GetFoundAccountCreationForms().size());
207 EXPECT_EQ(GURL("http://accounts.yahoo.com/"),
208 GetTestDriver()->GetFoundAccountCreationForms()[0].origin);
209 }
210
TEST_F(PasswordGenerationManagerTest,UpdatePasswordSyncStateIncognito)211 TEST_F(PasswordGenerationManagerTest, UpdatePasswordSyncStateIncognito) {
212 // Disable password manager by going incognito. Even though password
213 // syncing is enabled, generation should still
214 // be disabled.
215 GetTestDriver()->set_is_off_the_record(true);
216 PrefService* prefs = client_->GetPrefs();
217 prefs->SetBoolean(prefs::kPasswordManagerEnabled, true);
218 client_->set_is_password_sync_enabled(true);
219
220 EXPECT_FALSE(IsGenerationEnabled());
221 }
222
223 } // namespace password_manager
224