#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/search_engines/template_url_service.h"
#include <stddef.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_test_util.h"
#include "chrome/test/base/testing_profile.h"
#include "components/history/core/browser/history_service.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/search_engines/keyword_web_data_service.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/search_engines_test_util.h"
#include "components/search_engines/search_host_to_urls_map.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_data.h"
#include "components/search_engines/template_url_prepopulate_data.h"
#include "components/search_engines/template_url_starter_pack_data.h"
#include "components/search_engines/util.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
ASCIIToUTF16;
Time;
SiteSearchPolicyConflictType;
NotNull;
namespace {
static constexpr int kPrepopulatedId = …;
std::unique_ptr<TemplateURL> CreateKeywordWithDate(
TemplateURLService* model,
const std::string& short_name,
const std::string& keyword,
const std::string& url,
const std::string& suggest_url,
const std::string& alternate_url,
const std::string& favicon_url,
bool safe_for_autoreplace,
int prepopulate_id,
const std::string& encodings = "UTF-8",
Time date_created = Time(),
Time last_modified = Time(),
Time last_visited = Time(),
TemplateURL::Type type = TemplateURL::NORMAL) { … }
TemplateURL* AddKeywordWithDate(TemplateURLService* model,
const std::string& short_name,
const std::string& keyword,
const std::string& url,
const std::string& suggest_url,
const std::string& alternate_url,
const std::string& favicon_url,
bool safe_for_autoreplace,
const std::string& encodings,
Time date_created,
Time last_modified,
Time last_visited) { … }
void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual) { … }
std::unique_ptr<TemplateURLData> CreateTestSearchEngine() { … }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_CHROMEOS)
std::unique_ptr<TemplateURLData> CreateTestSiteSearchEntry(
const std::string& keyword,
bool featured_by_policy) { … }
std::unique_ptr<TemplateURLData> CreateTestSiteSearchEntry(
const std::string& keyword) { … }
TemplateURLData CreateTestSearchEngineWithSafeForAutoreplace(
const std::string& keyword,
bool safe_for_autoreplace) { … }
void VerifySiteSearchPolicyConflictHistograms(
const base::HistogramTester& histogram_tester,
const base::flat_map<SiteSearchPolicyConflictType, int>& expected_counts) { … }
#endif
std::string ParamToTestSuffix(const ::testing::TestParamInfo<bool>& info) { … }
}
class TemplateURLServiceTestBase : public testing::Test { … };
class TemplateURLServiceTest : public TemplateURLServiceTestBase,
public testing::WithParamInterface<bool> { … };
class TemplateURLServiceWithoutFallbackTest : public TemplateURLServiceTest { … };
#if BUILDFLAG(IS_ANDROID)
class TemplateURLServicePlayApiTest : public TemplateURLServiceTestBase,
public testing::WithParamInterface<bool> {
public:
static std::string ParamToTestSuffix(
const ::testing::TestParamInfo<bool>& info) {
std::string suffix =
info.param ? "SearchEngineChoiceEnabled" : "SearchEngineChoiceDisabled";
return suffix;
}
TemplateURLServicePlayApiTest() : TemplateURLServiceTestBase(GetParam()) {
EXPECT_EQ(
IsSearchEngineChoiceEnabled(),
base::FeatureList::IsEnabled(switches::kSearchEngineChoiceTrigger));
}
private:
base::test::ScopedFeatureList feature_list_;
};
#endif
TemplateURLServiceTestBase::TemplateURLServiceTestBase(
bool is_search_engine_choice_enabled)
: … { … }
void TemplateURLServiceTestBase::SetUp() { … }
void TemplateURLServiceTestBase::TearDown() { … }
TemplateURL* TemplateURLServiceTestBase::AddKeywordWithDate(
const std::string& short_name,
const std::string& keyword,
const std::string& url,
const std::string& suggest_url,
const std::string& alternate_url,
const std::string& favicon_url,
bool safe_for_autoreplace,
const std::string& encodings,
Time date_created,
Time last_modified,
Time last_visited) { … }
TemplateURL* TemplateURLServiceTestBase::AddExtensionSearchEngine(
const std::string& keyword,
const std::string& extension_name,
bool wants_to_be_default_engine,
const Time& install_time) { … }
void TemplateURLServiceTestBase::AssertEquals(const TemplateURL& expected,
const TemplateURL& actual) { … }
void TemplateURLServiceTestBase::AssertEquals(const TemplateURL* expected,
const TemplateURL* actual) { … }
void TemplateURLServiceTestBase::AssertTimesEqual(const Time& expected,
const Time& actual) { … }
std::unique_ptr<TemplateURL>
TemplateURLServiceTestBase::CreatePreloadedTemplateURL(
bool safe_for_autoreplace,
int prepopulate_id) { … }
void TemplateURLServiceTestBase::SetOverriddenEngines() { … }
void TemplateURLServiceTestBase::VerifyObserverCount(
int expected_changed_count) { … }
void TemplateURLServiceTestBase::VerifyObserverFired() { … }
TEST_P(TemplateURLServiceTest, Load) { … }
TEST_P(TemplateURLServiceTest, AddUpdateRemove) { … }
TEST_P(TemplateURLServiceTest, AddSameKeyword) { … }
TEST_P(TemplateURLServiceTest, AddOmniboxExtensionKeyword) { … }
TEST_P(TemplateURLServiceTest, AddSameKeywordWithOmniboxExtensionPresent) { … }
TEST_P(TemplateURLServiceTest, NotPersistOmniboxExtensionKeyword) { … }
TEST_P(TemplateURLServiceTest, ClearBrowsingData_Keywords) { … }
TEST_P(TemplateURLServiceTest, ClearBrowsingData_KeywordsForUrls) { … }
TEST_P(TemplateURLServiceTest, Reset) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_P(TemplateURLServicePlayApiTest, CreateFromPlayAPI) {
test_util()->VerifyLoad();
const size_t initial_count = model()->GetTemplateURLs().size();
const std::u16string short_name = u"google";
const std::u16string keyword = u"keyword";
const std::string search_url = "http://www.google.com/foo/bar";
const std::string suggest_url = "http://www.google.com/suggest";
const std::string favicon_url = "http://favicon.url";
const std::string new_tab_url = "https://site.com/newtab";
const std::string image_url = "https://site.com/img";
const std::string image_url_post_params = "param";
const std::string image_translate_url = "https://site.com/transl";
const std::string image_translate_source_language_param_key = "s";
const std::string image_translate_target_language_param_key = "t";
TemplateURL* t_url = model()->Add(std::make_unique<TemplateURL>(
TemplateURLService::CreatePlayAPITemplateURLData(
keyword, short_name, search_url, suggest_url, favicon_url,
new_tab_url, image_url, image_url_post_params, image_translate_url,
image_translate_source_language_param_key,
image_translate_target_language_param_key)));
ASSERT_TRUE(t_url);
ASSERT_EQ(short_name, t_url->short_name());
ASSERT_EQ(keyword, t_url->keyword());
ASSERT_EQ(search_url, t_url->url());
ASSERT_EQ(suggest_url, t_url->suggestions_url());
ASSERT_EQ(GURL(favicon_url), t_url->favicon_url());
ASSERT_EQ(new_tab_url, t_url->new_tab_url());
ASSERT_EQ(image_url, t_url->image_url());
ASSERT_EQ(image_url_post_params, t_url->image_url_post_params());
ASSERT_EQ(image_translate_url, t_url->image_translate_url());
ASSERT_EQ(image_translate_source_language_param_key,
t_url->image_translate_source_language_param_key());
ASSERT_EQ(image_translate_target_language_param_key,
t_url->image_translate_target_language_param_key());
ASSERT_TRUE(t_url->created_from_play_api());
ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(keyword));
auto cloned_url = std::make_unique<TemplateURL>(t_url->data());
test_util()->ResetModel(true);
EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size());
const TemplateURL* read_url = model()->GetTemplateURLForKeyword(keyword);
ASSERT_TRUE(read_url);
AssertEquals(*cloned_url, *read_url);
}
TEST_P(TemplateURLServicePlayApiTest, UpdateFromPlayAPI) {
std::u16string keyword = u"keyword";
test_util()->VerifyLoad();
const size_t initial_count = model()->GetTemplateURLs().size();
TemplateURLData data;
data.SetShortName(u"google");
data.SetKeyword(keyword);
data.SetURL("http://www.google.com/foo/bar");
data.favicon_url = GURL("http://favicon.url");
data.date_created = Time::FromTimeT(100);
data.last_modified = Time::FromTimeT(100);
data.last_visited = Time::FromTimeT(100);
data.safe_for_autoreplace = true;
TemplateURL* t_url = model()->Add(std::make_unique<TemplateURL>(data));
VerifyObserverCount(1);
base::RunLoop().RunUntilIdle();
auto clock = std::make_unique<base::SimpleTestClock>();
clock->SetNow(base::Time::FromTimeT(200));
model()->set_clock(std::move(clock));
const std::u16string new_short_name = u"new_name";
const std::string new_search_url = "new_url";
const std::string new_suggest_url = "new_suggest_url";
const std::string new_favicon_url = "new_favicon_url";
const std::string new_other_data = "other_data";
t_url = model()->Add(std::make_unique<TemplateURL>(
TemplateURLService::CreatePlayAPITemplateURLData(
keyword, new_short_name, new_search_url, new_suggest_url,
new_favicon_url, new_other_data, new_other_data, new_other_data,
new_other_data, new_other_data, new_other_data)));
ASSERT_TRUE(t_url);
ASSERT_EQ(new_short_name, t_url->short_name());
ASSERT_EQ(keyword, t_url->keyword());
ASSERT_EQ(new_search_url, t_url->url());
ASSERT_EQ(new_suggest_url, t_url->suggestions_url());
ASSERT_EQ(GURL(new_favicon_url), t_url->favicon_url());
ASSERT_EQ(new_other_data, t_url->new_tab_url());
ASSERT_EQ(new_other_data, t_url->image_url());
ASSERT_EQ(new_other_data, t_url->image_url_post_params());
ASSERT_EQ(new_other_data, t_url->image_translate_url());
ASSERT_EQ(new_other_data, t_url->image_translate_source_language_param_key());
ASSERT_EQ(new_other_data, t_url->image_translate_target_language_param_key());
ASSERT_TRUE(t_url->created_from_play_api());
ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(keyword));
auto cloned_url = std::make_unique<TemplateURL>(t_url->data());
test_util()->ResetModel(true);
EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size());
const TemplateURL* read_url = model()->GetTemplateURLForKeyword(keyword);
ASSERT_TRUE(read_url);
AssertEquals(*cloned_url, *read_url);
}
INSTANTIATE_TEST_SUITE_P(,
TemplateURLServicePlayApiTest,
testing::Values(true, false),
&TemplateURLServicePlayApiTest::ParamToTestSuffix);
#endif
TEST_P(TemplateURLServiceTest, DefaultSearchProvider) { … }
TEST_P(TemplateURLServiceTest, CantReplaceWithSameKeyword) { … }
TEST_P(TemplateURLServiceTest, CantReplaceWithSameHosts) { … }
TEST_P(TemplateURLServiceTest, HasDefaultSearchProvider) { … }
TEST_P(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) { … }
TEST_P(TemplateURLServiceTest,
DefaultSearchProviderShouldBeProtectedFromKeywordConflictDuringLoad) { … }
TEST_P(TemplateURLServiceTest, RepairPrepopulatedSearchEngines) { … }
TEST_P(TemplateURLServiceTest, RepairSearchEnginesWithManagedDefault) { … }
TEST_P(TemplateURLServiceTest, RepairPrepopulatedEnginesUpdatesSyncGuid) { … }
TEST_P(TemplateURLServiceTest,
RepairPrepopulatedEnginesWithOverridesUpdatesSyncGuid) { … }
TEST_P(TemplateURLServiceTest,
RepairPrepopulatedEnginesWithExtensionUpdatesSyncGuid) { … }
TEST_P(TemplateURLServiceTest, RepairStarterPackEngines) { … }
TEST_P(TemplateURLServiceTest, SetDefaultSearchProviderPref) { … }
TEST_P(TemplateURLServiceTest, GetDefaultSearchProviderPref) { … }
TEST_P(TemplateURLServiceTest, UpdateKeywordSearchTermsForURL) { … }
TEST_P(TemplateURLServiceTest, DontUpdateKeywordSearchForNonReplaceable) { … }
TEST_P(TemplateURLServiceWithoutFallbackTest, ManualCountrySpecificGoogleURL) { … }
INSTANTIATE_TEST_SUITE_P(…);
TEST_P(TemplateURLServiceTest, GenerateVisitOnKeyword) { … }
TEST_P(TemplateURLServiceTest, LoadDeletesUnusedProvider) { … }
TEST_P(TemplateURLServiceTest, LoadRetainsModifiedProvider) { … }
TEST_P(TemplateURLServiceTest, LoadSavesPrepopulatedDefaultSearchProvider) { … }
TEST_P(TemplateURLServiceTest, LoadRetainsDefaultProvider) { … }
TEST_P(TemplateURLServiceTest, LoadEnsuresDefaultSearchProviderExists) { … }
TEST_P(TemplateURLServiceTest,
LoadUpdatesStarterPackOnlyIfIncompatibleVersion) { … }
TEST_P(TemplateURLServiceTest, FailedInit) { … }
TEST_P(TemplateURLServiceTest, TestManagedDefaultSearch) { … }
TEST_P(TemplateURLServiceTest, PatchEmptySyncGUID) { … }
TEST_P(TemplateURLServiceTest, DuplicateInputEncodings) { … }
TEST_P(TemplateURLServiceTest, DefaultExtensionEngine) { … }
TEST_P(TemplateURLServiceTest, SetDefaultExtensionEngineAndRemoveUserDSE) { … }
TEST_P(TemplateURLServiceTest, DefaultExtensionEnginePersist) { … }
TEST_P(TemplateURLServiceTest, DefaultExtensionEnginePersistsBeforeLoad) { … }
TEST_P(TemplateURLServiceTest, KeywordConflictNonReplaceableEngines) { … }
TEST_P(TemplateURLServiceTest, DefaultSearchProviderKeywordConflictReentrancy) { … }
TEST_P(TemplateURLServiceTest, ReplaceableEngineUpdateHandlesKeywordConflicts) { … }
TEST_P(TemplateURLServiceTest, KeywordConflictFavorsPrepopulatedEngines) { … }
TEST_P(TemplateURLServiceTest, CheckNonreplaceableEnginesKeywordsConflicts) { … }
TEST_P(TemplateURLServiceTest, CheckReplaceableEnginesKeywordsConflicts) { … }
TEST_P(TemplateURLServiceTest, ExtensionsWithSameKeywords) { … }
TEST_P(TemplateURLServiceTest, ExtensionEngineVsPolicy) { … }
TEST_P(TemplateURLServiceTest, LastVisitedTimeUpdate) { … }
TEST_P(TemplateURLServiceTest, LastModifiedTimeUpdate) { … }
TEST_P(TemplateURLServiceTest, GetDefaultSearchProviderIgnoringExtensions) { … }
TEST_P(TemplateURLServiceTest,
EngineReturnedByGetDefaultSearchProviderIgnoringExtensionsTakesOver) { … }
TEST_P(
TemplateURLServiceTest,
GetDefaultSearchProviderIgnoringExtensionsWhenDefaultSearchDisabledByPolicy) { … }
TEST_P(TemplateURLServiceTest, SetIsActiveTemplateURL) { … }
TEST_P(TemplateURLServiceTest, EmitTemplateURLActiveOnStartupHistogram) { … }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
BUILDFLAG(IS_CHROMEOS)
TEST_P(TemplateURLServiceTest, SiteSearchPolicyBeforeLoading) { … }
TEST_P(TemplateURLServiceTest, SiteSearchPolicyAfterLoading) { … }
TEST_P(TemplateURLServiceTest, SiteSearchPolicyUpdates) { … }
TEST_P(TemplateURLServiceTest,
NonFeaturedSiteSearchPolicyConflictWithExistingEngines) { … }
TEST_P(TemplateURLServiceTest,
FeaturedSiteSearchPolicyConflictWithExistingEngines) { … }
TEST_P(TemplateURLServiceTest, NonFeaturedSiteSearchPolicyConflictWithDSP) { … }
TEST_P(TemplateURLServiceTest,
NonFeaturedSiteSearchPolicyConflictWithUserDefinedDSP) { … }
TEST_P(TemplateURLServiceTest,
NonFeaturedSiteSearchPolicyConflictWithDSPSetByExtension) { … }
TEST_P(TemplateURLServiceTest,
FeaturedSiteSearchPolicyConflictWithUserDefinedDSP) { … }
TEST_P(TemplateURLServiceTest,
FeaturedSiteSearchPolicyConflictWithDSPSetByExtension) { … }
TEST_P(TemplateURLServiceTest,
FeaturedSiteSearchPolicyConflictWithStarterPack) { … }
#endif
INSTANTIATE_TEST_SUITE_P(…);