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 30 using content::WebContents; 31 using testing::_; 32 33 namespace autofill { 34 35 namespace { 36 37 class 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 62 MockWebDataService* MockWebDataService::current_mock_web_data_service_ = NULL; 63 64 class 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 80 class 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 95 class 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. 121 TEST_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. 144 TEST_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. 165 TEST_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. 185 TEST_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 205 namespace { 206 207 class 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 227 class 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. 242 TEST_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