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 27 using base::ASCIIToUTF16; 28 using testing::_; 29 30 namespace autofill { 31 32 namespace { 33 34 class 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 46 class 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 65 class 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. 89 TEST_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. 111 TEST_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. 131 TEST_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. 150 TEST_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 169 namespace { 170 171 class 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 189 class 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. 200 TEST_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. 220 TEST_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