910e62b5创建于 1月15日历史提交
// 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 "chrome/browser/compose/compose_enabling.h"

#include <memory>

#include "base/json/values_util.h"
#include "base/memory/raw_ptr.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/types/expected.h"
#include "chrome/browser/about_flags.h"
#include "chrome/browser/optimization_guide/mock_optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/translate/chrome_translate_client.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/autofill/core/common/aliases.h"
#include "components/compose/core/browser/compose_features.h"
#include "components/compose/core/browser/config.h"
#include "components/language/core/browser/language_model.h"
#include "components/optimization_guide/core/optimization_guide_proto_util.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/supervised_user/core/common/pref_names.h"
#include "components/supervised_user/core/common/supervised_user_constants.h"
#include "components/translate/core/browser/language_state.h"
#include "components/translate/core/browser/mock_translate_client.h"
#include "components/translate/core/browser/mock_translate_driver.h"
#include "components/translate/core/browser/mock_translate_ranker.h"
#include "components/translate/core/browser/translate_manager.h"
#include "components/unified_consent/pref_names.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::test::ErrorIs;
using base::test::FeatureRef;
using testing::_;
using testing::Return;

namespace {
constexpr char kEmail[] = "example@gmail.com";
constexpr char kExampleURL[] = "https://example.com";
constexpr char kExampleBadURL[] = "chrome://version";
using translate::testing::MockTranslateClient;

class TestLanguageModel : public language::LanguageModel {
  std::vector<LanguageDetails> GetLanguages() override {
    return {LanguageDetails("en", 1.0)};
  }
};

class CustomMockOptimizationGuideKeyedService
    : public MockOptimizationGuideKeyedService {
 public:
  CustomMockOptimizationGuideKeyedService() = default;
  ~CustomMockOptimizationGuideKeyedService() override = default;

  MOCK_METHOD(void,
              CanApplyOptimization,
              (const GURL& url,
               optimization_guide::proto::OptimizationType optimization_type,
               optimization_guide::OptimizationGuideDecisionCallback callback));

  MOCK_METHOD(
      optimization_guide::OptimizationGuideDecision,
      CanApplyOptimization,
      (const GURL& url,
       optimization_guide::proto::OptimizationType optimization_type,
       optimization_guide::OptimizationMetadata* optimization_metadata));
  MOCK_METHOD(void,
              RegisterOptimizationTypes,
              (const std::vector<optimization_guide::proto::OptimizationType>&
                   optimization_types));
  MOCK_METHOD(
      void,
      CanApplyOptimizationOnDemand,
      (const std::vector<GURL>& urls,
       const base::flat_set<optimization_guide::proto::OptimizationType>&
           optimization_types,
       optimization_guide::proto::RequestContext request_context,
       optimization_guide::OnDemandOptimizationGuideDecisionRepeatingCallback
           callback,
       std::optional<optimization_guide::proto::RequestContextMetadata>
           request_context_metadata));
};

void RegisterMockOptimizationGuideKeyedServiceFactory(
    content::BrowserContext* context) {
  OptimizationGuideKeyedServiceFactory::GetInstance()->SetTestingFactory(
      context, base::BindRepeating([](content::BrowserContext* context)
                                       -> std::unique_ptr<KeyedService> {
        return std::make_unique<
            testing::NiceMock<CustomMockOptimizationGuideKeyedService>>();
      }));
}

}  // namespace

class ComposeEnablingTest : public BrowserWithTestWindowTest {
 public:
  ComposeEnablingTest() {
    // Allows early registration of a override of the factory that instantiates
    // OptimizationGuideKeyedService.
    subscription_ =
        BrowserContextDependencyManager::GetInstance()
            ->RegisterCreateServicesCallbackForTesting(base::BindRepeating(
                RegisterMockOptimizationGuideKeyedServiceFactory));
  }

  void SetUp() override {
    BrowserWithTestWindowTest::SetUp();

    // Set flags to their expected enabled/disabled state for these tests
    // without relyong on their default state. In other words, a change in
    // default state should not cause these tests to break.
    // Note: individual tests may reset flags to their default state.
    ResetFeaturesAndConfig(
        {compose::features::kEnableCompose,
         compose::features::kEnableComposeSavedStateNudge,
         compose::features::kEnableComposeLanguageBypassForContextMenu,
         compose::features::kEnableComposeSavedStateNotification},
        {compose::features::kEnableComposeProactiveNudge});

    mock_translate_ranker_ =
        std::make_unique<translate::testing::MockTranslateRanker>();
    mock_translate_client_ =
        std::make_unique<MockTranslateClient>(&translate_driver_, nullptr);
    translate_manager_ = std::make_unique<translate::TranslateManager>(
        mock_translate_client_.get(), mock_translate_ranker_.get(),
        language_model_.get());

    // Note that AddTab makes its own ComposeEnabling as part of
    // ChromeComposeClient. This can cause confusion when debugging tests.
    // Don't confuse the two ComposeEnabling objects when debugging.
    AddTab(browser(), GURL(kExampleBadURL));
    AddTab(browser(), GURL(kExampleURL));
    context_menu_params_.is_content_editable_for_autofill = true;
    context_menu_params_.frame_origin = GetOrigin();

    opt_guide_ = static_cast<
        testing::NiceMock<CustomMockOptimizationGuideKeyedService>*>(
        OptimizationGuideKeyedServiceFactory::GetForProfile(GetProfile()));
    ON_CALL(*opt_guide_,
            CanApplyOptimization(
                _, optimization_guide::proto::OptimizationType::COMPOSE,
                testing::An<optimization_guide::OptimizationMetadata*>()))
        .WillByDefault(
            [](const GURL& url,
               optimization_guide::proto::OptimizationType optimization_type,
               optimization_guide::OptimizationMetadata* metadata)
                -> optimization_guide::OptimizationGuideDecision {
              *metadata = {};
              compose::ComposeHintMetadata compose_hint_metadata;
              compose_hint_metadata.set_decision(
                  compose::ComposeHintDecision::COMPOSE_HINT_DECISION_ENABLED);
              metadata->set_any_metadata(
                  optimization_guide::AnyWrapProto(compose_hint_metadata));
              return optimization_guide::OptimizationGuideDecision::kTrue;
            });

    ASSERT_TRUE(opt_guide_);

    // Build the ComposeEnabling object the tests will use, providing it with
    // mocks for its dependencies.
    // TODO(b/316625561) Simplify these tests more now that we have dependency
    // injection.
    compose_enabling_ = std::make_unique<ComposeEnabling>(
        GetProfile(), identity_test_env_.identity_manager(), &opt_guide());

    // Override un-mockable per-user checks.
    scoped_skip_user_check_ = ComposeEnabling::ScopedSkipUserCheckForTesting();
    // Set the user country to US, a Compose default-enabled country.
    scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("us");
  }

  void TearDown() override {
    // We must destroy the ComposeEnabling while the opt_guide object is still
    // valid so we can call unregister in the destructor.
    compose_enabling_ = nullptr;
    opt_guide_ = nullptr;
    scoped_feature_list_.Reset();
    compose::ResetConfigForTesting();
    BrowserWithTestWindowTest::TearDown();
  }

  void SetProactiveNudgePref(bool pref_value) {
    PrefService* prefs = GetProfile()->GetPrefs();
    prefs->SetBoolean(prefs::kEnableProactiveNudge, pref_value);
  }

  void AddDomainToProactiveNudgeDisabledSitesPref() {
    ScopedDictPrefUpdate update(GetProfile()->GetPrefs(),
                                prefs::kProactiveNudgeDisabledSitesWithTime);
    update->Set(GetOrigin().Serialize(), base::TimeToValue(base::Time::Now()));
  }

  void SignIn() {
    identity_test_env_.MakePrimaryAccountAvailable(
        kEmail, signin::ConsentLevel::kSignin);
    identity_test_env_.SetAutomaticIssueOfAccessTokens(true);
  }

  // The Config depends on several features. Reset the config after setting
  // new features.
  void ResetFeaturesAndConfig(
      const std::vector<FeatureRef>& enabled_features,
      const std::vector<FeatureRef>& disabled_features) {
    scoped_feature_list_.Reset();
    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
    compose::ResetConfigForTesting();
  }

  CustomMockOptimizationGuideKeyedService& opt_guide() { return *opt_guide_; }

 protected:
  void SetLanguage(std::string lang) {
    translate_manager_->GetLanguageState()->SetSourceLanguage(lang);
  }

  url::Origin GetOrigin() {
    return url::Origin::Create(browser()
                                   ->tab_strip_model()
                                   ->GetWebContentsAt(0)
                                   ->GetLastCommittedURL());
  }

  content::RenderFrameHost* GetRenderFrameHost() {
    return browser()
        ->tab_strip_model()
        ->GetWebContentsAt(0)
        ->GetPrimaryMainFrame();
  }

  void CheckIsEnabledError(ComposeEnabling* compose_enabling,
                           compose::ComposeShowStatus error_show_status) {
    EXPECT_EQ(compose_enabling->IsEnabled(),
              base::unexpected(error_show_status));
  }

  base::test::ScopedFeatureList scoped_feature_list_;
  signin::IdentityTestEnvironment identity_test_env_;

  content::ContextMenuParams context_menu_params_;

  base::CallbackListSubscription subscription_;
  raw_ptr<testing::NiceMock<CustomMockOptimizationGuideKeyedService>>
      opt_guide_;

  translate::testing::MockTranslateDriver translate_driver_;
  std::unique_ptr<translate::testing::MockTranslateClient>
      mock_translate_client_;
  std::unique_ptr<translate::testing::MockTranslateRanker>
      mock_translate_ranker_;
  std::unique_ptr<TestLanguageModel> language_model_;
  std::unique_ptr<translate::TranslateManager> translate_manager_;

  std::unique_ptr<ComposeEnabling> compose_enabling_;
  ComposeEnabling::ScopedOverride scoped_skip_user_check_;
  ComposeEnabling::ScopedOverride scoped_country_override_;
};

TEST_F(ComposeEnablingTest, EverythingDisabledTest) {
  ResetFeaturesAndConfig({}, {compose::features::kEnableCompose});
  // We intentionally don't call sign in to make our state not signed in.
  EXPECT_NE(compose_enabling_->IsEnabled(), base::ok());
}

TEST_F(ComposeEnablingTest, FeatureNotEnabledTest) {
  ResetFeaturesAndConfig({}, {compose::features::kEnableCompose});
  SignIn();

  CheckIsEnabledError(compose_enabling_.get(),
                      compose::ComposeShowStatus::kComposeFeatureFlagDisabled);
}

TEST_F(ComposeEnablingTest, NotSignedInTest) {
  base::HistogramTester histogram_tester;
  // Intentionally skip the signin step.
  CheckIsEnabledError(compose_enabling_.get(),
                      compose::ComposeShowStatus::kSignedOut);

  std::string autocomplete_attribute;
  // Check that the proactive nudge does not show.
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);

  EXPECT_EQ(should_trigger.error(), compose::ComposeShowStatus::kSignedOut);
}

TEST_F(ComposeEnablingTest, SignedInErrorTest) {
  // Sign in, with error.
  AccountInfo account_info = identity_test_env_.MakePrimaryAccountAvailable(
      kEmail, signin::ConsentLevel::kSignin);
  identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
      account_info.account_id,
      GoogleServiceAuthError(
          GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));

  CheckIsEnabledError(compose_enabling_.get(),
                      compose::ComposeShowStatus::kSignedOut);
}

TEST_F(ComposeEnablingTest, ComposeEligibleTest) {
  scoped_feature_list_.Reset();
  // Turn on the enable switch and off the eligible switch.
  scoped_feature_list_.InitWithFeatures({compose::features::kEnableCompose},
                                        {compose::features::kComposeEligible});
  SignIn();

  // The ComposeEligible switch should win, and disable the feature.
  CheckIsEnabledError(compose_enabling_.get(),
                      compose::ComposeShowStatus::kNotComposeEligible);
}

TEST_F(ComposeEnablingTest, EverythingEnabledTest) {
  SignIn();
  EXPECT_EQ(compose_enabling_->IsEnabled(), base::ok());
}

TEST_F(ComposeEnablingTest, UserNotAllowedTest) {
  SignIn();
  // Cause per-user check to fail.
  scoped_skip_user_check_.reset();

  EXPECT_THAT(
      compose_enabling_->IsEnabled(),
      ErrorIs(compose::ComposeShowStatus::kUserNotAllowedByOptimizationGuide));
}

TEST_F(ComposeEnablingTest, StaticMethodEverythingDisabledTest) {
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeatures({},
                                        {compose::features::kEnableCompose});
  // We intentionally don't call sign in to make our state not signed in.
  EXPECT_FALSE(ComposeEnabling::IsEnabledForProfile(GetProfile()));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuDisabledTest) {
  // We intentionally disable the feature.
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeatures(
      {compose::features::kEnableComposeSavedStateNudge},
      {compose::features::kEnableCompose});

  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(),
      /*rfh=*/GetRenderFrameHost(), context_menu_params_));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuLanguageTest) {
  // Disable the language bypass.
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeatures(
      {compose::features::kEnableCompose},
      {compose::features::kEnableComposeLanguageBypassForContextMenu});
  // Enable all base requirements.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set the mock to return a language we support (English).
  SetLanguage("en");
  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
  EXPECT_TRUE(
      compose_enabling_->IsPageLanguageSupported(translate_manager_.get()));

  // Set the mock to return a language we don't support (Esperanto).
  SetLanguage("eo");
  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
  EXPECT_FALSE(
      compose_enabling_->IsPageLanguageSupported(translate_manager_.get()));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuLanguageBypassTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set the mock to return a language we don't support (Esperanto).
  SetLanguage("eo");
  // Although the language is unsupported, ShouldTrigger should return true as
  // the bypass is enabled.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
  EXPECT_FALSE(
      compose_enabling_->IsPageLanguageSupported(translate_manager_.get()));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuEmptyLanguageTest) {
  // Disable the language bypass.
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeatures(
      {compose::features::kEnableCompose},
      {compose::features::kEnableComposeLanguageBypassForContextMenu});
  // Enable all base requirements.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set the mock to return the empty string, simluating that translate doesn't
  // have the answer yet.
  SetLanguage("");
  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
  EXPECT_TRUE(
      compose_enabling_->IsPageLanguageSupported(translate_manager_.get()));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuUndeterminedLangugeTest) {
  // Disable the language bypass.
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeatures(
      {compose::features::kEnableCompose},
      {compose::features::kEnableComposeLanguageBypassForContextMenu});
  // Enable all base requirements.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set the mock to return "und", simluating that translate could not determine
  // the page language.
  SetLanguage("und");
  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
  EXPECT_TRUE(
      compose_enabling_->IsPageLanguageSupported(translate_manager_.get()));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuFieldTypeTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set ContextMenuParams to non-contenteditable and non-textarea, which we do
  // not support.
  context_menu_params_.is_content_editable_for_autofill = false;
  context_menu_params_.form_control_type =
      blink::mojom::FormControlType::kInputButton;

  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuIncorrectSchemeTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Get the rfh for the tab with the incorrect Scheme.
  auto* rfh =
      browser()->tab_strip_model()->GetWebContentsAt(1)->GetPrimaryMainFrame();

  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), rfh, context_menu_params_));
}

TEST_F(ComposeEnablingTest,
       ShouldTriggerContextMenuAllEnabledContentEditableTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuAllEnabledTextAreaTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set ContextMenuParams to textarea, which we support.
  context_menu_params_.is_content_editable_for_autofill = false;
  context_menu_params_.form_control_type =
      blink::mojom::FormControlType::kTextArea;

  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupDefaultTest) {
  // Use the default feature values set in SetUp.
  std::string autocomplete_attribute;

  // The saved state nudge is enabled by default.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  // The proactive nudge is disabled by default.
  EXPECT_FALSE(compose_enabling_
                   ->ShouldTriggerNoStatePopup(
                       autocomplete_attribute,
                       /*allows_writing_suggestions=*/true, GetProfile(),
                       GetProfile()->GetPrefs(), translate_manager_.get(),
                       GetOrigin(), GetOrigin(), GURL(kExampleURL),
                       /*is_msbb_enabled*/ true)
                   .has_value());
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupDisabledTest) {
  // We intentionally disable the feature.
  ResetFeaturesAndConfig({},
                         {// Disable saved state nudge.
                          compose::features::kEnableComposeSavedStateNudge});

  std::string autocomplete_attribute;

  EXPECT_FALSE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupLanguageTests) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});

  // Enable the feature.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // Check that a non-English page blocks the proactive nudge but not the
  // saved state nudge.
  SetLanguage("eo");

  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  EXPECT_FALSE(compose_enabling_
                   ->ShouldTriggerNoStatePopup(
                       autocomplete_attribute,
                       /*allows_writing_suggestions=*/true, GetProfile(),
                       GetProfile()->GetPrefs(), translate_manager_.get(),
                       GetOrigin(), GetOrigin(), GURL(kExampleURL),
                       /*is_msbb_enabled*/ true)
                   .has_value());

  // Check that both nudges are allowed with English.
  SetLanguage("en");

  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  EXPECT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());

  // Check that both nudges are allowed with "und".
  SetLanguage("und");

  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  EXPECT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());
}

TEST_F(ComposeEnablingTest, ShouldNotTriggerProactivePopupAutocompleteOffTest) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});
  base::HistogramTester histogram_tester;
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  // Autocomplete is set to off for this page.
  std::string autocomplete_attribute("off");

  // The autocomplete attribute is ignored with saved state.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  // The autocomplete attribute is checked for the proactive nudge.
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL),
      /*is_msbb_enabled*/ true);

  EXPECT_EQ(should_trigger.error(),
            compose::ComposeShowStatus::kAutocompleteOff);
}

TEST_F(ComposeEnablingTest, ShouldNotTriggerProactivePopupIfMSBBDisabled) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});
  base::HistogramTester histogram_tester;
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  std::string autocomplete_attribute;

  // The proactive nudge does not show when msbb is disabled.
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL),
      /*is_msbb_enabled=*/false);
  ASSERT_EQ(should_trigger.error(),
            compose::ComposeShowStatus::kProactiveNudgeDisabledByMSBB);

  // The proactive nudge shows when msbb is enabled.
  EXPECT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled=*/true)
                  .has_value());
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupWithSavedStateTest) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // test all variants of: popup with, popup without state.
  std::vector<std::pair<bool, bool>> tests = {
      {true, true}, {true, false}, {false, true}, {false, false}};
  for (auto [saved_state_nudge, proactive_nudge] : tests) {
    compose::Config& config = compose::GetMutableConfigForTesting();
    config.saved_state_nudge_enabled = saved_state_nudge;
    config.proactive_nudge_enabled = proactive_nudge;

    EXPECT_EQ(
        saved_state_nudge,
        compose_enabling_->ShouldTriggerSavedStatePopup(
            autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

    EXPECT_EQ(proactive_nudge,
              compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());
  }
}

TEST_F(ComposeEnablingTest, ComposeSavedStateNotificationEnabledByDefault) {
  std::string autocomplete_attribute;

  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kComposeDialogLostFocus));
}

TEST_F(ComposeEnablingTest, SavedStateNotificationWithSavedStateNudgeDisabled) {
  ResetFeaturesAndConfig({},
                         {compose::features::kEnableComposeSavedStateNudge});
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // Saved State Notification does not trigger if saved state nudge is disabled.
  EXPECT_FALSE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kComposeDialogLostFocus));
}

TEST_F(ComposeEnablingTest,
       ShouldTriggerPopupSavedStateNotificationDisabledTest) {
  // Disable the notification flag.
  ResetFeaturesAndConfig(
      {compose::features::kEnableComposeProactiveNudge},
      {compose::features::kEnableComposeSavedStateNotification});

  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // Nudge still works, even if Saved State Notification is disabled.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  // Saved state notification is disabled.
  EXPECT_FALSE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kComposeDialogLostFocus));
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupIncorrectSchemeTest) {
  base::HistogramTester histogram_tester;
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  compose::Config& config = compose::GetMutableConfigForTesting();
  config.saved_state_nudge_enabled = true;
  config.proactive_nudge_enabled = true;
  std::string autocomplete_attribute;

  // Use URL with incorrect scheme is checked when no previous state.
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      url::Origin(), GURL(kExampleBadURL),
      /*is_msbb_enabled*/ true);
  ASSERT_EQ(should_trigger.error(),
            compose::ComposeShowStatus::kIncorrectScheme);

  // Use URL with incorrect scheme is not checked when there is previous state.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));
}

TEST_F(ComposeEnablingTest, ShouldTriggerPopupCrossOrigin) {
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  compose::Config& config = compose::GetMutableConfigForTesting();
  config.proactive_nudge_enabled = true;
  std::string autocomplete_attribute;

  EXPECT_FALSE(compose_enabling_
                   ->ShouldTriggerNoStatePopup(
                       autocomplete_attribute,
                       /*allows_writing_suggestions=*/true, GetProfile(),
                       GetProfile()->GetPrefs(), translate_manager_.get(),
                       GetOrigin(), url::Origin(), GURL(kExampleURL),
                       /*is_msbb_enabled*/ true)
                   .has_value());
}

TEST_F(ComposeEnablingTest, ShouldTriggerContextMenuCrossOrigin) {
  base::HistogramTester histogram_tester;
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  context_menu_params_.frame_origin = url::Origin();
  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));

  // Check that a response result OK metric was emitted.
  histogram_tester.ExpectUniqueSample(
      compose::kComposeShowStatus,
      compose::ComposeShowStatus::kFormFieldInCrossOriginFrame, 1);
}

TEST_F(ComposeEnablingTest, GetOptimizationGuidanceShowNudgeTest) {
  // Set up a fake metadata to return from the mock.
  optimization_guide::OptimizationMetadata test_metadata;
  compose::ComposeHintMetadata compose_hint_metadata;
  compose_hint_metadata.set_decision(
      compose::ComposeHintDecision::COMPOSE_HINT_DECISION_ENABLED);
  test_metadata.set_any_metadata(
      optimization_guide::AnyWrapProto(compose_hint_metadata));

  EXPECT_CALL(opt_guide(),
              CanApplyOptimization(
                  GURL(kExampleURL),
                  optimization_guide::proto::OptimizationType::COMPOSE,
                  ::testing::An<optimization_guide::OptimizationMetadata*>()))
      .WillRepeatedly(testing::DoAll(
          testing::SetArgPointee<2>(test_metadata),
          testing::Return(
              optimization_guide::OptimizationGuideDecision::kTrue)));

  GURL example(kExampleURL);
  compose::ComposeHintDecision decision =
      compose_enabling_->GetOptimizationGuidanceForUrl(example, GetProfile());

  // Verify response from CanApplyOptimization is as we expect.
  EXPECT_EQ(compose::ComposeHintDecision::COMPOSE_HINT_DECISION_ENABLED,
            decision);
}

TEST_F(ComposeEnablingTest, GetOptimizationGuidanceNoFeedbackTest) {
  // Set up a fake metadata to return from the mock.
  optimization_guide::OptimizationMetadata test_metadata;
  compose::ComposeHintMetadata compose_hint_metadata;
  compose_hint_metadata.set_decision(
      compose::ComposeHintDecision::COMPOSE_HINT_DECISION_ENABLED);
  test_metadata.set_any_metadata(
      optimization_guide::AnyWrapProto(compose_hint_metadata));

  EXPECT_CALL(opt_guide(),
              CanApplyOptimization(
                  GURL(kExampleURL),
                  optimization_guide::proto::OptimizationType::COMPOSE,
                  ::testing::An<optimization_guide::OptimizationMetadata*>()))
      .WillRepeatedly(testing::DoAll(
          testing::SetArgPointee<2>(test_metadata),
          testing::Return(
              optimization_guide::OptimizationGuideDecision::kFalse)));

  GURL example(kExampleURL);
  compose::ComposeHintDecision decision =
      compose_enabling_->GetOptimizationGuidanceForUrl(example, GetProfile());

  // Verify response from CanApplyOptimization is as we expect.
  EXPECT_EQ(compose::ComposeHintDecision::COMPOSE_HINT_DECISION_UNSPECIFIED,
            decision);
}

TEST_F(ComposeEnablingTest, GetOptimizationGuidanceNoComposeMetadataTest) {
  // Set up a fake metadata to return from the mock.
  optimization_guide::OptimizationMetadata test_metadata;
  compose::ComposeHintMetadata compose_hint_metadata;
  test_metadata.set_any_metadata(
      optimization_guide::AnyWrapProto(compose_hint_metadata));

  EXPECT_CALL(opt_guide(),
              CanApplyOptimization(
                  GURL(kExampleURL),
                  optimization_guide::proto::OptimizationType::COMPOSE,
                  ::testing::An<optimization_guide::OptimizationMetadata*>()))
      .WillRepeatedly(testing::DoAll(
          testing::SetArgPointee<2>(test_metadata),
          testing::Return(
              optimization_guide::OptimizationGuideDecision::kTrue)));

  GURL example(kExampleURL);
  compose::ComposeHintDecision decision =
      compose_enabling_->GetOptimizationGuidanceForUrl(example, GetProfile());

  // Verify response from CanApplyOptimization is as we expect.
  EXPECT_EQ(compose::ComposeHintDecision::COMPOSE_HINT_DECISION_UNSPECIFIED,
            decision);
}

TEST_F(ComposeEnablingTest, ShouldTriggerDisableComposeByPolicyTest) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});
  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set ContextMenuParams to textarea, which we support.
  context_menu_params_.is_content_editable_for_autofill = false;
  context_menu_params_.form_control_type =
      blink::mojom::FormControlType::kTextArea;

  std::string autocomplete_attribute;
  base::HistogramTester histogram_tester;

  // Set up a fake metadata to return from the mock.
  optimization_guide::OptimizationMetadata test_metadata;
  compose::ComposeHintMetadata compose_hint_metadata;
  compose_hint_metadata.set_decision(
      compose::ComposeHintDecision::COMPOSE_HINT_DECISION_COMPOSE_DISABLED);
  test_metadata.set_any_metadata(
      optimization_guide::AnyWrapProto(compose_hint_metadata));

  EXPECT_CALL(opt_guide(),
              CanApplyOptimization(
                  GURL(kExampleURL),
                  optimization_guide::proto::OptimizationType::COMPOSE,
                  ::testing::An<optimization_guide::OptimizationMetadata*>()))
      .WillRepeatedly(testing::DoAll(
          testing::SetArgPointee<2>(test_metadata),
          testing::Return(
              optimization_guide::OptimizationGuideDecision::kTrue)));

  EXPECT_FALSE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));

  // Check that the proactive nudge is also disabled.
  EXPECT_FALSE(compose_enabling_
                   ->ShouldTriggerNoStatePopup(
                       autocomplete_attribute,
                       /*allows_writing_suggestions=*/true, GetProfile(),
                       GetProfile()->GetPrefs(), translate_manager_.get(),
                       GetOrigin(), GetOrigin(), GURL(kExampleURL),
                       /*is_msbb_enabled*/ true)
                   .has_value());

  // The saved state is not disabled.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  // Verify the metrics reflect the decision not to show the page.
  histogram_tester.ExpectUniqueSample(
      compose::kComposeShowStatus,
      compose::ComposeShowStatus::kPerUrlChecksFailed, 1);
}

TEST_F(ComposeEnablingTest, ShouldTriggerDisableNudgeByPolicy) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});

  // Enable everything.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();

  // Set ContextMenuParams to textarea, which we support.
  context_menu_params_.is_content_editable_for_autofill = false;
  context_menu_params_.form_control_type =
      blink::mojom::FormControlType::kTextArea;

  std::string autocomplete_attribute;

  // Set up a fake metadata to return from the mock.
  optimization_guide::OptimizationMetadata test_metadata;
  compose::ComposeHintMetadata compose_hint_metadata;
  compose_hint_metadata.set_decision(
      compose::ComposeHintDecision::COMPOSE_HINT_DECISION_DISABLE_NUDGE);
  test_metadata.set_any_metadata(
      optimization_guide::AnyWrapProto(compose_hint_metadata));

  EXPECT_CALL(opt_guide(),
              CanApplyOptimization(
                  GURL(kExampleURL),
                  optimization_guide::proto::OptimizationType::COMPOSE,
                  ::testing::An<optimization_guide::OptimizationMetadata*>()))
      .WillRepeatedly(testing::DoAll(
          testing::SetArgPointee<2>(test_metadata),
          testing::Return(
              optimization_guide::OptimizationGuideDecision::kTrue)));

  // The context is not disabled.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerContextMenu(
      GetProfile(), translate_manager_.get(), /*rfh=*/GetRenderFrameHost(),
      context_menu_params_));

  // The saved state nudge is not disabled.
  EXPECT_TRUE(compose_enabling_->ShouldTriggerSavedStatePopup(
      autofill::AutofillSuggestionTriggerSource::kTextFieldValueChanged));

  // Check that the proactive nudge is disabled.
  EXPECT_FALSE(compose_enabling_
                   ->ShouldTriggerNoStatePopup(
                       autocomplete_attribute,
                       /*allows_writing_suggestions=*/true, GetProfile(),
                       GetProfile()->GetPrefs(), translate_manager_.get(),
                       GetOrigin(), GetOrigin(), GURL(kExampleURL),
                       /*is_msbb_enabled*/ true)
                   .has_value());
  // Check that the proactive nudge is not disabled if override is set in the
  // config.
  compose::GetMutableConfigForTesting()
      .proactive_nudge_bypass_optimization_guide = true;
  EXPECT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());
}

TEST_F(ComposeEnablingTest, ProactiveNudgeGlobalPreferenceTest) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});
  base::HistogramTester histogram_tester;
  // Enable the feature.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // Preference is enabled by default, proactive nudge should trigger.
  EXPECT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());

  // When preference is disabled, proactive nudge should not trigger
  SetProactiveNudgePref(false);
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL),
      /*is_msbb_enabled*/ true);
  EXPECT_EQ(should_trigger.error(),
            compose::ComposeShowStatus::
                kProactiveNudgeDisabledGloballyByUserPreference);
}

TEST_F(ComposeEnablingTest, ProactiveNudgeDisabledSitesPreferenceTest) {
  ResetFeaturesAndConfig({compose::features::kEnableComposeProactiveNudge}, {});
  base::HistogramTester histogram_tester;
  // Enable the feature.
  auto scoped_compose_enabled =
      ComposeEnabling::ScopedEnableComposeForTesting();
  std::string autocomplete_attribute;

  // Preference is enabled by default, proactive nudge should trigger on default
  // origin.
  ASSERT_TRUE(compose_enabling_
                  ->ShouldTriggerNoStatePopup(
                      autocomplete_attribute,
                      /*allows_writing_suggestions=*/true, GetProfile(),
                      GetProfile()->GetPrefs(), translate_manager_.get(),
                      GetOrigin(), GetOrigin(), GURL(kExampleURL),
                      /*is_msbb_enabled*/ true)
                  .has_value());

  // When origin is added to disabled sites list, proactive nudge should not
  // trigger.
  AddDomainToProactiveNudgeDisabledSitesPref();
  auto should_trigger = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL),
      /*is_msbb_enabled*/ true);
  EXPECT_EQ(should_trigger.error(),
            compose::ComposeShowStatus::
                kProactiveNudgeDisabledForSiteByUserPreference);
}

TEST_F(ComposeEnablingTest, ClientCountryNotInFinchCountryListForCompose) {
  // Sets a country list via Finch that does not include "us".
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitAndEnableFeatureWithParameters(
      compose::features::kEnableCompose, {{"enabled_countries", "a, b, c"}});
  compose::ResetConfigForTesting();
  EXPECT_THAT(compose_enabling_->IsEnabled(),
              ErrorIs(compose::ComposeShowStatus::kComposeNotEnabledInCountry));
}

TEST_F(ComposeEnablingTest, ClientCountryUndefinedForCompose) {
  // Replace the client country override with an undefined country.
  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("");
  EXPECT_THAT(compose_enabling_->IsEnabled(),
              ErrorIs(compose::ComposeShowStatus::kUndefinedCountry));
}

TEST_F(ComposeEnablingTest, AnyAndAllCountriesAllowedForCompose) {
  // Set the country list to the wildcard element.
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitAndEnableFeatureWithParameters(
      compose::features::kEnableCompose, {{"enabled_countries", "*"}});
  compose::ResetConfigForTesting();

  // If the country check passes the signed out check will fail next.
  EXPECT_THAT(compose_enabling_->IsEnabled(),
              ErrorIs(compose::ComposeShowStatus::kSignedOut));

  // Check that country other than "us" is also accepted.
  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("aa");
  EXPECT_THAT(compose_enabling_->IsEnabled(),
              ErrorIs(compose::ComposeShowStatus::kSignedOut));

  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("");
  EXPECT_THAT(compose_enabling_->IsEnabled(),
              ErrorIs(compose::ComposeShowStatus::kSignedOut));
}

TEST_F(ComposeEnablingTest,
       ClientCountryNotInFinchCountryListForProactiveNudge) {
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeaturesAndParameters(
      {{compose::features::kEnableComposeProactiveNudge,
        // Sets a country list for the proactive nudge that does not include
        // "us".
        {{"proactive_nudge_countries", "a, b, c"}}},
       {compose::features::kEnableCompose, {{"enabled_countries", "*"}}}},
      {});
  compose::ResetConfigForTesting();

  std::string autocomplete_attribute;
  auto no_state_status = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);
  EXPECT_THAT(no_state_status,
              ErrorIs(compose::ComposeShowStatus::kComposeNotEnabledInCountry));
}

TEST_F(ComposeEnablingTest, ClientCountryUndefinedForProactiveNudge) {
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitAndEnableFeatureWithParameters(
      compose::features::kEnableCompose, {{"enabled_countries", "*"}});
  compose::ResetConfigForTesting();

  // Replace the client country override with an undefined country.
  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("");

  std::string autocomplete_attribute;
  auto no_state_status = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);
  EXPECT_THAT(no_state_status,
              ErrorIs(compose::ComposeShowStatus::kUndefinedCountry));
}

TEST_F(ComposeEnablingTest, AnyAndAllCountriesAllowedForProactiveNudge) {
  scoped_feature_list_.Reset();
  scoped_feature_list_.InitWithFeaturesAndParameters(
      {{compose::features::kEnableComposeProactiveNudge,
        // Set both client country lists to the wildcard element.
        {{"proactive_nudge_countries", "*"}}},
       {compose::features::kEnableCompose, {{"enabled_countries", "*"}}}},
      {});
  compose::ResetConfigForTesting();

  std::string autocomplete_attribute;
  auto no_state_status = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);
  // If the country check passes the signed out check will fail next.
  EXPECT_THAT(no_state_status, ErrorIs(compose::ComposeShowStatus::kSignedOut));

  // Check that country other than "us" is also accepted.
  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("aa");

  no_state_status = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);
  EXPECT_THAT(no_state_status, ErrorIs(compose::ComposeShowStatus::kSignedOut));

  // Replace the client country override with an undefined country.
  scoped_country_override_.reset();
  scoped_country_override_ = ComposeEnabling::OverrideCountryForTesting("");

  no_state_status = compose_enabling_->ShouldTriggerNoStatePopup(
      autocomplete_attribute, /*allows_writing_suggestions=*/true, GetProfile(),
      GetProfile()->GetPrefs(), translate_manager_.get(), GetOrigin(),
      GetOrigin(), GURL(kExampleURL), /*is_msbb_enabled*/ true);
  EXPECT_THAT(no_state_status, ErrorIs(compose::ComposeShowStatus::kSignedOut));
}