1 // Copyright (c) 2012 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 <string> 6 7 #include "base/basictypes.h" 8 #include "base/command_line.h" 9 #include "base/files/file_util.h" 10 #include "base/memory/ref_counted.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/rand_util.h" 13 #include "base/strings/string16.h" 14 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_split.h" 16 #include "base/strings/utf_string_conversions.h" 17 #include "base/time/time.h" 18 #include "chrome/browser/autofill/personal_data_manager_factory.h" 19 #include "chrome/browser/infobars/infobar_service.h" 20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/ui/browser.h" 22 #include "chrome/browser/ui/browser_window.h" 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" 24 #include "chrome/common/render_messages.h" 25 #include "chrome/test/base/in_process_browser_test.h" 26 #include "chrome/test/base/test_switches.h" 27 #include "chrome/test/base/ui_test_utils.h" 28 #include "components/autofill/content/browser/content_autofill_driver.h" 29 #include "components/autofill/core/browser/autofill_profile.h" 30 #include "components/autofill/core/browser/autofill_test_utils.h" 31 #include "components/autofill/core/browser/credit_card.h" 32 #include "components/autofill/core/browser/personal_data_manager.h" 33 #include "components/autofill/core/browser/personal_data_manager_observer.h" 34 #include "components/autofill/core/browser/validation.h" 35 #include "components/infobars/core/confirm_infobar_delegate.h" 36 #include "components/infobars/core/infobar.h" 37 #include "components/infobars/core/infobar_manager.h" 38 #include "content/public/browser/navigation_controller.h" 39 #include "content/public/browser/render_view_host.h" 40 #include "content/public/browser/web_contents.h" 41 #include "content/public/test/browser_test_utils.h" 42 #include "content/public/test/test_renderer_host.h" 43 #include "content/public/test/test_utils.h" 44 #include "net/url_request/test_url_fetcher_factory.h" 45 #include "testing/gmock/include/gmock/gmock.h" 46 #include "testing/gtest/include/gtest/gtest.h" 47 #include "ui/events/keycodes/keyboard_codes.h" 48 49 using base::ASCIIToUTF16; 50 using base::UTF16ToASCII; 51 using base::WideToUTF16; 52 53 namespace autofill { 54 55 class WindowedPersonalDataManagerObserver 56 : public PersonalDataManagerObserver, 57 public infobars::InfoBarManager::Observer { 58 public: 59 explicit WindowedPersonalDataManagerObserver(Browser* browser) 60 : alerted_(false), 61 has_run_message_loop_(false), 62 browser_(browser), 63 infobar_service_(InfoBarService::FromWebContents( 64 browser_->tab_strip_model()->GetActiveWebContents())) { 65 PersonalDataManagerFactory::GetForProfile(browser_->profile())-> 66 AddObserver(this); 67 infobar_service_->AddObserver(this); 68 } 69 70 virtual ~WindowedPersonalDataManagerObserver() { 71 infobar_service_->RemoveObserver(this); 72 73 if (infobar_service_->infobar_count() > 0) { 74 infobar_service_->RemoveInfoBar(infobar_service_->infobar_at(0)); 75 } 76 } 77 78 void Wait() { 79 if (!alerted_) { 80 has_run_message_loop_ = true; 81 content::RunMessageLoop(); 82 } 83 PersonalDataManagerFactory::GetForProfile(browser_->profile())-> 84 RemoveObserver(this); 85 } 86 87 // PersonalDataManagerObserver: 88 virtual void OnPersonalDataChanged() OVERRIDE { 89 if (has_run_message_loop_) { 90 base::MessageLoopForUI::current()->Quit(); 91 has_run_message_loop_ = false; 92 } 93 alerted_ = true; 94 } 95 96 virtual void OnInsufficientFormData() OVERRIDE { 97 OnPersonalDataChanged(); 98 } 99 100 // infobars::InfoBarManager::Observer: 101 virtual void OnInfoBarAdded(infobars::InfoBar* infobar) OVERRIDE { 102 ConfirmInfoBarDelegate* infobar_delegate = 103 infobar_service_->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate(); 104 ASSERT_TRUE(infobar_delegate); 105 infobar_delegate->Accept(); 106 } 107 108 private: 109 bool alerted_; 110 bool has_run_message_loop_; 111 Browser* browser_; 112 InfoBarService* infobar_service_; 113 }; 114 115 class AutofillTest : public InProcessBrowserTest { 116 protected: 117 AutofillTest() {} 118 119 virtual void SetUpOnMainThread() OVERRIDE { 120 // Don't want Keychain coming up on Mac. 121 test::DisableSystemServices(browser()->profile()->GetPrefs()); 122 } 123 124 virtual void TearDownOnMainThread() OVERRIDE { 125 // Make sure to close any showing popups prior to tearing down the UI. 126 content::WebContents* web_contents = 127 browser()->tab_strip_model()->GetActiveWebContents(); 128 AutofillManager* autofill_manager = ContentAutofillDriver::FromWebContents( 129 web_contents)->autofill_manager(); 130 autofill_manager->client()->HideAutofillPopup(); 131 } 132 133 PersonalDataManager* personal_data_manager() { 134 return PersonalDataManagerFactory::GetForProfile(browser()->profile()); 135 } 136 137 void SetProfiles(std::vector<AutofillProfile>* profiles) { 138 WindowedPersonalDataManagerObserver observer(browser()); 139 personal_data_manager()->SetProfiles(profiles); 140 observer.Wait(); 141 } 142 143 void SetProfile(const AutofillProfile& profile) { 144 std::vector<AutofillProfile> profiles; 145 profiles.push_back(profile); 146 SetProfiles(&profiles); 147 } 148 149 void SetCards(std::vector<CreditCard>* cards) { 150 WindowedPersonalDataManagerObserver observer(browser()); 151 personal_data_manager()->SetCreditCards(cards); 152 observer.Wait(); 153 } 154 155 void SetCard(const CreditCard& card) { 156 std::vector<CreditCard> cards; 157 cards.push_back(card); 158 SetCards(&cards); 159 } 160 161 typedef std::map<std::string, std::string> FormMap; 162 // Navigate to the form, input values into the fields, and submit the form. 163 // The function returns after the PersonalDataManager is updated. 164 void FillFormAndSubmit(const std::string& filename, const FormMap& data) { 165 GURL url = test_server()->GetURL("files/autofill/" + filename); 166 chrome::NavigateParams params(browser(), url, 167 ui::PAGE_TRANSITION_LINK); 168 params.disposition = NEW_FOREGROUND_TAB; 169 ui_test_utils::NavigateToURL(¶ms); 170 171 std::string js; 172 for (FormMap::const_iterator i = data.begin(); i != data.end(); ++i) { 173 js += "document.getElementById('" + i->first + "').value = '" + 174 i->second + "';"; 175 } 176 js += "document.onclick = function() {" 177 " document.getElementById('testform').submit();" 178 "};"; 179 180 WindowedPersonalDataManagerObserver observer(browser()); 181 ASSERT_TRUE(content::ExecuteScript(render_view_host(), js)); 182 // Simulate a mouse click to submit the form because form submissions not 183 // triggered by user gestures are ignored. 184 content::SimulateMouseClick( 185 browser()->tab_strip_model()->GetActiveWebContents(), 0, 186 blink::WebMouseEvent::ButtonLeft); 187 observer.Wait(); 188 } 189 190 void SubmitCreditCard(const char* name, 191 const char* number, 192 const char* exp_month, 193 const char* exp_year) { 194 FormMap data; 195 data["CREDIT_CARD_NAME"] = name; 196 data["CREDIT_CARD_NUMBER"] = number; 197 data["CREDIT_CARD_EXP_MONTH"] = exp_month; 198 data["CREDIT_CARD_EXP_4_DIGIT_YEAR"] = exp_year; 199 FillFormAndSubmit("autofill_creditcard_form.html", data); 200 } 201 202 // Aggregate profiles from forms into Autofill preferences. Returns the number 203 // of parsed profiles. 204 int AggregateProfilesIntoAutofillPrefs(const std::string& filename) { 205 CHECK(test_server()->Start()); 206 207 std::string data; 208 base::FilePath data_file = 209 ui_test_utils::GetTestFilePath(base::FilePath().AppendASCII("autofill"), 210 base::FilePath().AppendASCII(filename)); 211 CHECK(base::ReadFileToString(data_file, &data)); 212 std::vector<std::string> lines; 213 base::SplitString(data, '\n', &lines); 214 int parsed_profiles = 0; 215 for (size_t i = 0; i < lines.size(); ++i) { 216 if (StartsWithASCII(lines[i], "#", false)) 217 continue; 218 219 std::vector<std::string> fields; 220 base::SplitString(lines[i], '|', &fields); 221 if (fields.empty()) 222 continue; // Blank line. 223 224 ++parsed_profiles; 225 CHECK_EQ(12u, fields.size()); 226 227 FormMap data; 228 data["NAME_FIRST"] = fields[0]; 229 data["NAME_MIDDLE"] = fields[1]; 230 data["NAME_LAST"] = fields[2]; 231 data["EMAIL_ADDRESS"] = fields[3]; 232 data["COMPANY_NAME"] = fields[4]; 233 data["ADDRESS_HOME_LINE1"] = fields[5]; 234 data["ADDRESS_HOME_LINE2"] = fields[6]; 235 data["ADDRESS_HOME_CITY"] = fields[7]; 236 data["ADDRESS_HOME_STATE"] = fields[8]; 237 data["ADDRESS_HOME_ZIP"] = fields[9]; 238 data["ADDRESS_HOME_COUNTRY"] = fields[10]; 239 data["PHONE_HOME_WHOLE_NUMBER"] = fields[11]; 240 241 FillFormAndSubmit("duplicate_profiles_test.html", data); 242 } 243 return parsed_profiles; 244 } 245 246 void ExpectFieldValue(const std::string& field_name, 247 const std::string& expected_value) { 248 std::string value; 249 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 250 browser()->tab_strip_model()->GetActiveWebContents(), 251 "window.domAutomationController.send(" 252 " document.getElementById('" + field_name + "').value);", 253 &value)); 254 EXPECT_EQ(expected_value, value); 255 } 256 257 content::RenderViewHost* render_view_host() { 258 return browser()->tab_strip_model()->GetActiveWebContents()-> 259 GetRenderViewHost(); 260 } 261 262 void ExpectFilledTestForm() { 263 ExpectFieldValue("firstname", "Milton"); 264 ExpectFieldValue("lastname", "Waddams"); 265 ExpectFieldValue("address1", "4120 Freidrich Lane"); 266 ExpectFieldValue("address2", "Basement"); 267 ExpectFieldValue("city", "Austin"); 268 ExpectFieldValue("state", "TX"); 269 ExpectFieldValue("zip", "78744"); 270 ExpectFieldValue("country", "US"); 271 ExpectFieldValue("phone", "5125551234"); 272 } 273 274 private: 275 net::TestURLFetcherFactory url_fetcher_factory_; 276 }; 277 278 // Test filling profiles with unicode strings and crazy characters. 279 // TODO(isherman): rewrite as unit test under PersonalDataManagerTest. 280 IN_PROC_BROWSER_TEST_F(AutofillTest, FillProfileCrazyCharacters) { 281 std::vector<AutofillProfile> profiles; 282 AutofillProfile profile1; 283 profile1.SetRawInfo(NAME_FIRST, 284 WideToUTF16(L"\u0623\u0648\u0628\u0627\u0645\u0627 " 285 L"\u064a\u0639\u062a\u0630\u0631 " 286 L"\u0647\u0627\u062a\u0641\u064a\u0627 " 287 L"\u0644\u0645\u0648\u0638\u0641\u0629 " 288 L"\u0633\u0648\u062f\u0627\u0621 " 289 L"\u0627\u0633\u062a\u0642\u0627\u0644\u062a " 290 L"\u0628\u0633\u0628\u0628 " 291 L"\u062a\u0635\u0631\u064a\u062d\u0627\u062a " 292 L"\u0645\u062c\u062a\u0632\u0623\u0629")); 293 profile1.SetRawInfo(NAME_MIDDLE, WideToUTF16(L"BANK\xcBERF\xc4LLE")); 294 profile1.SetRawInfo(EMAIL_ADDRESS, 295 WideToUTF16(L"\uacbd\uc81c \ub274\uc2a4 " 296 L"\ub354\ubcf4\uae30 (at) google.com")); 297 profile1.SetRawInfo(ADDRESS_HOME_LINE1, 298 WideToUTF16(L"\uad6d\uc815\uc6d0\xb7\uac80\ucc30, " 299 L"\ub178\ubb34\ud604\uc815\ubd80 " 300 L"\ub300\ubd81\uc811\ucd09 \ub2f4\ub2f9 " 301 L"\uc778\uc0ac\ub4e4 \uc870\uc0ac")); 302 profile1.SetRawInfo(ADDRESS_HOME_CITY, 303 WideToUTF16(L"\u653f\u5e9c\u4e0d\u6392\u9664\u7acb\u6cd5" 304 L"\u898f\u7ba1\u5c0e\u904a")); 305 profile1.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"YOHO_54676")); 306 profile1.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, WideToUTF16(L"861088828000")); 307 profile1.SetInfo( 308 AutofillType(ADDRESS_HOME_COUNTRY), WideToUTF16(L"India"), "en-US"); 309 profiles.push_back(profile1); 310 311 AutofillProfile profile2; 312 profile2.SetRawInfo(NAME_FIRST, 313 WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a " 314 L"\u677e\u9690\u9547\u4ead\u67ab\u516c" 315 L"\u8def1915\u53f7")); 316 profile2.SetRawInfo(NAME_LAST, WideToUTF16(L"aguant")); 317 profile2.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"HOME 94043")); 318 profiles.push_back(profile2); 319 320 AutofillProfile profile3; 321 profile3.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"sue (at) example.com")); 322 profile3.SetRawInfo(COMPANY_NAME, WideToUTF16(L"Company X")); 323 profiles.push_back(profile3); 324 325 AutofillProfile profile4; 326 profile4.SetRawInfo(NAME_FIRST, WideToUTF16(L"Joe 3254")); 327 profile4.SetRawInfo(NAME_LAST, WideToUTF16(L"\u8bb0\u8d262\u5e74\u591a")); 328 profile4.SetRawInfo(ADDRESS_HOME_ZIP, 329 WideToUTF16(L"\uff08\u90ae\u7f16\uff1a201504\uff09")); 330 profile4.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"tlvision (at) example.com")); 331 profile4.SetRawInfo(COMPANY_NAME, 332 WideToUTF16(L"\u0907\u0932\u0947\u0915\u093f\u091f\u094d" 333 L"\u0930\u0928\u093f\u0915\u094d\u0938, " 334 L"\u0905\u092a\u094b\u0932\u094b " 335 L"\u091f\u093e\u092f\u0930\u094d\u0938 " 336 L"\u0906\u0926\u093f")); 337 profiles.push_back(profile4); 338 339 AutofillProfile profile5; 340 profile5.SetRawInfo(NAME_FIRST, WideToUTF16(L"Larry")); 341 profile5.SetRawInfo(NAME_LAST, 342 WideToUTF16(L"\u0938\u094d\u091f\u093e\u0902\u092a " 343 L"\u0921\u094d\u092f\u0942\u091f\u0940")); 344 profile5.SetRawInfo(ADDRESS_HOME_ZIP, 345 WideToUTF16(L"111111111111110000GOOGLE")); 346 profile5.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"page (at) 000000.com")); 347 profile5.SetRawInfo(COMPANY_NAME, WideToUTF16(L"Google")); 348 profiles.push_back(profile5); 349 350 AutofillProfile profile6; 351 profile6.SetRawInfo(NAME_FIRST, 352 WideToUTF16(L"\u4e0a\u6d77\u5e02\u91d1\u5c71\u533a " 353 L"\u677e\u9690\u9547\u4ead\u67ab\u516c" 354 L"\u8def1915\u53f7")); 355 profile6.SetRawInfo(NAME_LAST, 356 WideToUTF16(L"\u0646\u062c\u0627\u0645\u064a\u0646\u0627 " 357 L"\u062f\u0639\u0645\u0647\u0627 " 358 L"\u0644\u0644\u0631\u0626\u064a\u0633 " 359 L"\u0627\u0644\u0633\u0648\u062f\u0627\u0646" 360 L"\u064a \u0639\u0645\u0631 " 361 L"\u0627\u0644\u0628\u0634\u064a\u0631")); 362 profile6.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"HOME 94043")); 363 profiles.push_back(profile6); 364 365 AutofillProfile profile7; 366 profile7.SetRawInfo(NAME_FIRST, WideToUTF16(L"&$%$$$ TESTO *&*&^&^& MOKO")); 367 profile7.SetRawInfo(NAME_MIDDLE, WideToUTF16(L"WOHOOOO$$$$$$$$****")); 368 profile7.SetRawInfo(EMAIL_ADDRESS, WideToUTF16(L"yuvu (at) example.com")); 369 profile7.SetRawInfo(ADDRESS_HOME_LINE1, 370 WideToUTF16(L"34544, anderson ST.(120230)")); 371 profile7.SetRawInfo(ADDRESS_HOME_CITY, WideToUTF16(L"Sunnyvale")); 372 profile7.SetRawInfo(ADDRESS_HOME_STATE, WideToUTF16(L"CA")); 373 profile7.SetRawInfo(ADDRESS_HOME_ZIP, WideToUTF16(L"94086")); 374 profile7.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, WideToUTF16(L"15466784565")); 375 profile7.SetInfo( 376 AutofillType(ADDRESS_HOME_COUNTRY), WideToUTF16(L"United States"), 377 "en-US"); 378 profiles.push_back(profile7); 379 380 SetProfiles(&profiles); 381 ASSERT_EQ(profiles.size(), personal_data_manager()->GetProfiles().size()); 382 for (size_t i = 0; i < profiles.size(); ++i) { 383 EXPECT_TRUE(std::find(profiles.begin(), 384 profiles.end(), 385 *personal_data_manager()->GetProfiles()[i]) != 386 profiles.end()); 387 } 388 389 std::vector<CreditCard> cards; 390 CreditCard card1; 391 card1.SetRawInfo(CREDIT_CARD_NAME, 392 WideToUTF16(L"\u751f\u6d3b\u5f88\u6709\u89c4\u5f8b " 393 L"\u4ee5\u73a9\u4e3a\u4e3b")); 394 card1.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"6011111111111117")); 395 card1.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"12")); 396 card1.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2011")); 397 cards.push_back(card1); 398 399 CreditCard card2; 400 card2.SetRawInfo(CREDIT_CARD_NAME, WideToUTF16(L"John Williams")); 401 card2.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"WokoAwesome12345")); 402 card2.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"10")); 403 card2.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2015")); 404 cards.push_back(card2); 405 406 CreditCard card3; 407 card3.SetRawInfo(CREDIT_CARD_NAME, 408 WideToUTF16(L"\u0623\u062d\u0645\u062f\u064a " 409 L"\u0646\u062c\u0627\u062f " 410 L"\u0644\u0645\u062d\u0627\u0648\u0644\u0647 " 411 L"\u0627\u063a\u062a\u064a\u0627\u0644 " 412 L"\u0641\u064a \u0645\u062f\u064a\u0646\u0629 " 413 L"\u0647\u0645\u062f\u0627\u0646 ")); 414 card3.SetRawInfo(CREDIT_CARD_NUMBER, 415 WideToUTF16(L"\u092a\u0941\u0928\u0930\u094d\u091c\u0940" 416 L"\u0935\u093f\u0924 \u0939\u094b\u0917\u093e " 417 L"\u0928\u093e\u0932\u0902\u0926\u093e")); 418 card3.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"10")); 419 card3.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2015")); 420 cards.push_back(card3); 421 422 CreditCard card4; 423 card4.SetRawInfo(CREDIT_CARD_NAME, 424 WideToUTF16(L"\u039d\u03ad\u03b5\u03c2 " 425 L"\u03c3\u03c5\u03b3\u03c7\u03c9\u03bd\u03b5" 426 L"\u03cd\u03c3\u03b5\u03b9\u03c2 " 427 L"\u03ba\u03b1\u03b9 " 428 L"\u03ba\u03b1\u03c4\u03b1\u03c1\u03b3\u03ae" 429 L"\u03c3\u03b5\u03b9\u03c2")); 430 card4.SetRawInfo(CREDIT_CARD_NUMBER, WideToUTF16(L"00000000000000000000000")); 431 card4.SetRawInfo(CREDIT_CARD_EXP_MONTH, WideToUTF16(L"01")); 432 card4.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, WideToUTF16(L"2016")); 433 cards.push_back(card4); 434 435 SetCards(&cards); 436 ASSERT_EQ(cards.size(), personal_data_manager()->GetCreditCards().size()); 437 for (size_t i = 0; i < cards.size(); ++i) { 438 EXPECT_TRUE(std::find(cards.begin(), 439 cards.end(), 440 *personal_data_manager()->GetCreditCards()[i]) != 441 cards.end()); 442 } 443 } 444 445 // Test filling in invalid values for profiles are saved as-is. Phone 446 // information entered into the prefs UI is not validated or rejected except for 447 // duplicates. 448 // TODO(isherman): rewrite as WebUI test? 449 IN_PROC_BROWSER_TEST_F(AutofillTest, Invalid) { 450 // First try profiles with invalid ZIP input. 451 AutofillProfile without_invalid; 452 without_invalid.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Will")); 453 without_invalid.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Sunnyvale")); 454 without_invalid.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA")); 455 without_invalid.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("my_zip")); 456 without_invalid.SetInfo( 457 AutofillType(ADDRESS_HOME_COUNTRY), ASCIIToUTF16("United States"), 458 "en-US"); 459 460 AutofillProfile with_invalid = without_invalid; 461 with_invalid.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, 462 ASCIIToUTF16("Invalid_Phone_Number")); 463 SetProfile(with_invalid); 464 465 ASSERT_EQ(1u, personal_data_manager()->GetProfiles().size()); 466 AutofillProfile profile = *personal_data_manager()->GetProfiles()[0]; 467 ASSERT_NE(without_invalid.GetRawInfo(PHONE_HOME_WHOLE_NUMBER), 468 profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); 469 } 470 471 // Test invalid credit card numbers typed in prefs should be saved as-is. 472 // TODO(isherman): rewrite as WebUI test? 473 IN_PROC_BROWSER_TEST_F(AutofillTest, PrefsStringSavedAsIs) { 474 CreditCard card; 475 card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("Not_0123-5Checked")); 476 SetCard(card); 477 478 ASSERT_EQ(1u, personal_data_manager()->GetCreditCards().size()); 479 ASSERT_EQ(card, *personal_data_manager()->GetCreditCards()[0]); 480 } 481 482 // Test credit card info with an invalid number is not aggregated. 483 // When filling out a form with an invalid credit card number (one that does not 484 // pass the Luhn test) the credit card info should not be saved into Autofill 485 // preferences. 486 IN_PROC_BROWSER_TEST_F(AutofillTest, InvalidCreditCardNumberIsNotAggregated) { 487 #if defined(OS_WIN) && defined(USE_ASH) 488 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 489 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 490 return; 491 #endif 492 493 ASSERT_TRUE(test_server()->Start()); 494 std::string card("4408 0412 3456 7890"); 495 ASSERT_FALSE(autofill::IsValidCreditCardNumber(ASCIIToUTF16(card))); 496 SubmitCreditCard("Bob Smith", card.c_str(), "12", "2014"); 497 InfoBarService* infobar_service = InfoBarService::FromWebContents( 498 browser()->tab_strip_model()->GetActiveWebContents()); 499 ASSERT_EQ(0u, infobar_service->infobar_count()); 500 } 501 502 // Test whitespaces and separator chars are stripped for valid CC numbers. 503 // The credit card numbers used in this test pass the Luhn test. For reference: 504 // http://www.merriampark.com/anatomycc.htm 505 IN_PROC_BROWSER_TEST_F(AutofillTest, 506 WhitespacesAndSeparatorCharsStrippedForValidCCNums) { 507 #if defined(OS_WIN) && defined(USE_ASH) 508 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 509 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 510 return; 511 #endif 512 513 ASSERT_TRUE(test_server()->Start()); 514 SubmitCreditCard("Bob Smith", "4408 0412 3456 7893", "12", "2014"); 515 SubmitCreditCard("Jane Doe", "4417-1234-5678-9113", "10", "2013"); 516 517 ASSERT_EQ(2u, personal_data_manager()->GetCreditCards().size()); 518 base::string16 cc1 = personal_data_manager()->GetCreditCards()[0]->GetRawInfo( 519 CREDIT_CARD_NUMBER); 520 ASSERT_TRUE(autofill::IsValidCreditCardNumber(cc1)); 521 base::string16 cc2 = personal_data_manager()->GetCreditCards()[1]->GetRawInfo( 522 CREDIT_CARD_NUMBER); 523 ASSERT_TRUE(autofill::IsValidCreditCardNumber(cc2)); 524 } 525 526 // Test that Autofill aggregates a minimum valid profile. 527 // The minimum required address fields must be specified: First Name, Last Name, 528 // Address Line 1, City, Zip Code, and State. 529 IN_PROC_BROWSER_TEST_F(AutofillTest, AggregatesMinValidProfile) { 530 ASSERT_TRUE(test_server()->Start()); 531 FormMap data; 532 data["NAME_FIRST"] = "Bob"; 533 data["NAME_LAST"] = "Smith"; 534 data["ADDRESS_HOME_LINE1"] = "1234 H St."; 535 data["ADDRESS_HOME_CITY"] = "Mountain View"; 536 data["ADDRESS_HOME_STATE"] = "CA"; 537 data["ADDRESS_HOME_ZIP"] = "94043"; 538 FillFormAndSubmit("duplicate_profiles_test.html", data); 539 540 ASSERT_EQ(1u, personal_data_manager()->GetProfiles().size()); 541 } 542 543 // Test Autofill does not aggregate profiles with no address info. 544 // The minimum required address fields must be specified: First Name, Last Name, 545 // Address Line 1, City, Zip Code, and State. 546 IN_PROC_BROWSER_TEST_F(AutofillTest, ProfilesNotAggregatedWithNoAddress) { 547 ASSERT_TRUE(test_server()->Start()); 548 FormMap data; 549 data["NAME_FIRST"] = "Bob"; 550 data["NAME_LAST"] = "Smith"; 551 data["EMAIL_ADDRESS"] = "bsmith (at) example.com"; 552 data["COMPANY_NAME"] = "Mountain View"; 553 data["ADDRESS_HOME_CITY"] = "Mountain View"; 554 data["PHONE_HOME_WHOLE_NUMBER"] = "650-555-4567"; 555 FillFormAndSubmit("duplicate_profiles_test.html", data); 556 557 ASSERT_TRUE(personal_data_manager()->GetProfiles().empty()); 558 } 559 560 // Test Autofill does not aggregate profiles with an invalid email. 561 IN_PROC_BROWSER_TEST_F(AutofillTest, ProfilesNotAggregatedWithInvalidEmail) { 562 ASSERT_TRUE(test_server()->Start()); 563 FormMap data; 564 data["NAME_FIRST"] = "Bob"; 565 data["NAME_LAST"] = "Smith"; 566 data["EMAIL_ADDRESS"] = "garbage"; 567 data["ADDRESS_HOME_LINE1"] = "1234 H St."; 568 data["ADDRESS_HOME_CITY"] = "San Jose"; 569 data["ADDRESS_HOME_STATE"] = "CA"; 570 data["ADDRESS_HOME_ZIP"] = "95110"; 571 data["COMPANY_NAME"] = "Company X"; 572 data["PHONE_HOME_WHOLE_NUMBER"] = "408-871-4567"; 573 FillFormAndSubmit("duplicate_profiles_test.html", data); 574 575 ASSERT_TRUE(personal_data_manager()->GetProfiles().empty()); 576 } 577 578 // Test profile is saved if phone number is valid in selected country. 579 // The data file contains two profiles with valid phone numbers and two 580 // profiles with invalid phone numbers from their respective country. 581 IN_PROC_BROWSER_TEST_F(AutofillTest, ProfileSavedWithValidCountryPhone) { 582 ASSERT_TRUE(test_server()->Start()); 583 std::vector<FormMap> profiles; 584 585 FormMap data1; 586 data1["NAME_FIRST"] = "Bob"; 587 data1["NAME_LAST"] = "Smith"; 588 data1["ADDRESS_HOME_LINE1"] = "123 Cherry Ave"; 589 data1["ADDRESS_HOME_CITY"] = "Mountain View"; 590 data1["ADDRESS_HOME_STATE"] = "CA"; 591 data1["ADDRESS_HOME_ZIP"] = "94043"; 592 data1["ADDRESS_HOME_COUNTRY"] = "United States"; 593 data1["PHONE_HOME_WHOLE_NUMBER"] = "408-871-4567"; 594 profiles.push_back(data1); 595 596 FormMap data2; 597 data2["NAME_FIRST"] = "John"; 598 data2["NAME_LAST"] = "Doe"; 599 data2["ADDRESS_HOME_LINE1"] = "987 H St"; 600 data2["ADDRESS_HOME_CITY"] = "San Jose"; 601 data2["ADDRESS_HOME_STATE"] = "CA"; 602 data2["ADDRESS_HOME_ZIP"] = "95510"; 603 data2["ADDRESS_HOME_COUNTRY"] = "United States"; 604 data2["PHONE_HOME_WHOLE_NUMBER"] = "408-123-456"; 605 profiles.push_back(data2); 606 607 FormMap data3; 608 data3["NAME_FIRST"] = "Jane"; 609 data3["NAME_LAST"] = "Doe"; 610 data3["ADDRESS_HOME_LINE1"] = "1523 Garcia St"; 611 data3["ADDRESS_HOME_CITY"] = "Mountain View"; 612 data3["ADDRESS_HOME_STATE"] = "CA"; 613 data3["ADDRESS_HOME_ZIP"] = "94043"; 614 data3["ADDRESS_HOME_COUNTRY"] = "Germany"; 615 data3["PHONE_HOME_WHOLE_NUMBER"] = "+49 40-80-81-79-000"; 616 profiles.push_back(data3); 617 618 FormMap data4; 619 data4["NAME_FIRST"] = "Bonnie"; 620 data4["NAME_LAST"] = "Smith"; 621 data4["ADDRESS_HOME_LINE1"] = "6723 Roadway Rd"; 622 data4["ADDRESS_HOME_CITY"] = "San Jose"; 623 data4["ADDRESS_HOME_STATE"] = "CA"; 624 data4["ADDRESS_HOME_ZIP"] = "95510"; 625 data4["ADDRESS_HOME_COUNTRY"] = "Germany"; 626 data4["PHONE_HOME_WHOLE_NUMBER"] = "+21 08450 777 777"; 627 profiles.push_back(data4); 628 629 for (size_t i = 0; i < profiles.size(); ++i) 630 FillFormAndSubmit("autofill_test_form.html", profiles[i]); 631 632 ASSERT_EQ(2u, personal_data_manager()->GetProfiles().size()); 633 int us_address_index = 634 personal_data_manager()->GetProfiles()[0]->GetRawInfo( 635 ADDRESS_HOME_LINE1) == ASCIIToUTF16("123 Cherry Ave") 636 ? 0 637 : 1; 638 639 EXPECT_EQ( 640 ASCIIToUTF16("408-871-4567"), 641 personal_data_manager()->GetProfiles()[us_address_index]->GetRawInfo( 642 PHONE_HOME_WHOLE_NUMBER)); 643 ASSERT_EQ( 644 ASCIIToUTF16("+49 40-80-81-79-000"), 645 personal_data_manager()->GetProfiles()[1 - us_address_index]->GetRawInfo( 646 PHONE_HOME_WHOLE_NUMBER)); 647 } 648 649 // Prepend country codes when formatting phone numbers, but only if the user 650 // provided one in the first place. 651 IN_PROC_BROWSER_TEST_F(AutofillTest, AppendCountryCodeForAggregatedPhones) { 652 ASSERT_TRUE(test_server()->Start()); 653 FormMap data; 654 data["NAME_FIRST"] = "Bob"; 655 data["NAME_LAST"] = "Smith"; 656 data["ADDRESS_HOME_LINE1"] = "1234 H St."; 657 data["ADDRESS_HOME_CITY"] = "San Jose"; 658 data["ADDRESS_HOME_STATE"] = "CA"; 659 data["ADDRESS_HOME_ZIP"] = "95110"; 660 data["ADDRESS_HOME_COUNTRY"] = "Germany"; 661 data["PHONE_HOME_WHOLE_NUMBER"] = "+4908450777777"; 662 FillFormAndSubmit("autofill_test_form.html", data); 663 664 data["ADDRESS_HOME_LINE1"] = "4321 H St."; 665 data["PHONE_HOME_WHOLE_NUMBER"] = "08450777777"; 666 FillFormAndSubmit("autofill_test_form.html", data); 667 668 ASSERT_EQ(2u, personal_data_manager()->GetProfiles().size()); 669 int second_address_index = 670 personal_data_manager()->GetProfiles()[0]->GetRawInfo( 671 ADDRESS_HOME_LINE1) == ASCIIToUTF16("4321 H St.") 672 ? 0 673 : 1; 674 675 EXPECT_EQ(ASCIIToUTF16("+49 8450 777777"), 676 personal_data_manager() 677 ->GetProfiles()[1 - second_address_index] 678 ->GetRawInfo(PHONE_HOME_WHOLE_NUMBER)); 679 680 EXPECT_EQ( 681 ASCIIToUTF16("08450 777777"), 682 personal_data_manager()->GetProfiles()[second_address_index]->GetRawInfo( 683 PHONE_HOME_WHOLE_NUMBER)); 684 } 685 686 // Test that Autofill uses '+' sign for international numbers. 687 // This applies to the following cases: 688 // The phone number has a leading '+'. 689 // The phone number does not have a leading '+'. 690 // The phone number has a leading international direct dialing (IDD) code. 691 // This does not apply to US numbers. For US numbers, '+' is removed. 692 IN_PROC_BROWSER_TEST_F(AutofillTest, UsePlusSignForInternationalNumber) { 693 ASSERT_TRUE(test_server()->Start()); 694 std::vector<FormMap> profiles; 695 696 FormMap data1; 697 data1["NAME_FIRST"] = "Bonnie"; 698 data1["NAME_LAST"] = "Smith"; 699 data1["ADDRESS_HOME_LINE1"] = "6723 Roadway Rd"; 700 data1["ADDRESS_HOME_CITY"] = "Reading"; 701 data1["ADDRESS_HOME_STATE"] = "Berkshire"; 702 data1["ADDRESS_HOME_ZIP"] = "RG12 3BR"; 703 data1["ADDRESS_HOME_COUNTRY"] = "United Kingdom"; 704 data1["PHONE_HOME_WHOLE_NUMBER"] = "+44 7624-123456"; 705 profiles.push_back(data1); 706 707 FormMap data2; 708 data2["NAME_FIRST"] = "John"; 709 data2["NAME_LAST"] = "Doe"; 710 data2["ADDRESS_HOME_LINE1"] = "987 H St"; 711 data2["ADDRESS_HOME_CITY"] = "Reading"; 712 data2["ADDRESS_HOME_STATE"] = "BerkShire"; 713 data2["ADDRESS_HOME_ZIP"] = "RG12 3BR"; 714 data2["ADDRESS_HOME_COUNTRY"] = "United Kingdom"; 715 data2["PHONE_HOME_WHOLE_NUMBER"] = "44 7624 123456"; 716 profiles.push_back(data2); 717 718 FormMap data3; 719 data3["NAME_FIRST"] = "Jane"; 720 data3["NAME_LAST"] = "Doe"; 721 data3["ADDRESS_HOME_LINE1"] = "1523 Garcia St"; 722 data3["ADDRESS_HOME_CITY"] = "Reading"; 723 data3["ADDRESS_HOME_STATE"] = "BerkShire"; 724 data3["ADDRESS_HOME_ZIP"] = "RG12 3BR"; 725 data3["ADDRESS_HOME_COUNTRY"] = "United Kingdom"; 726 data3["PHONE_HOME_WHOLE_NUMBER"] = "0044 7624 123456"; 727 profiles.push_back(data3); 728 729 FormMap data4; 730 data4["NAME_FIRST"] = "Bob"; 731 data4["NAME_LAST"] = "Smith"; 732 data4["ADDRESS_HOME_LINE1"] = "123 Cherry Ave"; 733 data4["ADDRESS_HOME_CITY"] = "Mountain View"; 734 data4["ADDRESS_HOME_STATE"] = "CA"; 735 data4["ADDRESS_HOME_ZIP"] = "94043"; 736 data4["ADDRESS_HOME_COUNTRY"] = "United States"; 737 data4["PHONE_HOME_WHOLE_NUMBER"] = "+1 (408) 871-4567"; 738 profiles.push_back(data4); 739 740 for (size_t i = 0; i < profiles.size(); ++i) 741 FillFormAndSubmit("autofill_test_form.html", profiles[i]); 742 743 ASSERT_EQ(4u, personal_data_manager()->GetProfiles().size()); 744 745 for (size_t i = 0; i < personal_data_manager()->GetProfiles().size(); ++i) { 746 AutofillProfile* profile = personal_data_manager()->GetProfiles()[i]; 747 std::string expectation; 748 std::string name = UTF16ToASCII(profile->GetRawInfo(NAME_FIRST)); 749 750 if (name == "Bonnie") 751 expectation = "+447624123456"; 752 else if (name == "John") 753 expectation = "+447624123456"; 754 else if (name == "Jane") 755 expectation = "+447624123456"; 756 else if (name == "Bob") 757 expectation = "14088714567"; 758 759 EXPECT_EQ(ASCIIToUTF16(expectation), 760 profile->GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER), "")); 761 } 762 } 763 764 // Test CC info not offered to be saved when autocomplete=off for CC field. 765 // If the credit card number field has autocomplete turned off, then the credit 766 // card infobar should not offer to save the credit card info. The credit card 767 // number must be a valid Luhn number. 768 IN_PROC_BROWSER_TEST_F(AutofillTest, CCInfoNotStoredWhenAutocompleteOff) { 769 #if defined(OS_WIN) && defined(USE_ASH) 770 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 771 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 772 return; 773 #endif 774 775 ASSERT_TRUE(test_server()->Start()); 776 FormMap data; 777 data["CREDIT_CARD_NAME"] = "Bob Smith"; 778 data["CREDIT_CARD_NUMBER"] = "4408041234567893"; 779 data["CREDIT_CARD_EXP_MONTH"] = "12"; 780 data["CREDIT_CARD_EXP_4_DIGIT_YEAR"] = "2014"; 781 FillFormAndSubmit("cc_autocomplete_off_test.html", data); 782 783 InfoBarService* infobar_service = InfoBarService::FromWebContents( 784 browser()->tab_strip_model()->GetActiveWebContents()); 785 ASSERT_EQ(0u, infobar_service->infobar_count()); 786 } 787 788 // Test profile not aggregated if email found in non-email field. 789 IN_PROC_BROWSER_TEST_F(AutofillTest, ProfileWithEmailInOtherFieldNotSaved) { 790 ASSERT_TRUE(test_server()->Start()); 791 792 FormMap data; 793 data["NAME_FIRST"] = "Bob"; 794 data["NAME_LAST"] = "Smith"; 795 data["ADDRESS_HOME_LINE1"] = "bsmith (at) gmail.com"; 796 data["ADDRESS_HOME_CITY"] = "San Jose"; 797 data["ADDRESS_HOME_STATE"] = "CA"; 798 data["ADDRESS_HOME_ZIP"] = "95110"; 799 data["COMPANY_NAME"] = "Company X"; 800 data["PHONE_HOME_WHOLE_NUMBER"] = "408-871-4567"; 801 FillFormAndSubmit("duplicate_profiles_test.html", data); 802 803 ASSERT_EQ(0u, personal_data_manager()->GetProfiles().size()); 804 } 805 806 // Test that profiles merge for aggregated data with same address. 807 // The criterion for when two profiles are expected to be merged is when their 808 // 'Address Line 1' and 'City' data match. When two profiles are merged, any 809 // remaining address fields are expected to be overwritten. Any non-address 810 // fields should accumulate multi-valued data. 811 // DISABLED: http://crbug.com/281541 812 IN_PROC_BROWSER_TEST_F(AutofillTest, 813 DISABLED_MergeAggregatedProfilesWithSameAddress) { 814 AggregateProfilesIntoAutofillPrefs("dataset_same_address.txt"); 815 816 ASSERT_EQ(3u, personal_data_manager()->GetProfiles().size()); 817 } 818 819 // Test profiles are not merged without minimum address values. 820 // Mininum address values needed during aggregation are: address line 1, city, 821 // state, and zip code. 822 // Profiles are merged when data for address line 1 and city match. 823 // DISABLED: http://crbug.com/281541 824 IN_PROC_BROWSER_TEST_F(AutofillTest, 825 DISABLED_ProfilesNotMergedWhenNoMinAddressData) { 826 AggregateProfilesIntoAutofillPrefs("dataset_no_address.txt"); 827 828 ASSERT_EQ(0u, personal_data_manager()->GetProfiles().size()); 829 } 830 831 // Test Autofill ability to merge duplicate profiles and throw away junk. 832 // TODO(isherman): this looks redundant, consider removing. 833 // DISABLED: http://crbug.com/281541 834 IN_PROC_BROWSER_TEST_F(AutofillTest, 835 DISABLED_MergeAggregatedDuplicatedProfiles) { 836 int num_of_profiles = 837 AggregateProfilesIntoAutofillPrefs("dataset_duplicated_profiles.txt"); 838 839 ASSERT_GT(num_of_profiles, 840 static_cast<int>(personal_data_manager()->GetProfiles().size())); 841 } 842 843 } // namespace autofill 844