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