autocomplete_history_manager_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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 <vector>
6
7#include "base/memory/ref_counted.h"
8#include "base/prefs/testing_pref_service.h"
9#include "base/run_loop.h"
10#include "base/strings/string16.h"
11#include "base/strings/utf_string_conversions.h"
12#include "base/synchronization/waitable_event.h"
13#include "chrome/browser/webdata/web_data_service_factory.h"
14#include "chrome/test/base/chrome_render_view_host_test_harness.h"
15#include "chrome/test/base/testing_profile.h"
16#include "components/autofill/core/browser/autocomplete_history_manager.h"
17#include "components/autofill/core/browser/autofill_external_delegate.h"
18#include "components/autofill/core/browser/autofill_manager.h"
19#include "components/autofill/core/browser/test_autofill_driver.h"
20#include "components/autofill/core/browser/test_autofill_manager_delegate.h"
21#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
22#include "components/autofill/core/common/form_data.h"
23#include "components/webdata/common/web_data_service_test_util.h"
24#include "content/public/test/test_browser_thread.h"
25#include "content/public/test/test_utils.h"
26#include "testing/gmock/include/gmock/gmock.h"
27#include "testing/gtest/include/gtest/gtest.h"
28#include "ui/gfx/rect.h"
29
30using content::WebContents;
31using testing::_;
32
33namespace autofill {
34
35namespace {
36
37class MockWebDataService : public AutofillWebDataService {
38 public:
39  MockWebDataService()
40      : AutofillWebDataService() {
41    current_mock_web_data_service_ = this;
42  }
43
44  MOCK_METHOD1(AddFormFields, void(const std::vector<FormFieldData>&));
45
46  static scoped_refptr<MockWebDataService> GetCurrent() {
47    if (!current_mock_web_data_service_) {
48      return new MockWebDataService();
49    }
50    return current_mock_web_data_service_;
51  }
52
53 protected:
54  virtual ~MockWebDataService() {}
55
56 private:
57  // Keep track of the most recently created instance, so that it can be
58  // associated with the current profile when Build() is called.
59  static MockWebDataService* current_mock_web_data_service_;
60};
61
62MockWebDataService* MockWebDataService::current_mock_web_data_service_ = NULL;
63
64class MockWebDataServiceWrapperCurrent : public MockWebDataServiceWrapperBase {
65 public:
66  static BrowserContextKeyedService* Build(content::BrowserContext* profile) {
67    return new MockWebDataServiceWrapperCurrent();
68  }
69
70  MockWebDataServiceWrapperCurrent() {}
71
72  virtual scoped_refptr<AutofillWebDataService> GetAutofillWebData() OVERRIDE {
73    return MockWebDataService::GetCurrent();
74  }
75
76 private:
77  DISALLOW_COPY_AND_ASSIGN(MockWebDataServiceWrapperCurrent);
78};
79
80class MockAutofillManagerDelegate
81    : public autofill::TestAutofillManagerDelegate {
82 public:
83  MockAutofillManagerDelegate() {}
84  virtual ~MockAutofillManagerDelegate() {}
85  virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
86
87 private:
88  TestingPrefServiceSimple prefs_;
89
90  DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate);
91};
92
93}  // namespace
94
95class AutocompleteHistoryManagerTest : public ChromeRenderViewHostTestHarness {
96 protected:
97  virtual void SetUp() OVERRIDE {
98    ChromeRenderViewHostTestHarness::SetUp();
99    web_data_service_ = new MockWebDataService();
100    WebDataServiceFactory::GetInstance()->SetTestingFactory(
101        profile(), MockWebDataServiceWrapperCurrent::Build);
102    autofill_driver_.reset(new TestAutofillDriver(web_contents()));
103    autocomplete_manager_.reset(
104        new AutocompleteHistoryManager(autofill_driver_.get(),
105                                       &manager_delegate));
106  }
107
108  virtual void TearDown() OVERRIDE {
109    autocomplete_manager_.reset();
110    web_data_service_ = NULL;
111    ChromeRenderViewHostTestHarness::TearDown();
112  }
113
114  scoped_refptr<MockWebDataService> web_data_service_;
115  scoped_ptr<AutocompleteHistoryManager> autocomplete_manager_;
116  scoped_ptr<AutofillDriver> autofill_driver_;
117  MockAutofillManagerDelegate manager_delegate;
118};
119
120// Tests that credit card numbers are not sent to the WebDatabase to be saved.
121TEST_F(AutocompleteHistoryManagerTest, CreditCardNumberValue) {
122  FormData form;
123  form.name = ASCIIToUTF16("MyForm");
124  form.method = ASCIIToUTF16("POST");
125  form.origin = GURL("http://myform.com/form.html");
126  form.action = GURL("http://myform.com/submit.html");
127  form.user_submitted = true;
128
129  // Valid Visa credit card number pulled from the paypal help site.
130  FormFieldData valid_cc;
131  valid_cc.label = ASCIIToUTF16("Credit Card");
132  valid_cc.name = ASCIIToUTF16("ccnum");
133  valid_cc.value = ASCIIToUTF16("4012888888881881");
134  valid_cc.form_control_type = "text";
135  form.fields.push_back(valid_cc);
136
137  EXPECT_CALL(*web_data_service_.get(), AddFormFields(_)).Times(0);
138  autocomplete_manager_->OnFormSubmitted(form);
139}
140
141// Contrary test to AutocompleteHistoryManagerTest.CreditCardNumberValue.  The
142// value being submitted is not a valid credit card number, so it will be sent
143// to the WebDatabase to be saved.
144TEST_F(AutocompleteHistoryManagerTest, NonCreditCardNumberValue) {
145  FormData form;
146  form.name = ASCIIToUTF16("MyForm");
147  form.method = ASCIIToUTF16("POST");
148  form.origin = GURL("http://myform.com/form.html");
149  form.action = GURL("http://myform.com/submit.html");
150  form.user_submitted = true;
151
152  // Invalid credit card number.
153  FormFieldData invalid_cc;
154  invalid_cc.label = ASCIIToUTF16("Credit Card");
155  invalid_cc.name = ASCIIToUTF16("ccnum");
156  invalid_cc.value = ASCIIToUTF16("4580123456789012");
157  invalid_cc.form_control_type = "text";
158  form.fields.push_back(invalid_cc);
159
160  EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(1);
161  autocomplete_manager_->OnFormSubmitted(form);
162}
163
164// Tests that SSNs are not sent to the WebDatabase to be saved.
165TEST_F(AutocompleteHistoryManagerTest, SSNValue) {
166  FormData form;
167  form.name = ASCIIToUTF16("MyForm");
168  form.method = ASCIIToUTF16("POST");
169  form.origin = GURL("http://myform.com/form.html");
170  form.action = GURL("http://myform.com/submit.html");
171  form.user_submitted = true;
172
173  FormFieldData ssn;
174  ssn.label = ASCIIToUTF16("Social Security Number");
175  ssn.name = ASCIIToUTF16("ssn");
176  ssn.value = ASCIIToUTF16("078-05-1120");
177  ssn.form_control_type = "text";
178  form.fields.push_back(ssn);
179
180  EXPECT_CALL(*web_data_service_.get(), AddFormFields(_)).Times(0);
181  autocomplete_manager_->OnFormSubmitted(form);
182}
183
184// Verify that autocomplete text is saved for search fields.
185TEST_F(AutocompleteHistoryManagerTest, SearchField) {
186  FormData form;
187  form.name = ASCIIToUTF16("MyForm");
188  form.method = ASCIIToUTF16("POST");
189  form.origin = GURL("http://myform.com/form.html");
190  form.action = GURL("http://myform.com/submit.html");
191  form.user_submitted = true;
192
193  // Search field.
194  FormFieldData search_field;
195  search_field.label = ASCIIToUTF16("Search");
196  search_field.name = ASCIIToUTF16("search");
197  search_field.value = ASCIIToUTF16("my favorite query");
198  search_field.form_control_type = "search";
199  form.fields.push_back(search_field);
200
201  EXPECT_CALL(*(web_data_service_.get()), AddFormFields(_)).Times(1);
202  autocomplete_manager_->OnFormSubmitted(form);
203}
204
205namespace {
206
207class MockAutofillExternalDelegate : public AutofillExternalDelegate {
208 public:
209  MockAutofillExternalDelegate(content::WebContents* web_contents,
210                               AutofillManager* autofill_manager,
211                               AutofillDriver* autofill_driver)
212      : AutofillExternalDelegate(web_contents, autofill_manager,
213                                 autofill_driver) {}
214  virtual ~MockAutofillExternalDelegate() {}
215
216  MOCK_METHOD5(OnSuggestionsReturned,
217               void(int query_id,
218                    const std::vector<base::string16>& autofill_values,
219                    const std::vector<base::string16>& autofill_labels,
220                    const std::vector<base::string16>& autofill_icons,
221                    const std::vector<int>& autofill_unique_ids));
222
223 private:
224  DISALLOW_COPY_AND_ASSIGN(MockAutofillExternalDelegate);
225};
226
227class AutocompleteHistoryManagerNoIPC : public AutocompleteHistoryManager {
228  public:
229   AutocompleteHistoryManagerNoIPC(AutofillDriver* driver,
230                                   AutofillManagerDelegate* delegate)
231       : AutocompleteHistoryManager(driver, delegate) {
232     // Ensure that IPC is not sent during the test.
233     set_send_ipc(false);
234   }
235
236  using AutocompleteHistoryManager::SendSuggestions;
237};
238
239}  // namespace
240
241// Make sure our external delegate is called at the right time.
242TEST_F(AutocompleteHistoryManagerTest, ExternalDelegate) {
243  AutocompleteHistoryManagerNoIPC autocomplete_history_manager(
244      autofill_driver_.get(), &manager_delegate);
245
246  scoped_ptr<AutofillManager> autofill_manager(new AutofillManager(
247      autofill_driver_.get(),
248      &manager_delegate,
249      "en-US",
250      AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER));
251
252  MockAutofillExternalDelegate external_delegate(web_contents(),
253                                                 autofill_manager.get(),
254                                                 autofill_driver_.get());
255  autocomplete_history_manager.SetExternalDelegate(&external_delegate);
256
257  // Should trigger a call to OnSuggestionsReturned, verified by the mock.
258  EXPECT_CALL(external_delegate, OnSuggestionsReturned(_, _, _, _, _));
259  autocomplete_history_manager.SendSuggestions(NULL);
260}
261
262}  // namespace autofill
263