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 base::SplitString("UTF-8;UTF-16", ';', &data
->input_encodings
);
133 data
->date_created
= base::Time();
134 data
->last_modified
= base::Time();
140 class DefaultSearchManagerTest
: public testing::Test
{
142 DefaultSearchManagerTest() {};
144 void SetUp() override
{
145 pref_service_
.reset(new user_prefs::TestingPrefServiceSyncable
);
146 DefaultSearchManager::RegisterProfilePrefs(pref_service_
->registry());
147 TemplateURLPrepopulateData::RegisterProfilePrefs(pref_service_
->registry());
150 user_prefs::TestingPrefServiceSyncable
* pref_service() {
151 return pref_service_
.get();
155 scoped_ptr
<user_prefs::TestingPrefServiceSyncable
> pref_service_
;
157 DISALLOW_COPY_AND_ASSIGN(DefaultSearchManagerTest
);
160 // Test that a TemplateURLData object is properly written and read from Prefs.
161 TEST_F(DefaultSearchManagerTest
, ReadAndWritePref
) {
162 DefaultSearchManager
manager(pref_service(),
163 DefaultSearchManager::ObserverCallback());
164 TemplateURLData data
;
165 data
.SetShortName(base::UTF8ToUTF16("name1"));
166 data
.SetKeyword(base::UTF8ToUTF16("key1"));
167 data
.SetURL("http://foo1/{searchTerms}");
168 data
.suggestions_url
= "http://sugg1";
169 data
.alternate_urls
.push_back("http://foo1/alt");
170 data
.favicon_url
= GURL("http://icon1");
171 data
.safe_for_autoreplace
= true;
172 data
.show_in_default_list
= true;
173 base::SplitString("UTF-8;UTF-16", ';', &data
.input_encodings
);
174 data
.date_created
= base::Time();
175 data
.last_modified
= base::Time();
177 manager
.SetUserSelectedDefaultSearchEngine(data
);
178 TemplateURLData
* read_data
= manager
.GetDefaultSearchEngine(NULL
);
179 ExpectSimilar(&data
, read_data
);
182 // Test DefaultSearchmanager handles user-selected DSEs correctly.
183 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByUserPref
) {
184 size_t default_search_index
= 0;
185 DefaultSearchManager
manager(pref_service(),
186 DefaultSearchManager::ObserverCallback());
187 ScopedVector
<TemplateURLData
> prepopulated_urls
=
188 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
189 &default_search_index
);
190 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
191 // If no user pref is set, we should use the pre-populated values.
192 ExpectSimilar(prepopulated_urls
[default_search_index
],
193 manager
.GetDefaultSearchEngine(&source
));
194 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
196 // Setting a user pref overrides the pre-populated values.
197 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
198 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
200 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
201 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
203 // Updating the user pref (externally to this instance of
204 // DefaultSearchManager) triggers an update.
205 scoped_ptr
<TemplateURLData
> new_data
= GenerateDummyTemplateURLData("user2");
206 DefaultSearchManager
other_manager(pref_service(),
207 DefaultSearchManager::ObserverCallback());
208 other_manager
.SetUserSelectedDefaultSearchEngine(*new_data
.get());
210 ExpectSimilar(new_data
.get(), manager
.GetDefaultSearchEngine(&source
));
211 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
213 // Clearing the user pref should cause the default search to revert to the
214 // prepopulated vlaues.
215 manager
.ClearUserSelectedDefaultSearchEngine();
216 ExpectSimilar(prepopulated_urls
[default_search_index
],
217 manager
.GetDefaultSearchEngine(&source
));
218 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
221 // Test that DefaultSearch manager detects changes to kSearchProviderOverrides.
222 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByOverrides
) {
223 SetOverrides(pref_service(), false);
224 size_t default_search_index
= 0;
225 DefaultSearchManager
manager(pref_service(),
226 DefaultSearchManager::ObserverCallback());
227 ScopedVector
<TemplateURLData
> prepopulated_urls
=
228 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
229 &default_search_index
);
231 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
232 TemplateURLData
first_default(*manager
.GetDefaultSearchEngine(&source
));
233 ExpectSimilar(prepopulated_urls
[default_search_index
], &first_default
);
234 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
236 // Update the overrides:
237 SetOverrides(pref_service(), true);
238 prepopulated_urls
= TemplateURLPrepopulateData::GetPrepopulatedEngines(
239 pref_service(), &default_search_index
);
241 // Make sure DefaultSearchManager updated:
242 ExpectSimilar(prepopulated_urls
[default_search_index
],
243 manager
.GetDefaultSearchEngine(&source
));
244 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
245 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->short_name(),
246 first_default
.short_name());
247 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->keyword(),
248 first_default
.keyword());
251 // Test DefaultSearchManager handles policy-enforced DSEs correctly.
252 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByPolicy
) {
253 DefaultSearchManager
manager(pref_service(),
254 DefaultSearchManager::ObserverCallback());
255 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
256 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
258 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
259 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
260 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
262 scoped_ptr
<TemplateURLData
> policy_data
=
263 GenerateDummyTemplateURLData("policy");
264 SetPolicy(pref_service(), true, policy_data
.get());
266 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
267 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
269 TemplateURLData null_policy_data
;
270 SetPolicy(pref_service(), false, &null_policy_data
);
271 EXPECT_EQ(NULL
, manager
.GetDefaultSearchEngine(&source
));
272 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
274 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
275 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
276 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
279 // Test DefaultSearchManager handles extension-controlled DSEs correctly.
280 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByExtension
) {
281 DefaultSearchManager
manager(pref_service(),
282 DefaultSearchManager::ObserverCallback());
283 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
284 manager
.SetUserSelectedDefaultSearchEngine(*data
);
286 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
287 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
288 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
290 // Extension trumps prefs:
291 scoped_ptr
<TemplateURLData
> extension_data_1
=
292 GenerateDummyTemplateURLData("ext1");
293 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_1
);
295 ExpectSimilar(extension_data_1
.get(),
296 manager
.GetDefaultSearchEngine(&source
));
297 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
299 // Policy trumps extension:
300 scoped_ptr
<TemplateURLData
> policy_data
=
301 GenerateDummyTemplateURLData("policy");
302 SetPolicy(pref_service(), true, policy_data
.get());
304 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
305 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
306 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
308 // Extensions trump each other:
309 scoped_ptr
<TemplateURLData
> extension_data_2
=
310 GenerateDummyTemplateURLData("ext2");
311 scoped_ptr
<TemplateURLData
> extension_data_3
=
312 GenerateDummyTemplateURLData("ext3");
313 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_2
);
314 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_3
);
316 ExpectSimilar(extension_data_3
.get(),
317 manager
.GetDefaultSearchEngine(&source
));
318 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
320 manager
.ClearExtensionControlledDefaultSearchEngine();
322 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
323 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);