diff options
author | ramankk@chromium.org <ramankk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 22:34:20 +0000 |
---|---|---|
committer | ramankk@chromium.org <ramankk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 22:34:20 +0000 |
commit | 40c251ea27033cfe7798041feb88cdabb03364f3 (patch) | |
tree | 30a5b7d67808dd46ce58361192fe52020405782b | |
parent | 437d282dcef1f0f0d316d3f8574706aeb86fbfa2 (diff) | |
download | chromium_src-40c251ea27033cfe7798041feb88cdabb03364f3.zip chromium_src-40c251ea27033cfe7798041feb88cdabb03364f3.tar.gz chromium_src-40c251ea27033cfe7798041feb88cdabb03364f3.tar.bz2 |
Autofill:requestAutocomplete: Enable prompting for complete address when instrument being used doesn't have full address.
Resubmitting r201451 which is rolled back because of static initilizers in wallet_address.cc
BUG=173517
Review URL: https://chromiumcodereview.appspot.com/15697010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201907 0039d316-1c4b-4281-b951-d872f2087c98
11 files changed, 130 insertions, 28 deletions
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h index 36acceb..82e4c18 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h @@ -268,6 +268,11 @@ class AutofillDialogControllerImpl : public AutofillDialogController, // Opens the given URL in a new foreground tab. virtual void OpenTabWithUrl(const GURL& url); + // Exposed for testing. + const std::map<DialogSection, bool>& section_editing_state() const { + return section_editing_state_; + } + private: // Whether or not the current request wants credit info back. bool RequestingCreditCardInfo() const; diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc index 92de86c..fc43f4f 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc @@ -222,6 +222,11 @@ class TestAutofillDialogController void set_dialog_type(DialogType dialog_type) { dialog_type_ = dialog_type; } + bool IsSectionInEditState(DialogSection section) { + std::map<DialogSection, bool> state = section_editing_state(); + return state[section]; + } + protected: virtual PersonalDataManager* GetManager() OVERRIDE { return &test_manager_; @@ -672,11 +677,13 @@ TEST_F(AutofillDialogControllerTest, WalletDefaultItems) { controller()->MenuModelForSection(SECTION_CC_BILLING)->GetItemCount()); EXPECT_TRUE(controller()->MenuModelForSection(SECTION_CC_BILLING)-> IsItemCheckedAt(2)); + ASSERT_FALSE(controller()->IsSectionInEditState(SECTION_CC_BILLING)); // "use billing", "add", "manage", and 5 suggestions. EXPECT_EQ(8, controller()->MenuModelForSection(SECTION_SHIPPING)->GetItemCount()); EXPECT_TRUE(controller()->MenuModelForSection(SECTION_SHIPPING)-> IsItemCheckedAt(4)); + ASSERT_FALSE(controller()->IsSectionInEditState(SECTION_SHIPPING)); } // Tests that invalid and AMEX default instruments are ignored. @@ -1404,4 +1411,21 @@ TEST_F(AutofillDialogControllerTest, SaveDetailsInChrome) { EXPECT_FALSE(controller()->ShouldOfferToSaveInChrome()); } +// Tests that user is prompted when using instrument with minimal address. +TEST_F(AutofillDialogControllerTest, UpgradeMinimalAddress) { + scoped_ptr<wallet::WalletItems> wallet_items = wallet::GetTestWalletItems(); + wallet_items->AddInstrument(wallet::GetTestMaskedInstrumentWithIdAndAddress( + "id", wallet::GetTestMinimalAddress())); + scoped_ptr<wallet::Address> address(wallet::GetTestShippingAddress()); + address->set_is_complete_address(false); + wallet_items->AddAddress(address.Pass()); + controller()->OnDidGetWalletItems(wallet_items.Pass()); + + // Assert that dialog's SECTION_CC_BILLING section is in edit mode. + ASSERT_TRUE(controller()->IsSectionInEditState(SECTION_CC_BILLING)); + // Shipping section should be in edit mode because of + // is_minimal_shipping_address. + ASSERT_TRUE(controller()->IsSectionInEditState(SECTION_SHIPPING)); +} + } // namespace autofill diff --git a/chrome/browser/ui/autofill/data_model_wrapper.cc b/chrome/browser/ui/autofill/data_model_wrapper.cc index 418f4cb..a0fafe8 100644 --- a/chrome/browser/ui/autofill/data_model_wrapper.cc +++ b/chrome/browser/ui/autofill/data_model_wrapper.cc @@ -162,6 +162,13 @@ string16 WalletAddressWrapper::GetInfo(AutofillFieldType type) { return address_->GetInfo(type, g_browser_process->GetApplicationLocale()); } +string16 WalletAddressWrapper::GetDisplayText() { + if (!address_->is_complete_address()) + return string16(); + + return DataModelWrapper::GetDisplayText(); +} + // WalletInstrumentWrapper WalletInstrumentWrapper::WalletInstrumentWrapper( @@ -183,8 +190,10 @@ gfx::Image WalletInstrumentWrapper::GetIcon() { string16 WalletInstrumentWrapper::GetDisplayText() { // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048 - if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED) + if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED || + !instrument_->address().is_complete_address()) { return string16(); + } // TODO(estade): descriptive_name() is user-provided. Should we use it or // just type + last 4 digits? diff --git a/chrome/browser/ui/autofill/data_model_wrapper.h b/chrome/browser/ui/autofill/data_model_wrapper.h index 304f109..2bdaea0 100644 --- a/chrome/browser/ui/autofill/data_model_wrapper.h +++ b/chrome/browser/ui/autofill/data_model_wrapper.h @@ -126,6 +126,7 @@ class WalletAddressWrapper : public DataModelWrapper { virtual ~WalletAddressWrapper(); virtual string16 GetInfo(AutofillFieldType type) OVERRIDE; + virtual string16 GetDisplayText() OVERRIDE; private: const wallet::Address* address_; diff --git a/components/autofill/browser/wallet/wallet_address.cc b/components/autofill/browser/wallet/wallet_address.cc index d15c7ac..6035144 100644 --- a/components/autofill/browser/wallet/wallet_address.cc +++ b/components/autofill/browser/wallet/wallet_address.cc @@ -14,6 +14,10 @@ namespace autofill { namespace wallet { +// Server specified type for address with complete details. +const char kFullAddress[] = "FULL"; +const char kTrue[] = "true"; + namespace { Address* CreateAddressInternal(const base::DictionaryValue& dictionary, @@ -28,7 +32,7 @@ Address* CreateAddressInternal(const base::DictionaryValue& dictionary, string16 recipient_name; if (!dictionary.GetString("postal_address.recipient_name", &recipient_name)) { - DLOG(ERROR) << "Response from Google Wallet recipient name"; + DLOG(ERROR) << "Response from Google Wallet missing recipient name"; return NULL; } @@ -67,15 +71,22 @@ Address* CreateAddressInternal(const base::DictionaryValue& dictionary, DVLOG(1) << "Response from Google Wallet missing administrative area name"; } - return new Address(country_name_code, - recipient_name , - address_line_1, - address_line_2, - locality_name, - administrative_area_name, - postal_code_number, - phone_number, - object_id); + std::string is_minimal_address; + if (!dictionary.GetString("is_minimal_address", &is_minimal_address)) + DVLOG(1) << "Response from Google Wallet missing is_minimal_address bit"; + + Address* address = new Address(country_name_code, + recipient_name, + address_line_1, + address_line_2, + locality_name, + administrative_area_name, + postal_code_number, + phone_number, + object_id); + address->set_is_complete_address(is_minimal_address != kTrue); + + return address; } } // namespace @@ -91,7 +102,8 @@ Address::Address(const AutofillProfile& profile) locality_name_(profile.GetRawInfo(ADDRESS_HOME_CITY)), administrative_area_name_(profile.GetRawInfo(ADDRESS_HOME_STATE)), postal_code_number_(profile.GetRawInfo(ADDRESS_HOME_ZIP)), - phone_number_(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)) {} + phone_number_(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)), + is_complete_address_(true) {} Address::Address(const std::string& country_name_code, const string16& recipient_name, @@ -110,7 +122,8 @@ Address::Address(const std::string& country_name_code, administrative_area_name_(administrative_area_name), postal_code_number_(postal_code_number), phone_number_(phone_number), - object_id_(object_id) {} + object_id_(object_id), + is_complete_address_(true) {} Address::~Address() {} @@ -174,15 +187,23 @@ scoped_ptr<Address> Address::CreateDisplayAddress( if (!dictionary.GetString("phone_number", &phone_number)) DVLOG(1) << "Reponse from Google Wallet missing phone number"; - return scoped_ptr<Address>(new Address(country_code, - name, - address1, - address2, - city, - state, - postal_code, - phone_number, - std::string())); + std::string address_state; + if (!dictionary.GetString("type", &address_state)) + DVLOG(1) << "Response from Google Wallet missing type/state of address"; + + scoped_ptr<Address> address( + new Address(country_code, + name, + address1, + address2, + city, + state, + postal_code, + phone_number, + std::string())); + address->set_is_complete_address(address_state == kFullAddress); + + return address.Pass(); } scoped_ptr<base::DictionaryValue> Address::ToDictionaryWithID() const { @@ -279,7 +300,8 @@ bool Address::operator==(const Address& other) const { administrative_area_name_ == other.administrative_area_name_ && postal_code_number_ == other.postal_code_number_ && phone_number_ == other.phone_number_ && - object_id_ == other.object_id_; + object_id_ == other.object_id_ && + is_complete_address_ == other.is_complete_address_; } bool Address::operator!=(const Address& other) const { diff --git a/components/autofill/browser/wallet/wallet_address.h b/components/autofill/browser/wallet/wallet_address.h index 937553e..953af5a 100644 --- a/components/autofill/browser/wallet/wallet_address.h +++ b/components/autofill/browser/wallet/wallet_address.h @@ -60,6 +60,8 @@ class Address { static scoped_ptr<Address> CreateAddress( const base::DictionaryValue& dictionary); + // TODO(ahutter): Make obvious in the function name that this public method + // only works for shipping address and assumes existance of "postal_address". // Builds an Address from |dictionary|, which must have an "id" field. This // function is designed for use with shipping addresses. The function may fail // and return an empty pointer if its input is invalid. @@ -105,6 +107,9 @@ class Address { } const base::string16& phone_number() const { return phone_number_; } const std::string& object_id() const { return object_id_; } + bool is_complete_address() const { + return is_complete_address_; + } void set_country_name_code(const std::string& country_name_code) { country_name_code_ = country_name_code; @@ -134,6 +139,9 @@ class Address { void set_object_id(const std::string& object_id) { object_id_ = object_id; } + void set_is_complete_address(bool is_complete_address) { + is_complete_address_ = is_complete_address; + } bool operator==(const Address& other) const; bool operator!=(const Address& other) const; @@ -175,6 +183,9 @@ class Address { // Externalized Online Wallet id for this address. std::string object_id_; + // Server's understanding of this address as complete address or not. + bool is_complete_address_; + // This class is intentionally copyable. DISALLOW_ASSIGN(Address); }; diff --git a/components/autofill/browser/wallet/wallet_address_unittest.cc b/components/autofill/browser/wallet/wallet_address_unittest.cc index 7ac92f7..476d3ab 100644 --- a/components/autofill/browser/wallet/wallet_address_unittest.cc +++ b/components/autofill/browser/wallet/wallet_address_unittest.cc @@ -88,6 +88,7 @@ const char kValidAddress[] = "{" " \"id\":\"id\"," " \"phone_number\":\"phone_number\"," + " \"is_minimal_address\":\"true\"," " \"postal_address\":" " {" " \"recipient_name\":\"recipient_name\"," @@ -145,7 +146,8 @@ const char kClientValidAddress[] = " \"state\":\"state\"," " \"postal_code\":\"postal_code\"," " \"phone_number\":\"phone_number\"," - " \"country_code\":\"country_code\"" + " \"country_code\":\"country_code\"," + " \"type\":\"FULL\"" "}"; } // anonymous namespace @@ -214,6 +216,7 @@ TEST_F(WalletAddressTest, CreateAddressWithID) { ASCIIToUTF16("postal_code_number"), ASCIIToUTF16("phone_number"), "id"); + address.set_is_complete_address(false); ASSERT_EQ(address, *Address::CreateAddress(*dict_)); ASSERT_EQ(address, *Address::CreateAddressWithID(*dict_)); } diff --git a/components/autofill/browser/wallet/wallet_items.h b/components/autofill/browser/wallet/wallet_items.h index f9707da..19b90ef 100644 --- a/components/autofill/browser/wallet/wallet_items.h +++ b/components/autofill/browser/wallet/wallet_items.h @@ -109,7 +109,8 @@ class WalletItems { private: friend class WalletItemsTest; friend scoped_ptr<MaskedInstrument> GetTestMaskedInstrumentWithDetails( - const std::string&, Type type, Status status); + const std::string&, scoped_ptr<Address> address, + Type type, Status status); FRIEND_TEST_ALL_PREFIXES(::autofill::WalletInstrumentWrapperTest, GetInfoCreditCardExpMonth); FRIEND_TEST_ALL_PREFIXES(::autofill::WalletInstrumentWrapperTest, diff --git a/components/autofill/browser/wallet/wallet_items_unittest.cc b/components/autofill/browser/wallet/wallet_items_unittest.cc index 7d1a2e3..e4b62ee 100644 --- a/components/autofill/browser/wallet/wallet_items_unittest.cc +++ b/components/autofill/browser/wallet/wallet_items_unittest.cc @@ -34,7 +34,8 @@ const char kMaskedInstrument[] = " \"state\":\"state\"," " \"postal_code\":\"postal_code\"," " \"phone_number\":\"phone_number\"," - " \"country_code\":\"country_code\"" + " \"country_code\":\"country_code\"," + " \"type\":\"FULL\"" " }," " \"status\":\"VALID\"," " \"object_id\":\"object_id\"" @@ -313,7 +314,8 @@ const char kWalletItems[] = " \"state\":\"state\"," " \"postal_code\":\"postal_code\"," " \"phone_number\":\"phone_number\"," - " \"country_code\":\"country_code\"" + " \"country_code\":\"country_code\"," + " \"type\":\"FULL\"" " }," " \"status\":\"VALID\"," " \"object_id\":\"object_id\"" diff --git a/components/autofill/browser/wallet/wallet_test_util.cc b/components/autofill/browser/wallet/wallet_test_util.cc index 22a05af..f4f1dc0 100644 --- a/components/autofill/browser/wallet/wallet_test_util.cc +++ b/components/autofill/browser/wallet/wallet_test_util.cc @@ -30,6 +30,7 @@ int FutureYear() { scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentWithDetails( const std::string& id, + scoped_ptr<Address> address, WalletItems::MaskedInstrument::Type type, WalletItems::MaskedInstrument::Status status) { return scoped_ptr<WalletItems::MaskedInstrument>( @@ -39,7 +40,7 @@ scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentWithDetails( ASCIIToUTF16("1111"), 12, FutureYear(), - GetTestAddress(), + address.Pass(), status, id)); } @@ -48,6 +49,17 @@ scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentWithId( const std::string& id) { return GetTestMaskedInstrumentWithDetails( id, + GetTestAddress(), + WalletItems::MaskedInstrument::VISA, + WalletItems::MaskedInstrument::VALID); +} + +scoped_ptr<WalletItems::MaskedInstrument> +GetTestMaskedInstrumentWithIdAndAddress( + const std::string& id, scoped_ptr<Address> address) { + return GetTestMaskedInstrumentWithDetails( + id, + address.Pass(), WalletItems::MaskedInstrument::VISA, WalletItems::MaskedInstrument::VALID); } @@ -64,6 +76,12 @@ scoped_ptr<Address> GetTestAddress() { std::string())); } +scoped_ptr<Address> GetTestMinimalAddress() { + scoped_ptr<Address> address = GetTestAddress(); + address->set_is_complete_address(false); + return address.Pass(); +} + scoped_ptr<FullWallet> GetTestFullWallet() { base::Time::Exploded exploded; base::Time::Now().LocalExplode(&exploded); @@ -99,6 +117,7 @@ scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrument() { scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentInvalid() { return GetTestMaskedInstrumentWithDetails( "default_instrument_id", + GetTestAddress(), WalletItems::MaskedInstrument::VISA, WalletItems::MaskedInstrument::DECLINED); } @@ -106,6 +125,7 @@ scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentInvalid() { scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentAmex() { return GetTestMaskedInstrumentWithDetails( "default_instrument_id", + GetTestAddress(), WalletItems::MaskedInstrument::AMEX, WalletItems::MaskedInstrument::VALID); } diff --git a/components/autofill/browser/wallet/wallet_test_util.h b/components/autofill/browser/wallet/wallet_test_util.h index 75f4e56..76a0396 100644 --- a/components/autofill/browser/wallet/wallet_test_util.h +++ b/components/autofill/browser/wallet/wallet_test_util.h @@ -16,6 +16,7 @@ class FullWallet; class Instrument; scoped_ptr<Address> GetTestAddress(); +scoped_ptr<Address> GetTestMinimalAddress(); scoped_ptr<FullWallet> GetTestFullWallet(); scoped_ptr<Instrument> GetTestInstrument(); scoped_ptr<WalletItems::LegalDocument> GetTestLegalDocument(); @@ -23,6 +24,9 @@ scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrument(); scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentInvalid(); scoped_ptr<WalletItems::MaskedInstrument> GetTestMaskedInstrumentAmex(); scoped_ptr<WalletItems::MaskedInstrument> GetTestNonDefaultMaskedInstrument(); +scoped_ptr<WalletItems::MaskedInstrument> + GetTestMaskedInstrumentWithIdAndAddress( + const std::string& id, scoped_ptr<Address> address); scoped_ptr<Address> GetTestSaveableAddress(); scoped_ptr<Address> GetTestShippingAddress(); scoped_ptr<Address> GetTestNonDefaultShippingAddress(); |