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