1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/search_engines/default_search_manager.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/time/time.h"
17 #include "components/pref_registry/pref_registry_syncable.h"
18 #include "components/search_engines/search_engines_pref_names.h"
19 #include "components/search_engines/search_engines_test_util.h"
20 #include "components/search_engines/template_url_data.h"
21 #include "components/search_engines/template_url_data_util.h"
22 #include "components/search_engines/template_url_prepopulate_data.h"
23 #include "components/sync_preferences/testing_pref_service_syncable.h"
24 #include "components/variations/scoped_variations_ids_provider.h"
25 #include "testing/gtest/include/gtest/gtest.h"
29 // TODO(caitkp): TemplateURLData-ify this.
30 void SetOverrides(sync_preferences::TestingPrefServiceSyncable* prefs,
32 prefs->SetUserPref(prefs::kSearchProviderOverridesVersion, base::Value(1));
33 base::Value::List overrides;
34 base::Value::Dict entry;
36 entry.Set("name", update ? "new_foo" : "foo");
37 entry.Set("keyword", update ? "new_fook" : "fook");
38 entry.Set("search_url", "http://foo.com/s?q={searchTerms}");
39 entry.Set("favicon_url", "http://foi.com/favicon.ico");
40 entry.Set("encoding", "UTF-8");
41 entry.Set("id", 1001);
42 entry.Set("suggest_url", "http://foo.com/suggest?q={searchTerms}");
43 base::Value::List alternate_urls;
44 alternate_urls.Append("http://foo.com/alternate?q={searchTerms}");
45 entry.Set("alternate_urls", std::move(alternate_urls));
46 overrides.Append(std::move(entry));
48 entry = base::Value::Dict();
49 entry.Set("id", 1002);
50 entry.Set("name", update ? "new_bar" : "bar");
51 entry.Set("keyword", update ? "new_bark" : "bark");
52 entry.Set("encoding", std::string());
53 overrides.Append(entry.Clone());
54 entry.Set("id", 1003);
55 entry.Set("name", "baz");
56 entry.Set("keyword", "bazk");
57 entry.Set("encoding", "UTF-8");
58 overrides.Append(std::move(entry));
59 prefs->SetUserPref(prefs::kSearchProviderOverrides,
60 base::Value(std::move(overrides)));
63 void SetPolicy(sync_preferences::TestingPrefServiceSyncable* prefs,
65 TemplateURLData* data,
68 EXPECT_FALSE(data->keyword().empty());
69 EXPECT_FALSE(data->url().empty());
71 base::Value::Dict entry = TemplateURLDataToDictionary(*data);
72 entry.Set(DefaultSearchManager::kDisabledByPolicy, !enabled);
74 is_mandatory ? prefs->SetManagedPref(
75 DefaultSearchManager::kDefaultSearchProviderDataPrefName,
77 : prefs->SetRecommendedPref(
78 DefaultSearchManager::kDefaultSearchProviderDataPrefName,
84 class DefaultSearchManagerTest : public testing::Test {
86 DefaultSearchManagerTest() {}
88 DefaultSearchManagerTest(const DefaultSearchManagerTest&) = delete;
89 DefaultSearchManagerTest& operator=(const DefaultSearchManagerTest&) = delete;
91 void SetUp() override {
93 std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
94 DefaultSearchManager::RegisterProfilePrefs(pref_service_->registry());
95 TemplateURLPrepopulateData::RegisterProfilePrefs(pref_service_->registry());
98 sync_preferences::TestingPrefServiceSyncable* pref_service() {
99 return pref_service_.get();
103 variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
104 variations::VariationsIdsProvider::Mode::kUseSignedInState};
105 std::unique_ptr<sync_preferences::TestingPrefServiceSyncable> pref_service_;
108 // Test that a TemplateURLData object is properly written and read from Prefs.
109 TEST_F(DefaultSearchManagerTest, ReadAndWritePref) {
110 DefaultSearchManager manager(pref_service(),
111 DefaultSearchManager::ObserverCallback());
112 TemplateURLData data;
113 data.SetShortName(u"name1");
114 data.SetKeyword(u"key1");
115 data.SetURL("http://foo1/{searchTerms}");
116 data.suggestions_url = "http://sugg1";
117 data.alternate_urls.push_back("http://foo1/alt");
118 data.favicon_url = GURL("http://icon1");
119 data.safe_for_autoreplace = true;
120 data.input_encodings = base::SplitString(
121 "UTF-8;UTF-16", ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
122 data.date_created = base::Time();
123 data.last_modified = base::Time();
124 data.last_modified = base::Time();
125 data.created_from_play_api = true;
127 manager.SetUserSelectedDefaultSearchEngine(data);
128 const TemplateURLData* read_data = manager.GetDefaultSearchEngine(nullptr);
129 ExpectSimilar(&data, read_data);
132 // Test DefaultSearchmanager handles user-selected DSEs correctly.
133 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByUserPref) {
134 size_t default_search_index = 0;
135 DefaultSearchManager manager(pref_service(),
136 DefaultSearchManager::ObserverCallback());
137 std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls =
138 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
139 &default_search_index);
140 DefaultSearchManager::Source source = DefaultSearchManager::FROM_POLICY;
141 // If no user pref is set, we should use the pre-populated values.
142 ExpectSimilar(prepopulated_urls[default_search_index].get(),
143 manager.GetDefaultSearchEngine(&source));
144 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
146 // Setting a user pref overrides the pre-populated values.
147 std::unique_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
148 manager.SetUserSelectedDefaultSearchEngine(*data);
150 ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
151 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
153 // Updating the user pref (externally to this instance of
154 // DefaultSearchManager) triggers an update.
155 std::unique_ptr<TemplateURLData> new_data =
156 GenerateDummyTemplateURLData("user2");
157 DefaultSearchManager other_manager(pref_service(),
158 DefaultSearchManager::ObserverCallback());
159 other_manager.SetUserSelectedDefaultSearchEngine(*new_data);
161 ExpectSimilar(new_data.get(), manager.GetDefaultSearchEngine(&source));
162 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
164 // Clearing the user pref should cause the default search to revert to the
165 // prepopulated vlaues.
166 manager.ClearUserSelectedDefaultSearchEngine();
167 ExpectSimilar(prepopulated_urls[default_search_index].get(),
168 manager.GetDefaultSearchEngine(&source));
169 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
172 // Test that DefaultSearch manager detects changes to kSearchProviderOverrides.
173 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByOverrides) {
174 SetOverrides(pref_service(), false);
175 size_t default_search_index = 0;
176 DefaultSearchManager manager(pref_service(),
177 DefaultSearchManager::ObserverCallback());
178 std::vector<std::unique_ptr<TemplateURLData>> prepopulated_urls =
179 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
180 &default_search_index);
182 DefaultSearchManager::Source source = DefaultSearchManager::FROM_POLICY;
183 TemplateURLData first_default(*manager.GetDefaultSearchEngine(&source));
184 ExpectSimilar(prepopulated_urls[default_search_index].get(), &first_default);
185 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
187 // Update the overrides:
188 SetOverrides(pref_service(), true);
189 prepopulated_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(
190 pref_service(), &default_search_index);
192 // Make sure DefaultSearchManager updated:
193 ExpectSimilar(prepopulated_urls[default_search_index].get(),
194 manager.GetDefaultSearchEngine(&source));
195 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK, source);
196 EXPECT_NE(manager.GetDefaultSearchEngine(nullptr)->short_name(),
197 first_default.short_name());
198 EXPECT_NE(manager.GetDefaultSearchEngine(nullptr)->keyword(),
199 first_default.keyword());
202 // Test DefaultSearchManager handles policy-enforced DSEs correctly.
203 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByEnforcedPolicy) {
204 DefaultSearchManager manager(pref_service(),
205 DefaultSearchManager::ObserverCallback());
206 std::unique_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
207 manager.SetUserSelectedDefaultSearchEngine(*data);
209 DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
210 ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
211 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
213 std::unique_ptr<TemplateURLData> policy_data =
214 GenerateDummyTemplateURLData("policy");
215 SetPolicy(pref_service(), true, policy_data.get(), /*is_mandatory=*/true);
217 ExpectSimilar(policy_data.get(), manager.GetDefaultSearchEngine(&source));
218 EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
220 TemplateURLData null_policy_data;
221 SetPolicy(pref_service(), false, &null_policy_data, /*is_mandatory=*/true);
222 EXPECT_EQ(nullptr, manager.GetDefaultSearchEngine(&source));
223 EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
225 pref_service()->RemoveManagedPref(
226 DefaultSearchManager::kDefaultSearchProviderDataPrefName);
227 ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
228 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
231 // Policy-recommended DSE is handled correctly when no existing DSE is present.
232 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByRecommendedPolicy) {
233 DefaultSearchManager manager(pref_service(),
234 DefaultSearchManager::ObserverCallback());
235 DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
237 // Set recommended policy DSE with valid data.
238 std::unique_ptr<TemplateURLData> policy_data =
239 GenerateDummyTemplateURLData("policy");
240 SetPolicy(pref_service(), true, policy_data.get(), /*is_mandatory=*/false);
241 ExpectSimilar(policy_data.get(), manager.GetDefaultSearchEngine(&source));
242 EXPECT_EQ(DefaultSearchManager::FROM_POLICY_RECOMMENDED, source);
244 // Set recommended policy DSE with null data.
245 TemplateURLData null_policy_data;
246 SetPolicy(pref_service(), false, &null_policy_data, /*is_mandatory=*/false);
247 EXPECT_EQ(nullptr, manager.GetDefaultSearchEngine(&source));
248 EXPECT_EQ(DefaultSearchManager::FROM_POLICY_RECOMMENDED, source);
250 // Set user-configured DSE.
251 std::unique_ptr<TemplateURLData> user_data =
252 GenerateDummyTemplateURLData("user");
253 manager.SetUserSelectedDefaultSearchEngine(*user_data);
254 // The user-configured DSE overrides the recommended policy DSE.
255 ExpectSimilar(user_data.get(), manager.GetDefaultSearchEngine(&source));
256 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
258 // Remove the recommended policy DSE.
259 pref_service()->RemoveRecommendedPref(
260 DefaultSearchManager::kDefaultSearchProviderDataPrefName);
261 ExpectSimilar(user_data.get(), manager.GetDefaultSearchEngine(&source));
262 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
265 // Policy-recommended DSE does not override existing DSE set by user.
266 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByUserAndRecommendedPolicy) {
267 DefaultSearchManager manager(pref_service(),
268 DefaultSearchManager::ObserverCallback());
269 // Set user-configured DSE.
270 std::unique_ptr<TemplateURLData> user_data =
271 GenerateDummyTemplateURLData("user");
272 manager.SetUserSelectedDefaultSearchEngine(*user_data);
273 DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
274 ExpectSimilar(user_data.get(), manager.GetDefaultSearchEngine(&source));
275 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
277 // Set recommended policy DSE.
278 std::unique_ptr<TemplateURLData> policy_data =
279 GenerateDummyTemplateURLData("policy");
280 SetPolicy(pref_service(), true, policy_data.get(), /*is_mandatory=*/false);
281 // The recommended policy DSE does not override the existing user DSE.
282 ExpectSimilar(user_data.get(), manager.GetDefaultSearchEngine(&source));
283 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
285 // Remove the recommended policy DSE.
286 pref_service()->RemoveRecommendedPref(
287 DefaultSearchManager::kDefaultSearchProviderDataPrefName);
288 ExpectSimilar(user_data.get(), manager.GetDefaultSearchEngine(&source));
289 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
292 // Test DefaultSearchManager handles extension-controlled DSEs correctly.
293 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByExtension) {
294 DefaultSearchManager manager(pref_service(),
295 DefaultSearchManager::ObserverCallback());
296 std::unique_ptr<TemplateURLData> data = GenerateDummyTemplateURLData("user");
297 manager.SetUserSelectedDefaultSearchEngine(*data);
299 DefaultSearchManager::Source source = DefaultSearchManager::FROM_FALLBACK;
300 ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
301 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
303 // Extension trumps prefs:
304 std::unique_ptr<TemplateURLData> extension_data_1 =
305 GenerateDummyTemplateURLData("ext1");
306 SetExtensionDefaultSearchInPrefs(pref_service(), *extension_data_1);
307 ExpectSimilar(extension_data_1.get(),
308 manager.GetDefaultSearchEngine(&source));
309 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION, source);
311 // Policy trumps extension:
312 std::unique_ptr<TemplateURLData> policy_data =
313 GenerateDummyTemplateURLData("policy");
314 SetPolicy(pref_service(), true, policy_data.get(), /*is_mandatory=*/true);
316 ExpectSimilar(policy_data.get(), manager.GetDefaultSearchEngine(&source));
317 EXPECT_EQ(DefaultSearchManager::FROM_POLICY, source);
318 pref_service()->RemoveManagedPref(
319 DefaultSearchManager::kDefaultSearchProviderDataPrefName);
321 // Extensions trump each other:
322 std::unique_ptr<TemplateURLData> extension_data_2 =
323 GenerateDummyTemplateURLData("ext2");
324 std::unique_ptr<TemplateURLData> extension_data_3 =
325 GenerateDummyTemplateURLData("ext3");
327 SetExtensionDefaultSearchInPrefs(pref_service(), *extension_data_2);
328 SetExtensionDefaultSearchInPrefs(pref_service(), *extension_data_3);
329 ExpectSimilar(extension_data_3.get(),
330 manager.GetDefaultSearchEngine(&source));
331 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION, source);
333 RemoveExtensionDefaultSearchFromPrefs(pref_service());
334 ExpectSimilar(data.get(), manager.GetDefaultSearchEngine(&source));
335 EXPECT_EQ(DefaultSearchManager::FROM_USER, source);
338 // Verify that DefaultSearchManager preserves search engine parameters for
339 // search engine created from Play API data.
340 TEST_F(DefaultSearchManagerTest, DefaultSearchSetByPlayAPI) {
341 DefaultSearchManager manager(pref_service(),
342 DefaultSearchManager::ObserverCallback());
343 const TemplateURLData* prepopulated_data =
344 manager.GetDefaultSearchEngine(nullptr);
346 // The test tries to set DSE to the one with prepopulate_id, matching existing
347 // prepopulated search engine.
348 std::unique_ptr<TemplateURLData> data = GenerateDummyTemplateURLData(
349 base::UTF16ToUTF8(prepopulated_data->keyword()));
350 data->prepopulate_id = prepopulated_data->prepopulate_id;
351 data->favicon_url = prepopulated_data->favicon_url;
353 // If the new search engine was not created form Play API data its parameters
354 // should be overwritten with prepopulated data.
355 manager.SetUserSelectedDefaultSearchEngine(*data);
356 const TemplateURLData* read_data = manager.GetDefaultSearchEngine(nullptr);
357 ExpectSimilar(prepopulated_data, read_data);
359 // If the new search engine was created form Play API data its parameters
360 // should be preserved.
361 data->created_from_play_api = true;
362 manager.SetUserSelectedDefaultSearchEngine(*data);
363 read_data = manager.GetDefaultSearchEngine(nullptr);
364 ExpectSimilar(data.get(), read_data);