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