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