Commit f64b47d5 authored by Sujie Zhu's avatar Sujie Zhu Committed by Commit Bot

[Autofill local card migration] Send migration request only once risk data has been loaded

In this CL, we finish the basic two round pop-up window workflow.

We add LoadRiskData at the same time the first prompt pops up when the legal docs are successfully fetched. The callback of the first prompt(ShowLocalCardMigrationPrompt) is OnUserAcceptedIntermediateMigrationDialog() which will trigger the second prompt.

We will send the Migration request only when both the risk data is prepared and user accepted on the main prompt. Send Migration Request will included in the following CL.

Use the intermediate bubble as the main prompt for now. Need to wait for Siyu's Main Prompt skeleton check-in to replace the main prompt call.

TBR=rogerm@chromium.org

Bug: 852904
Change-Id: Ic881a64b7da93316ff8a8a0e84bc0c20a39a030d
Reviewed-on: https://chromium-review.googlesource.com/1149151
Commit-Queue: Sujie Zhu <sujiezhu@google.com>
Reviewed-by: default avatarMoe Ahmadi <mahmadi@chromium.org>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Cr-Commit-Position: refs/heads/master@{#585579}
parent f6ef3693
...@@ -138,7 +138,8 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form, ...@@ -138,7 +138,8 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
if (local_card_migration_manager_ && if (local_card_migration_manager_ &&
local_card_migration_manager_->ShouldOfferLocalCardMigration( local_card_migration_manager_->ShouldOfferLocalCardMigration(
imported_credit_card_record_type_)) { imported_credit_card_record_type_)) {
local_card_migration_manager_->AttemptToOfferLocalCardMigration(); local_card_migration_manager_->AttemptToOfferLocalCardMigration(
/*is_from_settings_page=*/false);
return; return;
} }
......
...@@ -68,7 +68,8 @@ bool LocalCardMigrationManager::ShouldOfferLocalCardMigration( ...@@ -68,7 +68,8 @@ bool LocalCardMigrationManager::ShouldOfferLocalCardMigration(
!migratable_credit_cards_.empty()); !migratable_credit_cards_.empty());
} }
void LocalCardMigrationManager::AttemptToOfferLocalCardMigration() { void LocalCardMigrationManager::AttemptToOfferLocalCardMigration(
bool is_from_settings_page) {
// Abort the migration if |payments_client_| is nullptr. // Abort the migration if |payments_client_| is nullptr.
if (!payments_client_) if (!payments_client_)
return; return;
...@@ -88,21 +89,26 @@ void LocalCardMigrationManager::AttemptToOfferLocalCardMigration() { ...@@ -88,21 +89,26 @@ void LocalCardMigrationManager::AttemptToOfferLocalCardMigration() {
/*pan_first_six=*/std::string(), upload_request_.active_experiments, /*pan_first_six=*/std::string(), upload_request_.active_experiments,
app_locale_, app_locale_,
base::BindOnce(&LocalCardMigrationManager::OnDidGetUploadDetails, base::BindOnce(&LocalCardMigrationManager::OnDidGetUploadDetails,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr(), is_from_settings_page),
payments::kMigrateCardBillableServiceNumber); payments::kMigrateCardBillableServiceNumber);
} }
// TODO(crbug.com/852904): Pops up a larger, modal dialog showing the local // Callback function when user agrees to migration on the intermediate dialog.
// cards to be uploaded. Pass the reference of vector<MigratableCreditCard> and // Call ShowMainMigrationDialog() to pop up a larger, modal dialog showing the
// the callback function is OnConfirmLocalCardsMigration(). // local cards to be uploaded.
void LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog() { void LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog() {
user_accepted_main_migration_dialog_ = false; ShowMainMigrationDialog();
// Pops up a larger, modal dialog showing the local cards to be uploaded. }
client_->ConfirmMigrateLocalCardToCloud(
migratable_credit_cards_, // Send the migration request once risk data is available.
base::BindOnce( void LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog() {
&LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog, user_accepted_main_migration_dialog_ = true;
weak_ptr_factory_.GetWeakPtr())); // Populating risk data and offering migration two-round pop-ups occur
// asynchronously. If |migration_risk_data_| has already been loaded, send the
// migrate local cards request. Otherwise, continue to wait and let
// OnDidGetUploadRiskData handle it.
if (!migration_risk_data_.empty())
SendMigrateLocalCardsRequest();
} }
bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() { bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() {
...@@ -122,24 +128,61 @@ bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() { ...@@ -122,24 +128,61 @@ bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() {
} }
void LocalCardMigrationManager::OnDidGetUploadDetails( void LocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result, AutofillClient::PaymentsRpcResult result,
const base::string16& context_token, const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message) { std::unique_ptr<base::DictionaryValue> legal_message) {
if (result == AutofillClient::SUCCESS) { if (result == AutofillClient::SUCCESS) {
upload_request_.context_token = context_token; upload_request_.context_token = context_token;
legal_message_ = std::move(legal_message); legal_message_ = std::move(legal_message);
migration_risk_data_.clear();
// If we successfully received the legal docs, trigger the offer-to-migrate // If we successfully received the legal docs, trigger the offer-to-migrate
// dialog. // dialog. If triggered from settings page, we pop-up the main prompt
client_->ShowLocalCardMigrationDialog(base::BindOnce( // directly. If not, we pop up the intermediate bubble.
&LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog, if (is_from_settings_page) {
// Pops up a larger, modal dialog showing the local cards to be uploaded.
ShowMainMigrationDialog();
} else {
client_->ShowLocalCardMigrationDialog(base::BindOnce(
&LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog,
weak_ptr_factory_.GetWeakPtr()));
}
// TODO(crbug.com/876895): Clean up the LoadRiskData Bind/BindRepeating
// usages
client_->LoadRiskData(base::BindRepeating(
&LocalCardMigrationManager::OnDidGetMigrationRiskData,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
// TODO(crbug.com/852904): Call the client LoadRiskData()
} }
} }
// TODO(crbug.com/852904): Send the upload request once risk data is available. void LocalCardMigrationManager::OnDidGetMigrationRiskData(
void LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog() { const std::string& risk_data) {
user_accepted_main_migration_dialog_ = true; migration_risk_data_ = risk_data;
// Populating risk data and offering migration two-round pop-ups occur
// asynchronously. If the main migration dialog has already been accepted,
// send the migrate local cards request. Otherwise, continue to wait for the
// user to accept the two round dialog.
if (user_accepted_main_migration_dialog_)
SendMigrateLocalCardsRequest();
}
// TODO(crbug.com/852904): Send the migration request. Will call payments_client
// to create a new PaymentsRequest. Also create a new callback function
// OnDidMigrateLocalCards.
void LocalCardMigrationManager::SendMigrateLocalCardsRequest() {}
// Pops up a larger, modal dialog showing the local cards to be uploaded. Pass
// the reference of vector<MigratableCreditCard> and the callback function is
// OnUserAcceptedMainMigrationDialog(). Can be called when user agrees to
// migration on the intermediate dialog or directly from settings page.
void LocalCardMigrationManager::ShowMainMigrationDialog() {
user_accepted_main_migration_dialog_ = false;
// Pops up a larger, modal dialog showing the local cards to be uploaded.
client_->ConfirmMigrateLocalCardToCloud(
migratable_credit_cards_,
base::BindOnce(
&LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog,
weak_ptr_factory_.GetWeakPtr()));
} }
int LocalCardMigrationManager::GetDetectedValues() const { int LocalCardMigrationManager::GetDetectedValues() const {
......
...@@ -59,13 +59,22 @@ class LocalCardMigrationManager { ...@@ -59,13 +59,22 @@ class LocalCardMigrationManager {
// migration are satisfied. Initializes the local card list for upload. // migration are satisfied. Initializes the local card list for upload.
bool ShouldOfferLocalCardMigration(int imported_credit_card_record_type); bool ShouldOfferLocalCardMigration(int imported_credit_card_record_type);
// Called from FormDataImporter when all migration requirements are met. // Called from FormDataImporter or settings page when all migration
// Fetches legal documents and triggers the OnDidGetUploadDetails callback. // requirements are met. Fetches legal documents and triggers the
void AttemptToOfferLocalCardMigration(); // OnDidGetUploadDetails callback. |is_from_settings_page| to denote the user
// triggers the migration from settings page. It will trigger the main prompt
// directly if the get upload details call returns success.
void AttemptToOfferLocalCardMigration(bool is_from_settings_page);
// Callback function when user agrees to migration on the intermediate dialog. // Callback function when user agrees to migration on the intermediate dialog.
// Pops up a larger, modal dialog showing the local cards to be uploaded. // Pops up a larger, modal dialog showing the local cards to be uploaded.
void OnUserAcceptedIntermediateMigrationDialog(); // Exposed for testing.
virtual void OnUserAcceptedIntermediateMigrationDialog();
// Callback function when user confirms migration on the main migration
// dialog. Sets |user_accepted_main_migration_dialog_| and sends the migration
// request once risk data is available. Exposed for testing.
virtual void OnUserAcceptedMainMigrationDialog();
// Check that the user is signed in, syncing, and the proper experiment // Check that the user is signed in, syncing, and the proper experiment
// flags are enabled. Override in the test class. // flags are enabled. Override in the test class.
...@@ -75,18 +84,20 @@ class LocalCardMigrationManager { ...@@ -75,18 +84,20 @@ class LocalCardMigrationManager {
// name if it exists on all cards, and existence of Payments customer). // name if it exists on all cards, and existence of Payments customer).
int GetDetectedValues() const; int GetDetectedValues() const;
// Fetch all migratable credit cards and store in |migratable_credit_cards_|.
void GetMigratableCreditCards();
protected: protected:
// Callback after successfully getting the legal documents. On success, // Callback after successfully getting the legal documents. On success,
// displays the offer-to-migrate dialog, which the user can accept or not. // displays the offer-to-migrate dialog, which the user can accept or not.
// Exposed for testing. // When |is_from_settings_page| is true, it will trigger the main prompt
// directly. If not, trigger the intermediate prompt. Exposed for testing.
virtual void OnDidGetUploadDetails( virtual void OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result, AutofillClient::PaymentsRpcResult result,
const base::string16& context_token, const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message); std::unique_ptr<base::DictionaryValue> legal_message);
// Fetch all migratable credit cards and store in |migratable_credit_cards_|.
void GetMigratableCreditCards();
AutofillClient* const client_; AutofillClient* const client_;
// Handles Payments service requests. // Handles Payments service requests.
...@@ -94,10 +105,16 @@ class LocalCardMigrationManager { ...@@ -94,10 +105,16 @@ class LocalCardMigrationManager {
payments::PaymentsClient* payments_client_; payments::PaymentsClient* payments_client_;
private: private:
// Callback function when user confirms migration on the main migration // Pops up a larger, modal dialog showing the local cards to be uploaded.
// dialog. Sets |user_accepted_main_migration_dialog_| and sends the upload void ShowMainMigrationDialog();
// request.
void OnUserAcceptedMainMigrationDialog(); // Callback function when migration risk data is ready. Saves risk data in
// |migration_risk_data_| and calls SendMigrateLocalCardsRequest if the user
// has accepted the main migration dialog.
void OnDidGetMigrationRiskData(const std::string& risk_data);
// Finalizes the migration request and calls PaymentsClient.
void SendMigrateLocalCardsRequest();
std::unique_ptr<base::DictionaryValue> legal_message_; std::unique_ptr<base::DictionaryValue> legal_message_;
...@@ -119,6 +136,8 @@ class LocalCardMigrationManager { ...@@ -119,6 +136,8 @@ class LocalCardMigrationManager {
// on the main dialog. // on the main dialog.
bool user_accepted_main_migration_dialog_ = false; bool user_accepted_main_migration_dialog_ = false;
std::string migration_risk_data_;
base::WeakPtrFactory<LocalCardMigrationManager> weak_ptr_factory_; base::WeakPtrFactory<LocalCardMigrationManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationManager); DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationManager);
......
...@@ -595,4 +595,62 @@ TEST_F(LocalCardMigrationManagerTest, ...@@ -595,4 +595,62 @@ TEST_F(LocalCardMigrationManagerTest,
CreditCardSaveManager::DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT); CreditCardSaveManager::DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT);
} }
// Verify that when triggering from settings page, intermediate prompt will not
// be triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSettingsPage) {
EnableAutofillCreditCardLocalCardMigrationExperiment();
personal_data_.ClearCreditCards();
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
12345);
// Add a local credit card. One migratable credit card will still trigger
// migration on settings page.
AddLocalCrediCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1");
// Do the same operation as we bridge back from the settings page.
local_card_migration_manager_->GetMigratableCreditCards();
local_card_migration_manager_->AttemptToOfferLocalCardMigration(true);
EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown());
EXPECT_TRUE(local_card_migration_manager_->MainPromptWasShown());
}
// Verify that when triggering from submitted form, intermediate prompt and main
// prompt are both triggered.
TEST_F(LocalCardMigrationManagerTest,
MigrateCreditCard_TriggerFromSubmittedForm) {
EnableAutofillCreditCardLocalCardMigrationExperiment();
personal_data_.ClearCreditCards();
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
// Set the billing_customer_number Priority Preference to designate
// existence of a Payments account.
autofill_client_.GetPrefs()->SetDouble(prefs::kAutofillBillingCustomerNumber,
12345);
// Add a local credit card whose |TypeAndLastFourDigits| matches what we will
// enter below.
AddLocalCrediCard(personal_data_, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "1");
// Add another local credit card, so it will trigger migration.
AddLocalCrediCard(personal_data_, "Flo Master", "5555555555554444", "11",
test::NextYear().c_str(), "1");
// Set up our credit card form data.
FormData credit_card_form;
test::CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
EditCreditCardFrom(credit_card_form, "Flo Master", "4111111111111111", "11",
test::NextYear().c_str(), "123");
FormSubmitted(credit_card_form);
EXPECT_TRUE(local_card_migration_manager_->IntermediatePromptWasShown());
EXPECT_TRUE(local_card_migration_manager_->MainPromptWasShown());
}
} // namespace autofill } // namespace autofill
...@@ -38,14 +38,34 @@ bool TestLocalCardMigrationManager::LocalCardMigrationWasTriggered() { ...@@ -38,14 +38,34 @@ bool TestLocalCardMigrationManager::LocalCardMigrationWasTriggered() {
return local_card_migration_was_triggered_; return local_card_migration_was_triggered_;
} }
bool TestLocalCardMigrationManager::IntermediatePromptWasShown() {
return intermediate_prompt_was_shown_;
}
bool TestLocalCardMigrationManager::MainPromptWasShown() {
return main_prompt_was_shown_;
}
void TestLocalCardMigrationManager::
OnUserAcceptedIntermediateMigrationDialog() {
intermediate_prompt_was_shown_ = true;
LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog();
}
void TestLocalCardMigrationManager::OnUserAcceptedMainMigrationDialog() {
main_prompt_was_shown_ = true;
LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog();
}
void TestLocalCardMigrationManager::OnDidGetUploadDetails( void TestLocalCardMigrationManager::OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result, AutofillClient::PaymentsRpcResult result,
const base::string16& context_token, const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message) { std::unique_ptr<base::DictionaryValue> legal_message) {
if (result == AutofillClient::SUCCESS) { if (result == AutofillClient::SUCCESS) {
local_card_migration_was_triggered_ = true; local_card_migration_was_triggered_ = true;
LocalCardMigrationManager::OnDidGetUploadDetails(result, context_token, LocalCardMigrationManager::OnDidGetUploadDetails(
std::move(legal_message)); is_from_settings_page, result, context_token, std::move(legal_message));
} }
} }
......
...@@ -32,17 +32,36 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager { ...@@ -32,17 +32,36 @@ class TestLocalCardMigrationManager : public LocalCardMigrationManager {
// user is signed in/syncing. // user is signed in/syncing.
bool IsCreditCardMigrationEnabled() override; bool IsCreditCardMigrationEnabled() override;
// Returns whether the first round migration pop-up window was triggered. // Returns whether the local card migration was triggered.
bool LocalCardMigrationWasTriggered(); bool LocalCardMigrationWasTriggered();
// Returns whether the first round intermediate pop-up window was shown.
bool IntermediatePromptWasShown();
// Returns whether the main prompt window was shown.
bool MainPromptWasShown();
// Override the base function. When called, represents the intermediate prompt
// is shown. Set the |intermediate_prompt_was_shown_|.
void OnUserAcceptedIntermediateMigrationDialog() override;
// Override the base function. When called, represent the main prompt is
// shown. Set the |main_prompt_was_shown_|.
void OnUserAcceptedMainMigrationDialog() override;
private: private:
void OnDidGetUploadDetails( void OnDidGetUploadDetails(
bool is_from_settings_page,
AutofillClient::PaymentsRpcResult result, AutofillClient::PaymentsRpcResult result,
const base::string16& context_token, const base::string16& context_token,
std::unique_ptr<base::DictionaryValue> legal_message) override; std::unique_ptr<base::DictionaryValue> legal_message) override;
bool local_card_migration_was_triggered_ = false; bool local_card_migration_was_triggered_ = false;
bool intermediate_prompt_was_shown_ = false;
bool main_prompt_was_shown_ = false;
DISALLOW_COPY_AND_ASSIGN(TestLocalCardMigrationManager); DISALLOW_COPY_AND_ASSIGN(TestLocalCardMigrationManager);
}; };
......
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