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