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