1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/files/scoped_temp_dir.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/time/time.h"
11 #include "components/pref_registry/pref_registry_syncable.h"
12 #include "components/pref_registry/testing_pref_service_syncable.h"
13 #include "components/search_engines/default_search_manager.h"
14 #include "components/search_engines/search_engines_pref_names.h"
15 #include "components/search_engines/template_url_data.h"
16 #include "components/search_engines/template_url_prepopulate_data.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 // A dictionary to hold all data related to the Default Search Engine.
21 // Eventually, this should replace all the data stored in the
22 // default_search_provider.* prefs.
23 const char kDefaultSearchProviderData
[] =
24 "default_search_provider_data.template_url_data";
26 // Checks that the two TemplateURLs are similar. Does not check the id, the
27 // date_created or the last_modified time. Neither pointer should be NULL.
28 void ExpectSimilar(const TemplateURLData
* expected
,
29 const TemplateURLData
* actual
) {
30 ASSERT_TRUE(expected
!= NULL
);
31 ASSERT_TRUE(actual
!= NULL
);
33 EXPECT_EQ(expected
->short_name(), actual
->short_name());
34 EXPECT_EQ(expected
->keyword(), actual
->keyword());
35 EXPECT_EQ(expected
->url(), actual
->url());
36 EXPECT_EQ(expected
->suggestions_url
, actual
->suggestions_url
);
37 EXPECT_EQ(expected
->favicon_url
, actual
->favicon_url
);
38 EXPECT_EQ(expected
->alternate_urls
, actual
->alternate_urls
);
39 EXPECT_EQ(expected
->show_in_default_list
, actual
->show_in_default_list
);
40 EXPECT_EQ(expected
->safe_for_autoreplace
, actual
->safe_for_autoreplace
);
41 EXPECT_EQ(expected
->input_encodings
, actual
->input_encodings
);
42 EXPECT_EQ(expected
->search_terms_replacement_key
,
43 actual
->search_terms_replacement_key
);
46 // TODO(caitkp): TemplateURLData-ify this.
47 void SetOverrides(user_prefs::TestingPrefServiceSyncable
* prefs
, bool update
) {
48 prefs
->SetUserPref(prefs::kSearchProviderOverridesVersion
,
49 new base::FundamentalValue(1));
50 base::ListValue
* overrides
= new base::ListValue
;
51 scoped_ptr
<base::DictionaryValue
> entry(new base::DictionaryValue
);
53 entry
->SetString("name", update
? "new_foo" : "foo");
54 entry
->SetString("keyword", update
? "new_fook" : "fook");
55 entry
->SetString("search_url", "http://foo.com/s?q={searchTerms}");
56 entry
->SetString("favicon_url", "http://foi.com/favicon.ico");
57 entry
->SetString("encoding", "UTF-8");
58 entry
->SetInteger("id", 1001);
59 entry
->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
60 entry
->SetString("instant_url", "http://foo.com/instant?q={searchTerms}");
61 base::ListValue
* alternate_urls
= new base::ListValue
;
62 alternate_urls
->AppendString("http://foo.com/alternate?q={searchTerms}");
63 entry
->Set("alternate_urls", alternate_urls
);
64 entry
->SetString("search_terms_replacement_key", "espv");
65 overrides
->Append(entry
->DeepCopy());
67 entry
.reset(new base::DictionaryValue
);
68 entry
->SetInteger("id", 1002);
69 entry
->SetString("name", update
? "new_bar" : "bar");
70 entry
->SetString("keyword", update
? "new_bark" : "bark");
71 entry
->SetString("encoding", std::string());
72 overrides
->Append(entry
->DeepCopy());
73 entry
->SetInteger("id", 1003);
74 entry
->SetString("name", "baz");
75 entry
->SetString("keyword", "bazk");
76 entry
->SetString("encoding", "UTF-8");
77 overrides
->Append(entry
->DeepCopy());
78 prefs
->SetUserPref(prefs::kSearchProviderOverrides
, overrides
);
81 void SetPolicy(user_prefs::TestingPrefServiceSyncable
* prefs
,
83 TemplateURLData
* data
) {
85 EXPECT_FALSE(data
->keyword().empty());
86 EXPECT_FALSE(data
->url().empty());
88 scoped_ptr
<base::DictionaryValue
> entry(new base::DictionaryValue
);
89 entry
->SetString(DefaultSearchManager::kShortName
, data
->short_name());
90 entry
->SetString(DefaultSearchManager::kKeyword
, data
->keyword());
91 entry
->SetString(DefaultSearchManager::kURL
, data
->url());
92 entry
->SetString(DefaultSearchManager::kFaviconURL
, data
->favicon_url
.spec());
93 entry
->SetString(DefaultSearchManager::kSuggestionsURL
,
94 data
->suggestions_url
);
95 entry
->SetBoolean(DefaultSearchManager::kSafeForAutoReplace
,
96 data
->safe_for_autoreplace
);
97 scoped_ptr
<base::ListValue
> alternate_urls(new base::ListValue
);
98 for (std::vector
<std::string
>::const_iterator it
=
99 data
->alternate_urls
.begin();
100 it
!= data
->alternate_urls
.end();
102 alternate_urls
->AppendString(*it
);
104 entry
->Set(DefaultSearchManager::kAlternateURLs
, alternate_urls
.release());
106 scoped_ptr
<base::ListValue
> encodings(new base::ListValue
);
107 for (std::vector
<std::string
>::const_iterator it
=
108 data
->input_encodings
.begin();
109 it
!= data
->input_encodings
.end();
111 encodings
->AppendString(*it
);
113 entry
->Set(DefaultSearchManager::kInputEncodings
, encodings
.release());
115 entry
->SetString(DefaultSearchManager::kSearchTermsReplacementKey
,
116 data
->search_terms_replacement_key
);
117 entry
->SetBoolean(DefaultSearchManager::kDisabledByPolicy
, !enabled
);
118 prefs
->SetManagedPref(kDefaultSearchProviderData
, entry
.release());
121 scoped_ptr
<TemplateURLData
> GenerateDummyTemplateURLData(std::string type
) {
122 scoped_ptr
<TemplateURLData
> data(new TemplateURLData());
123 data
->SetShortName(base::UTF8ToUTF16(std::string(type
).append("name")));
124 data
->SetKeyword(base::UTF8ToUTF16(std::string(type
).append("key")));
125 data
->SetURL(std::string("http://").append(type
).append("foo/{searchTerms}"));
126 data
->suggestions_url
= std::string("http://").append(type
).append("sugg");
127 data
->alternate_urls
.push_back(
128 std::string("http://").append(type
).append("foo/alt"));
129 data
->favicon_url
= GURL("http://icon1");
130 data
->safe_for_autoreplace
= true;
131 data
->show_in_default_list
= true;
132 data
->input_encodings
= base::SplitString(
133 "UTF-8;UTF-16", ";", base::TRIM_WHITESPACE
, base::SPLIT_WANT_ALL
);
134 data
->date_created
= base::Time();
135 data
->last_modified
= base::Time();
141 class DefaultSearchManagerTest
: public testing::Test
{
143 DefaultSearchManagerTest() {};
145 void SetUp() override
{
146 pref_service_
.reset(new user_prefs::TestingPrefServiceSyncable
);
147 DefaultSearchManager::RegisterProfilePrefs(pref_service_
->registry());
148 TemplateURLPrepopulateData::RegisterProfilePrefs(pref_service_
->registry());
151 user_prefs::TestingPrefServiceSyncable
* pref_service() {
152 return pref_service_
.get();
156 scoped_ptr
<user_prefs::TestingPrefServiceSyncable
> pref_service_
;
158 DISALLOW_COPY_AND_ASSIGN(DefaultSearchManagerTest
);
161 // Test that a TemplateURLData object is properly written and read from Prefs.
162 TEST_F(DefaultSearchManagerTest
, ReadAndWritePref
) {
163 DefaultSearchManager
manager(pref_service(),
164 DefaultSearchManager::ObserverCallback());
165 TemplateURLData data
;
166 data
.SetShortName(base::UTF8ToUTF16("name1"));
167 data
.SetKeyword(base::UTF8ToUTF16("key1"));
168 data
.SetURL("http://foo1/{searchTerms}");
169 data
.suggestions_url
= "http://sugg1";
170 data
.alternate_urls
.push_back("http://foo1/alt");
171 data
.favicon_url
= GURL("http://icon1");
172 data
.safe_for_autoreplace
= true;
173 data
.show_in_default_list
= true;
174 data
.input_encodings
= base::SplitString(
175 "UTF-8;UTF-16", ";", base::TRIM_WHITESPACE
, base::SPLIT_WANT_ALL
);
176 data
.date_created
= base::Time();
177 data
.last_modified
= base::Time();
179 manager
.SetUserSelectedDefaultSearchEngine(data
);
180 TemplateURLData
* read_data
= manager
.GetDefaultSearchEngine(NULL
);
181 ExpectSimilar(&data
, read_data
);
184 // Test DefaultSearchmanager handles user-selected DSEs correctly.
185 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByUserPref
) {
186 size_t default_search_index
= 0;
187 DefaultSearchManager
manager(pref_service(),
188 DefaultSearchManager::ObserverCallback());
189 ScopedVector
<TemplateURLData
> prepopulated_urls
=
190 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
191 &default_search_index
);
192 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
193 // If no user pref is set, we should use the pre-populated values.
194 ExpectSimilar(prepopulated_urls
[default_search_index
],
195 manager
.GetDefaultSearchEngine(&source
));
196 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
198 // Setting a user pref overrides the pre-populated values.
199 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
200 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
202 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
203 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
205 // Updating the user pref (externally to this instance of
206 // DefaultSearchManager) triggers an update.
207 scoped_ptr
<TemplateURLData
> new_data
= GenerateDummyTemplateURLData("user2");
208 DefaultSearchManager
other_manager(pref_service(),
209 DefaultSearchManager::ObserverCallback());
210 other_manager
.SetUserSelectedDefaultSearchEngine(*new_data
.get());
212 ExpectSimilar(new_data
.get(), manager
.GetDefaultSearchEngine(&source
));
213 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
215 // Clearing the user pref should cause the default search to revert to the
216 // prepopulated vlaues.
217 manager
.ClearUserSelectedDefaultSearchEngine();
218 ExpectSimilar(prepopulated_urls
[default_search_index
],
219 manager
.GetDefaultSearchEngine(&source
));
220 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
223 // Test that DefaultSearch manager detects changes to kSearchProviderOverrides.
224 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByOverrides
) {
225 SetOverrides(pref_service(), false);
226 size_t default_search_index
= 0;
227 DefaultSearchManager
manager(pref_service(),
228 DefaultSearchManager::ObserverCallback());
229 ScopedVector
<TemplateURLData
> prepopulated_urls
=
230 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
231 &default_search_index
);
233 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
234 TemplateURLData
first_default(*manager
.GetDefaultSearchEngine(&source
));
235 ExpectSimilar(prepopulated_urls
[default_search_index
], &first_default
);
236 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
238 // Update the overrides:
239 SetOverrides(pref_service(), true);
240 prepopulated_urls
= TemplateURLPrepopulateData::GetPrepopulatedEngines(
241 pref_service(), &default_search_index
);
243 // Make sure DefaultSearchManager updated:
244 ExpectSimilar(prepopulated_urls
[default_search_index
],
245 manager
.GetDefaultSearchEngine(&source
));
246 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
247 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->short_name(),
248 first_default
.short_name());
249 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->keyword(),
250 first_default
.keyword());
253 // Test DefaultSearchManager handles policy-enforced DSEs correctly.
254 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByPolicy
) {
255 DefaultSearchManager
manager(pref_service(),
256 DefaultSearchManager::ObserverCallback());
257 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
258 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
260 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
261 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
262 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
264 scoped_ptr
<TemplateURLData
> policy_data
=
265 GenerateDummyTemplateURLData("policy");
266 SetPolicy(pref_service(), true, policy_data
.get());
268 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
269 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
271 TemplateURLData null_policy_data
;
272 SetPolicy(pref_service(), false, &null_policy_data
);
273 EXPECT_EQ(NULL
, manager
.GetDefaultSearchEngine(&source
));
274 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
276 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
277 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
278 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
281 // Test DefaultSearchManager handles extension-controlled DSEs correctly.
282 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByExtension
) {
283 DefaultSearchManager
manager(pref_service(),
284 DefaultSearchManager::ObserverCallback());
285 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
286 manager
.SetUserSelectedDefaultSearchEngine(*data
);
288 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
289 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
290 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
292 // Extension trumps prefs:
293 scoped_ptr
<TemplateURLData
> extension_data_1
=
294 GenerateDummyTemplateURLData("ext1");
295 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_1
);
297 ExpectSimilar(extension_data_1
.get(),
298 manager
.GetDefaultSearchEngine(&source
));
299 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
301 // Policy trumps extension:
302 scoped_ptr
<TemplateURLData
> policy_data
=
303 GenerateDummyTemplateURLData("policy");
304 SetPolicy(pref_service(), true, policy_data
.get());
306 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
307 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
308 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
310 // Extensions trump each other:
311 scoped_ptr
<TemplateURLData
> extension_data_2
=
312 GenerateDummyTemplateURLData("ext2");
313 scoped_ptr
<TemplateURLData
> extension_data_3
=
314 GenerateDummyTemplateURLData("ext3");
315 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_2
);
316 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_3
);
318 ExpectSimilar(extension_data_3
.get(),
319 manager
.GetDefaultSearchEngine(&source
));
320 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
322 manager
.ClearExtensionControlledDefaultSearchEngine();
324 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
325 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);