chromium/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h"

#include <optional>

#include "base/memory/raw_ptr.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/autofill/mock_manual_filling_view.h"
#include "chrome/browser/keyboard_accessory/android/manual_filling_controller_impl.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_address_accessory_controller.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_password_accessory_controller.h"
#include "chrome/browser/keyboard_accessory/test_utils/android/mock_payment_method_accessory_controller.h"
#include "chrome/browser/ui/autofill/payments/autofill_snackbar_view.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/strings/grit/components_strings.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"

using testing::NiceMock;

namespace autofill {

class AutofillSnackbarControllerImplTest
    : public ChromeRenderViewHostTestHarness {
 public:
  AutofillSnackbarControllerImplTest() = default;

  void SetUp() override {
    ChromeRenderViewHostTestHarness::SetUp();
    ManualFillingControllerImpl::CreateForWebContentsForTesting(
        web_contents(), mock_pwd_controller_.AsWeakPtr(),
        mock_address_controller_.AsWeakPtr(),
        mock_payment_method_controller_.AsWeakPtr(),
        std::make_unique<NiceMock<MockManualFillingView>>());
  }

  AutofillSnackbarControllerImpl* controller() {
    if (!controller_)
      controller_ = new AutofillSnackbarControllerImpl(web_contents());
    return controller_;
  }

  void ShowWithOnDismissCallback(AutofillSnackbarType autofill_snackbar_type) {
    controller()->ShowWithDurationAndCallback(
        autofill_snackbar_type,
        AutofillSnackbarControllerImpl::kDefaultSnackbarDuration,
        base::BindOnce(&AutofillSnackbarControllerImplTest::OnDismissCallback,
                       weak_ptr_factory_.GetWeakPtr()));
  }

 protected:
  int on_dismiss_callback_call_count_ = 0;

 private:
  void OnDismissCallback() { ++on_dismiss_callback_call_count_; }

  raw_ptr<AutofillSnackbarControllerImpl> controller_ = nullptr;
  NiceMock<MockPasswordAccessoryController> mock_pwd_controller_;
  NiceMock<MockAddressAccessoryController> mock_address_controller_;
  NiceMock<MockPaymentMethodAccessoryController>
      mock_payment_method_controller_;

  base::WeakPtrFactory<AutofillSnackbarControllerImplTest> weak_ptr_factory_{
      this};
};

TEST_F(AutofillSnackbarControllerImplTest, Metrics_VirtualCard) {
  base::HistogramTester histogram_tester;
  controller()->Show(AutofillSnackbarType::kVirtualCard);
  // Verify that the count for Shown is incremented and ActionClicked hasn't
  // changed.
  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1,
                                      1);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 0);
  controller()->OnDismissed();

  controller()->Show(AutofillSnackbarType::kVirtualCard);
  controller()->OnActionClicked();
  // Verify that the count for both Shown and ActionClicked is incremented.
  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1,
                                      2);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 1);
}

TEST_F(AutofillSnackbarControllerImplTest,
       Metrics_ShowVirtualCardWhenAlreadyShowing) {
  base::HistogramTester histogram_tester;
  controller()->Show(AutofillSnackbarType::kVirtualCard);
  // Verify that the count for Shown is incremented and ActionClicked hasn't
  // changed.
  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1,
                                      1);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 0);

  // Attempt to show another dialog without dismissing the previous one.
  controller()->Show(AutofillSnackbarType::kVirtualCard);

  // Verify that the count for both Shown is not incremented.
  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1,
                                      1);
}

TEST_F(AutofillSnackbarControllerImplTest, Metrics_ShowMandatoryReauth) {
  base::HistogramTester histogram_tester;
  controller()->Show(AutofillSnackbarType::kMandatoryReauth);
  // Verify that the count for Shown is incremented and ActionClicked hasn't
  // changed.
  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.MandatoryReauth.Shown",
                                      1, 1);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.MandatoryReauth.ActionClicked", 1, 0);
  controller()->OnDismissed();

  // TODO(crbug.com/40570965): Figure out how to mock
  // ShowAutofillCreditCardSettings to test ActionClicked metric.
}

TEST_F(AutofillSnackbarControllerImplTest, Metrics_SaveCardSuccess) {
  base::HistogramTester histogram_tester;

  controller()->Show(AutofillSnackbarType::kSaveCardSuccess);

  histogram_tester.ExpectUniqueSample("Autofill.Snackbar.SaveCardSuccess.Shown",
                                      true, 1);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.SaveCardSuccess.ActionClicked", true, 0);

  controller()->OnActionClicked();

  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.SaveCardSuccess.ActionClicked", true, 1);
}

TEST_F(AutofillSnackbarControllerImplTest, Metrics_VirtualCardEnrollSuccess) {
  base::HistogramTester histogram_tester;

  controller()->Show(AutofillSnackbarType::kVirtualCardEnrollSuccess);

  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCardEnrollSuccess.Shown", true, 1);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCardEnrollSuccess.ActionClicked", true, 0);

  controller()->OnActionClicked();

  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.VirtualCardEnrollSuccess.ActionClicked", true, 1);
}

TEST_F(AutofillSnackbarControllerImplTest,
       SaveCardSuccessMessageAndActionButtonText) {
  controller()->Show(AutofillSnackbarType::kSaveCardSuccess);

  EXPECT_EQ(controller()->GetMessageText(),
            l10n_util::GetStringUTF16(
                IDS_AUTOFILL_SAVE_CARD_CONFIRMATION_SUCCESS_DESCRIPTION_TEXT));
  EXPECT_EQ(
      controller()->GetActionButtonText(),
      l10n_util::GetStringUTF16(
          IDS_AUTOFILL_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_BUTTON_TEXT));
}

TEST_F(AutofillSnackbarControllerImplTest,
       VirtualCardEnrollSuccessMessageAndActionButtonText) {
  controller()->Show(AutofillSnackbarType::kVirtualCardEnrollSuccess);

  EXPECT_EQ(
      controller()->GetMessageText(),
      l10n_util::GetStringUTF16(
          IDS_AUTOFILL_VIRTUAL_CARD_ENROLL_CONFIRMATION_SUCCESS_DESCRIPTION_TEXT));
  EXPECT_EQ(
      controller()->GetActionButtonText(),
      l10n_util::GetStringUTF16(
          IDS_AUTOFILL_SAVE_CARD_AND_VIRTUAL_CARD_ENROLL_CONFIRMATION_BUTTON_TEXT));
}

TEST_F(AutofillSnackbarControllerImplTest, Metrics_SaveServerIbanSuccess) {
  base::HistogramTester histogram_tester;
  controller()->Show(AutofillSnackbarType::kSaveServerIbanSuccess);
  // Verify that the count for Shown is incremented and ActionClicked hasn't
  // changed.
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.SaveServerIbanSuccess.Shown", 1, 1);
  histogram_tester.ExpectTotalCount(
      "Autofill.Snackbar.SaveServerIbanSuccess.ActionClicked", 0);
  controller()->OnDismissed();

  controller()->Show(AutofillSnackbarType::kSaveServerIbanSuccess);
  controller()->OnActionClicked();

  // Verify that the count for both Shown and ActionClicked is incremented.
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.SaveServerIbanSuccess.Shown", 1, 2);
  histogram_tester.ExpectUniqueSample(
      "Autofill.Snackbar.SaveServerIbanSuccess.ActionClicked", true, 1);
}

TEST_F(AutofillSnackbarControllerImplTest,
       SaveServerIbanSuccessMessageAndActionButtonText) {
  controller()->Show(AutofillSnackbarType::kSaveServerIbanSuccess);

  EXPECT_EQ(controller()->GetMessageText(),
            l10n_util::GetStringUTF16(
                IDS_AUTOFILL_SAVE_SERVER_IBAN_SUCCESS_SNACKBAR_MESSAGE_TEXT));
  EXPECT_EQ(controller()->GetActionButtonText(),
            l10n_util::GetStringUTF16(
                IDS_AUTOFILL_SAVE_SERVER_IBAN_SUCCESS_SNACKBAR_BUTTON_TEXT));
}

TEST_F(AutofillSnackbarControllerImplTest, OnShowDefaultDurationSet) {
  controller()->Show(AutofillSnackbarType::kSaveCardSuccess);
  EXPECT_EQ(controller()->GetDuration(),
            AutofillSnackbarControllerImpl::kDefaultSnackbarDuration);
}

TEST_F(AutofillSnackbarControllerImplTest,
       OnShowWithDurationCustomDurationSet) {
  base::TimeDelta duration = base::Seconds(3);
  controller()->ShowWithDurationAndCallback(
      AutofillSnackbarType::kSaveCardSuccess, duration, std::nullopt);
  EXPECT_EQ(controller()->GetDuration(), duration);
}

TEST_F(AutofillSnackbarControllerImplTest, OnDismissCallbackCalled) {
  ShowWithOnDismissCallback(AutofillSnackbarType::kSaveCardSuccess);
  EXPECT_EQ(on_dismiss_callback_call_count_, 0);

  controller()->OnDismissed();
  EXPECT_EQ(on_dismiss_callback_call_count_, 1);
}

TEST_F(AutofillSnackbarControllerImplTest, OnDismissTwiceCallbackCalledOnce) {
  ShowWithOnDismissCallback(AutofillSnackbarType::kSaveCardSuccess);
  controller()->OnDismissed();
  controller()->Show(AutofillSnackbarType::kSaveCardSuccess);
  controller()->OnDismissed();

  EXPECT_EQ(on_dismiss_callback_call_count_, 1);
}

}  // namespace autofill