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