diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 00:57:33 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-01 00:57:33 +0000 |
commit | cea1d11b9375368e29906255b7f865f78045200b (patch) | |
tree | b8cde41281263b22a948510933ee5e82c6ffa9b9 /chrome/browser/autofill | |
parent | e7c3784d1fb8d5f1862409fe62feab2112b70af0 (diff) | |
download | chromium_src-cea1d11b9375368e29906255b7f865f78045200b.zip chromium_src-cea1d11b9375368e29906255b7f865f78045200b.tar.gz chromium_src-cea1d11b9375368e29906255b7f865f78045200b.tar.bz2 |
AutoFill: Aggregate profile data. Remove the AutoFill InfoBar. Remove more remnants of shipping address and CVV.
BUG=47426,47423
TEST=PersonalDataManager.*
Review URL: http://codereview.chromium.org/2818033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51322 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autofill')
32 files changed, 815 insertions, 890 deletions
diff --git a/chrome/browser/autofill/address.cc b/chrome/browser/autofill/address.cc index e84e3e2..cd5358e 100644 --- a/chrome/browser/autofill/address.cc +++ b/chrome/browser/autofill/address.cc @@ -30,8 +30,6 @@ const int kAutoFillAddressLength = arraysize(kAutoFillAddressTypes); void Address::GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const { DCHECK(possible_types); - if (!possible_types) - return; // If the text to match against the field types is empty, then no results will // match. @@ -60,12 +58,35 @@ void Address::GetPossibleFieldTypes(const string16& text, possible_types->insert(GetCountryType()); } +void Address::GetAvailableFieldTypes(FieldTypeSet* available_types) const { + DCHECK(available_types); + + if (!line1().empty()) + available_types->insert(GetLine1Type()); + + if (!line2().empty()) + available_types->insert(GetLine2Type()); + + if (!apt_num().empty()) + available_types->insert(GetAptNumType()); + + if (!city().empty()) + available_types->insert(GetCityType()); + + if (!state().empty()) + available_types->insert(GetStateType()); + + if (!zip_code().empty()) + available_types->insert(GetZipCodeType()); + + if (!country().empty()) + available_types->insert(GetCountryType()); +} + void Address::FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const { DCHECK(matched_text); - if (!matched_text) - return; string16 match; if (type.field_type() == UNKNOWN_TYPE) { diff --git a/chrome/browser/autofill/address.h b/chrome/browser/autofill/address.h index dea406a..80ba9fb 100644 --- a/chrome/browser/autofill/address.h +++ b/chrome/browser/autofill/address.h @@ -20,6 +20,7 @@ class Address : public FormGroup { virtual FormGroup* Clone() const = 0; virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const; + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const; virtual void FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const; diff --git a/chrome/browser/autofill/autofill_common_unittest.cc b/chrome/browser/autofill/autofill_common_unittest.cc index 2e2fd61..b7997cc 100644 --- a/chrome/browser/autofill/autofill_common_unittest.cc +++ b/chrome/browser/autofill/autofill_common_unittest.cc @@ -3,11 +3,28 @@ // found in the LICENSE file. #include "chrome/browser/autofill/autofill_common_unittest.h" + #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/autofill/credit_card.h" +#include "webkit/glue/form_field.h" namespace autofill_unittest { +void CreateTestFormField(const char* label, + const char* name, + const char* value, + const char* type, + webkit_glue::FormField* field) { + *field = webkit_glue::FormField(ASCIIToUTF16(label), ASCIIToUTF16(name), + ASCIIToUTF16(value), ASCIIToUTF16(type), 0); +} + +inline void check_and_set( + FormGroup* profile, AutoFillFieldType type, const char* value) { + if (value) + profile->SetInfo(AutoFillType(type), ASCIIToUTF16(value)); +} + void SetProfileInfo(AutoFillProfile* profile, const char* label, const char* first_name, const char* middle_name, const char* last_name, const char* email, const char* company, @@ -15,40 +32,33 @@ void SetProfileInfo(AutoFillProfile* profile, const char* state, const char* zipcode, const char* country, const char* phone, const char* fax) { profile->set_label(ASCIIToUTF16(label)); - profile->SetInfo(AutoFillType(NAME_FIRST), ASCIIToUTF16(first_name)); - profile->SetInfo(AutoFillType(NAME_MIDDLE), ASCIIToUTF16(middle_name)); - profile->SetInfo(AutoFillType(NAME_LAST), ASCIIToUTF16(last_name)); - profile->SetInfo(AutoFillType(EMAIL_ADDRESS), ASCIIToUTF16(email)); - profile->SetInfo(AutoFillType(COMPANY_NAME), ASCIIToUTF16(company)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE1), ASCIIToUTF16(address1)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_LINE2), ASCIIToUTF16(address2)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_CITY), ASCIIToUTF16(city)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_STATE), ASCIIToUTF16(state)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_ZIP), ASCIIToUTF16(zipcode)); - profile->SetInfo(AutoFillType(ADDRESS_HOME_COUNTRY), ASCIIToUTF16(country)); - profile->SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), ASCIIToUTF16(phone)); - profile->SetInfo(AutoFillType(PHONE_FAX_WHOLE_NUMBER), ASCIIToUTF16(fax)); + check_and_set(profile, NAME_FIRST, first_name); + check_and_set(profile, NAME_MIDDLE, middle_name); + check_and_set(profile, NAME_LAST, last_name); + check_and_set(profile, EMAIL_ADDRESS, email); + check_and_set(profile, COMPANY_NAME, company); + check_and_set(profile, ADDRESS_HOME_LINE1, address1); + check_and_set(profile, ADDRESS_HOME_LINE2, address2); + check_and_set(profile, ADDRESS_HOME_CITY, city); + check_and_set(profile, ADDRESS_HOME_STATE, state); + check_and_set(profile, ADDRESS_HOME_ZIP, zipcode); + check_and_set(profile, ADDRESS_HOME_COUNTRY, country); + check_and_set(profile, PHONE_HOME_WHOLE_NUMBER, phone); + check_and_set(profile, PHONE_FAX_WHOLE_NUMBER, fax); } void SetCreditCardInfo(CreditCard* credit_card, const char* label, const char* name_on_card, const char* type, const char* card_number, const char* expiration_month, - const char* expiration_year, const char* verification_code, - const char* billing_address, const char* shipping_address) { + const char* expiration_year, const char* billing_address) { credit_card->set_label(ASCIIToUTF16(label)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_NAME), - ASCIIToUTF16(name_on_card)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_TYPE), ASCIIToUTF16(type)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_NUMBER), - ASCIIToUTF16(card_number)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_EXP_MONTH), - ASCIIToUTF16(expiration_month)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), - ASCIIToUTF16(expiration_year)); - credit_card->SetInfo(AutoFillType(CREDIT_CARD_VERIFICATION_CODE), - ASCIIToUTF16(verification_code)); - credit_card->set_billing_address(ASCIIToUTF16(billing_address)); - credit_card->set_shipping_address(ASCIIToUTF16(shipping_address)); + check_and_set(credit_card, CREDIT_CARD_NAME, name_on_card); + check_and_set(credit_card, CREDIT_CARD_TYPE, type); + check_and_set(credit_card, CREDIT_CARD_NUMBER, card_number); + check_and_set(credit_card, CREDIT_CARD_EXP_MONTH, expiration_month); + check_and_set(credit_card, CREDIT_CARD_EXP_4_DIGIT_YEAR, expiration_year); + if (billing_address) + credit_card->set_billing_address(ASCIIToUTF16(billing_address)); } -} // namespace +} // namespace autofill_unittest diff --git a/chrome/browser/autofill/autofill_common_unittest.h b/chrome/browser/autofill/autofill_common_unittest.h index eef9210..fdb965f 100644 --- a/chrome/browser/autofill/autofill_common_unittest.h +++ b/chrome/browser/autofill/autofill_common_unittest.h @@ -8,10 +8,21 @@ class AutoFillProfile; class CreditCard; -// Common utilities shared amongst autofill unit tests. +namespace webkit_glue { +class FormField; +} // namespace webkit_glue + +// Common utilities shared amongst AutoFill unit tests. namespace autofill_unittest { -// A unit testing utility that is common to a number of the autofill unit +// Provides a quick way to populate a FormField with c-strings. +void CreateTestFormField(const char* label, + const char* name, + const char* value, + const char* type, + webkit_glue::FormField* field); + +// A unit testing utility that is common to a number of the AutoFill unit // tests. |SetProfileInfo| provides a quick way to populate a profile with // c-strings. void SetProfileInfo(AutoFillProfile* profile, @@ -21,15 +32,14 @@ void SetProfileInfo(AutoFillProfile* profile, const char* state, const char* zipcode, const char* country, const char* phone, const char* fax); -// A unit testing utility that is common to a number of the autofill unit +// A unit testing utility that is common to a number of the AutoFill unit // tests. |SetCreditCardInfo| provides a quick way to populate a credit card // with c-strings. void SetCreditCardInfo(CreditCard* credit_card, const char* label, const char* name_on_card, const char* type, const char* card_number, const char* expiration_month, - const char* expiration_year, const char* verification_code, - const char* billing_address, const char* shipping_address); + const char* expiration_year, const char* billing_address); -} // namespace +} // namespace autofill_unittest #endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_UNITTEST_H_ diff --git a/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm b/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm index bb041ce..8f41133 100644 --- a/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm +++ b/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm @@ -25,17 +25,8 @@ TEST(AutoFillCreditCardModelTest, Basic) { TEST(AutoFillCreditCardModelTest, InitializationFromCreditCard) { CreditCard credit_card(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card, - "Corporate", - "John Dillinger", - "Visa", - "123456789012", - "01", - "2010", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card, "Corporate", + "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago"); scoped_nsobject<AutoFillCreditCardModel> model( [[AutoFillCreditCardModel alloc] initWithCreditCard:credit_card]); EXPECT_TRUE(model.get()); @@ -50,17 +41,8 @@ TEST(AutoFillCreditCardModelTest, InitializationFromCreditCard) { TEST(AutoFillCreditCardModelTest, CopyModelToCreditCard) { CreditCard credit_card(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card, - "Corporate", - "John Dillinger", - "Visa", - "123456789012", - "01", - "2010", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card, "Corporate", + "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago"); scoped_nsobject<AutoFillCreditCardModel> model( [[AutoFillCreditCardModel alloc] initWithCreditCard:credit_card]); EXPECT_TRUE(model.get()); diff --git a/chrome/browser/autofill/autofill_dialog_gtk.cc b/chrome/browser/autofill/autofill_dialog_gtk.cc index 0578dec..14f9777 100644 --- a/chrome/browser/autofill/autofill_dialog_gtk.cc +++ b/chrome/browser/autofill/autofill_dialog_gtk.cc @@ -24,7 +24,6 @@ #include "chrome/browser/gtk/gtk_chrome_link_button.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/gtk/options/options_layout_gtk.h" -#include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/common/pref_names.h" #include "gfx/gtk_util.h" @@ -230,7 +229,6 @@ class AutoFillDialog : public PersonalDataManager::Observer { public: AutoFillDialog(AutoFillDialogObserver* observer, PersonalDataManager* personal_data_manager, - PrefService* pref_service, AutoFillProfile* imported_profile, CreditCard* imported_credit_card); ~AutoFillDialog(); @@ -317,9 +315,6 @@ class AutoFillDialog : public PersonalDataManager::Observer { // Unowned pointer, may not be NULL. PersonalDataManager* personal_data_; - // The preference service. Unowned pointer, may not be NULL. - PrefService* pref_service_; - // The imported profile. May be NULL. AutoFillProfile* imported_profile_; @@ -355,17 +350,14 @@ static AutoFillDialog* dialog = NULL; AutoFillDialog::AutoFillDialog(AutoFillDialogObserver* observer, PersonalDataManager* personal_data_manager, - PrefService* pref_service, AutoFillProfile* imported_profile, CreditCard* imported_credit_card) : observer_(observer), personal_data_(personal_data_manager), - pref_service_(pref_service), imported_profile_(imported_profile), imported_credit_card_(imported_credit_card) { DCHECK(observer_); DCHECK(personal_data_); - DCHECK(pref_service_); InitializeWidgets(); LoadAutoFillData(); @@ -991,15 +983,9 @@ void ShowAutoFillDialog(gfx::NativeView parent, CreditCard* imported_credit_card) { DCHECK(profile); - // It's possible we haven't shown the InfoBar yet, but if the user is in the - // AutoFill dialog, she doesn't need to be asked to enable or disable - // AutoFill. - profile->GetPrefs()->SetBoolean(prefs::kAutoFillInfoBarShown, true); - if (!dialog) { dialog = new AutoFillDialog(observer, profile->GetPersonalDataManager(), - profile->GetPrefs(), imported_profile, imported_credit_card); } diff --git a/chrome/browser/autofill/autofill_dialog_mac.mm b/chrome/browser/autofill/autofill_dialog_mac.mm index 63d5478..ad0c9e2 100644 --- a/chrome/browser/autofill/autofill_dialog_mac.mm +++ b/chrome/browser/autofill/autofill_dialog_mac.mm @@ -15,11 +15,6 @@ void ShowAutoFillDialog(gfx::NativeView parent, Profile* profile, AutoFillProfile* imported_profile, CreditCard* imported_credit_card) { - // It's possible we haven't shown the InfoBar yet, but if the user is in the - // AutoFill dialog, she doesn't need to be asked to enable or disable - // AutoFill. - profile->GetPrefs()->SetBoolean(prefs::kAutoFillInfoBarShown, true); - [AutoFillDialogController showAutoFillDialogWithObserver:observer profile:profile diff --git a/chrome/browser/autofill/autofill_infobar_delegate.cc b/chrome/browser/autofill/autofill_infobar_delegate.cc deleted file mode 100644 index d0465dc..0000000 --- a/chrome/browser/autofill/autofill_infobar_delegate.cc +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/autofill/autofill_infobar_delegate.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "chrome/browser/autofill/autofill_manager.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/pref_service.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/tab_contents/tab_contents_delegate.h" -#include "chrome/common/pref_names.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "third_party/skia/include/core/SkBitmap.h" - -AutoFillInfoBarDelegate::AutoFillInfoBarDelegate(TabContents* tab_contents, - AutoFillManager* host) - : ConfirmInfoBarDelegate(tab_contents), - browser_(NULL), - host_(host) { - if (tab_contents) { - // This is NULL for TestTabContents. - if (tab_contents->delegate()) - browser_ = tab_contents->delegate()->GetBrowser(); - - PrefService* prefs = tab_contents->profile()->GetPrefs(); - prefs->SetBoolean(prefs::kAutoFillInfoBarShown, true); - tab_contents->AddInfoBar(this); - } -} - -AutoFillInfoBarDelegate::~AutoFillInfoBarDelegate() { -} - -bool AutoFillInfoBarDelegate::ShouldExpire( - const NavigationController::LoadCommittedDetails& details) const { - // The user has submitted a form, causing the page to navigate elsewhere. We - // don't want the infobar to be expired at this point, because the user won't - // get a chance to answer the question. - return false; -} - -void AutoFillInfoBarDelegate::InfoBarClosed() { - if (host_) { - host_->OnInfoBarClosed(); - host_ = NULL; - } - - // This will delete us. - ConfirmInfoBarDelegate::InfoBarClosed(); -} - -std::wstring AutoFillInfoBarDelegate::GetMessageText() const { - return l10n_util::GetString(IDS_AUTOFILL_INFOBAR_TEXT); -} - -SkBitmap* AutoFillInfoBarDelegate::GetIcon() const { - return ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_INFOBAR_AUTOFILL); -} - -int AutoFillInfoBarDelegate::GetButtons() const { - return BUTTON_OK | BUTTON_CANCEL; -} - -std::wstring AutoFillInfoBarDelegate::GetButtonLabel( - ConfirmInfoBarDelegate::InfoBarButton button) const { - if (button == BUTTON_OK) - return l10n_util::GetString(IDS_AUTOFILL_INFOBAR_ACCEPT); - else if (button == BUTTON_CANCEL) - return l10n_util::GetString(IDS_AUTOFILL_INFOBAR_DENY); - else - NOTREACHED(); - - return std::wstring(); -} - -bool AutoFillInfoBarDelegate::Accept() { - if (host_) { - host_->OnInfoBarAccepted(); - host_ = NULL; - } - return true; -} - -bool AutoFillInfoBarDelegate::Cancel() { - if (host_) { - host_->OnInfoBarCancelled(); - host_ = NULL; - } - return true; -} - -std::wstring AutoFillInfoBarDelegate::GetLinkText() { - return l10n_util::GetString(IDS_AUTOFILL_LEARN_MORE); -} - -bool AutoFillInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) { - browser_->OpenURL(GURL(kAutoFillLearnMoreUrl), GURL(), NEW_FOREGROUND_TAB, - PageTransition::TYPED); - return true; -} diff --git a/chrome/browser/autofill/autofill_infobar_delegate.h b/chrome/browser/autofill/autofill_infobar_delegate.h deleted file mode 100644 index 73a52a4..0000000 --- a/chrome/browser/autofill/autofill_infobar_delegate.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_INFOBAR_DELEGATE_H_ -#define CHROME_BROWSER_AUTOFILL_AUTOFILL_INFOBAR_DELEGATE_H_ - -#include <string> - -#include "chrome/browser/tab_contents/infobar_delegate.h" - -class AutoFillManager; -class Browser; -class SkBitmap; -class TabContents; - -// An InfoBar delegate that enables the user to allow or deny storing personal -// information gathered from a form submission. -class AutoFillInfoBarDelegate : public ConfirmInfoBarDelegate { - public: - AutoFillInfoBarDelegate(TabContents* tab_contents, AutoFillManager* host); - virtual ~AutoFillInfoBarDelegate(); - - // ConfirmInfoBarDelegate implementation. - virtual bool ShouldExpire( - const NavigationController::LoadCommittedDetails& details) const; - virtual void InfoBarClosed(); - virtual std::wstring GetMessageText() const; - virtual SkBitmap* GetIcon() const; - virtual int GetButtons() const; - virtual std::wstring GetButtonLabel( - ConfirmInfoBarDelegate::InfoBarButton button) const; - virtual bool Accept(); - virtual bool Cancel(); - virtual std::wstring GetLinkText(); - virtual bool LinkClicked(WindowOpenDisposition disposition); - - private: - // The browser. - Browser* browser_; - - // The AutoFillManager that initiated this InfoBar. - AutoFillManager* host_; - - DISALLOW_COPY_AND_ASSIGN(AutoFillInfoBarDelegate); -}; - -#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_INFOBAR_DELEGATE_H_ diff --git a/chrome/browser/autofill/autofill_infobar_delegate_unittest.cc b/chrome/browser/autofill/autofill_infobar_delegate_unittest.cc deleted file mode 100644 index 1c40557..0000000 --- a/chrome/browser/autofill/autofill_infobar_delegate_unittest.cc +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "app/l10n_util.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/autofill/autofill_infobar_delegate.h" -#include "chrome/browser/autofill/autofill_manager.h" -#include "chrome/browser/tab_contents/infobar_delegate.h" -#include "chrome/browser/tab_contents/navigation_controller.h" -#include "grit/chromium_strings.h" -#include "grit/generated_resources.h" -#include "testing/gtest/include/gtest/gtest.h" - -class SkBitmap; - -namespace { - -class MockAutoFillManager : public AutoFillManager { - public: - explicit MockAutoFillManager() - : responded_(false), - accepted_(false) {} - - virtual void OnInfoBarClosed() { - EXPECT_FALSE(responded_); - responded_ = true; - accepted_ = true; - } - - virtual void OnInfoBarAccepted() { - EXPECT_FALSE(responded_); - responded_ = true; - accepted_ = true; - } - - virtual void OnInfoBarCancelled() { - EXPECT_FALSE(responded_); - responded_ = true; - accepted_ = false; - } - - bool responded() { - return responded_; - } - - bool accepted() { - return accepted_; - } - - private: - // True if we have gotten some sort of response. - bool responded_; - - // True if we have gotten an Accept response. Meaningless if |responded_| is - // not true. - bool accepted_; - - DISALLOW_COPY_AND_ASSIGN(MockAutoFillManager); -}; - -class AutoFillInfoBarDelegateTest : public testing::Test { - public: - AutoFillInfoBarDelegateTest() {} - - virtual void SetUp() { - autofill_manager_.reset(new MockAutoFillManager()); - infobar_.reset(new AutoFillInfoBarDelegate(NULL, autofill_manager_.get())); - } - - protected: - scoped_ptr<MockAutoFillManager> autofill_manager_; - scoped_ptr<AutoFillInfoBarDelegate> infobar_; - - private: - DISALLOW_COPY_AND_ASSIGN(AutoFillInfoBarDelegateTest); -}; - -TEST_F(AutoFillInfoBarDelegateTest, ShouldExpire) { - NavigationController::LoadCommittedDetails details; - EXPECT_FALSE(infobar_->ShouldExpire(details)); -} - -TEST_F(AutoFillInfoBarDelegateTest, InfoBarClosed) { - infobar_->InfoBarClosed(); - EXPECT_TRUE(autofill_manager_->responded()); - EXPECT_TRUE(autofill_manager_->accepted()); -} - -TEST_F(AutoFillInfoBarDelegateTest, GetMessageText) { - std::wstring text = l10n_util::GetString(IDS_AUTOFILL_INFOBAR_TEXT); - EXPECT_EQ(text, infobar_->GetMessageText()); -} - -TEST_F(AutoFillInfoBarDelegateTest, GetIcon) { - SkBitmap* icon = infobar_->GetIcon(); - EXPECT_NE(static_cast<SkBitmap*>(NULL), icon); -} - -TEST_F(AutoFillInfoBarDelegateTest, GetButtons) { - int buttons = - ConfirmInfoBarDelegate::BUTTON_OK | ConfirmInfoBarDelegate::BUTTON_CANCEL; - EXPECT_EQ(buttons, infobar_->GetButtons()); -} - -TEST_F(AutoFillInfoBarDelegateTest, GetButtonLabel) { - std::wstring accept = l10n_util::GetString(IDS_AUTOFILL_INFOBAR_ACCEPT); - EXPECT_EQ(accept, - infobar_->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)); - - std::wstring deny = l10n_util::GetString(IDS_AUTOFILL_INFOBAR_DENY); - EXPECT_EQ(deny, - infobar_->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL)); -} - -TEST_F(AutoFillInfoBarDelegateTest, Accept) { - infobar_->Accept(); - EXPECT_TRUE(autofill_manager_->responded()); - EXPECT_TRUE(autofill_manager_->accepted()); -} - -TEST_F(AutoFillInfoBarDelegateTest, Cancel) { - infobar_->Cancel(); - EXPECT_TRUE(autofill_manager_->responded()); - EXPECT_FALSE(autofill_manager_->accepted()); -} - -} // namespace diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index 2be20db..5343db2 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -9,7 +9,6 @@ #include "base/basictypes.h" #include "base/string16.h" #include "chrome/browser/autofill/autofill_dialog.h" -#include "chrome/browser/autofill/autofill_infobar_delegate.h" #include "chrome/browser/autofill/form_structure.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" @@ -47,8 +46,7 @@ const char* kAutoFillLearnMoreUrl = AutoFillManager::AutoFillManager(TabContents* tab_contents) : tab_contents_(tab_contents), personal_data_(NULL), - download_manager_(tab_contents_->profile()), - infobar_(NULL) { + download_manager_(tab_contents_->profile()) { DCHECK(tab_contents); // |personal_data_| is NULL when using TestTabContents. @@ -68,7 +66,6 @@ void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) { // static void AutoFillManager::RegisterUserPrefs(PrefService* prefs) { - prefs->RegisterBooleanPref(prefs::kAutoFillInfoBarShown, false); prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true); prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true); @@ -95,15 +92,6 @@ void AutoFillManager::FormSubmitted(const FormData& form) { // PersonalDataManager. DeterminePossibleFieldTypes(upload_form_structure_.get()); HandleSubmit(); - - if (upload_form_structure_->HasAutoFillableValues()) { - PrefService* prefs = tab_contents_->profile()->GetPrefs(); - bool infobar_shown = prefs->GetBoolean(prefs::kAutoFillInfoBarShown); - if (!infobar_shown) { - // Ask the user for permission to save form information. - infobar_.reset(new AutoFillInfoBarDelegate(tab_contents_, this)); - } - } } void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { @@ -328,38 +316,6 @@ void AutoFillManager::ShowAutoFillDialog() { NULL); } -void AutoFillManager::OnInfoBarClosed() { - PrefService* prefs = tab_contents_->profile()->GetPrefs(); - prefs->SetBoolean(prefs::kAutoFillEnabled, true); - - // Save the imported form data as a profile. - personal_data_->SaveImportedFormData(); -} - -void AutoFillManager::OnInfoBarAccepted() { - PrefService* prefs = tab_contents_->profile()->GetPrefs(); - prefs->SetBoolean(prefs::kAutoFillEnabled, true); - - // This is the first time the user is interacting with AutoFill, so set the - // uploaded form structure as the initial profile and credit card in the - // AutoFillDialog. - AutoFillProfile* profile = NULL; - CreditCard* credit_card = NULL; - // TODO(dhollowa) Now that we aren't immediately saving the imported form - // data, we should store the profile and CC in the AFM instead of the PDM. - personal_data_->GetImportedFormData(&profile, &credit_card); - ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(), - personal_data_, - tab_contents_->profile()->GetOriginalProfile(), - profile, - credit_card); -} - -void AutoFillManager::OnInfoBarCancelled() { - PrefService* prefs = tab_contents_->profile()->GetPrefs(); - prefs->SetBoolean(prefs::kAutoFillEnabled, false); -} - void AutoFillManager::Reset() { upload_form_structure_.reset(); form_structures_.reset(); @@ -438,8 +394,7 @@ AutoFillManager::AutoFillManager(TabContents* tab_contents, PersonalDataManager* personal_data) : tab_contents_(tab_contents), personal_data_(personal_data), - download_manager_(NULL), // No download manager in tests. - infobar_(NULL) { + download_manager_(NULL) { DCHECK(tab_contents); } diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index f45f7ed..f4fdb44 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -15,7 +15,6 @@ #include "chrome/browser/autofill/personal_data_manager.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" -class AutoFillInfoBarDelegate; class AutoFillProfile; class CreditCard; class FormStructure; @@ -57,15 +56,6 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, const string16& label); virtual void ShowAutoFillDialog(); - // Called by the AutoFillInfoBarDelegate when the user closes the infobar. - virtual void OnInfoBarClosed(); - - // Called by the AutoFillInfoBarDelegate when the user accepts the infobar. - virtual void OnInfoBarAccepted(); - - // Called by the AutoFillInfoBarDelegate when the user cancels the infobar. - virtual void OnInfoBarCancelled(); - // Resets the stored form data. virtual void Reset(); @@ -164,9 +154,6 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // The form data the user has submitted. scoped_ptr<FormStructure> upload_form_structure_; - // The InfoBar that asks for permission to store form information. - scoped_ptr<AutoFillInfoBarDelegate> infobar_; - DISALLOW_COPY_AND_ASSIGN(AutoFillManager); }; diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc index 700966d..fbb5f3e 100644 --- a/chrome/browser/autofill/autofill_manager_unittest.cc +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -85,16 +85,16 @@ class TestPersonalDataManager : public PersonalDataManager { CreditCard* credit_card = new CreditCard; autofill_unittest::SetCreditCardInfo(credit_card, "First", "Elvis Presley", "Visa", "1234567890123456", "04", - "2012", "456", "Home", ""); + "2012", "Home"); credit_cards->push_back(credit_card); credit_card = new CreditCard; autofill_unittest::SetCreditCardInfo(credit_card, "Second", "Buddy Holly", "Mastercard", "0987654321098765", "10", - "2014", "678", "", ""); + "2014", ""); credit_cards->push_back(credit_card); credit_card = new CreditCard; autofill_unittest::SetCreditCardInfo(credit_card, "Empty", "", "", "", "", - "", "", "", ""); + "", ""); credit_cards->push_back(credit_card); } @@ -125,15 +125,6 @@ class TestAutoFillManager : public AutoFillManager { DISALLOW_COPY_AND_ASSIGN(TestAutoFillManager); }; -void CreateTestFormField(const char* label, - const char* name, - const char* value, - const char* type, - webkit_glue::FormField* field) { - *field = webkit_glue::FormField(ASCIIToUTF16(label), ASCIIToUTF16(name), - ASCIIToUTF16(value), ASCIIToUTF16(type), 0); -} - void CreateTestFormData(FormData* form) { form->name = ASCIIToUTF16("MyForm"); form->method = ASCIIToUTF16("POST"); @@ -141,27 +132,38 @@ void CreateTestFormData(FormData* form) { form->action = GURL("http://myform.com/submit.html"); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Last Name", "lastname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Address Line 1", "addr1", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Address Line 1", "addr1", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Address Line 2", "addr2", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Address Line 2", "addr2", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("City", "city", "", "text", &field); + autofill_unittest::CreateTestFormField( + "City", "city", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("State", "state", "", "text", &field); + autofill_unittest::CreateTestFormField( + "State", "state", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Postal Code", "zipcode", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Postal Code", "zipcode", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Country", "country", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Country", "country", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Number", "phonenumber", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Email", "email", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "", "text", &field); form->fields.push_back(field); } @@ -172,35 +174,50 @@ void CreateTestFormDataBilling(FormData* form) { form->action = GURL("http://myform.com/submit.html"); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Last Name", "lastname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Address Line 1", "billingAddr1", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Address Line 1", "billingAddr1", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Address Line 2", "billingAddr2", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Address Line 2", "billingAddr2", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("City", "billingCity", "", "text", &field); + autofill_unittest::CreateTestFormField( + "City", "billingCity", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("State", "billingState", "", "text", &field); + autofill_unittest::CreateTestFormField( + "State", "billingState", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Postal Code", "billingZipcode", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Postal Code", "billingZipcode", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Country", "billingCountry", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Country", "billingCountry", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Number", "phonenumber", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Email", "email", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Name on Card", "nameoncard", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Card Number", "cardnumber", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("Expiration Date", "ccmonth", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Expiration Date", "ccmonth", "", "text", &field); form->fields.push_back(field); - CreateTestFormField("", "ccyear", "", "text", &field); + autofill_unittest::CreateTestFormField( + "", "ccyear", "", "text", &field); form->fields.push_back(field); } @@ -274,7 +291,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -305,7 +323,8 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "E", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "E", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -334,7 +353,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("Card Number", "cardnumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Card Number", "cardnumber", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -373,7 +393,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("Card Number", "cardnumber", "1", "text", &field); + autofill_unittest::CreateTestFormField( + "Card Number", "cardnumber", "1", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -406,7 +427,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Name on Card", "nameoncard", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -447,7 +469,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsSemicolon) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("Name on Card", "nameoncard", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Name on Card", "nameoncard", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); // Test that we sent the right message to the renderer. @@ -490,7 +513,8 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFormIsAutoFilled) { const int kPageID = 1; webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); // Test that we sent the right message to the renderer. @@ -535,40 +559,51 @@ TEST_F(AutoFillManagerTest, FillCreditCardForm) { ASSERT_EQ(15U, results.fields.size()); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "Elvis", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - CreateTestFormField("Middle Name", "middlename", "Aaron", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - CreateTestFormField("Last Name", "lastname", "Presley", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - CreateTestFormField("Address Line 1", "billingAddr1", + autofill_unittest::CreateTestFormField( + "Address Line 1", "billingAddr1", "3734 Elvis Presley Blvd.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Address Line 2", "billingAddr2", "Apt. 10", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - CreateTestFormField("City", "billingCity", "Memphis", "text", &field); + autofill_unittest::CreateTestFormField( + "City", "billingCity", "Memphis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - CreateTestFormField("State", "billingState", "Tennessee", "text", &field); + autofill_unittest::CreateTestFormField( + "State", "billingState", "Tennessee", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - CreateTestFormField("Postal Code", "billingZipcode", "38116", "text", &field); + autofill_unittest::CreateTestFormField( + "Postal Code", "billingZipcode", "38116", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - CreateTestFormField("Country", "billingCountry", "USA", "text", &field); + autofill_unittest::CreateTestFormField( + "Country", "billingCountry", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - CreateTestFormField("Email", "email", "theking@gmail.com", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Name on Card", "nameoncard", "Elvis Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[11])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Card Number", "cardnumber", "1234567890123456", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[12])); - CreateTestFormField("Expiration Date", "ccmonth", "04", "text", &field); + autofill_unittest::CreateTestFormField( + "Expiration Date", "ccmonth", "04", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[13])); - CreateTestFormField("", "ccyear", "2012", "text", &field); + autofill_unittest::CreateTestFormField( + "", "ccyear", "2012", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[14])); } @@ -602,30 +637,38 @@ TEST_F(AutoFillManagerTest, FillNonBillingFormSemicolon) { ASSERT_EQ(11U, results.fields.size()); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "Joe", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "Joe", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - CreateTestFormField("Last Name", "lastname", "Ely", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "Ely", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Address Line 1", "addr1", "916 16th St.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Address Line 2", "addr2", "Apt. 6", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - CreateTestFormField("City", "city", "Lubbock", "text", &field); + autofill_unittest::CreateTestFormField( + "City", "city", "Lubbock", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - CreateTestFormField("State", "state", "Texas", "text", &field); + autofill_unittest::CreateTestFormField( + "State", "state", "Texas", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - CreateTestFormField("Postal Code", "zipcode", "79401", "text", &field); + autofill_unittest::CreateTestFormField( + "Postal Code", "zipcode", "79401", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - CreateTestFormField("Country", "country", "USA", "text", &field); + autofill_unittest::CreateTestFormField( + "Country", "country", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - CreateTestFormField("Email", "email", "flatlander@gmail.com", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "flatlander@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); } @@ -656,40 +699,51 @@ TEST_F(AutoFillManagerTest, FillBillFormSemicolon) { ASSERT_EQ(15U, results.fields.size()); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "Joe", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "Joe", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - CreateTestFormField("Last Name", "lastname", "Ely", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "Ely", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - CreateTestFormField("Address Line 1", "billingAddr1", + autofill_unittest::CreateTestFormField( + "Address Line 1", "billingAddr1", "3734 Elvis Presley Blvd.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Address Line 2", "billingAddr2", "Apt. 10", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - CreateTestFormField("City", "billingCity", "Memphis", "text", &field); + autofill_unittest::CreateTestFormField( + "City", "billingCity", "Memphis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - CreateTestFormField("State", "billingState", "Tennessee", "text", &field); + autofill_unittest::CreateTestFormField( + "State", "billingState", "Tennessee", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - CreateTestFormField("Postal Code", "billingZipcode", "38116", "text", &field); + autofill_unittest::CreateTestFormField( + "Postal Code", "billingZipcode", "38116", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - CreateTestFormField("Country", "billingCountry", "USA", "text", &field); + autofill_unittest::CreateTestFormField( + "Country", "billingCountry", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - CreateTestFormField("Email", "email", "flatlander@gmail.com", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "flatlander@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Name on Card", "nameoncard", "Elvis Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[11])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Card Number", "cardnumber", "1234567890123456", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[12])); - CreateTestFormField("Expiration Date", "ccmonth", "04", "text", &field); + autofill_unittest::CreateTestFormField( + "Expiration Date", "ccmonth", "04", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[13])); - CreateTestFormField("", "ccyear", "2012", "text", &field); + autofill_unittest::CreateTestFormField( + "", "ccyear", "2012", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[14])); } @@ -703,19 +757,24 @@ TEST_F(AutoFillManagerTest, FillPhoneNumberTest) { webkit_glue::FormField field; - CreateTestFormField("country code", "country code", "", "text", &field); + autofill_unittest::CreateTestFormField( + "country code", "country code", "", "text", &field); field.set_size(1); form.fields.push_back(field); - CreateTestFormField("area code", "area code", "", "text", &field); + autofill_unittest::CreateTestFormField( + "area code", "area code", "", "text", &field); field.set_size(3); form.fields.push_back(field); - CreateTestFormField("phone", "phone prefix", "1", "text", &field); + autofill_unittest::CreateTestFormField( + "phone", "phone prefix", "1", "text", &field); field.set_size(3); form.fields.push_back(field); - CreateTestFormField("-", "phone suffix", "", "text", &field); + autofill_unittest::CreateTestFormField( + "-", "phone suffix", "", "text", &field); field.set_size(4); form.fields.push_back(field); - CreateTestFormField("Phone Extension", "ext", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Extension", "ext", "", "text", &field); field.set_size(3); form.fields.push_back(field); @@ -766,15 +825,20 @@ TEST_F(AutoFillManagerTest, FormChangesRemoveField) { form.action = GURL("http://myform.com/submit.html"); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Last Name", "lastname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Number", "phonenumber", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Email", "email", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "", "text", &field); form.fields.push_back(field); // Set up our FormStructures. @@ -804,13 +868,16 @@ TEST_F(AutoFillManagerTest, FormChangesRemoveField) { EXPECT_EQ(GURL("http://myform.com/submit.html"), results.action); ASSERT_EQ(4U, results.fields.size()); - CreateTestFormField("First Name", "firstname", "Elvis", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - CreateTestFormField("Middle Name", "middlename", "Aaron", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - CreateTestFormField("Last Name", "lastname", "Presley", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); } @@ -823,14 +890,18 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { form.action = GURL("http://myform.com/submit.html"); webkit_glue::FormField field; - CreateTestFormField("First Name", "firstname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Middle Name", "middlename", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "", "text", &field); form.fields.push_back(field); - CreateTestFormField("Last Name", "lastname", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "", "text", &field); // Note: absent phone number. Adding this below. form.fields.push_back(field); - CreateTestFormField("Email", "email", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Email", "email", "", "text", &field); form.fields.push_back(field); // Set up our FormStructures. @@ -840,7 +911,8 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { // Now, after the call to |FormsSeen| we add the phone number field before // filling. - CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Number", "phonenumber", "", "text", &field); form.fields.insert(form.fields.begin() + 3, field); // The page ID sent to the AutoFillManager from the RenderView, used to send @@ -861,47 +933,23 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { EXPECT_EQ(GURL("http://myform.com/submit.html"), results.action); ASSERT_EQ(5U, results.fields.size()); - CreateTestFormField("First Name", "firstname", "Elvis", "text", &field); + autofill_unittest::CreateTestFormField( + "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - CreateTestFormField("Middle Name", "middlename", "Aaron", "text", &field); + autofill_unittest::CreateTestFormField( + "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - CreateTestFormField("Last Name", "lastname", "Presley", "text", &field); + autofill_unittest::CreateTestFormField( + "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - CreateTestFormField("Phone Number", "phonenumber", "", "text", &field); + autofill_unittest::CreateTestFormField( + "Phone Number", "phonenumber", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - CreateTestFormField( + autofill_unittest::CreateTestFormField( "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); } -TEST_F(AutoFillManagerTest, InfoBarShown) { - FormData form; - form.name = ASCIIToUTF16("MyForm"); - form.method = ASCIIToUTF16("POST"); - form.origin = GURL("http://myform.com/form.html"); - form.action = GURL("http://myform.com/submit.html"); - - webkit_glue::FormField field; - CreateTestFormField("E-mail", "one", "one", "text", &field); - form.fields.push_back(field); - CreateTestFormField("E-mail", "two", "two", "text", &field); - form.fields.push_back(field); - CreateTestFormField("E-mail", "three", "three", "text", &field); - form.fields.push_back(field); - - // Set up our FormStructures. - std::vector<FormData> forms; - forms.push_back(form); - autofill_manager_->FormsSeen(forms); - - // Submit the form. - autofill_manager_->FormSubmitted(form); - - // Check that the 'AutoFill InfoBar shown' pref is set. - PrefService* prefs = profile()->GetPrefs(); - EXPECT_TRUE(prefs->GetBoolean(prefs::kAutoFillInfoBarShown)); -} - TEST_F(AutoFillManagerTest, HiddenFields) { FormData form; form.name = ASCIIToUTF16("MyForm"); @@ -910,11 +958,14 @@ TEST_F(AutoFillManagerTest, HiddenFields) { form.action = GURL("http://myform.com/submit.html"); webkit_glue::FormField field; - CreateTestFormField("E-mail", "one", "one", "hidden", &field); + autofill_unittest::CreateTestFormField( + "E-mail", "one", "one", "hidden", &field); form.fields.push_back(field); - CreateTestFormField("E-mail", "two", "two", "hidden", &field); + autofill_unittest::CreateTestFormField( + "E-mail", "two", "two", "hidden", &field); form.fields.push_back(field); - CreateTestFormField("E-mail", "three", "three", "hidden", &field); + autofill_unittest::CreateTestFormField( + "E-mail", "three", "three", "hidden", &field); form.fields.push_back(field); // Set up our FormStructures. @@ -925,9 +976,8 @@ TEST_F(AutoFillManagerTest, HiddenFields) { // Submit the form. autofill_manager_->FormSubmitted(form); - // Check that the 'AutoFill InfoBar shown' pref is not set. - PrefService* prefs = profile()->GetPrefs(); - EXPECT_FALSE(prefs->GetBoolean(prefs::kAutoFillInfoBarShown)); + // TODO(jhawkins): We can't use the InfoBar anymore to determine if we saved + // fields. Need to query the PDM. } } // namespace diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc index 655f938..a0d1282 100644 --- a/chrome/browser/autofill/autofill_profile.cc +++ b/chrome/browser/autofill/autofill_profile.cc @@ -4,6 +4,7 @@ #include "chrome/browser/autofill/autofill_profile.h" +#include <algorithm> #include <vector> #include "app/l10n_util.h" @@ -52,12 +53,21 @@ AutoFillProfile::~AutoFillProfile() { void AutoFillProfile::GetPossibleFieldTypes( const string16& text, FieldTypeSet* possible_types) const { - FormGroupMap::const_iterator iter; - for (iter = personal_info_.begin(); iter != personal_info_.end(); ++iter) { + for (FormGroupMap::const_iterator iter = personal_info_.begin(); + iter != personal_info_.end(); ++iter) { + FormGroup* data = iter->second; + DCHECK(data != NULL); + data->GetPossibleFieldTypes(text, possible_types); + } +} + +void AutoFillProfile::GetAvailableFieldTypes( + FieldTypeSet* available_types) const { + for (FormGroupMap::const_iterator iter = personal_info_.begin(); + iter != personal_info_.end(); ++iter) { FormGroup* data = iter->second; DCHECK(data != NULL); - if (data != NULL) - data->GetPossibleFieldTypes(text, possible_types); + data->GetAvailableFieldTypes(available_types); } } @@ -148,6 +158,58 @@ FormGroup* AutoFillProfile::Clone() const { return profile; } +bool AutoFillProfile::IsSubsetOf(const AutoFillProfile& profile) const { + FieldTypeSet types; + GetAvailableFieldTypes(&types); + + for (FieldTypeSet::const_iterator iter = types.begin(); iter != types.end(); + ++iter) { + AutoFillType type(*iter); + if (GetFieldText(type) != profile.GetFieldText(type)) + return false; + } + + return true; +} + +bool AutoFillProfile::IntersectionOfTypesHasEqualValues( + const AutoFillProfile& profile) const { + FieldTypeSet a, b, intersection; + GetAvailableFieldTypes(&a); + profile.GetAvailableFieldTypes(&b); + std::set_intersection(a.begin(), a.end(), + b.begin(), b.end(), + std::inserter(intersection, intersection.begin())); + + // An empty intersection can't have equal values. + if (intersection.empty()) + return false; + + for (FieldTypeSet::const_iterator iter = intersection.begin(); + iter != intersection.end(); ++iter) { + AutoFillType type(*iter); + if (GetFieldText(type) != profile.GetFieldText(type)) + return false; + } + + return true; +} + +void AutoFillProfile::MergeWith(const AutoFillProfile& profile) { + FieldTypeSet a, b, intersection; + GetAvailableFieldTypes(&a); + profile.GetAvailableFieldTypes(&b); + std::set_difference(b.begin(), b.end(), + a.begin(), a.end(), + std::inserter(intersection, intersection.begin())); + + for (FieldTypeSet::const_iterator iter = intersection.begin(); + iter != intersection.end(); ++iter) { + AutoFillType type(*iter); + SetInfo(type, profile.GetFieldText(type)); + } +} + string16 AutoFillProfile::PreviewSummary() const { // Fetch the components of the summary string. Any or all of these // may be an empty string. diff --git a/chrome/browser/autofill/autofill_profile.h b/chrome/browser/autofill/autofill_profile.h index 2dbcd2f..189bc55 100644 --- a/chrome/browser/autofill/autofill_profile.h +++ b/chrome/browser/autofill/autofill_profile.h @@ -29,6 +29,7 @@ class AutoFillProfile : public FormGroup { // FormGroup implementation: virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const; + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const; virtual string16 GetFieldText(const AutoFillType& type) const; // Returns true if the info matches the profile data corresponding to type. // If the type is UNKNOWN_TYPE then info will be matched against all of the @@ -45,6 +46,17 @@ class AutoFillProfile : public FormGroup { void set_unique_id(int id) { unique_id_ = id; } int unique_id() const { return unique_id_; } + // Returns true if the data in this profile is a subset of the data in + // |profile|. + bool IsSubsetOf(const AutoFillProfile& profile) const; + + // Returns true if the values of the intersection of the available field types + // are equal. If the intersection is empty, the method returns false. + bool IntersectionOfTypesHasEqualValues(const AutoFillProfile& profile) const; + + // Merges the profile data in |profile| with this profile. + void MergeWith(const AutoFillProfile& profile); + // Profile summary string for UI. // Constructs a summary string based on NAME_FIRST, NAME_LAST, and // ADDRESS_HOME_LINE1 fields of the profile. The summary string is of the diff --git a/chrome/browser/autofill/autofill_profile_unittest.cc b/chrome/browser/autofill/autofill_profile_unittest.cc index 969a44a..6c3c759 100644 --- a/chrome/browser/autofill/autofill_profile_unittest.cc +++ b/chrome/browser/autofill/autofill_profile_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/basictypes.h" +#include "base/scoped_ptr.h" #include "base/string16.h" #include "chrome/browser/autofill/autofill_common_unittest.h" #include "chrome/browser/autofill/autofill_profile.h" @@ -20,164 +21,168 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 0/empty: "" AutoFillProfile profile00(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile00, - "Billing", - "", - "Mitchell", - "", - "johnwayne@me.xyz", - "Fox", - "", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile00, "Billing", "", "Mitchell", "", + "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US", + "12345678910", "01987654321"); string16 summary00 = profile00.PreviewSummary(); EXPECT_EQ(string16(), summary00); // Case 1: "<address>" AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile1, - "Billing", - "", - "Mitchell", - "", - "johnwayne@me.xyz", - "Fox", - "123 Zoo St.", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile1, "Billing", "", "Mitchell", "", + "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", + "91601", "US", "12345678910", "01987654321"); string16 summary1 = profile1.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("123 Zoo St.")), summary1); // Case 2: "<lastname>" AutoFillProfile profile2(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile2, - "Billing", - "", - "Mitchell", - "Morrison", - "johnwayne@me.xyz", - "Fox", - "", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile2, "Billing", "", "Mitchell", + "Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", + "91601", "US", "12345678910", "01987654321"); string16 summary2 = profile2.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Morrison")), summary2); // Case 3: "<lastname>, <address>" AutoFillProfile profile3(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile3, - "Billing", - "", - "Mitchell", - "Morrison", - "johnwayne@me.xyz", - "Fox", - "123 Zoo St.", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile3, "Billing", "", "Mitchell", + "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", + "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary3 = profile3.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Morrison, 123 Zoo St.")), summary3); // Case 4: "<firstname>" AutoFillProfile profile4(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile4, - "Billing", - "Marion", - "Mitchell", - "", - "johnwayne@me.xyz", - "Fox", - "", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile4, "Billing", "Marion", "Mitchell", + "", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", + "US", "12345678910", "01987654321"); string16 summary4 = profile4.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion")), summary4); // Case 5: "<firstname>, <address>" AutoFillProfile profile5(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile5, - "Billing", - "Marion", - "Mitchell", - "", - "johnwayne@me.xyz", - "Fox", - "123 Zoo St.", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile5, "Billing", "Marion", "Mitchell", + "", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", + "91601", "US", "12345678910", "01987654321"); string16 summary5 = profile5.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion, 123 Zoo St.")), summary5); // Case 6: "<firstname> <lastname>" AutoFillProfile profile6(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile6, - "Billing", - "Marion", - "Mitchell", - "Morrison", - "johnwayne@me.xyz", - "Fox", - "", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile6, "Billing", "Marion", "Mitchell", + "Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", + "91601", "US", "12345678910", "01987654321"); string16 summary6 = profile6.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion Morrison")), summary6); // Case 7: "<firstname> <lastname>, <address>" AutoFillProfile profile7(string16(), 0); - autofill_unittest::SetProfileInfo( - &profile7, - "Billing", - "Marion", - "Mitchell", - "Morrison", - "johnwayne@me.xyz", - "Fox", - "123 Zoo St.", - "unit 5", - "Hollywood", "CA", - "91601", - "US", - "12345678910", - "01987654321"); + autofill_unittest::SetProfileInfo(&profile7, "Billing", "Marion", "Mitchell", + "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", + "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary7 = profile7.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion Morrison, 123 Zoo St.")), summary7); } +TEST(AutoFillProfileTest, IsSubsetOf) { + scoped_ptr<AutoFillProfile> a, b; + + // |a| is a subset of |b|. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", "United States Government", + "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, + NULL); + EXPECT_TRUE(a->IsSubsetOf(*b)); + + // |b| is not a subset of |a|. + EXPECT_FALSE(b->IsSubsetOf(*a)); + + // |a| is a subset of |a|. + EXPECT_TRUE(a->IsSubsetOf(*a)); + + // One field in |b| is different. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + autofill_unittest::SetProfileInfo(a.get(), "label2", "Thomas", NULL, + "Adams", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + EXPECT_FALSE(a->IsSubsetOf(*b)); +} + +TEST(AutoFillProfileTest, IntersectionOfTypesHasEqualValues) { + scoped_ptr<AutoFillProfile> a, b; + + // Intersection of types contains the fields NAME_FIRST, NAME_LAST, + // EMAIL_ADDRESS. The values of these field types are equal between the two + // profiles. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "12134759123", "19384284720"); + autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", "United States Government", + "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, + NULL); + EXPECT_TRUE(a->IntersectionOfTypesHasEqualValues(*b)); + + // Intersection of types contains the fields NAME_FIRST, NAME_LAST, + // EMAIL_ADDRESS. The value of EMAIL_ADDRESS differs between the two profiles. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, + "Jefferson", "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "12134759123", "19384284720"); + autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, + "Jefferson", "declaration_guy@gmail.com", "United States Government", + "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, + NULL); + EXPECT_FALSE(a->IntersectionOfTypesHasEqualValues(*b)); + + // Intersection of types is empty. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, + "Jefferson", "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "12134759123", "19384284720"); + autofill_unittest::SetProfileInfo(b.get(), "label2", NULL, NULL, NULL, NULL, + "United States Government", "Monticello", NULL, "Charlottesville", + "Virginia", "22902", NULL, NULL, NULL); + EXPECT_FALSE(a->IntersectionOfTypesHasEqualValues(*b)); +} + +TEST(AutoFillProfileTest, MergeWith) { + scoped_ptr<AutoFillProfile> a, b; + + // Merge |b| into |a|. + a.reset(new AutoFillProfile); + b.reset(new AutoFillProfile); + autofill_unittest::SetProfileInfo(a.get(), "label1", "Jimmy", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "12134759123", "19384284720"); + autofill_unittest::SetProfileInfo(b.get(), "label2", "James", NULL, + "Madison", "constitutionalist@gmail.com", "United States Government", + "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, + NULL); + AutoFillProfile expected_b(*b); + a->MergeWith(*b); + + AutoFillProfile expected_a; + autofill_unittest::SetProfileInfo(&expected_a, "label1", "Jimmy", NULL, + "Madison", "constitutionalist@gmail.com", "United States Government", + "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, + "12134759123", "19384284720"); + EXPECT_EQ(expected_a, *a); + EXPECT_EQ(expected_b, *b); +} + } // namespace diff --git a/chrome/browser/autofill/contact_info.cc b/chrome/browser/autofill/contact_info.cc index 0355fd0..0709a24 100644 --- a/chrome/browser/autofill/contact_info.cc +++ b/chrome/browser/autofill/contact_info.cc @@ -28,6 +28,8 @@ FormGroup* ContactInfo::Clone() const { void ContactInfo::GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const { + DCHECK(possible_types); + if (IsFirstName(text)) possible_types->insert(NAME_FIRST); @@ -53,13 +55,38 @@ void ContactInfo::GetPossibleFieldTypes(const string16& text, possible_types->insert(COMPANY_NAME); } +void ContactInfo::GetAvailableFieldTypes(FieldTypeSet* available_types) const { + DCHECK(available_types); + + if (!first().empty()) + available_types->insert(NAME_FIRST); + + if (!middle().empty()) + available_types->insert(NAME_MIDDLE); + + if (!last().empty()) + available_types->insert(NAME_LAST); + + if (!MiddleInitial().empty()) + available_types->insert(NAME_MIDDLE_INITIAL); + + if (!FullName().empty()) + available_types->insert(NAME_FULL); + + if (!suffix().empty()) + available_types->insert(NAME_SUFFIX); + + if (!email().empty()) + available_types->insert(EMAIL_ADDRESS); + + if (!company_name().empty()) + available_types->insert(COMPANY_NAME); +} + void ContactInfo::FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const { - if (matched_text == NULL) { - DLOG(ERROR) << "NULL matched vector passed in"; - return; - } + DCHECK(matched_text); string16 match; if (type.field_type() == UNKNOWN_TYPE) { diff --git a/chrome/browser/autofill/contact_info.h b/chrome/browser/autofill/contact_info.h index a1325ea..a2aa6cb 100644 --- a/chrome/browser/autofill/contact_info.h +++ b/chrome/browser/autofill/contact_info.h @@ -21,6 +21,7 @@ class ContactInfo : public FormGroup { virtual FormGroup* Clone() const; virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const; + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const; virtual void FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const; diff --git a/chrome/browser/autofill/credit_card.cc b/chrome/browser/autofill/credit_card.cc index f694cda..dcebb32 100644 --- a/chrome/browser/autofill/credit_card.cc +++ b/chrome/browser/autofill/credit_card.cc @@ -21,7 +21,6 @@ static const AutoFillFieldType kAutoFillCreditCardTypes[] = { CREDIT_CARD_TYPE, CREDIT_CARD_EXP_MONTH, CREDIT_CARD_EXP_4_DIGIT_YEAR, - CREDIT_CARD_VERIFICATION_CODE, }; static const int kAutoFillCreditCardLength = @@ -66,18 +65,34 @@ void CreditCard::GetPossibleFieldTypes(const string16& text, if (IsCardType(text)) possible_types->insert(CREDIT_CARD_TYPE); +} + +void CreditCard::GetAvailableFieldTypes(FieldTypeSet* available_types) const { + DCHECK(available_types); + + if (!name_on_card().empty()) + available_types->insert(CREDIT_CARD_NAME); + + if (!ExpirationMonthAsString().empty()) + available_types->insert(CREDIT_CARD_EXP_MONTH); + + if (!Expiration2DigitYearAsString().empty()) + available_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); + + if (!Expiration4DigitYearAsString().empty()) + available_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR); - if (IsVerificationCode(text)) - possible_types->insert(CREDIT_CARD_VERIFICATION_CODE); + if (!type().empty()) + available_types->insert(CREDIT_CARD_TYPE); + + if (!number().empty()) + available_types->insert(CREDIT_CARD_NUMBER); } void CreditCard::FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const { - if (matched_text == NULL) { - DLOG(ERROR) << "NULL matched vector passed in"; - return; - } + DCHECK(matched_text); string16 match; switch (type.field_type()) { @@ -92,6 +107,7 @@ void CreditCard::FindInfoMatches(const AutoFillType& type, } case CREDIT_CARD_VERIFICATION_CODE: + NOTREACHED(); break; case UNKNOWN_TYPE: @@ -145,7 +161,8 @@ string16 CreditCard::GetFieldText(const AutoFillType& type) const { return number(); case CREDIT_CARD_VERIFICATION_CODE: - return verification_code(); + NOTREACHED(); + return string16(); default: // ComputeDataPresentForArray will hit this repeatedly. @@ -159,7 +176,8 @@ string16 CreditCard::GetPreviewText(const AutoFillType& type) const { return last_four_digits(); case CREDIT_CARD_VERIFICATION_CODE: - return ASCIIToUTF16("xxx"); + NOTREACHED(); + return string16(); default: return GetFieldText(type); @@ -198,7 +216,7 @@ void CreditCard::SetInfo(const AutoFillType& type, const string16& value) { } break; case CREDIT_CARD_VERIFICATION_CODE: - set_verification_code(value); + NOTREACHED(); break; default: @@ -223,8 +241,8 @@ string16 CreditCard::PreviewSummary() const { return preview; // No CC number, means empty preview. string16 obfuscated_cc_number = ObfuscatedNumber(); if (!expiration_month() || !expiration_year()) - return obfuscated_cc_number; // no expiration date set - // TODO(georgey): internationalize date + return obfuscated_cc_number; // No expiration date set. + // TODO(georgey): Internationalize date. string16 formatted_date(ExpirationMonthAsString()); formatted_date.append(ASCIIToUTF16("/")); formatted_date.append(Expiration4DigitYearAsString()); @@ -249,13 +267,11 @@ void CreditCard::operator=(const CreditCard& source) { number_ = source.number_; name_on_card_ = source.name_on_card_; type_ = source.type_; - verification_code_ = source.verification_code_; last_four_digits_ = source.last_four_digits_; expiration_month_ = source.expiration_month_; expiration_year_ = source.expiration_year_; label_ = source.label_; billing_address_ = source.billing_address_; - shipping_address_ = source.shipping_address_; unique_id_ = source.unique_id_; } @@ -266,14 +282,12 @@ bool CreditCard::operator==(const CreditCard& creditcard) const { const AutoFillFieldType types[] = { CREDIT_CARD_NAME, CREDIT_CARD_TYPE, CREDIT_CARD_NUMBER, - CREDIT_CARD_VERIFICATION_CODE, CREDIT_CARD_EXP_MONTH, CREDIT_CARD_EXP_4_DIGIT_YEAR }; if (label_ != creditcard.label_ || unique_id_ != creditcard.unique_id_ || - billing_address_ != creditcard.billing_address_ || - shipping_address_ != creditcard.shipping_address_) { + billing_address_ != creditcard.billing_address_) { return false; } @@ -377,10 +391,7 @@ void CreditCard::set_expiration_year(int expiration_year) { bool CreditCard::FindInfoMatchesHelper(const AutoFillFieldType& field_type, const string16& info, string16* match) const { - if (match == NULL) { - DLOG(ERROR) << "NULL match string passed in"; - return false; - } + DCHECK(match); match->clear(); switch (field_type) { @@ -428,10 +439,9 @@ bool CreditCard::FindInfoMatchesHelper(const AutoFillFieldType& field_type, *match = card_type; } - case CREDIT_CARD_VERIFICATION_CODE: { - if (StartsWith(verification_code(), info, true)) - *match = verification_code(); - } + case CREDIT_CARD_VERIFICATION_CODE: + NOTREACHED(); + break; default: break; @@ -443,10 +453,6 @@ bool CreditCard::IsNameOnCard(const string16& text) const { return StringToLowerASCII(text) == StringToLowerASCII(name_on_card_); } -bool CreditCard::IsVerificationCode(const string16& text) const { - return StringToLowerASCII(text) == StringToLowerASCII(verification_code_); -} - bool CreditCard::IsExpirationMonth(const string16& text) const { int month; if (!StringToInt(text, &month)) @@ -498,8 +504,6 @@ std::ostream& operator<<(std::ostream& os, const CreditCard& creditcard) { << " " << UTF16ToUTF8(creditcard.billing_address()) << " " - << UTF16ToUTF8(creditcard.shipping_address()) - << " " << UTF16ToUTF8(creditcard.GetFieldText(AutoFillType(CREDIT_CARD_NAME))) << " " << UTF16ToUTF8(creditcard.GetFieldText(AutoFillType(CREDIT_CARD_TYPE))) @@ -507,9 +511,6 @@ std::ostream& operator<<(std::ostream& os, const CreditCard& creditcard) { << UTF16ToUTF8(creditcard.GetFieldText(AutoFillType(CREDIT_CARD_NUMBER))) << " " << UTF16ToUTF8(creditcard.GetFieldText( - AutoFillType(CREDIT_CARD_VERIFICATION_CODE))) - << " " - << UTF16ToUTF8(creditcard.GetFieldText( AutoFillType(CREDIT_CARD_EXP_MONTH))) << " " << UTF16ToUTF8(creditcard.GetFieldText( diff --git a/chrome/browser/autofill/credit_card.h b/chrome/browser/autofill/credit_card.h index 00e5f39..faf4326 100644 --- a/chrome/browser/autofill/credit_card.h +++ b/chrome/browser/autofill/credit_card.h @@ -22,6 +22,7 @@ class CreditCard : public FormGroup { FormGroup* Clone() const; virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const; + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const; virtual void FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const; @@ -38,18 +39,12 @@ class CreditCard : public FormGroup { string16 LastFourDigits() const; const string16& billing_address() const { return billing_address_; } - const string16& shipping_address() const { return shipping_address_; } int unique_id() const { return unique_id_; } - // The caller should verify that the corresponding AutoFillProfile exists. If - // the shipping address should be the same as the billing address, send in an - // empty string to set_shipping_address. + // The caller should verify that the corresponding AutoFillProfile exists. void set_billing_address(const string16& address) { billing_address_ = address; } - void set_shipping_address(const string16& address) { - shipping_address_ = address; - } void set_unique_id(int id) { unique_id_ = id; } // For use in STL containers. @@ -81,7 +76,6 @@ class CreditCard : public FormGroup { const string16& number() const { return number_; } const string16& name_on_card() const { return name_on_card_; } const string16& type() const { return type_; } - const string16& verification_code() const { return verification_code_; } const string16& last_four_digits() const { return last_four_digits_; } int expiration_month() const { return expiration_month_; } int expiration_year() const { return expiration_year_; } @@ -91,9 +85,6 @@ class CreditCard : public FormGroup { name_on_card_ = name_on_card; } void set_type(const string16& type) { type_ = type; } - void set_verification_code(const string16& verification_code) { - verification_code_ = verification_code; - } void set_last_four_digits(const string16& last_four_digits) { last_four_digits_ = last_four_digits; } @@ -116,10 +107,6 @@ class CreditCard : public FormGroup { // Returns true if |text| matches the expiration month of the card. bool IsExpirationMonth(const string16& text) const; - // Returns true if |text| matches the CVV of the card. The comparison is - // case-insensitive. - bool IsVerificationCode(const string16& text) const; - // Returns true if the integer value of |text| matches the 2-digit expiration // year. bool Is2DigitExpirationYear(const string16& text) const; @@ -139,7 +126,6 @@ class CreditCard : public FormGroup { string16 number_; // The credit card number. string16 name_on_card_; // The cardholder's name. string16 type_; // The type of the card. - string16 verification_code_; // The CVV. // Stores the last four digits of the credit card number. string16 last_four_digits_; @@ -151,12 +137,9 @@ class CreditCard : public FormGroup { // This is the display name of the card set by the user, e.g., Amazon Visa. string16 label_; - // The billing and shipping addresses. The are the labels of - // AutoFillProfiles that contain the corresponding address. If - // |shipping_address_| is empty, the billing address is used for the shipping - // address. + // The billing address. This is the label of the AutoFillProfile that contains + // the corresponding billing address. string16 billing_address_; - string16 shipping_address_; // The unique ID of this credit card. int unique_id_; diff --git a/chrome/browser/autofill/credit_card_field.cc b/chrome/browser/autofill/credit_card_field.cc index ba55746..770cff4 100644 --- a/chrome/browser/autofill/credit_card_field.cc +++ b/chrome/browser/autofill/credit_card_field.cc @@ -30,9 +30,6 @@ bool CreditCardField::GetFieldInfo(FieldTypeMap* field_type_map) const { AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR)); DCHECK(ok); - Add(field_type_map, verification_, - AutoFillType(CREDIT_CARD_VERIFICATION_CODE)); - return ok; } @@ -88,23 +85,6 @@ CreditCardField* CreditCardField::Parse( // TODO(jhawkins): Parse the type select control. - // We look for a card security code before we look for a credit card number - // and match the general term "number". The security code has a plethora of - // names; we've seen "verification #", "verification number", - // "card identification number" and others listed in the ParseText() call - // below. - if (is_ecml) { - pattern = GetEcmlPattern(kEcmlCardVerification); - } else { - pattern = ASCIIToUTF16( - "verification|card identification|cvn|security code|cvv code|cvc"); - } - - if (credit_card_field->verification_ == NULL && - ParseText(&q, pattern, &credit_card_field->verification_)) { - continue; - } - if (is_ecml) pattern = GetEcmlPattern(kEcmlCardNumber); else @@ -177,7 +157,6 @@ CreditCardField::CreditCardField() cardholder_last_(NULL), type_(NULL), number_(NULL), - verification_(NULL), expiration_month_(NULL), expiration_year_(NULL) { } diff --git a/chrome/browser/autofill/credit_card_field.h b/chrome/browser/autofill/credit_card_field.h index 581ab56..bd128d3 100644 --- a/chrome/browser/autofill/credit_card_field.h +++ b/chrome/browser/autofill/credit_card_field.h @@ -38,9 +38,6 @@ class CreditCardField : public FormField { AutoFillField* type_; // Optional. TODO(jhawkins): Parse the select control. AutoFillField* number_; // Required. - // The 3-digit card verification number; we don't currently fill this. - AutoFillField* verification_; - // Both required. TODO(jhawkins): Parse the select control. AutoFillField* expiration_month_; AutoFillField* expiration_year_; diff --git a/chrome/browser/autofill/credit_card_field_unittest.cc b/chrome/browser/autofill/credit_card_field_unittest.cc index 684ac78..61e6840 100644 --- a/chrome/browser/autofill/credit_card_field_unittest.cc +++ b/chrome/browser/autofill/credit_card_field_unittest.cc @@ -206,10 +206,9 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCard) { field_type_map_.find(ASCIIToUTF16("year1")) != field_type_map_.end()); EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, field_type_map_[ASCIIToUTF16("year1")]); - ASSERT_TRUE( - field_type_map_.find(ASCIIToUTF16("cvc1")) != field_type_map_.end()); - EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, - field_type_map_[ASCIIToUTF16("cvc1")]); + // We don't store CVV. + EXPECT_TRUE( + field_type_map_.find(ASCIIToUTF16("cvc1")) == field_type_map_.end()); } TEST_F(CreditCardFieldTest, ParseFullCreditCardEcml) { @@ -266,10 +265,9 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCardEcml) { field_type_map_.find(ASCIIToUTF16("year1")) != field_type_map_.end()); EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, field_type_map_[ASCIIToUTF16("year1")]); - ASSERT_TRUE( - field_type_map_.find(ASCIIToUTF16("cvc1")) != field_type_map_.end()); - EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, - field_type_map_[ASCIIToUTF16("cvc1")]); + // We don't store the CVV. + EXPECT_TRUE( + field_type_map_.find(ASCIIToUTF16("cvc1")) == field_type_map_.end()); } TEST_F(CreditCardFieldTest, ParseExpMonthYear) { diff --git a/chrome/browser/autofill/credit_card_unittest.cc b/chrome/browser/autofill/credit_card_unittest.cc index 8241e0b..f065a9f 100644 --- a/chrome/browser/autofill/credit_card_unittest.cc +++ b/chrome/browser/autofill/credit_card_unittest.cc @@ -22,17 +22,8 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 00: Empty credit card with empty strings. CreditCard credit_card00(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card00, - "Corporate", - "John Dillinger", - "Visa", - "", - "", - "", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card00, "Corporate", + "John Dillinger", "Visa", "", "", "", "Chicago"); string16 summary00 = credit_card00.PreviewSummary(); EXPECT_EQ(summary00, string16()); string16 obfuscated00 = credit_card00.ObfuscatedNumber(); @@ -40,17 +31,8 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 1: No credit card number. CreditCard credit_card1(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card1, - "Corporate", - "John Dillinger", - "Visa", - "", - "01", - "2010", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card1, "Corporate", + "John Dillinger", "Visa", "", "01", "2010", "Chicago"); string16 summary1 = credit_card1.PreviewSummary(); EXPECT_EQ(summary1, string16()); string16 obfuscated1 = credit_card1.ObfuscatedNumber(); @@ -58,17 +40,8 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 2: No month. CreditCard credit_card2(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card2, - "Corporate", - "John Dillinger", - "Visa", - "123456789012", - "", - "2010", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card2, "Corporate", + "John Dillinger", "Visa", "123456789012", "", "2010", "Chicago"); string16 summary2 = credit_card2.PreviewSummary(); EXPECT_EQ(summary2, string16(ASCIIToUTF16("************9012"))); string16 obfuscated2 = credit_card2.ObfuscatedNumber(); @@ -76,17 +49,8 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 3: No year. CreditCard credit_card3(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card3, - "Corporate", - "John Dillinger", - "Visa", - "123456789012", - "01", - "", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card3, "Corporate", + "John Dillinger", "Visa", "123456789012", "01", "", "Chicago"); string16 summary3 = credit_card3.PreviewSummary(); EXPECT_EQ(summary3, string16(ASCIIToUTF16("************9012"))); string16 obfuscated3 = credit_card3.ObfuscatedNumber(); @@ -94,17 +58,8 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 4: Have everything. CreditCard credit_card4(string16(), 0); - autofill_unittest::SetCreditCardInfo( - &credit_card4, - "Corporate", - "John Dillinger", - "Visa", - "123456789012", - "01", - "2010", - "123", - "Chicago", - "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&credit_card4, "Corporate", + "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago"); string16 summary4 = credit_card4.PreviewSummary(); EXPECT_EQ(summary4, string16(ASCIIToUTF16("************9012, Exp: 01/2010"))); string16 obfuscated4 = credit_card4.ObfuscatedNumber(); diff --git a/chrome/browser/autofill/field_types.h b/chrome/browser/autofill/field_types.h index ff713c2..934fa45 100644 --- a/chrome/browser/autofill/field_types.h +++ b/chrome/browser/autofill/field_types.h @@ -15,8 +15,8 @@ typedef enum _AddressType { // NOTE: This list MUST not be modified. The server aggregates and stores these // types over several versions, so we must remain fully compatible with the -// autofill server, which is itself backward-compatible. The list must be kept -// up to date with the autofill server list. +// AutoFill server, which is itself backward-compatible. The list must be kept +// up to date with the AutoFill server list. // // This is the list of all valid field types. typedef enum _FieldType { diff --git a/chrome/browser/autofill/form_group.h b/chrome/browser/autofill/form_group.h index 63315ea..8e9ab98 100644 --- a/chrome/browser/autofill/form_group.h +++ b/chrome/browser/autofill/form_group.h @@ -28,7 +28,11 @@ class FormGroup { virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const = 0; - // Returns the string that should be autofilled into a text field given the + // Returns a set of AutoFillFieldTypes for which this FormGroup has non-empty + // data. + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const = 0; + + // Returns the string that should be auto-filled into a text field given the // type of that field. virtual string16 GetFieldText(const AutoFillType& type) const = 0; diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc index ed90de3..7b8848f 100644 --- a/chrome/browser/autofill/form_structure_unittest.cc +++ b/chrome/browser/autofill/form_structure_unittest.cc @@ -615,7 +615,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { form_structure.reset(new FormStructure(form)); EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(6U, form_structure->field_count()); - ASSERT_EQ(5U, form_structure->autofill_count()); + ASSERT_EQ(4U, form_structure->autofill_count()); // Credit card name. EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); @@ -626,9 +626,8 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { // Credit card expiration year. EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, form_structure->field(3)->heuristic_type()); - // Credit card cvc. - EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, - form_structure->field(4)->heuristic_type()); + // We don't determine CVV. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(4)->heuristic_type()); // Submit. EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); } @@ -678,7 +677,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { form_structure.reset(new FormStructure(form)); EXPECT_TRUE(form_structure->IsAutoFillable()); ASSERT_EQ(7U, form_structure->field_count()); - ASSERT_EQ(5U, form_structure->autofill_count()); + ASSERT_EQ(4U, form_structure->autofill_count()); // Credit card name. EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); @@ -691,9 +690,8 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { // Credit card expiration year. EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, form_structure->field(4)->heuristic_type()); - // Credit card cvc. - EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, - form_structure->field(5)->heuristic_type()); + // We don't determine CVV. + EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); // Submit. EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); } diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc index 05bc8ab..43c06d1 100644 --- a/chrome/browser/autofill/personal_data_manager.cc +++ b/chrome/browser/autofill/personal_data_manager.cc @@ -22,8 +22,8 @@ namespace { // The minimum number of fields that must contain user data and have known types -// before autofill will attempt to import the data into a profile. -const int kMinImportSize = 5; +// before AutoFill will attempt to import the data into a profile. +const int kMinImportSize = 3; const char kUnlabeled[] = "Unlabeled"; @@ -78,8 +78,8 @@ void PersonalDataManager::OnWebDataServiceRequestDone( void PersonalDataManager::OnAutoFillDialogApply( std::vector<AutoFillProfile>* profiles, std::vector<CreditCard>* credit_cards) { - // |profiles| may be NULL - // |credit_cards| may be NULL + // |profiles| may be NULL. + // |credit_cards| may be NULL. if (profiles) { CancelPendingQuery(&pending_profiles_query_); SetProfiles(profiles); @@ -205,28 +205,16 @@ bool PersonalDataManager::ImportFormData( if (importable_credit_card_fields == 0) imported_credit_card_.reset(); - return true; -} - -void PersonalDataManager::SaveImportedFormData() { - if (profile_->IsOffTheRecord()) - return; + { + // We're now done with the unique IDs, and SaveImportedProfile() needs the + // lock, so release it. + AutoUnlock unlock(unique_ids_lock_); - if (imported_profile_.get()) { - imported_profile_->set_label(ASCIIToUTF16(kUnlabeled)); - - std::vector<AutoFillProfile> profiles; - profiles.push_back(*imported_profile_); - SetProfiles(&profiles); + // We always save imported profiles. + SaveImportedProfile(); } - if (imported_credit_card_.get()) { - imported_credit_card_->set_label(ASCIIToUTF16(kUnlabeled)); - - std::vector<CreditCard> credit_cards; - credit_cards.push_back(*imported_credit_card_); - SetCreditCards(&credit_cards); - } + return true; } void PersonalDataManager::GetImportedFormData(AutoFillProfile** profile, @@ -256,6 +244,7 @@ void PersonalDataManager::SetProfiles(std::vector<AutoFillProfile>* profiles) { return; AutoLock lock(unique_ids_lock_); + // Remove the unique IDs of the new set of profiles from the unique ID set. for (std::vector<AutoFillProfile>::iterator iter = profiles->begin(); iter != profiles->end(); ++iter) { @@ -320,6 +309,7 @@ void PersonalDataManager::SetCreditCards( return; AutoLock lock(unique_ids_lock_); + // Remove the unique IDs of the new set of credit cards from the unique ID // set. for (std::vector<CreditCard>::iterator iter = credit_cards->begin(); @@ -603,3 +593,49 @@ void PersonalDataManager::SetUniqueCreditCardLabels( } } } + +void PersonalDataManager::SaveImportedProfile() { + if (profile_->IsOffTheRecord()) + return; + + if (!imported_profile_.get()) + return; + + // Set to true if |imported_profile_| is merged into the profile list. + bool merged = false; + + imported_profile_->set_label(ASCIIToUTF16(kUnlabeled)); + + // Don't save a web profile if the data in the profile is a subset of an + // auxiliary profile. + for (std::vector<AutoFillProfile*>::const_iterator iter = + auxiliary_profiles_.begin(); + iter != auxiliary_profiles_.end(); ++iter) { + if (imported_profile_->IsSubsetOf(**iter)) + return; + } + + std::vector<AutoFillProfile> profiles; + for (std::vector<AutoFillProfile*>::const_iterator iter = + web_profiles_.begin(); + iter != web_profiles_.end(); ++iter) { + if (imported_profile_->IsSubsetOf(**iter)) { + // In this case, the existing profile already contains all of the data + // in |imported_profile|, so consider the profiles already merged. + merged = true; + } else if ((*iter)->IntersectionOfTypesHasEqualValues( + *imported_profile_)) { + // |imported_profile| contains all of the data in this profile, plus + // more. + merged = true; + (*iter)->MergeWith(*imported_profile_); + } + + profiles.push_back(**iter); + } + + if (!merged) + profiles.push_back(*imported_profile_); + + SetProfiles(&profiles); +} diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h index cfa7109..a719de8 100644 --- a/chrome/browser/autofill/personal_data_manager.h +++ b/chrome/browser/autofill/personal_data_manager.h @@ -64,10 +64,6 @@ class PersonalDataManager bool ImportFormData(const std::vector<FormStructure*>& form_structures, AutoFillManager* autofill_manager); - // Saves |imported_profile_| and |imported_credit_card_| to the WebDB if they - // exist. - virtual void SaveImportedFormData(); - // Gets |imported_profile_| and |imported_credit_card_| and returns their // values in |profile| and |credit_card| parameters respectively. One or // both may return NULL. The objects returned are owned by the @@ -82,7 +78,7 @@ class PersonalDataManager // // The relationship between this and Refresh is subtle. // A call to SetProfile could include out-of-date data that may conflict - // if we didn't refresh-to-latest before an autofill window was opened for + // if we didn't refresh-to-latest before an AutoFill window was opened for // editing. SetProfile is implemented to make a "best effort" to apply the // changes, but in extremely rare edge cases it is possible not all of the // updates in |profiles| make it to the DB. This is why SetProfiles will @@ -192,6 +188,10 @@ class PersonalDataManager void SetUniqueProfileLabels(std::vector<AutoFillProfile>* profiles); void SetUniqueCreditCardLabels(std::vector<CreditCard>* credit_cards); + // Saves |imported_profile_| to the WebDB if it exists. + // TODO(jhawkins): SaveImportedCreditCard. + void SaveImportedProfile(); + // The profile hosting this PersonalDataManager. Profile* profile_; diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc index 41b051f..c709f09 100644 --- a/chrome/browser/autofill/personal_data_manager_unittest.cc +++ b/chrome/browser/autofill/personal_data_manager_unittest.cc @@ -23,6 +23,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using webkit_glue::FormData; + ACTION(QuitUIMessageLoop) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); MessageLoop::current()->Quit(); @@ -178,19 +180,16 @@ TEST_F(PersonalDataManagerTest, SetProfiles) { // TODO(jhawkins): Test SetCreditCards w/out a WebDataService in the profile. TEST_F(PersonalDataManagerTest, SetCreditCards) { CreditCard creditcard0(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard0, - "Corporate", "John Dillinger", "Visa", - "123456789012", "01", "2010", "123", "Chicago", "Indianapolis"); + autofill_unittest::SetCreditCardInfo(&creditcard0, "Corporate", + "John Dillinger", "Visa", "123456789012", "01", "2010", "Chicago"); CreditCard creditcard1(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard1, - "Personal", "Bonnie Parker", "Mastercard", - "098765432109", "12", "2012", "987", "Dallas", ""); + autofill_unittest::SetCreditCardInfo(&creditcard1, "Personal", + "Bonnie Parker", "Mastercard", "098765432109", "12", "2012", "Dallas"); CreditCard creditcard2(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard2, - "Savings", "Clyde Barrow", "American Express", - "777666888555", "04", "2015", "445", "Home", "Farm"); + autofill_unittest::SetCreditCardInfo(&creditcard2, "Savings", "Clyde Barrow", + "American Express", "777666888555", "04", "2015", "Home"); // This will verify that the web database has been loaded and the notification // sent out. @@ -347,12 +346,21 @@ TEST_F(PersonalDataManagerTest, Refresh) { } TEST_F(PersonalDataManagerTest, ImportFormData) { - webkit_glue::FormData form; + FormData form; + webkit_glue::FormField field; + autofill_unittest::CreateTestFormField( + "First name:", "first_name", "George", "text", &field); + form.fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Last name:", "last_name", "Washington", "text", &field); + form.fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Email:", "email", "theprez@gmail.com", "text", &field); + form.fields.push_back(field); FormStructure form_structure(form); std::vector<FormStructure*> forms; forms.push_back(&form_structure); personal_data_->ImportFormData(forms, NULL); - personal_data_->SaveImportedFormData(); // And wait for the refresh. EXPECT_CALL(personal_data_observer_, @@ -361,9 +369,12 @@ TEST_F(PersonalDataManagerTest, ImportFormData) { MessageLoop::current()->Run(); AutoFillProfile expected(ASCIIToUTF16("Unlabeled"), 1); + autofill_unittest::SetProfileInfo(&expected, "Unlabeled", "George", NULL, + "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL); const std::vector<AutoFillProfile*>& results = personal_data_->profiles(); ASSERT_EQ(1U, results.size()); - ASSERT_EQ(expected, *results[0]); + EXPECT_EQ(expected, *results[0]); } TEST_F(PersonalDataManagerTest, SetUniqueProfileLabels) { @@ -443,3 +454,124 @@ TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) { EXPECT_EQ(ASCIIToUTF16("Work"), results[4]->Label()); EXPECT_EQ(ASCIIToUTF16("Work2"), results[5]->Label()); } + +TEST_F(PersonalDataManagerTest, AggregateProfileData) { + scoped_ptr<FormData> form(new FormData); + + webkit_glue::FormField field; + autofill_unittest::CreateTestFormField( + "First name:", "first_name", "George", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Last name:", "last_name", "Washington", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Email:", "email", "theprez@gmail.com", "text", &field); + form->fields.push_back(field); + + scoped_ptr<FormStructure> form_structure(new FormStructure(*form)); + scoped_ptr<std::vector<FormStructure*> > forms( + new std::vector<FormStructure*>); + forms->push_back(form_structure.get()); + personal_data_->ImportFormData(*forms, NULL); + + // And wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + scoped_ptr<AutoFillProfile> expected( + new AutoFillProfile(ASCIIToUTF16("Unlabeled"), 1)); + autofill_unittest::SetProfileInfo(expected.get(), "Unlabeled", "George", NULL, + "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL); + const std::vector<AutoFillProfile*>& results = personal_data_->profiles(); + ASSERT_EQ(1U, results.size()); + EXPECT_EQ(*expected, *results[0]); + + // Now create a completely different profile. + form.reset(new FormData); + autofill_unittest::CreateTestFormField( + "First name:", "first_name", "John", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Last name:", "last_name", "Adams", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Email:", "email", "second@gmail.com", "text", &field); + form->fields.push_back(field); + + form_structure.reset(new FormStructure(*form)); + forms.reset(new std::vector<FormStructure*>); + forms->push_back(form_structure.get()); + personal_data_->ImportFormData(*forms, NULL); + + // And wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + const std::vector<AutoFillProfile*>& results2 = personal_data_->profiles(); + ASSERT_EQ(2U, results2.size()); + + expected.reset(new AutoFillProfile(ASCIIToUTF16("Unlabeled"), 1)); + autofill_unittest::SetProfileInfo(expected.get(), "Unlabeled", "George", NULL, + "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL); + EXPECT_EQ(*expected, *results2[0]); + + expected.reset(new AutoFillProfile(ASCIIToUTF16("Unlabeled2"), 2)); + autofill_unittest::SetProfileInfo(expected.get(), "Unlabeled2", "John", NULL, + "Adams", "second@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); + EXPECT_EQ(*expected, *results2[1]); + + // Submit a form with new data for the first profile. + form.reset(new FormData); + autofill_unittest::CreateTestFormField( + "First name:", "first_name", "George", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Last name:", "last_name", "Washington", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Address Line 1:", "address", "190 High Street", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "City:", "city", "Philadelphia", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "State:", "state", "Pennsylvania", "text", &field); + form->fields.push_back(field); + autofill_unittest::CreateTestFormField( + "Zip:", "zipcode", "19106", "text", &field); + form->fields.push_back(field); + + form_structure.reset(new FormStructure(*form)); + forms.reset(new std::vector<FormStructure*>); + forms->push_back(form_structure.get()); + personal_data_->ImportFormData(*forms, NULL); + + // And wait for the refresh. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + MessageLoop::current()->Run(); + + const std::vector<AutoFillProfile*>& results3 = personal_data_->profiles(); + ASSERT_EQ(2U, results3.size()); + + expected.reset(new AutoFillProfile(ASCIIToUTF16("Unlabeled"), 1)); + autofill_unittest::SetProfileInfo(expected.get(), "Unlabeled", "George", NULL, + "Washington", "theprez@gmail.com", NULL, "190 High Street", NULL, + "Philadelphia", "Pennsylvania", "19106", NULL, NULL, NULL); + EXPECT_EQ(*expected, *results3[0]); + + expected.reset(new AutoFillProfile(ASCIIToUTF16("Unlabeled2"), 2)); + autofill_unittest::SetProfileInfo(expected.get(), "Unlabeled2", "John", NULL, + "Adams", "second@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); + EXPECT_EQ(*expected, *results3[1]); +} diff --git a/chrome/browser/autofill/phone_number.cc b/chrome/browser/autofill/phone_number.cc index 9605d1d..997edd9 100644 --- a/chrome/browser/autofill/phone_number.cc +++ b/chrome/browser/autofill/phone_number.cc @@ -55,6 +55,25 @@ void PhoneNumber::GetPossibleFieldTypes(const string16& text, possible_types->insert(GetWholeNumberType()); } +void PhoneNumber::GetAvailableFieldTypes(FieldTypeSet* available_types) const { + DCHECK(available_types); + + if (!number().empty()) + available_types->insert(GetNumberType()); + + if (!city_code().empty()) + available_types->insert(GetCityCodeType()); + + if (!country_code().empty()) + available_types->insert(GetCountryCodeType()); + + if (!CityAndNumber().empty()) + available_types->insert(GetCityAndNumberType()); + + if (!WholeNumber().empty()) + available_types->insert(GetWholeNumberType()); +} + string16 PhoneNumber::GetFieldText(const AutoFillType& type) const { AutoFillFieldType field_type = type.field_type(); if (field_type == GetNumberType()) @@ -72,7 +91,7 @@ string16 PhoneNumber::GetFieldText(const AutoFillType& type) const { if (field_type == GetWholeNumberType()) return WholeNumber(); - return EmptyString16(); + return string16(); } void PhoneNumber::FindInfoMatches(const AutoFillType& type, @@ -113,7 +132,8 @@ void PhoneNumber::SetInfo(const AutoFillType& type, const string16& value) { set_city_code(number); else if (subgroup == AutoFillType::PHONE_COUNTRY_CODE) set_country_code(number); - else if (subgroup == AutoFillType::PHONE_WHOLE_NUMBER) + else if (subgroup == AutoFillType::PHONE_CITY_AND_NUMBER || + subgroup == AutoFillType::PHONE_WHOLE_NUMBER) set_whole_number(number); else NOTREACHED(); diff --git a/chrome/browser/autofill/phone_number.h b/chrome/browser/autofill/phone_number.h index 9da3b98..a4cd6bb 100644 --- a/chrome/browser/autofill/phone_number.h +++ b/chrome/browser/autofill/phone_number.h @@ -20,6 +20,7 @@ class PhoneNumber : public FormGroup { virtual FormGroup* Clone() const = 0; virtual void GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const; + virtual void GetAvailableFieldTypes(FieldTypeSet* available_types) const; virtual void FindInfoMatches(const AutoFillType& type, const string16& info, std::vector<string16>* matched_text) const; |