#include "chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h"
#include <optional>
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/ui/autofill/chrome_autofill_client.h"
#include "chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h"
#include "chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/virtual_card_enroll_bubble_controller_impl_test_api.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/autofill/core/browser/payments/payments_autofill_client.h"
#include "components/autofill/core/common/autofill_payments_features.h"
#include "content/public/browser/web_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/ui/android/autofill/autofill_save_card_bottom_sheet_bridge.h"
#include "chrome/browser/ui/android/autofill/autofill_save_card_delegate_android.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#include "chrome/browser/ui/android/tab_model/tab_model_test_helper.h"
#include "chrome/browser/ui/autofill/payments/autofill_message_controller.h"
#include "chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h"
#include "components/autofill/core/browser/payments/autofill_save_card_ui_info.h"
#include "ui/android/window_android.h"
#else
#include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h"
#endif
_;
AllOf;
Field;
NotNull;
namespace autofill {
#if BUILDFLAG(IS_ANDROID)
class MockAutofillSaveCardBottomSheetBridge
: public AutofillSaveCardBottomSheetBridge {
public:
MockAutofillSaveCardBottomSheetBridge()
: AutofillSaveCardBottomSheetBridge(
base::android::ScopedJavaGlobalRef<jobject>(nullptr)) {}
MOCK_METHOD(void,
RequestShowContent,
(const AutofillSaveCardUiInfo&,
std::unique_ptr<AutofillSaveCardDelegateAndroid>),
(override));
MOCK_METHOD(void, Hide, (), (override));
};
class MockAutofillSnackbarControllerImpl
: public AutofillSnackbarControllerImpl {
public:
explicit MockAutofillSnackbarControllerImpl(
content::WebContents* web_contents)
: AutofillSnackbarControllerImpl(web_contents) {}
MOCK_METHOD(void, Show, (AutofillSnackbarType), (override));
MOCK_METHOD(void,
ShowWithDurationAndCallback,
(AutofillSnackbarType,
base::TimeDelta,
std::optional<base::OnceClosure>),
(override));
};
class MockAutofillMessageController : public AutofillMessageController {
public:
explicit MockAutofillMessageController(content::WebContents* web_contents)
: AutofillMessageController(web_contents) {}
MOCK_METHOD(void, Show, (std::unique_ptr<AutofillMessageModel>), (override));
};
#else
class MockSaveCardBubbleController : public SaveCardBubbleControllerImpl { … };
#endif
class MockVirtualCardEnrollBubbleController
: public VirtualCardEnrollBubbleControllerImpl { … };
class ChromePaymentsAutofillClientTest
: public ChromeRenderViewHostTestHarness { … };
#if BUILDFLAG(IS_ANDROID)
TEST_F(ChromePaymentsAutofillClientTest,
GetOrCreateAutofillSaveCardBottomSheetBridge_IsNotNull) {
std::unique_ptr<ui::WindowAndroid::ScopedWindowAndroidForTesting> window =
ui::WindowAndroid::CreateForTesting();
window.get()->get()->AddChild(web_contents()->GetNativeView());
TestTabModel tab_model(profile());
tab_model.SetWebContentsList({web_contents()});
TabModelList::AddTabModel(&tab_model);
EXPECT_NE(
chrome_payments_client()->GetOrCreateAutofillSaveCardBottomSheetBridge(),
nullptr);
TabModelList::RemoveTabModel(&tab_model);
}
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardLocally_CardSaveOnly_RequestsBottomSheet) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
EXPECT_CALL(
*save_card_bridge,
RequestShowContent(
AllOf(
Field(&AutofillSaveCardUiInfo::is_for_upload, false),
Field(&AutofillSaveCardUiInfo::description_text,
u"To pay faster next time, save your card to your device")),
NotNull()));
chrome_payments_client()->ConfirmSaveCreditCardLocally(
CreditCard(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_card_save_type(payments::ChromePaymentsAutofillClient::
CardSaveType::kCardSaveOnly)
.with_show_prompt(true),
base::DoNothing());
}
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardLocally_CardSaveWithCvc_RequestsBottomSheet) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
EXPECT_CALL(*save_card_bridge,
RequestShowContent(
AllOf(Field(&AutofillSaveCardUiInfo::is_for_upload, false),
Field(&AutofillSaveCardUiInfo::description_text,
u"To pay faster next time, save your card and "
u"encrypted security code to your device")),
NotNull()));
chrome_payments_client()->ConfirmSaveCreditCardLocally(
CreditCard(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_card_save_type(payments::ChromePaymentsAutofillClient::
CardSaveType::kCardSaveWithCvc)
.with_show_prompt(true),
base::DoNothing());
}
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardLocally_WindowNotSet_DoesNotFail) {
EXPECT_NO_FATAL_FAILURE(
chrome_payments_client()->ConfirmSaveCreditCardLocally(
CreditCard(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_show_prompt(true),
base::DoNothing()));
}
TEST_F(
ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardToCloud_CardSaveTypeIsOnlyCard_RequestsBottomSheet) {
MockAutofillSaveCardBottomSheetBridge* bottom_sheet_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
std::u16string expected_description;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
expected_description =
u"To pay faster next time, save your card and billing address in your "
u"Google Account";
#endif
EXPECT_CALL(*bottom_sheet_bridge,
RequestShowContent(
AllOf(Field(&AutofillSaveCardUiInfo::is_for_upload, true),
Field(&AutofillSaveCardUiInfo::description_text,
expected_description)),
testing::NotNull()));
chrome_payments_client()->ConfirmSaveCreditCardToCloud(
CreditCard(), LegalMessageLines(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_card_save_type(payments::ChromePaymentsAutofillClient::
CardSaveType::kCardSaveOnly)
.with_show_prompt(true),
base::DoNothing());
}
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardToCloud_CardSaveTypeIsWithCvc_RequestsBottomSheet) {
MockAutofillSaveCardBottomSheetBridge* bottom_sheet_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
std::u16string expected_description;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
expected_description =
u"To pay faster next time, save your card, encrypted security code, and "
u"billing address in your Google Account";
#endif
EXPECT_CALL(*bottom_sheet_bridge,
RequestShowContent(
AllOf(Field(&AutofillSaveCardUiInfo::is_for_upload, true),
Field(&AutofillSaveCardUiInfo::description_text,
expected_description)),
testing::NotNull()));
chrome_payments_client()->ConfirmSaveCreditCardToCloud(
CreditCard(), LegalMessageLines(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_card_save_type(payments::ChromePaymentsAutofillClient::
CardSaveType::kCardSaveWithCvc)
.with_show_prompt(true),
base::DoNothing());
}
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardToCloud_DoesNotFailWithoutAWindow) {
EXPECT_NO_FATAL_FAILURE(
chrome_payments_client()->ConfirmSaveCreditCardToCloud(
CreditCard(), LegalMessageLines(),
payments::ChromePaymentsAutofillClient::SaveCreditCardOptions()
.with_show_prompt(true),
base::DoNothing()));
}
TEST_F(
ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedSuccessful_CallsSaveCardBottomSheetBridgeAndSnackbarControllerWithDurationAndCallback) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
MockAutofillSnackbarControllerImpl* snackbar_controller =
InjectMockAutofillSnackbarControllerImpl();
EXPECT_CALL(*save_card_bridge, Hide);
EXPECT_CALL(
*snackbar_controller,
ShowWithDurationAndCallback(AutofillSnackbarType::kSaveCardSuccess,
payments::ChromePaymentsAutofillClient::
kSaveCardConfirmationSnackbarDuration,
testing::Ne(std::nullopt)));
std::optional<base::OnceClosure> callback = base::OnceClosure();
chrome_payments_client()->CreditCardUploadCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kSuccess,
std::move(callback));
}
TEST_F(
ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedSuccessfulButNoCallback_CallsSaveCardBottomSheetBridgeAndSnackbarControllerWithoutDuration) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
MockAutofillSnackbarControllerImpl* snackbar_controller =
InjectMockAutofillSnackbarControllerImpl();
EXPECT_CALL(*save_card_bridge, Hide);
EXPECT_CALL(*snackbar_controller,
Show(AutofillSnackbarType::kSaveCardSuccess));
chrome_payments_client()->CreditCardUploadCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kSuccess,
std::nullopt);
}
TEST_F(
ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedFailure_CallsSaveCardBottomSheetBridgeAndAutofillMessageController) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
MockAutofillMessageController* message_controller =
InjectMockAutofillMessageController();
EXPECT_CALL(*save_card_bridge, Hide);
EXPECT_CALL(*message_controller, Show)
.WillOnce([](std::unique_ptr<AutofillMessageModel> model) {
EXPECT_EQ(model->GetType(),
AutofillMessageModel::Type::kSaveCardFailure);
});
chrome_payments_client()->CreditCardUploadCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kPermanentFailure,
std::nullopt);
}
TEST_F(
ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedOnClientSideTimeout_HidesSaveCardBottomSheetBridge_NoErrorConfirmation) {
MockAutofillSaveCardBottomSheetBridge* save_card_bridge =
InjectMockAutofillSaveCardBottomSheetBridge();
MockAutofillMessageController* message_controller =
InjectMockAutofillMessageController();
EXPECT_CALL(*save_card_bridge, Hide);
EXPECT_CALL(*message_controller, Show).Times(0);
chrome_payments_client()->CreditCardUploadCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kClientSideTimeout,
std::nullopt);
}
TEST_F(ChromePaymentsAutofillClientTest,
VirtualCardEnrollSuccessful_CallsSnackbarController) {
MockAutofillSnackbarControllerImpl* snackbar_controller =
InjectMockAutofillSnackbarControllerImpl();
EXPECT_CALL(*snackbar_controller,
Show(AutofillSnackbarType::kVirtualCardEnrollSuccess));
chrome_payments_client()->VirtualCardEnrollCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kSuccess);
}
TEST_F(ChromePaymentsAutofillClientTest,
VirtualCardEnrollFailure_CallsAutofillMessageController) {
MockAutofillMessageController* message_controller =
InjectMockAutofillMessageController();
test_api(virtual_card_bubble_controller())
.SetUiModel(std::make_unique<VirtualCardEnrollUiModel>(
VirtualCardEnrollmentFields()));
EXPECT_CALL(*message_controller, Show)
.WillOnce([](std::unique_ptr<AutofillMessageModel> model) {
EXPECT_EQ(model->GetType(),
AutofillMessageModel::Type::kVirtualCardEnrollFailure);
});
chrome_payments_client()->VirtualCardEnrollCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kPermanentFailure);
}
TEST_F(
ChromePaymentsAutofillClientTest,
VirtualCardEnrollClientSideTimeout_DoesNotCallAutofillMessageController) {
MockAutofillMessageController* message_controller =
InjectMockAutofillMessageController();
EXPECT_CALL(*message_controller, Show).Times(0);
chrome_payments_client()->VirtualCardEnrollCompleted(
payments::PaymentsAutofillClient::PaymentsRpcResult::kClientSideTimeout);
}
TEST_F(ChromePaymentsAutofillClientTest,
GetOrCreateAutofillSaveIbanBottomSheetBridge_IsNotNull) {
std::unique_ptr<ui::WindowAndroid::ScopedWindowAndroidForTesting> window =
ui::WindowAndroid::CreateForTesting();
window.get()->get()->AddChild(web_contents()->GetNativeView());
TestTabModel tab_model(profile());
tab_model.SetWebContentsList({web_contents()});
TabModelList::AddTabModel(&tab_model);
EXPECT_NE(
chrome_payments_client()->GetOrCreateAutofillSaveIbanBottomSheetBridge(),
nullptr);
TabModelList::RemoveTabModel(&tab_model);
}
#else
TEST_F(ChromePaymentsAutofillClientTest,
ConfirmSaveCreditCardLocally_CallsOfferLocalSave) { … }
TEST_F(ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedSuccess_CallsShowConfirmationBubbleView) { … }
TEST_F(ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedFailure_CallsShowConfirmationBubbleView) { … }
TEST_F(
ChromePaymentsAutofillClientTest,
CreditCardUploadCompletedClientSideTimeout_CallsShowConfirmationBubbleView) { … }
#endif
TEST_F(ChromePaymentsAutofillClientTest,
VirtualCardEnrollCompleted_ShowsConfirmation) { … }
TEST_F(ChromePaymentsAutofillClientTest, GetPaymentsWindowManager) { … }
TEST_F(ChromePaymentsAutofillClientTest, RiskDataCaching_DataCached) { … }
}