Skip to content

Commit

Permalink
Extract ui info and delegate from AutofillSaveCardInfoBarDelegateMobile
Browse files Browse the repository at this point in the history
* Move non-infobar code out of AutofillSaveCardInfoBarDelegateMobile to
  be reusable for the upcoming save card bottom sheet on Chrome for
  Android.

Bug: 1454271
Low-Coverage-Reason: Coverage not run in CQ.
Change-Id: I968e4683b77615d5318dc22479d9b869e6f7d91c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4721765
Reviewed-by: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: Stephen McGruer <smcgruer@chromium.org>
Reviewed-by: Rouslan Solomakhin <rouslan@chromium.org>
Commit-Queue: Slobodan Pejic <slobodan@chromium.org>
Reviewed-by: Jan Keitel <jkeitel@google.com>
Reviewed-by: Tommy Martino <tmartino@chromium.org>
Reviewed-by: Peter Kotwicz <pkotwicz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1186485}
  • Loading branch information
Slobodan Pejic authored and Chromium LUCI CQ committed Aug 22, 2023
1 parent 8bade2d commit eecf6b1
Show file tree
Hide file tree
Showing 13 changed files with 1,032 additions and 287 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,18 @@
#include <memory>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/json/json_reader.h"
#include "base/test/metrics/histogram_tester.h"
#include "build/branding_buildflags.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/metrics/payments/credit_card_save_metrics.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/test_personal_data_manager.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/prefs/pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
Expand All @@ -31,6 +28,15 @@ namespace autofill {
class AutofillSaveCardInfoBarDelegateMobileTest
: public ChromeRenderViewHostTestHarness {
public:
struct CreateDelegateOptions {
int logo_icon_id = -1;
std::u16string title_text;
std::u16string confirm_text;
std::u16string cancel_text;
std::u16string description_text;
bool is_google_pay_branding_enabled = false;
};

AutofillSaveCardInfoBarDelegateMobileTest();

AutofillSaveCardInfoBarDelegateMobileTest(
Expand All @@ -47,6 +53,8 @@ class AutofillSaveCardInfoBarDelegateMobileTest
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> CreateDelegate(
bool is_uploading,
CreditCard credit_card = CreditCard());
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> CreateDelegate(
CreateDelegateOptions options);
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile>
CreateDelegateWithLegalMessage(
bool is_uploading,
Expand Down Expand Up @@ -105,6 +113,24 @@ AutofillSaveCardInfoBarDelegateMobileTest::CreateDelegate(
return CreateDelegateWithLegalMessage(is_uploading, "", credit_card);
}

std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile>
AutofillSaveCardInfoBarDelegateMobileTest::CreateDelegate(
CreateDelegateOptions options) {
AutofillSaveCardUiInfo ui_info;
ui_info.logo_icon_id = options.logo_icon_id;
ui_info.title_text = options.title_text;
ui_info.confirm_text = options.confirm_text;
ui_info.cancel_text = options.cancel_text;
ui_info.description_text = options.description_text;
ui_info.is_google_pay_branding_enabled =
options.is_google_pay_branding_enabled;
return std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
std::move(ui_info),
std::make_unique<AutofillSaveCardDelegate>(
(AutofillClient::LocalSaveCardPromptCallback)base::DoNothing(),
AutofillClient::SaveCreditCardOptions()));
}

std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile>
AutofillSaveCardInfoBarDelegateMobileTest::CreateDelegateWithLegalMessage(
bool is_uploading,
Expand All @@ -131,18 +157,24 @@ AutofillSaveCardInfoBarDelegateMobileTest::
/*escape_apostrophes=*/true);
}
credit_card_to_save_ = credit_card;
return is_uploading
? AutofillSaveCardInfoBarDelegateMobile::CreateForUploadSave(
options, credit_card,
base::BindOnce(&AutofillSaveCardInfoBarDelegateMobileTest::
UploadSaveCardPromptCallback,
base::Unretained(this)),
legal_message_lines, AccountInfo())
: AutofillSaveCardInfoBarDelegateMobile::CreateForLocalSave(
options, credit_card,
base::BindOnce(&AutofillSaveCardInfoBarDelegateMobileTest::
LocalSaveCardPromptCallback,
base::Unretained(this)));
if (is_uploading) {
return std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
AutofillSaveCardUiInfo::CreateForUploadSave(
options, credit_card, legal_message_lines, AccountInfo()),
std::make_unique<AutofillSaveCardDelegate>(
base::BindOnce(&AutofillSaveCardInfoBarDelegateMobileTest::
UploadSaveCardPromptCallback,
base::Unretained(this)),
options));
} else {
return std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
AutofillSaveCardUiInfo::CreateForLocalSave(options, credit_card),
std::make_unique<AutofillSaveCardDelegate>(
base::BindOnce(&AutofillSaveCardInfoBarDelegateMobileTest::
LocalSaveCardPromptCallback,
base::Unretained(this)),
options));
}
}

// Test that local credit card save infobar metrics are logged correctly.
Expand Down Expand Up @@ -441,4 +473,66 @@ TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, LocalCardHasNoNickname) {
EXPECT_EQ(delegate->card_label(), card.NetworkAndLastFourDigits());
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, IsGooglePayBrandingEnabled) {
for (bool param : {true, false}) {
auto delegate = CreateDelegate({
.is_google_pay_branding_enabled = param,
});

EXPECT_EQ(delegate->IsGooglePayBrandingEnabled(), param);
}
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, GetDescriptionText) {
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate =
CreateDelegate({
.description_text = u"Mock Description Text",
});

EXPECT_EQ(delegate->GetDescriptionText(), u"Mock Description Text");
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, GetIconId) {
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate =
CreateDelegate({
.logo_icon_id = 123456,
});

EXPECT_EQ(delegate->GetIconId(), 123456);
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, GetMessageText) {
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate =
CreateDelegate({
.title_text = u"Mock Title Text",
});

EXPECT_EQ(delegate->GetMessageText(), u"Mock Title Text");
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest, GetButtonLabelForOkButton) {
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate =
CreateDelegate({
.confirm_text = u"Mock Confirm Text",
});

EXPECT_EQ(
delegate->GetButtonLabel(
AutofillSaveCardInfoBarDelegateMobile::InfoBarButton::BUTTON_OK),
u"Mock Confirm Text");
}

TEST_F(AutofillSaveCardInfoBarDelegateMobileTest,
GetButtonLabelForCancelButton) {
std::unique_ptr<AutofillSaveCardInfoBarDelegateMobile> delegate =
CreateDelegate({
.cancel_text = u"Mock Cancel Text",
});

EXPECT_EQ(
delegate->GetButtonLabel(
AutofillSaveCardInfoBarDelegateMobile::InfoBarButton::BUTTON_CANCEL),
u"Mock Cancel Text");
}

} // namespace autofill
16 changes: 10 additions & 6 deletions chrome/browser/ui/autofill/chrome_autofill_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -738,8 +738,10 @@ void ChromeAutofillClient::ConfirmSaveCreditCardLocally(
DCHECK(options.show_prompt);
infobars::ContentInfoBarManager::FromWebContents(web_contents())
->AddInfoBar(CreateSaveCardInfoBarMobile(
AutofillSaveCardInfoBarDelegateMobile::CreateForLocalSave(
options, card, std::move(callback))));
std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
AutofillSaveCardUiInfo::CreateForLocalSave(options, card),
std::make_unique<AutofillSaveCardDelegate>(std::move(callback),
options))));
#else
// Do lazy initialization of SaveCardBubbleControllerImpl.
SaveCardBubbleControllerImpl::CreateForWebContents(web_contents());
Expand All @@ -765,16 +767,18 @@ void ChromeAutofillClient::ConfirmSaveCreditCardToCloud(
autofill_save_card_bottom_sheet_bridge_->RequestShowContent();
return;
}

signin::IdentityManager* identity_manager =
IdentityManagerFactory::GetForProfile(GetProfile());
AccountInfo account_info = identity_manager->FindExtendedAccountInfo(
identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin));
AutofillSaveCardUiInfo ui_info = AutofillSaveCardUiInfo::CreateForUploadSave(
options, card, legal_message_lines, account_info);
auto common_delegate =
std::make_unique<AutofillSaveCardDelegate>(std::move(callback), options);
infobars::ContentInfoBarManager::FromWebContents(web_contents())
->AddInfoBar(CreateSaveCardInfoBarMobile(
AutofillSaveCardInfoBarDelegateMobile::CreateForUploadSave(
options, card, std::move(callback), legal_message_lines,
account_info)));
std::make_unique<AutofillSaveCardInfoBarDelegateMobile>(
std::move(ui_info), std::move(common_delegate))));
#else
// Do lazy initialization of SaveCardBubbleControllerImpl.
SaveCardBubbleControllerImpl::CreateForWebContents(web_contents());
Expand Down
10 changes: 10 additions & 0 deletions components/autofill/core/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,13 @@ static_library("browser") {
"payments/autofill_credit_card_filling_infobar_delegate_mobile.h",
"payments/autofill_offer_notification_infobar_delegate_mobile.cc",
"payments/autofill_offer_notification_infobar_delegate_mobile.h",
"payments/autofill_save_card_delegate.cc",
"payments/autofill_save_card_delegate.h",
"payments/autofill_save_card_infobar_delegate_mobile.cc",
"payments/autofill_save_card_infobar_delegate_mobile.h",
"payments/autofill_save_card_infobar_mobile.h",
"payments/autofill_save_card_ui_info.cc",
"payments/autofill_save_card_ui_info.h",
"payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.cc",
"payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.h",
"payments/autofill_virtual_card_enrollment_infobar_mobile.h",
Expand Down Expand Up @@ -1089,6 +1093,8 @@ source_set("unit_tests") {

if (is_ios || is_android) {
sources += [
"payments/autofill_save_card_delegate_unittest.cc",
"payments/autofill_save_card_ui_info_unittest.cc",
"ui/mobile_label_formatter_unittest.cc",
"ui/payments/card_expiration_date_fix_flow_controller_impl_unittest.cc",
"ui/payments/card_name_fix_flow_controller_impl_unittest.cc",
Expand Down Expand Up @@ -1193,6 +1199,10 @@ source_set("unit_tests") {
"//url",
]

if (is_ios || is_android) {
deps += [ "//build:branding_buildflags" ]
}

if (use_blink) {
deps += [
"//content/test:test_support",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/autofill/core/browser/payments/autofill_save_card_delegate.h"

#include "components/autofill/core/browser/metrics/payments/credit_card_save_metrics.h"

namespace autofill {

AutofillSaveCardDelegate::AutofillSaveCardDelegate(
absl::variant<AutofillClient::LocalSaveCardPromptCallback,
AutofillClient::UploadSaveCardPromptCallback> callback,
AutofillClient::SaveCreditCardOptions options)
: options_(options),
had_user_interaction_(false),
callback_(std::move(callback)) {}

AutofillSaveCardDelegate::~AutofillSaveCardDelegate() = default;

void AutofillSaveCardDelegate::OnUiShown() {
AutofillMetrics::LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN,
is_for_upload(), options_);
}

void AutofillSaveCardDelegate::OnUiAccepted() {
// Acceptance can be logged immediately if:
// 1. the user is accepting local save.
// 2. or when we don't need more info in order to upload.
if (!is_for_upload() ||
(!options_.should_request_name_from_user &&
!options_.should_request_expiration_date_from_user)) {
LogSaveCreditCardPromptResult(
autofill_metrics::SaveCreditCardPromptResult::kAccepted,
is_for_upload(), options_);
}
LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED);
RunSaveCardPromptCallback(
AutofillClient::SaveCardOfferUserDecision::kAccepted,
/*user_provided_details=*/{});
}

void AutofillSaveCardDelegate::OnUiUpdatedAndAccepted(
AutofillClient::UserProvidedCardDetails user_provided_details) {
LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED);
RunSaveCardPromptCallback(
AutofillClient::SaveCardOfferUserDecision::kAccepted,
user_provided_details);
}

void AutofillSaveCardDelegate::OnUiCanceled() {
RunSaveCardPromptCallback(
AutofillClient::SaveCardOfferUserDecision::kDeclined,
/*user_provided_details=*/{});
LogUserAction(AutofillMetrics::INFOBAR_DENIED);
LogSaveCreditCardPromptResult(
autofill_metrics::SaveCreditCardPromptResult::kDenied, is_for_upload(),
options_);
}

void AutofillSaveCardDelegate::OnUiIgnored() {
if (!had_user_interaction_) {
RunSaveCardPromptCallback(
AutofillClient::SaveCardOfferUserDecision::kIgnored,
/*user_provided_details=*/{});
LogUserAction(AutofillMetrics::INFOBAR_IGNORED);
LogSaveCreditCardPromptResult(
autofill_metrics::SaveCreditCardPromptResult::kIgnored, is_for_upload(),
options_);
}
}

void AutofillSaveCardDelegate::RunSaveCardPromptCallback(
AutofillClient::SaveCardOfferUserDecision user_decision,
AutofillClient::UserProvidedCardDetails user_provided_details) {
if (is_for_upload()) {
absl::get<AutofillClient::UploadSaveCardPromptCallback>(
std::move(callback_))
.Run(user_decision, user_provided_details);
} else {
absl::get<AutofillClient::LocalSaveCardPromptCallback>(std::move(callback_))
.Run(user_decision);
}
}

void AutofillSaveCardDelegate::LogUserAction(
AutofillMetrics::InfoBarMetric user_action) {
DCHECK(!had_user_interaction_);

AutofillMetrics::LogCreditCardInfoBarMetric(user_action, is_for_upload(),
options_);
had_user_interaction_ = true;
}

} // namespace autofill

0 comments on commit eecf6b1

Please sign in to comment.