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