Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / search_engines / template_url_prepopulate_data_unittest.cc
blob294d823a47ee8fe1fa4785fe8bbcdd0f4ea4b83d
1 // Copyright (c) 2012 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/command_line.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/memory/scoped_vector.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/search_engines/prepopulated_engines.h"
10 #include "chrome/browser/search_engines/search_terms_data.h"
11 #include "chrome/browser/search_engines/template_url.h"
12 #include "chrome/browser/search_engines/template_url_prepopulate_data.h"
13 #include "chrome/browser/search_engines/template_url_service.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/test/base/testing_pref_service_syncable.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "grit/generated_resources.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/base/l10n/l10n_util.h"
22 using base::ASCIIToUTF16;
24 namespace {
25 SearchEngineType GetEngineType(const std::string& url) {
26 TemplateURLData data;
27 data.SetURL(url);
28 return TemplateURLPrepopulateData::GetEngineType(TemplateURL(NULL, data));
30 } // namespace
32 typedef testing::Test TemplateURLPrepopulateDataTest;
34 // Verifies the set of prepopulate data doesn't contain entries with duplicate
35 // ids.
36 TEST(TemplateURLPrepopulateDataTest, UniqueIDs) {
37 const int kCountryIds[] = {
38 'A'<<8|'D', 'A'<<8|'E', 'A'<<8|'F', 'A'<<8|'G', 'A'<<8|'I',
39 'A'<<8|'L', 'A'<<8|'M', 'A'<<8|'N', 'A'<<8|'O', 'A'<<8|'Q',
40 'A'<<8|'R', 'A'<<8|'S', 'A'<<8|'T', 'A'<<8|'U', 'A'<<8|'W',
41 'A'<<8|'X', 'A'<<8|'Z', 'B'<<8|'A', 'B'<<8|'B', 'B'<<8|'D',
42 'B'<<8|'E', 'B'<<8|'F', 'B'<<8|'G', 'B'<<8|'H', 'B'<<8|'I',
43 'B'<<8|'J', 'B'<<8|'M', 'B'<<8|'N', 'B'<<8|'O', 'B'<<8|'R',
44 'B'<<8|'S', 'B'<<8|'T', 'B'<<8|'V', 'B'<<8|'W', 'B'<<8|'Y',
45 'B'<<8|'Z', 'C'<<8|'A', 'C'<<8|'C', 'C'<<8|'D', 'C'<<8|'F',
46 'C'<<8|'G', 'C'<<8|'H', 'C'<<8|'I', 'C'<<8|'K', 'C'<<8|'L',
47 'C'<<8|'M', 'C'<<8|'N', 'C'<<8|'O', 'C'<<8|'R', 'C'<<8|'U',
48 'C'<<8|'V', 'C'<<8|'X', 'C'<<8|'Y', 'C'<<8|'Z', 'D'<<8|'E',
49 'D'<<8|'J', 'D'<<8|'K', 'D'<<8|'M', 'D'<<8|'O', 'D'<<8|'Z',
50 'E'<<8|'C', 'E'<<8|'E', 'E'<<8|'G', 'E'<<8|'R', 'E'<<8|'S',
51 'E'<<8|'T', 'F'<<8|'I', 'F'<<8|'J', 'F'<<8|'K', 'F'<<8|'M',
52 'F'<<8|'O', 'F'<<8|'R', 'G'<<8|'A', 'G'<<8|'B', 'G'<<8|'D',
53 'G'<<8|'E', 'G'<<8|'F', 'G'<<8|'G', 'G'<<8|'H', 'G'<<8|'I',
54 'G'<<8|'L', 'G'<<8|'M', 'G'<<8|'N', 'G'<<8|'P', 'G'<<8|'Q',
55 'G'<<8|'R', 'G'<<8|'S', 'G'<<8|'T', 'G'<<8|'U', 'G'<<8|'W',
56 'G'<<8|'Y', 'H'<<8|'K', 'H'<<8|'M', 'H'<<8|'N', 'H'<<8|'R',
57 'H'<<8|'T', 'H'<<8|'U', 'I'<<8|'D', 'I'<<8|'E', 'I'<<8|'L',
58 'I'<<8|'M', 'I'<<8|'N', 'I'<<8|'O', 'I'<<8|'P', 'I'<<8|'Q',
59 'I'<<8|'R', 'I'<<8|'S', 'I'<<8|'T', 'J'<<8|'E', 'J'<<8|'M',
60 'J'<<8|'O', 'J'<<8|'P', 'K'<<8|'E', 'K'<<8|'G', 'K'<<8|'H',
61 'K'<<8|'I', 'K'<<8|'M', 'K'<<8|'N', 'K'<<8|'P', 'K'<<8|'R',
62 'K'<<8|'W', 'K'<<8|'Y', 'K'<<8|'Z', 'L'<<8|'A', 'L'<<8|'B',
63 'L'<<8|'C', 'L'<<8|'I', 'L'<<8|'K', 'L'<<8|'R', 'L'<<8|'S',
64 'L'<<8|'T', 'L'<<8|'U', 'L'<<8|'V', 'L'<<8|'Y', 'M'<<8|'A',
65 'M'<<8|'C', 'M'<<8|'D', 'M'<<8|'E', 'M'<<8|'G', 'M'<<8|'H',
66 'M'<<8|'K', 'M'<<8|'L', 'M'<<8|'M', 'M'<<8|'N', 'M'<<8|'O',
67 'M'<<8|'P', 'M'<<8|'Q', 'M'<<8|'R', 'M'<<8|'S', 'M'<<8|'T',
68 'M'<<8|'U', 'M'<<8|'V', 'M'<<8|'W', 'M'<<8|'X', 'M'<<8|'Y',
69 'M'<<8|'Z', 'N'<<8|'A', 'N'<<8|'C', 'N'<<8|'E', 'N'<<8|'F',
70 'N'<<8|'G', 'N'<<8|'I', 'N'<<8|'L', 'N'<<8|'O', 'N'<<8|'P',
71 'N'<<8|'R', 'N'<<8|'U', 'N'<<8|'Z', 'O'<<8|'M', 'P'<<8|'A',
72 'P'<<8|'E', 'P'<<8|'F', 'P'<<8|'G', 'P'<<8|'H', 'P'<<8|'K',
73 'P'<<8|'L', 'P'<<8|'M', 'P'<<8|'N', 'P'<<8|'R', 'P'<<8|'S',
74 'P'<<8|'T', 'P'<<8|'W', 'P'<<8|'Y', 'Q'<<8|'A', 'R'<<8|'E',
75 'R'<<8|'O', 'R'<<8|'S', 'R'<<8|'U', 'R'<<8|'W', 'S'<<8|'A',
76 'S'<<8|'B', 'S'<<8|'C', 'S'<<8|'D', 'S'<<8|'E', 'S'<<8|'G',
77 'S'<<8|'H', 'S'<<8|'I', 'S'<<8|'J', 'S'<<8|'K', 'S'<<8|'L',
78 'S'<<8|'M', 'S'<<8|'N', 'S'<<8|'O', 'S'<<8|'R', 'S'<<8|'T',
79 'S'<<8|'V', 'S'<<8|'Y', 'S'<<8|'Z', 'T'<<8|'C', 'T'<<8|'D',
80 'T'<<8|'F', 'T'<<8|'G', 'T'<<8|'H', 'T'<<8|'J', 'T'<<8|'K',
81 'T'<<8|'L', 'T'<<8|'M', 'T'<<8|'N', 'T'<<8|'O', 'T'<<8|'R',
82 'T'<<8|'T', 'T'<<8|'V', 'T'<<8|'W', 'T'<<8|'Z', 'U'<<8|'A',
83 'U'<<8|'G', 'U'<<8|'M', 'U'<<8|'S', 'U'<<8|'Y', 'U'<<8|'Z',
84 'V'<<8|'A', 'V'<<8|'C', 'V'<<8|'E', 'V'<<8|'G', 'V'<<8|'I',
85 'V'<<8|'N', 'V'<<8|'U', 'W'<<8|'F', 'W'<<8|'S', 'Y'<<8|'E',
86 'Y'<<8|'T', 'Z'<<8|'A', 'Z'<<8|'M', 'Z'<<8|'W', -1 };
88 TestingProfile profile;
89 for (size_t i = 0; i < arraysize(kCountryIds); ++i) {
90 profile.GetPrefs()->SetInteger(prefs::kCountryIDAtInstall, kCountryIds[i]);
91 size_t default_index;
92 ScopedVector<TemplateURL> urls =
93 TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
94 &default_index);
95 std::set<int> unique_ids;
96 for (size_t turl_i = 0; turl_i < urls.size(); ++turl_i) {
97 ASSERT_TRUE(unique_ids.find(urls[turl_i]->prepopulate_id()) ==
98 unique_ids.end());
99 unique_ids.insert(urls[turl_i]->prepopulate_id());
104 // Verifies that default search providers from the preferences file
105 // override the built-in ones.
106 TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
107 TestingProfile profile;
108 TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
109 prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
110 base::Value::CreateIntegerValue(1));
111 base::ListValue* overrides = new base::ListValue;
112 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
113 // Set only the minimal required settings for a search provider configuration.
114 entry->SetString("name", "foo");
115 entry->SetString("keyword", "fook");
116 entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
117 entry->SetString("favicon_url", "http://foi.com/favicon.ico");
118 entry->SetString("encoding", "UTF-8");
119 entry->SetInteger("id", 1001);
120 overrides->Append(entry->DeepCopy());
121 prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
123 int version = TemplateURLPrepopulateData::GetDataVersion(prefs);
124 EXPECT_EQ(1, version);
126 size_t default_index;
127 ScopedVector<TemplateURL> t_urls =
128 TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
129 &default_index);
131 ASSERT_EQ(1u, t_urls.size());
132 EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
133 EXPECT_EQ(ASCIIToUTF16("fook"), t_urls[0]->keyword());
134 EXPECT_EQ("foo.com", t_urls[0]->url_ref().GetHost());
135 EXPECT_EQ("foi.com", t_urls[0]->favicon_url().host());
136 EXPECT_EQ(1u, t_urls[0]->input_encodings().size());
137 EXPECT_EQ(1001, t_urls[0]->prepopulate_id());
138 EXPECT_TRUE(t_urls[0]->suggestions_url().empty());
139 EXPECT_TRUE(t_urls[0]->instant_url().empty());
140 EXPECT_EQ(0u, t_urls[0]->alternate_urls().size());
141 EXPECT_TRUE(t_urls[0]->search_terms_replacement_key().empty());
143 // Test the optional settings too.
144 entry->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
145 entry->SetString("instant_url", "http://foo.com/instant?q={searchTerms}");
146 base::ListValue* alternate_urls = new base::ListValue;
147 alternate_urls->AppendString("http://foo.com/alternate?q={searchTerms}");
148 entry->Set("alternate_urls", alternate_urls);
149 entry->SetString("search_terms_replacement_key", "espv");
150 overrides = new base::ListValue;
151 overrides->Append(entry->DeepCopy());
152 prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
154 t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
155 &default_index);
156 ASSERT_EQ(1u, t_urls.size());
157 EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
158 EXPECT_EQ(ASCIIToUTF16("fook"), t_urls[0]->keyword());
159 EXPECT_EQ("foo.com", t_urls[0]->url_ref().GetHost());
160 EXPECT_EQ("foi.com", t_urls[0]->favicon_url().host());
161 EXPECT_EQ(1u, t_urls[0]->input_encodings().size());
162 EXPECT_EQ(1001, t_urls[0]->prepopulate_id());
163 EXPECT_EQ("http://foo.com/suggest?q={searchTerms}",
164 t_urls[0]->suggestions_url());
165 EXPECT_EQ("http://foo.com/instant?q={searchTerms}",
166 t_urls[0]->instant_url());
167 ASSERT_EQ(1u, t_urls[0]->alternate_urls().size());
168 EXPECT_EQ("http://foo.com/alternate?q={searchTerms}",
169 t_urls[0]->alternate_urls()[0]);
170 EXPECT_EQ("espv", t_urls[0]->search_terms_replacement_key());
172 // Test that subsequent providers are loaded even if an intermediate
173 // provider has an incomplete configuration.
174 overrides = new base::ListValue;
175 overrides->Append(entry->DeepCopy());
176 entry->SetInteger("id", 1002);
177 entry->SetString("name", "bar");
178 entry->SetString("keyword", "bark");
179 entry->SetString("encoding", std::string());
180 overrides->Append(entry->DeepCopy());
181 entry->SetInteger("id", 1003);
182 entry->SetString("name", "baz");
183 entry->SetString("keyword", "bazk");
184 entry->SetString("encoding", "UTF-8");
185 overrides->Append(entry->DeepCopy());
186 prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
188 t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
189 &default_index);
190 EXPECT_EQ(2u, t_urls.size());
193 TEST(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
194 TestingProfile profile;
195 TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
196 prefs->SetUserPref(prefs::kSearchProviderOverridesVersion,
197 base::Value::CreateIntegerValue(1));
198 base::ListValue* overrides = new base::ListValue;
199 base::DictionaryValue* entry(new base::DictionaryValue);
200 // Set only the minimal required settings for a search provider configuration.
201 entry->SetString("name", "foo");
202 entry->SetString("keyword", "fook");
203 entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
204 entry->SetString("favicon_url", "http://foi.com/favicon.ico");
205 entry->SetString("encoding", "UTF-8");
206 entry->SetInteger("id", 1001);
207 overrides->Append(entry);
208 prefs->SetUserPref(prefs::kSearchProviderOverrides, overrides);
210 int version = TemplateURLPrepopulateData::GetDataVersion(prefs);
211 EXPECT_EQ(1, version);
213 // This call removes the above search engine.
214 TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(&profile);
216 version = TemplateURLPrepopulateData::GetDataVersion(prefs);
217 EXPECT_EQ(TemplateURLPrepopulateData::kCurrentDataVersion, version);
219 size_t default_index;
220 ScopedVector<TemplateURL> t_urls =
221 TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
222 &default_index);
223 ASSERT_FALSE(t_urls.empty());
224 for (size_t i = 0; i < t_urls.size(); ++i) {
225 EXPECT_NE(ASCIIToUTF16("foo"), t_urls[i]->short_name());
226 EXPECT_NE(ASCIIToUTF16("fook"), t_urls[i]->keyword());
227 EXPECT_NE("foi.com", t_urls[i]->favicon_url().host());
228 EXPECT_NE("foo.com", t_urls[i]->url_ref().GetHost());
229 EXPECT_NE(1001, t_urls[i]->prepopulate_id());
231 // Ensures the default URL is Google and has the optional fields filled.
232 EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
233 EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
234 EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
235 EXPECT_FALSE(t_urls[default_index]->image_url().empty());
236 EXPECT_FALSE(t_urls[default_index]->new_tab_url().empty());
237 EXPECT_FALSE(t_urls[default_index]->image_url_post_params().empty());
238 EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
239 TemplateURLPrepopulateData::GetEngineType(*t_urls[default_index]));
242 // Verifies that built-in search providers are processed correctly.
243 TEST(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) {
244 // Use United States.
245 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
246 switches::kCountry, "US");
247 TestingProfile profile;
248 size_t default_index;
249 ScopedVector<TemplateURL> t_urls =
250 TemplateURLPrepopulateData::GetPrepopulatedEngines(&profile,
251 &default_index);
253 // Ensure all the URLs have the required fields populated.
254 ASSERT_FALSE(t_urls.empty());
255 for (size_t i = 0; i < t_urls.size(); ++i) {
256 ASSERT_FALSE(t_urls[i]->short_name().empty());
257 ASSERT_FALSE(t_urls[i]->keyword().empty());
258 ASSERT_FALSE(t_urls[i]->favicon_url().host().empty());
259 ASSERT_FALSE(t_urls[i]->url_ref().GetHost().empty());
260 ASSERT_FALSE(t_urls[i]->input_encodings().empty());
261 EXPECT_GT(t_urls[i]->prepopulate_id(), 0);
264 // Ensures the default URL is Google and has the optional fields filled.
265 EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
266 EXPECT_FALSE(t_urls[default_index]->suggestions_url().empty());
267 EXPECT_FALSE(t_urls[default_index]->instant_url().empty());
268 EXPECT_FALSE(t_urls[default_index]->image_url().empty());
269 EXPECT_FALSE(t_urls[default_index]->new_tab_url().empty());
270 EXPECT_FALSE(t_urls[default_index]->image_url_post_params().empty());
271 // Expect at least 2 alternate_urls.
272 // This caught a bug with static initialization of arrays, so leave this in.
273 EXPECT_GT(t_urls[default_index]->alternate_urls().size(), 1u);
274 for (size_t i = 0; i < t_urls[default_index]->alternate_urls().size(); ++i)
275 EXPECT_FALSE(t_urls[default_index]->alternate_urls()[i].empty());
276 EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
277 TemplateURLPrepopulateData::GetEngineType(*t_urls[default_index]));
278 EXPECT_FALSE(t_urls[default_index]->search_terms_replacement_key().empty());
281 TEST(TemplateURLPrepopulateDataTest, GetEngineTypeBasic) {
282 EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("http://example.com/"));
283 EXPECT_EQ(SEARCH_ENGINE_ASK, GetEngineType("http://www.ask.com/"));
284 EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("http://search.atlas.cz/"));
285 EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType("http://www.google.com/"));
288 TEST(TemplateURLPrepopulateDataTest, GetEngineTypeAdvanced) {
289 // Google URLs in different forms.
290 const char* kGoogleURLs[] = {
291 // Original with google:baseURL:
292 "{google:baseURL}search?q={searchTerms}&{google:RLZ}"
293 "{google:originalQueryForSuggestion}{google:searchFieldtrialParameter}"
294 "sourceid=chrome&ie={inputEncoding}",
295 // Custom with google.com and reordered query params:
296 "http://google.com/search?{google:RLZ}{google:originalQueryForSuggestion}"
297 "{google:searchFieldtrialParameter}"
298 "sourceid=chrome&ie={inputEncoding}&q={searchTerms}",
299 // Custom with a country TLD and almost no query params:
300 "http://www.google.ru/search?q={searchTerms}"
302 for (size_t i = 0; i < arraysize(kGoogleURLs); ++i) {
303 EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType(kGoogleURLs[i]));
306 // Non-Google URLs.
307 const char* kYahooURLs[] = {
308 "http://search.yahoo.com/search?"
309 "ei={inputEncoding}&fr=crmas&p={searchTerms}",
310 "http://search.yahoo.com/search?p={searchTerms}",
311 // Aggressively match types by checking just TLD+1.
312 "http://someothersite.yahoo.com/",
314 for (size_t i = 0; i < arraysize(kYahooURLs); ++i) {
315 EXPECT_EQ(SEARCH_ENGINE_YAHOO, GetEngineType(kYahooURLs[i]));
318 // URLs for engines not present in country-specific lists.
319 EXPECT_EQ(SEARCH_ENGINE_NIGMA,
320 GetEngineType("http://nigma.ru/?s={searchTerms}&arg1=value1"));
321 // Also test matching against alternate URLs (and TLD+1 matching).
322 EXPECT_EQ(SEARCH_ENGINE_SOFTONIC,
323 GetEngineType("http://test.softonic.com.br/?{searchTerms}"));
325 // Search URL for which no prepopulated search provider exists.
326 EXPECT_EQ(SEARCH_ENGINE_OTHER,
327 GetEngineType("http://example.net/search?q={searchTerms}"));
328 EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("invalid:search:url"));
330 // URL that doesn't look Google-related, but matches a Google base URL
331 // specified on the command line.
332 const std::string foo_url("http://www.foo.com/search?q={searchTerms}");
333 EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType(foo_url));
334 CommandLine::ForCurrentProcess()->AppendSwitchASCII(switches::kGoogleBaseURL,
335 "http://www.foo.com/");
336 EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType(foo_url));
339 TEST(TemplateURLPrepopulateDataTest, GetLogoURLGoogle) {
340 TemplateURLData data;
341 data.SetURL("http://www.google.com/");
342 TemplateURL turl(NULL, data);
343 GURL logo_100_url = TemplateURLPrepopulateData::GetLogoURL(
344 turl, TemplateURLPrepopulateData::LOGO_100_PERCENT);
345 GURL logo_200_url = TemplateURLPrepopulateData::GetLogoURL(
346 turl, TemplateURLPrepopulateData::LOGO_200_PERCENT);
348 EXPECT_EQ("www.google.com", logo_100_url.host());
349 EXPECT_EQ("www.google.com", logo_200_url.host());
350 EXPECT_NE(logo_100_url, logo_200_url);
353 TEST(TemplateURLPrepopulateDataTest, GetLogoURLUnknown) {
354 TemplateURLData data;
355 data.SetURL("http://webalta.ru/");
356 TemplateURL turl(NULL, data);
357 GURL logo_url = TemplateURLPrepopulateData::GetLogoURL(
358 turl, TemplateURLPrepopulateData::LOGO_100_PERCENT);
360 EXPECT_TRUE(logo_url.is_empty());
363 TEST(TemplateURLPrepopulateDataTest, GetLogoURLInvalid) {
364 TemplateURLData data;
365 data.SetURL("http://invalid:search:url/");
366 TemplateURL turl(NULL, data);
367 GURL logo_url = TemplateURLPrepopulateData::GetLogoURL(
368 turl, TemplateURLPrepopulateData::LOGO_100_PERCENT);
370 EXPECT_TRUE(logo_url.is_empty());