chromium/components/search_engines/search_engine_choice/search_engine_choice_service_unittest.cc

// Copyright 2024 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/search_engines/search_engine_choice/search_engine_choice_service.h"

#include <memory>
#include <string_view>
#include <vector>

#include "base/check_deref.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/version.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/country_codes/country_codes.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/policy/core/common/mock_policy_service.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/policy_types.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h"
#include "components/search_engines/eea_countries_ids.h"
#include "components/search_engines/prepopulated_engines.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_metrics_service_accessor.h"
#include "components/search_engines/search_engine_choice/search_engine_choice_utils.h"
#include "components/search_engines/search_engine_type.h"
#include "components/search_engines/search_engines_pref_names.h"
#include "components/search_engines/search_engines_switches.h"
#include "components/search_engines/template_url_data.h"
#include "components/search_engines/template_url_data_util.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/version_info/version_info.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "components/search_engines/android/test_utils_jni_headers/SearchEngineChoiceServiceTestUtil_jni.h"
#endif

RepromptResult;
WipeSearchEngineChoiceReason;
NiceMock;

namespace search_engines {
namespace {
#if BUILDFLAG(IS_ANDROID)
class TestSupportAndroid {
 public:
  TestSupportAndroid() {
    JNIEnv* env = base::android::AttachCurrentThread();
    base::android::ScopedJavaLocalRef<jobject> java_ref =
        Java_SearchEngineChoiceServiceTestUtil_Constructor(env);
    java_test_util_ref_.Reset(env, java_ref.obj());
  }

  ~TestSupportAndroid() {
    JNIEnv* env = base::android::AttachCurrentThread();
    Java_SearchEngineChoiceServiceTestUtil_destroy(env, java_test_util_ref_);
  }

  void ReturnDeviceCountry(const std::string& device_country) {
    JNIEnv* env = base::android::AttachCurrentThread();
    Java_SearchEngineChoiceServiceTestUtil_returnDeviceCountry(
        env, java_test_util_ref_,
        base::android::ConvertUTF8ToJavaString(env, device_country));
  }

 private:
  base::android::ScopedJavaGlobalRef<jobject> java_test_util_ref_;
};
#endif

const int kBelgiumCountryId =;

}  // namespace

class SearchEngineChoiceServiceTest : public ::testing::Test {};

// Test that the choice screen doesn't get displayed if the profile is not
// regular.
TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenWithNotRegularProfile) {}

// Test that the choice screen gets displayed if the
// `DefaultSearchProviderEnabled` policy is not set.
TEST_F(SearchEngineChoiceServiceTest, ShowChoiceScreenIfPoliciesAreNotSet) {}

// Test that the choice screen does not get displayed if the provider list is
// overridden in the intial_preferences file.
TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenWithProviderListOverride) {}

// Test that the choice screen doesn't get displayed if the
// 'DefaultSearchProviderEnabled' policy is set to false.
TEST_F(SearchEngineChoiceServiceTest, DoNotShowChoiceScreenIfPolicySetToFalse) {}

// Test that the choice screen gets displayed if the
// 'DefaultSearchProviderEnabled' policy is set to true but the
// 'DefaultSearchProviderSearchURL' policy is not set.
TEST_F(SearchEngineChoiceServiceTest,
       ShowChoiceScreenIfPolicySetToTrueWithoutUrlSet) {}

// Test that the choice screen doesn't get displayed if the
// 'DefaultSearchProviderEnabled' policy is set to true and the
// DefaultSearchProviderSearchURL' is set.
TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenIfPolicySetToTrueWithUrlSet) {}

// Test that the choice screen gets displayed if and only if the
// `kDefaultSearchProviderChoiceScreenTimestamp` pref is not set. Setting this
// pref means that the user has made a search engine choice in the choice
// screen.
TEST_F(SearchEngineChoiceServiceTest,
       ShowChoiceScreenIfTheTimestampPrefIsNotSet) {}

// Test that there is a regional condition controlling eligibility.
TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenIfCountryOutOfScope) {}

// Test that the choice screen does get displayed even if completed if the
// command line argument for forcing it is set.
TEST_F(SearchEngineChoiceServiceTest,
       ShowChoiceScreenWithForceCommandLineFlag) {}
TEST_F(SearchEngineChoiceServiceTest,
       ShowChoiceScreenWithForceCommandLineFlag_Counterfactual) {}

// Ensure that the choice screen doesn't get displayed if the flag is disabled.
TEST_F(SearchEngineChoiceServiceTest, DoNotShowChoiceScreenIfFlagIsDisabled) {}

// Test that the choice screen does not get displayed if the command line
// argument for disabling it is set.
TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenWithDisableCommandLineFlag) {}

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdCommandLineOverride) {}

TEST_F(SearchEngineChoiceServiceTest,
       GetCountryIdCommandLineOverrideSetsToUnknownOnFormatMismatch) {}

#if BUILDFLAG(IS_ANDROID)
TEST_F(SearchEngineChoiceServiceTest, PlayResponseBeforeGetCountryId) {
  base::CommandLine::ForCurrentProcess()->RemoveSwitch(
      switches::kSearchEngineChoiceCountry);
  TestSupportAndroid test_support;
  test_support.ReturnDeviceCountry(
      country_codes::CountryIDToCountryString(kBelgiumCountryId));

  // We got response from Play API before `GetCountryId` was invoked for the
  // first time this run, so the new value should be used right away.
  EXPECT_EQ(search_engine_choice_service().GetCountryId(), kBelgiumCountryId);
  // The pref should be updated as well.
  EXPECT_EQ(pref_service()->GetInteger(country_codes::kCountryIDAtInstall),
            kBelgiumCountryId);
}

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdBeforePlayResponse) {
  base::CommandLine::ForCurrentProcess()->RemoveSwitch(
      switches::kSearchEngineChoiceCountry);

  TestSupportAndroid test_support;
  // We didn't get a response from Play API before `GetCountryId` was invoked,
  // so the last known country from prefs should be used.
  EXPECT_EQ(search_engine_choice_service().GetCountryId(),
            country_codes::GetCurrentCountryID());

  // Simulate a response arriving after the first `GetCountryId` call.
  test_support.ReturnDeviceCountry(
      country_codes::CountryIDToCountryString(kBelgiumCountryId));

  // The pref should be updated so the new country can be used the next run.
  EXPECT_EQ(pref_service()->GetInteger(country_codes::kCountryIDAtInstall),
            kBelgiumCountryId);
  // However, `GetCountryId` result shouldn't change until the next run.
  EXPECT_EQ(search_engine_choice_service().GetCountryId(),
            country_codes::GetCurrentCountryID());
}

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdPrefAlreadyWritten) {
  // The value set from the pref should be used.
  pref_service()->SetInteger(country_codes::kCountryIDAtInstall,
                             kBelgiumCountryId);
  // Don't create `TestSupportAndroid` - since the pref isn't set we should not
  // reach out to Java.
  EXPECT_EQ(search_engine_choice_service().GetCountryId(), kBelgiumCountryId);
}
#endif  // BUILDFLAG(IS_ANDROID)

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdDefault) {}

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdFromPrefs) {}

TEST_F(SearchEngineChoiceServiceTest, GetCountryIdChangesAfterReading) {}

TEST_F(SearchEngineChoiceServiceTest, ChoiceScreenConditions_SkipFor3p) {}

TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenIfUserHasCustomSearchEngineSetAsDefault) {}

TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenIfUserHasCustomSearchEngineSetAsDefault_Skip3p) {}

TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenForDefaultDistributionCustomSearchEngine) {}

TEST_F(SearchEngineChoiceServiceTest,
       DoNotShowChoiceScreenForRemovedPrepopulatedSearchEngine) {}

TEST_F(SearchEngineChoiceServiceTest, RecordChoiceMade) {}

TEST_F(SearchEngineChoiceServiceTest, RecordChoiceMade_DistributionCustom) {}

TEST_F(SearchEngineChoiceServiceTest, RecordChoiceMade_RemovedPrepopulated) {}

TemplateURL::OwnedTemplateURLVector
OwnedTemplateURLVectorFromPrepopulatedEngines(
    const std::vector<const TemplateURLPrepopulateData::PrepopulatedEngine*>&
        engines) {}

TEST_F(SearchEngineChoiceServiceTest, MaybeRecordChoiceScreenDisplayState) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_NoopUnsupportedCountry) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_MismatchingCountry) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_OnServiceStartup) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_OnServiceStartup_CountryMismatch) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_OnServiceStartup_ChoicePrefCleared) {}

TEST_F(SearchEngineChoiceServiceTest,
       MaybeRecordChoiceScreenDisplayState_OnServiceStartup_UmaDisabled) {}

// Test that the user is not reprompted if the reprompt parameter is not a valid
// JSON string.
TEST_F(SearchEngineChoiceServiceTest, NoRepromptForSyntaxError) {}

// Test that the user is not reprompted by default.
TEST_F(SearchEngineChoiceServiceTest, NoRepromptByDefault) {}

// The user is reprompted if the version preference is missing.
TEST_F(SearchEngineChoiceServiceTest, RepromptForMissingChoiceVersion) {}

struct RepromptTestParam {};

class SearchEngineChoiceUtilsParamTest
    : public SearchEngineChoiceServiceTest,
      public testing::WithParamInterface<RepromptTestParam> {};

TEST_P(SearchEngineChoiceUtilsParamTest, Reprompt) {}

constexpr RepromptTestParam kRepromptTestParams[] =;

INSTANTIATE_TEST_SUITE_P();

#if !BUILDFLAG(IS_ANDROID)

class SearchEngineChoiceUtilsResourceIdsTest : public ::testing::Test {};

// Verifies that all prepopulated search engines associated with EEA countries
// have an icon.
TEST_F(SearchEngineChoiceUtilsResourceIdsTest, GetIconResourceId) {}

#endif  // !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)

class SearchEngineChoiceServiceWithVariationsTest : public ::testing::Test {};

// Tests that the country falls back to `country_codes::GetCurrentCountryID()`
// when the variations country is not available.
TEST_F(SearchEngineChoiceServiceWithVariationsTest, NoVariationsCountry) {}

// Tests that the country is read from the variations service when available.
TEST_F(SearchEngineChoiceServiceWithVariationsTest, WithVariationsCountry) {}

#endif  // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)

}  // namespace search_engines