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 "chrome/browser/search_engines/default_search_manager.h"
12 #include "chrome/browser/search_engines/template_url.h"
13 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "components/pref_registry/pref_registry_syncable.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(TestingPrefServiceSyncable
* prefs
, bool update
) {
48 prefs
->SetUserPref(prefs::kSearchProviderOverridesVersion
,
49 base::Value::CreateIntegerValue(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(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
->short_name
= 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 virtual void SetUp() OVERRIDE
{
145 pref_service_
.reset(new TestingPrefServiceSyncable
);
146 DefaultSearchManager::RegisterProfilePrefs(pref_service_
->registry());
147 TemplateURLPrepopulateData::RegisterProfilePrefs(pref_service_
->registry());
150 TestingPrefServiceSyncable
* pref_service() { return pref_service_
.get(); }
153 scoped_ptr
<TestingPrefServiceSyncable
> pref_service_
;
155 DISALLOW_COPY_AND_ASSIGN(DefaultSearchManagerTest
);
158 // Test that a TemplateURLData object is properly written and read from Prefs.
159 TEST_F(DefaultSearchManagerTest
, ReadAndWritePref
) {
160 DefaultSearchManager
manager(pref_service(),
161 DefaultSearchManager::ObserverCallback());
162 TemplateURLData data
;
163 data
.short_name
= base::UTF8ToUTF16("name1");
164 data
.SetKeyword(base::UTF8ToUTF16("key1"));
165 data
.SetURL("http://foo1/{searchTerms}");
166 data
.suggestions_url
= "http://sugg1";
167 data
.alternate_urls
.push_back("http://foo1/alt");
168 data
.favicon_url
= GURL("http://icon1");
169 data
.safe_for_autoreplace
= true;
170 data
.show_in_default_list
= true;
171 base::SplitString("UTF-8;UTF-16", ';', &data
.input_encodings
);
172 data
.date_created
= base::Time();
173 data
.last_modified
= base::Time();
175 manager
.SetUserSelectedDefaultSearchEngine(data
);
176 TemplateURLData
* read_data
= manager
.GetDefaultSearchEngine(NULL
);
177 ExpectSimilar(&data
, read_data
);
180 // Test DefaultSearchmanager handles user-selected DSEs correctly.
181 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByUserPref
) {
182 size_t default_search_index
= 0;
183 DefaultSearchManager
manager(pref_service(),
184 DefaultSearchManager::ObserverCallback());
185 ScopedVector
<TemplateURLData
> prepopulated_urls
=
186 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
187 &default_search_index
);
188 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
189 // If no user pref is set, we should use the pre-populated values.
190 ExpectSimilar(prepopulated_urls
[default_search_index
],
191 manager
.GetDefaultSearchEngine(&source
));
192 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
194 // Setting a user pref overrides the pre-populated values.
195 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
196 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
198 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
199 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
201 // Updating the user pref (externally to this instance of
202 // DefaultSearchManager) triggers an update.
203 scoped_ptr
<TemplateURLData
> new_data
= GenerateDummyTemplateURLData("user2");
204 DefaultSearchManager
other_manager(pref_service(),
205 DefaultSearchManager::ObserverCallback());
206 other_manager
.SetUserSelectedDefaultSearchEngine(*new_data
.get());
208 ExpectSimilar(new_data
.get(), manager
.GetDefaultSearchEngine(&source
));
209 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
211 // Clearing the user pref should cause the default search to revert to the
212 // prepopulated vlaues.
213 manager
.ClearUserSelectedDefaultSearchEngine();
214 ExpectSimilar(prepopulated_urls
[default_search_index
],
215 manager
.GetDefaultSearchEngine(&source
));
216 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
219 // Test that DefaultSearch manager detects changes to kSearchProviderOverrides.
220 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByOverrides
) {
221 SetOverrides(pref_service(), false);
222 size_t default_search_index
= 0;
223 DefaultSearchManager
manager(pref_service(),
224 DefaultSearchManager::ObserverCallback());
225 ScopedVector
<TemplateURLData
> prepopulated_urls
=
226 TemplateURLPrepopulateData::GetPrepopulatedEngines(pref_service(),
227 &default_search_index
);
229 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_POLICY
;
230 TemplateURLData
first_default(*manager
.GetDefaultSearchEngine(&source
));
231 ExpectSimilar(prepopulated_urls
[default_search_index
], &first_default
);
232 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
234 // Update the overrides:
235 SetOverrides(pref_service(), true);
236 prepopulated_urls
= TemplateURLPrepopulateData::GetPrepopulatedEngines(
237 pref_service(), &default_search_index
);
239 // Make sure DefaultSearchManager updated:
240 ExpectSimilar(prepopulated_urls
[default_search_index
],
241 manager
.GetDefaultSearchEngine(&source
));
242 EXPECT_EQ(DefaultSearchManager::FROM_FALLBACK
, source
);
243 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->short_name
,
244 first_default
.short_name
);
245 EXPECT_NE(manager
.GetDefaultSearchEngine(NULL
)->keyword(),
246 first_default
.keyword());
249 // Test DefaultSearchManager handles policy-enforced DSEs correctly.
250 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByPolicy
) {
251 DefaultSearchManager
manager(pref_service(),
252 DefaultSearchManager::ObserverCallback());
253 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
254 manager
.SetUserSelectedDefaultSearchEngine(*data
.get());
256 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
257 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
258 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
260 scoped_ptr
<TemplateURLData
> policy_data
=
261 GenerateDummyTemplateURLData("policy");
262 SetPolicy(pref_service(), true, policy_data
.get());
264 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
265 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
267 TemplateURLData null_policy_data
;
268 SetPolicy(pref_service(), false, &null_policy_data
);
269 EXPECT_EQ(NULL
, manager
.GetDefaultSearchEngine(&source
));
270 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
272 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
273 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
274 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
277 // Test DefaultSearchManager handles extension-controlled DSEs correctly.
278 TEST_F(DefaultSearchManagerTest
, DefaultSearchSetByExtension
) {
279 DefaultSearchManager
manager(pref_service(),
280 DefaultSearchManager::ObserverCallback());
281 scoped_ptr
<TemplateURLData
> data
= GenerateDummyTemplateURLData("user");
282 manager
.SetUserSelectedDefaultSearchEngine(*data
);
284 DefaultSearchManager::Source source
= DefaultSearchManager::FROM_FALLBACK
;
285 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
286 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);
288 // Extension trumps prefs:
289 scoped_ptr
<TemplateURLData
> extension_data_1
=
290 GenerateDummyTemplateURLData("ext1");
291 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_1
);
293 ExpectSimilar(extension_data_1
.get(),
294 manager
.GetDefaultSearchEngine(&source
));
295 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
297 // Policy trumps extension:
298 scoped_ptr
<TemplateURLData
> policy_data
=
299 GenerateDummyTemplateURLData("policy");
300 SetPolicy(pref_service(), true, policy_data
.get());
302 ExpectSimilar(policy_data
.get(), manager
.GetDefaultSearchEngine(&source
));
303 EXPECT_EQ(DefaultSearchManager::FROM_POLICY
, source
);
304 pref_service()->RemoveManagedPref(kDefaultSearchProviderData
);
306 // Extensions trump each other:
307 scoped_ptr
<TemplateURLData
> extension_data_2
=
308 GenerateDummyTemplateURLData("ext2");
309 scoped_ptr
<TemplateURLData
> extension_data_3
=
310 GenerateDummyTemplateURLData("ext3");
311 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_2
);
312 manager
.SetExtensionControlledDefaultSearchEngine(*extension_data_3
);
314 ExpectSimilar(extension_data_3
.get(),
315 manager
.GetDefaultSearchEngine(&source
));
316 EXPECT_EQ(DefaultSearchManager::FROM_EXTENSION
, source
);
318 manager
.ClearExtensionControlledDefaultSearchEngine();
320 ExpectSimilar(data
.get(), manager
.GetDefaultSearchEngine(&source
));
321 EXPECT_EQ(DefaultSearchManager::FROM_USER
, source
);