• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 "base/compiler_specific.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/autofill/core/browser/popup_item_ids.h"
9 #include "components/autofill/core/browser/test_autofill_client.h"
10 #include "components/autofill/core/browser/test_autofill_driver.h"
11 #include "components/password_manager/core/browser/password_autofill_manager.h"
12 #include "components/password_manager/core/browser/stub_password_manager_client.h"
13 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/gfx/geometry/rect_f.h"
17 
18 // The name of the username/password element in the form.
19 const char kUsernameName[] = "username";
20 const char kInvalidUsername[] = "no-username";
21 const char kPasswordName[] = "password";
22 
23 const char kAliceUsername[] = "alice";
24 const char kAlicePassword[] = "password";
25 
26 using testing::_;
27 
28 namespace autofill {
29 class AutofillPopupDelegate;
30 }
31 
32 namespace password_manager {
33 
34 namespace {
35 
36 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
37  public:
38   MOCK_METHOD2(FillSuggestion,
39                void(const base::string16&, const base::string16&));
40   MOCK_METHOD2(PreviewSuggestion,
41                void(const base::string16&, const base::string16&));
42 };
43 
44 class TestPasswordManagerClient : public StubPasswordManagerClient {
45  public:
GetDriver()46   virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
47 
mock_driver()48   MockPasswordManagerDriver* mock_driver() { return &driver_; }
49 
50  private:
51   MockPasswordManagerDriver driver_;
52 };
53 
54 class MockAutofillClient : public autofill::TestAutofillClient {
55  public:
56   MOCK_METHOD7(ShowAutofillPopup,
57                void(const gfx::RectF& element_bounds,
58                     base::i18n::TextDirection text_direction,
59                     const std::vector<base::string16>& values,
60                     const std::vector<base::string16>& labels,
61                     const std::vector<base::string16>& icons,
62                     const std::vector<int>& identifiers,
63                     base::WeakPtr<autofill::AutofillPopupDelegate> delegate));
64   MOCK_METHOD0(HideAutofillPopup, void());
65 };
66 
67 }  // namespace
68 
69 class PasswordAutofillManagerTest : public testing::Test {
70  protected:
PasswordAutofillManagerTest()71   PasswordAutofillManagerTest()
72       : test_username_(base::ASCIIToUTF16(kAliceUsername)),
73         test_password_(base::ASCIIToUTF16(kAlicePassword)) {}
74 
SetUp()75   virtual void SetUp() OVERRIDE {
76     // Add a preferred login and an additional login to the FillData.
77     username_field_.name = base::ASCIIToUTF16(kUsernameName);
78     username_field_.value = test_username_;
79     fill_data_.basic_data.fields.push_back(username_field_);
80 
81     autofill::FormFieldData password_field;
82     password_field.name = base::ASCIIToUTF16(kPasswordName);
83     password_field.value = test_password_;
84     fill_data_.basic_data.fields.push_back(password_field);
85   }
86 
InitializePasswordAutofillManager(PasswordManagerClient * client,autofill::AutofillClient * autofill_client)87   void InitializePasswordAutofillManager(
88       PasswordManagerClient* client,
89       autofill::AutofillClient* autofill_client) {
90     password_autofill_manager_.reset(
91         new PasswordAutofillManager(client, autofill_client));
92     password_autofill_manager_->OnAddPasswordFormMapping(username_field_,
93                                                          fill_data_);
94   }
95 
96  protected:
97   scoped_ptr<PasswordAutofillManager> password_autofill_manager_;
98 
99   autofill::FormFieldData username_field_;
100   base::string16 test_username_;
101   base::string16 test_password_;
102 
103  private:
104   autofill::PasswordFormFillData fill_data_;
105 
106   // The TestAutofillDriver uses a SequencedWorkerPool which expects the
107   // existence of a MessageLoop.
108   base::MessageLoop message_loop_;
109 };
110 
TEST_F(PasswordAutofillManagerTest,FillSuggestion)111 TEST_F(PasswordAutofillManagerTest, FillSuggestion) {
112   scoped_ptr<TestPasswordManagerClient> client(new TestPasswordManagerClient);
113   InitializePasswordAutofillManager(client.get(), NULL);
114 
115   EXPECT_CALL(*client->mock_driver(),
116               FillSuggestion(test_username_, test_password_));
117   EXPECT_TRUE(password_autofill_manager_->FillSuggestionForTest(
118       username_field_, test_username_));
119   testing::Mock::VerifyAndClearExpectations(client->mock_driver());
120 
121   EXPECT_CALL(*client->mock_driver(),
122               FillSuggestion(_, _)).Times(0);
123   EXPECT_FALSE(password_autofill_manager_->FillSuggestionForTest(
124       username_field_, base::ASCIIToUTF16(kInvalidUsername)));
125 
126   autofill::FormFieldData invalid_username_field;
127   invalid_username_field.name = base::ASCIIToUTF16(kInvalidUsername);
128 
129   EXPECT_FALSE(password_autofill_manager_->FillSuggestionForTest(
130       invalid_username_field, test_username_));
131 
132   password_autofill_manager_->Reset();
133   EXPECT_FALSE(password_autofill_manager_->FillSuggestionForTest(
134       username_field_, test_username_));
135 }
136 
TEST_F(PasswordAutofillManagerTest,PreviewSuggestion)137 TEST_F(PasswordAutofillManagerTest, PreviewSuggestion) {
138   scoped_ptr<TestPasswordManagerClient> client(new TestPasswordManagerClient);
139   InitializePasswordAutofillManager(client.get(), NULL);
140 
141   EXPECT_CALL(*client->mock_driver(),
142               PreviewSuggestion(test_username_, test_password_));
143   EXPECT_TRUE(password_autofill_manager_->PreviewSuggestionForTest(
144       username_field_, test_username_));
145   testing::Mock::VerifyAndClearExpectations(client->mock_driver());
146 
147   EXPECT_CALL(*client->mock_driver(), PreviewSuggestion(_, _)).Times(0);
148   EXPECT_FALSE(password_autofill_manager_->PreviewSuggestionForTest(
149       username_field_, base::ASCIIToUTF16(kInvalidUsername)));
150 
151   autofill::FormFieldData invalid_username_field;
152   invalid_username_field.name = base::ASCIIToUTF16(kInvalidUsername);
153 
154   EXPECT_FALSE(password_autofill_manager_->PreviewSuggestionForTest(
155       invalid_username_field, test_username_));
156 
157   password_autofill_manager_->Reset();
158   EXPECT_FALSE(password_autofill_manager_->PreviewSuggestionForTest(
159       username_field_, test_username_));
160 }
161 
162 // Test that the popup is marked as visible after recieving password
163 // suggestions.
TEST_F(PasswordAutofillManagerTest,ExternalDelegatePasswordSuggestions)164 TEST_F(PasswordAutofillManagerTest, ExternalDelegatePasswordSuggestions) {
165   scoped_ptr<TestPasswordManagerClient> client(new TestPasswordManagerClient);
166   scoped_ptr<MockAutofillClient> autofill_client(new MockAutofillClient);
167   InitializePasswordAutofillManager(client.get(), autofill_client.get());
168 
169   gfx::RectF element_bounds;
170   std::vector<base::string16> suggestions;
171   suggestions.push_back(test_username_);
172   std::vector<base::string16> realms;
173   realms.push_back(base::ASCIIToUTF16("http://foo.com/"));
174 
175   // The enums must be cast to ints to prevent compile errors on linux_rel.
176   EXPECT_CALL(*autofill_client,
177               ShowAutofillPopup(
178                   _,
179                   _,
180                   _,
181                   _,
182                   _,
183                   testing::ElementsAre(autofill::POPUP_ITEM_ID_PASSWORD_ENTRY),
184                   _));
185   password_autofill_manager_->OnShowPasswordSuggestions(
186       username_field_, element_bounds, suggestions, realms);
187 
188   // Accepting a suggestion should trigger a call to hide the popup.
189   EXPECT_CALL(*autofill_client, HideAutofillPopup());
190   password_autofill_manager_->DidAcceptSuggestion(
191       suggestions[0], autofill::POPUP_ITEM_ID_PASSWORD_ENTRY);
192 }
193 
194 }  // namespace password_manager
195