Commit 36a93578 authored by sebsg's avatar sebsg Committed by Commit Bot

When updating credit card in settings use existing card instance.

The current code creates a new card instance and sets all the values
form the settings page. It then replaces the existing card instance in
the DB. This is dangerous because it's easy to forget some. It would
also reset all the metadata associated with this card.

More specifically in this example, the settings don't have a way to set
the billing address id. Instead of passing the value along in the
settings to set it back on save, using the existing card and updating it
is much more simple.

Bug: 800829
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ia6ce196c16295961bb6536a609ea866f953e1590
Reviewed-on: https://chromium-review.googlesource.com/860200
Commit-Queue: Sebastien Seguin-Gagnon <sebsg@chromium.org>
Reviewed-by: default avatarToni Barzic <tbarzic@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Reviewed-by: default avatarMichael Giuffrida <michaelpg@chromium.org>
Reviewed-by: default avatarRoger McFarlane <rogerm@chromium.org>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Cr-Commit-Position: refs/heads/master@{#531710}
parent a44af4d9
...@@ -186,8 +186,20 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() { ...@@ -186,8 +186,20 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() {
api::autofill_private::AddressEntry* address = &parameters->address; api::autofill_private::AddressEntry* address = &parameters->address;
// If a profile guid is specified, get a copy of the profile identified by it.
// Otherwise create a new one.
std::string guid = address->guid ? *address->guid : ""; std::string guid = address->guid ? *address->guid : "";
autofill::AutofillProfile profile(guid, kSettingsOrigin); const bool use_existing_profile = !guid.empty();
const autofill::AutofillProfile* existing_profile = nullptr;
if (use_existing_profile) {
existing_profile = personal_data->GetProfileByGUID(guid);
if (!existing_profile)
return RespondNow(Error(kErrorDataUnavailable));
}
autofill::AutofillProfile profile =
existing_profile
? *existing_profile
: autofill::AutofillProfile(base::GenerateGUID(), kSettingsOrigin);
// Strings from JavaScript use UTF-8 encoding. This container is used as an // Strings from JavaScript use UTF-8 encoding. This container is used as an
// intermediate container for functions which require UTF-16 strings. // intermediate container for functions which require UTF-16 strings.
...@@ -268,11 +280,10 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() { ...@@ -268,11 +280,10 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() {
if (address->language_code) if (address->language_code)
profile.set_language_code(*address->language_code); profile.set_language_code(*address->language_code);
if (!base::IsValidGUID(profile.guid())) { if (use_existing_profile) {
profile.set_guid(base::GenerateGUID());
personal_data->AddProfile(profile);
} else {
personal_data->UpdateProfile(profile); personal_data->UpdateProfile(profile);
} else {
personal_data->AddProfile(profile);
} }
return RespondNow(NoArguments()); return RespondNow(NoArguments());
...@@ -373,8 +384,20 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() { ...@@ -373,8 +384,20 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() {
api::autofill_private::CreditCardEntry* card = &parameters->card; api::autofill_private::CreditCardEntry* card = &parameters->card;
// If a card guid is specified, get a copy of the card identified by it.
// Otherwise create a new one.
std::string guid = card->guid ? *card->guid : ""; std::string guid = card->guid ? *card->guid : "";
autofill::CreditCard credit_card(guid, kSettingsOrigin); const bool use_existing_card = !guid.empty();
const autofill::CreditCard* existing_card = nullptr;
if (use_existing_card) {
existing_card = personal_data->GetCreditCardByGUID(guid);
if (!existing_card)
return RespondNow(Error(kErrorDataUnavailable));
}
autofill::CreditCard credit_card =
existing_card
? *existing_card
: autofill::CreditCard(base::GenerateGUID(), kSettingsOrigin);
if (card->name) { if (card->name) {
credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL, credit_card.SetRawInfo(autofill::CREDIT_CARD_NAME_FULL,
...@@ -399,15 +422,10 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() { ...@@ -399,15 +422,10 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveCreditCardFunction::Run() {
base::UTF8ToUTF16(*card->expiration_year)); base::UTF8ToUTF16(*card->expiration_year));
} }
if (card->billing_address_id) { if (use_existing_card) {
credit_card.set_billing_address_id(*card->billing_address_id);
}
if (!base::IsValidGUID(credit_card.guid())) {
credit_card.set_guid(base::GenerateGUID());
personal_data->AddCreditCard(credit_card);
} else {
personal_data->UpdateCreditCard(credit_card); personal_data->UpdateCreditCard(credit_card);
} else {
personal_data->AddCreditCard(credit_card);
} }
return RespondNow(NoArguments()); return RespondNow(NoArguments());
......
...@@ -44,11 +44,6 @@ class AutofillPrivateApiTest : public ExtensionApiTest { ...@@ -44,11 +44,6 @@ class AutofillPrivateApiTest : public ExtensionApiTest {
// TODO(hcarmona): Investigate converting these tests to unittests. // TODO(hcarmona): Investigate converting these tests to unittests.
// TODO(crbug.com/643097) Disabled for flakiness.
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_SaveAddress) {
EXPECT_TRUE(RunAutofillSubtest("saveAddress")) << message_;
}
// TODO(crbug.com/643097) Disabled for flakiness. // TODO(crbug.com/643097) Disabled for flakiness.
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_GetCountryList) { IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_GetCountryList) {
EXPECT_TRUE(RunAutofillSubtest("getCountryList")) << message_; EXPECT_TRUE(RunAutofillSubtest("getCountryList")) << message_;
...@@ -58,11 +53,6 @@ IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, GetAddressComponents) { ...@@ -58,11 +53,6 @@ IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, GetAddressComponents) {
EXPECT_TRUE(RunAutofillSubtest("getAddressComponents")) << message_; EXPECT_TRUE(RunAutofillSubtest("getAddressComponents")) << message_;
} }
// TODO(crbug.com/643097) Disabled for flakiness.
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_SaveCreditCard) {
EXPECT_TRUE(RunAutofillSubtest("saveCreditCard")) << message_;
}
// TODO(crbug.com/643097) Disabled for flakiness. // TODO(crbug.com/643097) Disabled for flakiness.
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_RemoveEntry) { IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, DISABLED_RemoveEntry) {
EXPECT_TRUE(RunAutofillSubtest("removeEntry")) << message_; EXPECT_TRUE(RunAutofillSubtest("removeEntry")) << message_;
...@@ -72,5 +62,13 @@ IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, ValidatePhoneNumbers) { ...@@ -72,5 +62,13 @@ IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, ValidatePhoneNumbers) {
EXPECT_TRUE(RunAutofillSubtest("ValidatePhoneNumbers")) << message_; EXPECT_TRUE(RunAutofillSubtest("ValidatePhoneNumbers")) << message_;
} }
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, AddAndUpdateAddress) {
EXPECT_TRUE(RunAutofillSubtest("addAndUpdateAddress")) << message_;
}
IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, AddAndUpdateCreditCard) {
EXPECT_TRUE(RunAutofillSubtest("addAndUpdateCreditCard")) << message_;
}
} // namespace extensions } // namespace extensions
...@@ -145,8 +145,6 @@ autofill_private::CreditCardEntry CreditCardToCreditCardEntry( ...@@ -145,8 +145,6 @@ autofill_private::CreditCardEntry CreditCardToCreditCardEntry(
credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH)))); credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_MONTH))));
card.expiration_year.reset(new std::string(base::UTF16ToUTF8( card.expiration_year.reset(new std::string(base::UTF16ToUTF8(
credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)))); credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR))));
card.billing_address_id.reset(
new std::string(credit_card.billing_address_id()));
// Create address metadata and add it to |address|. // Create address metadata and add it to |address|.
std::unique_ptr<autofill_private::AutofillMetadata> metadata( std::unique_ptr<autofill_private::AutofillMetadata> metadata(
......
...@@ -157,9 +157,6 @@ namespace autofillPrivate { ...@@ -157,9 +157,6 @@ namespace autofillPrivate {
// Year as a 4-character string (as in "2015"). // Year as a 4-character string (as in "2015").
DOMString? expirationYear; DOMString? expirationYear;
// The identifier of the billing address for the card.
DOMString? billingAddressId;
AutofillMetadata? metadata; AutofillMetadata? metadata;
}; };
......
...@@ -6,29 +6,23 @@ ...@@ -6,29 +6,23 @@
// that callbacks are correctly invoked, expected parameters are correct, // that callbacks are correctly invoked, expected parameters are correct,
// and failures are detected. // and failures are detected.
var availableTests = [ // Constants for the tests.
function saveAddress() { var NAME = 'Name';
var NAME = 'Name'; var COMPANY_NAME = 'Company name';
var ADDRESS_LEVEL1 = 'Address level 1';
var numCalls = 0; var ADDRESS_LEVEL2 = 'Address level 2';
var handler = function(addressList) { var ADDRESS_LEVEL3 = 'Address level 3';
numCalls++; var POSTAL_CODE = 'Postal code';
var SORTING_CODE = 'Sorting code';
if (numCalls == 1) { var COUNTRY_CODE = 'US';
chrome.test.assertEq(addressList.length, 0); var PHONE = '1 123-123-1234';
} else { var EMAIL = 'johndoe@gmail.com';
chrome.test.assertEq(addressList.length, 1); var CARD_NAME = 'CardName';
var address = addressList[0]; var NUMBER = '4111 1111 1111 1111';
chrome.test.assertEq(address.fullNames[0], NAME); var EXP_MONTH = '02';
chrome.test.succeed(); var EXP_YEAR = '2999';
}
}
chrome.autofillPrivate.onAddressListChanged.addListener(handler);
chrome.autofillPrivate.getAddressList(handler);
chrome.autofillPrivate.saveAddress({fullNames: [NAME]});
},
var availableTests = [
function getCountryList() { function getCountryList() {
var handler = function(countries) { var handler = function(countries) {
var numSeparators = 0; var numSeparators = 0;
...@@ -83,30 +77,197 @@ var availableTests = [ ...@@ -83,30 +77,197 @@ var availableTests = [
chrome.autofillPrivate.getAddressComponents(COUNTRY_CODE, handler); chrome.autofillPrivate.getAddressComponents(COUNTRY_CODE, handler);
}, },
function saveCreditCard() { function addNewAddress() {
var NAME = 'Name'; function filterAddressProperties(addresses) {
return addresses.map(address => {
var filteredAddress = {};
['fullNames', 'addressLevel1', 'addressLevel2', 'addressLevel3',
'postalCode', 'sortingCode', 'phoneNumbers', 'emailAddresses']
.forEach(property => {
filteredAddress[property] = address[property];
});
return filteredAddress;
});
}
var numCalls = 0; chrome.autofillPrivate.getAddressList(
var handler = function(creditCardList) { chrome.test.callbackPass(function(addressList) {
numCalls++; chrome.test.assertEq([], addressList);
// Setup the callback that verifies that the address was correctly
// added.
chrome.test.listenOnce(
chrome.autofillPrivate.onAddressListChanged,
chrome.test.callbackPass(function(addressList) {
chrome.test.assertEq(
[{
fullNames: [NAME],
addressLevel1: ADDRESS_LEVEL1,
addressLevel2: ADDRESS_LEVEL2,
addressLevel3: ADDRESS_LEVEL3,
postalCode: POSTAL_CODE,
sortingCode: SORTING_CODE,
phoneNumbers: [PHONE],
emailAddresses: [EMAIL]
}],
filterAddressProperties(addressList));
}));
chrome.autofillPrivate.saveAddress({
fullNames: [NAME],
addressLevel1: ADDRESS_LEVEL1,
addressLevel2: ADDRESS_LEVEL2,
addressLevel3: ADDRESS_LEVEL3,
postalCode: POSTAL_CODE,
sortingCode: SORTING_CODE,
countryCode: COUNTRY_CODE,
phoneNumbers: [PHONE],
emailAddresses: [EMAIL]
});
}));
},
if (numCalls == 1) { function updateExistingAddress() {
chrome.test.assertEq(creditCardList.length, 0); // The information that will be updated. It should be different than the
} else { // information in the addNewAddress function.
chrome.test.assertEq(creditCardList.length, 1); var UPDATED_NAME = 'UpdatedName';
var creditCard = creditCardList[0]; var UPDATED_PHONE = '1 987-987-9876'
chrome.test.assertEq(creditCard.name, NAME);
chrome.test.succeed(); function filterAddressProperties(addresses) {
} return addresses.map(address => {
var filteredAddress = {};
['guid', 'fullNames', 'addressLevel1', 'addressLevel2', 'addressLevel3',
'postalCode', 'sortingCode', 'phoneNumbers', 'emailAddresses']
.forEach(property => {
filteredAddress[property] = address[property];
});
return filteredAddress;
});
} }
chrome.autofillPrivate.onCreditCardListChanged.addListener(handler); chrome.autofillPrivate.getAddressList(
chrome.autofillPrivate.getCreditCardList(handler); chrome.test.callbackPass(function(addressList) {
chrome.autofillPrivate.saveCreditCard({name: NAME}); // The address from the addNewAddress function should still be there.
chrome.test.assertEq(1, addressList.length);
var addressGuid = addressList[0].guid;
// Setup the callback that verifies that the address was correctly
// updated.
chrome.test.listenOnce(
chrome.autofillPrivate.onAddressListChanged,
chrome.test.callbackPass(function(addressList) {
chrome.test.assertEq(
[{
guid: addressGuid,
fullNames: [UPDATED_NAME],
addressLevel1: ADDRESS_LEVEL1,
addressLevel2: ADDRESS_LEVEL2,
addressLevel3: ADDRESS_LEVEL3,
postalCode: POSTAL_CODE,
sortingCode: SORTING_CODE,
phoneNumbers: [UPDATED_PHONE],
emailAddresses: [EMAIL]
}],
filterAddressProperties(addressList));
}));
// Update the address by saving an address with the same guid and
// using some different information.
chrome.autofillPrivate.saveAddress({
guid: addressGuid,
fullNames: [UPDATED_NAME],
phoneNumbers: [UPDATED_PHONE]
});
}));
},
function addNewCreditCard() {
function filterCardProperties(cards) {
return cards.map(cards => {
var filteredCards = {};
['name', 'cardNumber', 'expirationMonth', 'expirationYear'].forEach(
property => {
filteredCards[property] = cards[property];
});
return filteredCards;
});
}
chrome.autofillPrivate.getCreditCardList(
chrome.test.callbackPass(function(cardList) {
chrome.test.assertEq([], cardList);
// Setup the callback that verifies that the card was correctly added.
chrome.test.listenOnce(
chrome.autofillPrivate.onCreditCardListChanged,
chrome.test.callbackPass(function(cardList) {
chrome.test.assertEq(
[{
name: CARD_NAME,
cardNumber: NUMBER,
expirationMonth: EXP_MONTH,
expirationYear: EXP_YEAR
}],
filterCardProperties(cardList));
}));
chrome.autofillPrivate.saveCreditCard({
name: CARD_NAME,
cardNumber: NUMBER,
expirationMonth: EXP_MONTH,
expirationYear: EXP_YEAR
});
}));
},
function updateExistingCreditCard() {
var UPDATED_CARD_NAME = 'UpdatedCardName';
var UPDATED_EXP_YEAR = '2888';
function filterCardProperties(cards) {
return cards.map(cards => {
var filteredCards = {};
['guid', 'name', 'cardNumber', 'expirationMonth', 'expirationYear']
.forEach(property => {
filteredCards[property] = cards[property];
});
return filteredCards;
});
}
chrome.autofillPrivate.getCreditCardList(
chrome.test.callbackPass(function(cardList) {
// The card from the addNewCreditCard function should still be there.
chrome.test.assertEq(1, cardList.length);
var cardGuid = cardList[0].guid;
// Setup the callback that verifies that the address was correctly
// updated.
chrome.test.listenOnce(
chrome.autofillPrivate.onCreditCardListChanged,
chrome.test.callbackPass(function(cardList) {
chrome.test.assertEq(
[{
guid: cardGuid,
name: UPDATED_CARD_NAME,
cardNumber: NUMBER,
expirationMonth: EXP_MONTH,
expirationYear: UPDATED_EXP_YEAR
}],
filterCardProperties(cardList));
}));
// Update the card by saving a card with the same guid and using some
// different information.
chrome.autofillPrivate.saveCreditCard({
guid: cardGuid,
name: UPDATED_CARD_NAME,
expirationYear: UPDATED_EXP_YEAR
});
}));
}, },
function removeEntry() { function removeEntry() {
var NAME = 'Name';
var guid; var guid;
var numCalls = 0; var numCalls = 0;
...@@ -180,7 +341,14 @@ var availableTests = [ ...@@ -180,7 +341,14 @@ var availableTests = [
}, },
]; ];
var testToRun = window.location.search.substring(1); /** @const */
var TESTS_FOR_CONFIG = {
'addAndUpdateAddress': ['addNewAddress', 'updateExistingAddress'],
'addAndUpdateCreditCard': ['addNewCreditCard', 'updateExistingCreditCard']
};
var testConfig = window.location.search.substring(1);
var testsToRun = TESTS_FOR_CONFIG[testConfig] || [testConfig];
chrome.test.runTests(availableTests.filter(function(op) { chrome.test.runTests(availableTests.filter(function(op) {
return op.name == testToRun; return testsToRun.includes(op.name);
})); }));
...@@ -108,7 +108,6 @@ chrome.autofillPrivate.AddressComponents; ...@@ -108,7 +108,6 @@ chrome.autofillPrivate.AddressComponents;
* cardNumber: (string|undefined), * cardNumber: (string|undefined),
* expirationMonth: (string|undefined), * expirationMonth: (string|undefined),
* expirationYear: (string|undefined), * expirationYear: (string|undefined),
* billingAddressId: (string|undefined),
* metadata: (!chrome.autofillPrivate.AutofillMetadata|undefined) * metadata: (!chrome.autofillPrivate.AutofillMetadata|undefined)
* }} * }}
* @see https://developer.chrome.com/extensions/autofillPrivate#type-CreditCardEntry * @see https://developer.chrome.com/extensions/autofillPrivate#type-CreditCardEntry
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment