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.
4 
5 #include "components/search_engines/template_url_prepopulate_data.h"
6 
7 #include <stddef.h>
8 
9 #include <memory>
10 #include <utility>
11 
12 #include "base/command_line.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/stl_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h"
17 #include "components/country_codes/country_codes.h"
18 #include "components/google/core/common/google_switches.h"
19 #include "components/search_engines/prepopulated_engines.h"
20 #include "components/search_engines/search_engines_pref_names.h"
21 #include "components/search_engines/search_terms_data.h"
22 #include "components/search_engines/template_url.h"
23 #include "components/search_engines/template_url_data_util.h"
24 #include "components/search_engines/template_url_service.h"
25 #include "components/search_engines/testing_search_terms_data.h"
26 #include "components/sync_preferences/testing_pref_service_syncable.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 
29 using base::ASCIIToUTF16;
30 
31 namespace {
32 
GetEngineType(const std::string & url)33 SearchEngineType GetEngineType(const std::string& url) {
34   TemplateURLData data;
35   data.SetURL(url);
36   return TemplateURL(data).GetEngineType(SearchTermsData());
37 }
38 
GetHostFromTemplateURLData(const TemplateURLData & data)39 std::string GetHostFromTemplateURLData(const TemplateURLData& data) {
40   return TemplateURL(data).url_ref().GetHost(SearchTermsData());
41 }
42 
43 }  // namespace
44 
45 class TemplateURLPrepopulateDataTest : public testing::Test {
46  public:
SetUp()47   void SetUp() override {
48     TemplateURLPrepopulateData::RegisterProfilePrefs(prefs_.registry());
49   }
50 
51  protected:
52   sync_preferences::TestingPrefServiceSyncable prefs_;
53 };
54 
55 // Verifies the set of prepopulate data doesn't contain entries with duplicate
56 // ids.
TEST_F(TemplateURLPrepopulateDataTest,UniqueIDs)57 TEST_F(TemplateURLPrepopulateDataTest, UniqueIDs) {
58   const int kCountryIds[] = {
59       'A'<<8|'D', 'A'<<8|'E', 'A'<<8|'F', 'A'<<8|'G', 'A'<<8|'I',
60       'A'<<8|'L', 'A'<<8|'M', 'A'<<8|'N', 'A'<<8|'O', 'A'<<8|'Q',
61       'A'<<8|'R', 'A'<<8|'S', 'A'<<8|'T', 'A'<<8|'U', 'A'<<8|'W',
62       'A'<<8|'X', 'A'<<8|'Z', 'B'<<8|'A', 'B'<<8|'B', 'B'<<8|'D',
63       'B'<<8|'E', 'B'<<8|'F', 'B'<<8|'G', 'B'<<8|'H', 'B'<<8|'I',
64       'B'<<8|'J', 'B'<<8|'M', 'B'<<8|'N', 'B'<<8|'O', 'B'<<8|'R',
65       'B'<<8|'S', 'B'<<8|'T', 'B'<<8|'V', 'B'<<8|'W', 'B'<<8|'Y',
66       'B'<<8|'Z', 'C'<<8|'A', 'C'<<8|'C', 'C'<<8|'D', 'C'<<8|'F',
67       'C'<<8|'G', 'C'<<8|'H', 'C'<<8|'I', 'C'<<8|'K', 'C'<<8|'L',
68       'C'<<8|'M', 'C'<<8|'N', 'C'<<8|'O', 'C'<<8|'R', 'C'<<8|'U',
69       'C'<<8|'V', 'C'<<8|'X', 'C'<<8|'Y', 'C'<<8|'Z', 'D'<<8|'E',
70       'D'<<8|'J', 'D'<<8|'K', 'D'<<8|'M', 'D'<<8|'O', 'D'<<8|'Z',
71       'E'<<8|'C', 'E'<<8|'E', 'E'<<8|'G', 'E'<<8|'R', 'E'<<8|'S',
72       'E'<<8|'T', 'F'<<8|'I', 'F'<<8|'J', 'F'<<8|'K', 'F'<<8|'M',
73       'F'<<8|'O', 'F'<<8|'R', 'G'<<8|'A', 'G'<<8|'B', 'G'<<8|'D',
74       'G'<<8|'E', 'G'<<8|'F', 'G'<<8|'G', 'G'<<8|'H', 'G'<<8|'I',
75       'G'<<8|'L', 'G'<<8|'M', 'G'<<8|'N', 'G'<<8|'P', 'G'<<8|'Q',
76       'G'<<8|'R', 'G'<<8|'S', 'G'<<8|'T', 'G'<<8|'U', 'G'<<8|'W',
77       'G'<<8|'Y', 'H'<<8|'K', 'H'<<8|'M', 'H'<<8|'N', 'H'<<8|'R',
78       'H'<<8|'T', 'H'<<8|'U', 'I'<<8|'D', 'I'<<8|'E', 'I'<<8|'L',
79       'I'<<8|'M', 'I'<<8|'N', 'I'<<8|'O', 'I'<<8|'P', 'I'<<8|'Q',
80       'I'<<8|'R', 'I'<<8|'S', 'I'<<8|'T', 'J'<<8|'E', 'J'<<8|'M',
81       'J'<<8|'O', 'J'<<8|'P', 'K'<<8|'E', 'K'<<8|'G', 'K'<<8|'H',
82       'K'<<8|'I', 'K'<<8|'M', 'K'<<8|'N', 'K'<<8|'P', 'K'<<8|'R',
83       'K'<<8|'W', 'K'<<8|'Y', 'K'<<8|'Z', 'L'<<8|'A', 'L'<<8|'B',
84       'L'<<8|'C', 'L'<<8|'I', 'L'<<8|'K', 'L'<<8|'R', 'L'<<8|'S',
85       'L'<<8|'T', 'L'<<8|'U', 'L'<<8|'V', 'L'<<8|'Y', 'M'<<8|'A',
86       'M'<<8|'C', 'M'<<8|'D', 'M'<<8|'E', 'M'<<8|'G', 'M'<<8|'H',
87       'M'<<8|'K', 'M'<<8|'L', 'M'<<8|'M', 'M'<<8|'N', 'M'<<8|'O',
88       'M'<<8|'P', 'M'<<8|'Q', 'M'<<8|'R', 'M'<<8|'S', 'M'<<8|'T',
89       'M'<<8|'U', 'M'<<8|'V', 'M'<<8|'W', 'M'<<8|'X', 'M'<<8|'Y',
90       'M'<<8|'Z', 'N'<<8|'A', 'N'<<8|'C', 'N'<<8|'E', 'N'<<8|'F',
91       'N'<<8|'G', 'N'<<8|'I', 'N'<<8|'L', 'N'<<8|'O', 'N'<<8|'P',
92       'N'<<8|'R', 'N'<<8|'U', 'N'<<8|'Z', 'O'<<8|'M', 'P'<<8|'A',
93       'P'<<8|'E', 'P'<<8|'F', 'P'<<8|'G', 'P'<<8|'H', 'P'<<8|'K',
94       'P'<<8|'L', 'P'<<8|'M', 'P'<<8|'N', 'P'<<8|'R', 'P'<<8|'S',
95       'P'<<8|'T', 'P'<<8|'W', 'P'<<8|'Y', 'Q'<<8|'A', 'R'<<8|'E',
96       'R'<<8|'O', 'R'<<8|'S', 'R'<<8|'U', 'R'<<8|'W', 'S'<<8|'A',
97       'S'<<8|'B', 'S'<<8|'C', 'S'<<8|'D', 'S'<<8|'E', 'S'<<8|'G',
98       'S'<<8|'H', 'S'<<8|'I', 'S'<<8|'J', 'S'<<8|'K', 'S'<<8|'L',
99       'S'<<8|'M', 'S'<<8|'N', 'S'<<8|'O', 'S'<<8|'R', 'S'<<8|'T',
100       'S'<<8|'V', 'S'<<8|'Y', 'S'<<8|'Z', 'T'<<8|'C', 'T'<<8|'D',
101       'T'<<8|'F', 'T'<<8|'G', 'T'<<8|'H', 'T'<<8|'J', 'T'<<8|'K',
102       'T'<<8|'L', 'T'<<8|'M', 'T'<<8|'N', 'T'<<8|'O', 'T'<<8|'R',
103       'T'<<8|'T', 'T'<<8|'V', 'T'<<8|'W', 'T'<<8|'Z', 'U'<<8|'A',
104       'U'<<8|'G', 'U'<<8|'M', 'U'<<8|'S', 'U'<<8|'Y', 'U'<<8|'Z',
105       'V'<<8|'A', 'V'<<8|'C', 'V'<<8|'E', 'V'<<8|'G', 'V'<<8|'I',
106       'V'<<8|'N', 'V'<<8|'U', 'W'<<8|'F', 'W'<<8|'S', 'Y'<<8|'E',
107       'Y'<<8|'T', 'Z'<<8|'A', 'Z'<<8|'M', 'Z'<<8|'W', -1 };
108 
109   for (size_t i = 0; i < base::size(kCountryIds); ++i) {
110     prefs_.SetInteger(country_codes::kCountryIDAtInstall, kCountryIds[i]);
111     std::vector<std::unique_ptr<TemplateURLData>> urls =
112         TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_, nullptr);
113     std::set<int> unique_ids;
114     for (size_t turl_i = 0; turl_i < urls.size(); ++turl_i) {
115       ASSERT_TRUE(unique_ids.find(urls[turl_i]->prepopulate_id) ==
116                   unique_ids.end());
117       unique_ids.insert(urls[turl_i]->prepopulate_id);
118     }
119   }
120 }
121 
122 // Verifies that default search providers from the preferences file
123 // override the built-in ones.
TEST_F(TemplateURLPrepopulateDataTest,ProvidersFromPrefs)124 TEST_F(TemplateURLPrepopulateDataTest, ProvidersFromPrefs) {
125   prefs_.SetUserPref(prefs::kSearchProviderOverridesVersion,
126                      std::make_unique<base::Value>(1));
127   auto overrides = std::make_unique<base::ListValue>();
128   std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
129   // Set only the minimal required settings for a search provider configuration.
130   entry->SetString("name", "foo");
131   entry->SetString("keyword", "fook");
132   entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
133   entry->SetString("favicon_url", "http://foi.com/favicon.ico");
134   entry->SetString("encoding", "UTF-8");
135   entry->SetInteger("id", 1001);
136   overrides->Append(entry->CreateDeepCopy());
137   prefs_.SetUserPref(prefs::kSearchProviderOverrides, std::move(overrides));
138 
139   int version = TemplateURLPrepopulateData::GetDataVersion(&prefs_);
140   EXPECT_EQ(1, version);
141 
142   size_t default_index;
143   std::vector<std::unique_ptr<TemplateURLData>> t_urls =
144       TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
145                                                          &default_index);
146 
147   ASSERT_EQ(1u, t_urls.size());
148   EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
149   EXPECT_EQ(ASCIIToUTF16("fook"), t_urls[0]->keyword());
150   EXPECT_EQ("foo.com", GetHostFromTemplateURLData(*t_urls[0]));
151   EXPECT_EQ("foi.com", t_urls[0]->favicon_url.host());
152   EXPECT_EQ(1u, t_urls[0]->input_encodings.size());
153   EXPECT_EQ(1001, t_urls[0]->prepopulate_id);
154   EXPECT_TRUE(t_urls[0]->suggestions_url.empty());
155   EXPECT_EQ(0u, t_urls[0]->alternate_urls.size());
156   EXPECT_TRUE(t_urls[0]->safe_for_autoreplace);
157   EXPECT_TRUE(t_urls[0]->date_created.is_null());
158   EXPECT_TRUE(t_urls[0]->last_modified.is_null());
159 
160   // Test the optional settings too.
161   entry->SetString("suggest_url", "http://foo.com/suggest?q={searchTerms}");
162   auto alternate_urls = std::make_unique<base::ListValue>();
163   alternate_urls->AppendString("http://foo.com/alternate?q={searchTerms}");
164   entry->Set("alternate_urls", std::move(alternate_urls));
165   overrides = std::make_unique<base::ListValue>();
166   overrides->Append(entry->CreateDeepCopy());
167   prefs_.SetUserPref(prefs::kSearchProviderOverrides, std::move(overrides));
168 
169   t_urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(
170       &prefs_, &default_index);
171   ASSERT_EQ(1u, t_urls.size());
172   EXPECT_EQ(ASCIIToUTF16("foo"), t_urls[0]->short_name());
173   EXPECT_EQ(ASCIIToUTF16("fook"), t_urls[0]->keyword());
174   EXPECT_EQ("foo.com", GetHostFromTemplateURLData(*t_urls[0]));
175   EXPECT_EQ("foi.com", t_urls[0]->favicon_url.host());
176   EXPECT_EQ(1u, t_urls[0]->input_encodings.size());
177   EXPECT_EQ(1001, t_urls[0]->prepopulate_id);
178   EXPECT_EQ("http://foo.com/suggest?q={searchTerms}",
179             t_urls[0]->suggestions_url);
180   ASSERT_EQ(1u, t_urls[0]->alternate_urls.size());
181   EXPECT_EQ("http://foo.com/alternate?q={searchTerms}",
182             t_urls[0]->alternate_urls[0]);
183 
184   // Test that subsequent providers are loaded even if an intermediate
185   // provider has an incomplete configuration.
186   overrides = std::make_unique<base::ListValue>();
187   overrides->Append(entry->CreateDeepCopy());
188   entry->SetInteger("id", 1002);
189   entry->SetString("name", "bar");
190   entry->SetString("keyword", "bark");
191   entry->SetString("encoding", std::string());
192   overrides->Append(entry->CreateDeepCopy());
193   entry->SetInteger("id", 1003);
194   entry->SetString("name", "baz");
195   entry->SetString("keyword", "bazk");
196   entry->SetString("encoding", "UTF-8");
197   overrides->Append(entry->CreateDeepCopy());
198   prefs_.SetUserPref(prefs::kSearchProviderOverrides, std::move(overrides));
199 
200   t_urls =
201       TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
202                                                          &default_index);
203   EXPECT_EQ(2u, t_urls.size());
204 }
205 
TEST_F(TemplateURLPrepopulateDataTest,ClearProvidersFromPrefs)206 TEST_F(TemplateURLPrepopulateDataTest, ClearProvidersFromPrefs) {
207   prefs_.SetUserPref(prefs::kSearchProviderOverridesVersion,
208                      std::make_unique<base::Value>(1));
209   auto overrides = std::make_unique<base::ListValue>();
210   std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
211   // Set only the minimal required settings for a search provider configuration.
212   entry->SetString("name", "foo");
213   entry->SetString("keyword", "fook");
214   entry->SetString("search_url", "http://foo.com/s?q={searchTerms}");
215   entry->SetString("favicon_url", "http://foi.com/favicon.ico");
216   entry->SetString("encoding", "UTF-8");
217   entry->SetInteger("id", 1001);
218   overrides->Append(std::move(entry));
219   prefs_.SetUserPref(prefs::kSearchProviderOverrides, std::move(overrides));
220 
221   int version = TemplateURLPrepopulateData::GetDataVersion(&prefs_);
222   EXPECT_EQ(1, version);
223 
224   // This call removes the above search engine.
225   TemplateURLPrepopulateData::ClearPrepopulatedEnginesInPrefs(&prefs_);
226 
227   version = TemplateURLPrepopulateData::GetDataVersion(&prefs_);
228   EXPECT_EQ(TemplateURLPrepopulateData::kCurrentDataVersion, version);
229 
230   size_t default_index;
231   std::vector<std::unique_ptr<TemplateURLData>> t_urls =
232       TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
233                                                          &default_index);
234   ASSERT_FALSE(t_urls.empty());
235   for (size_t i = 0; i < t_urls.size(); ++i) {
236     EXPECT_NE(ASCIIToUTF16("foo"), t_urls[i]->short_name());
237     EXPECT_NE(ASCIIToUTF16("fook"), t_urls[i]->keyword());
238     EXPECT_NE("foi.com", t_urls[i]->favicon_url.host());
239     EXPECT_NE("foo.com", GetHostFromTemplateURLData(*t_urls[i]));
240     EXPECT_NE(1001, t_urls[i]->prepopulate_id);
241   }
242   // Ensures the default URL is Google and has the optional fields filled.
243   EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
244   EXPECT_FALSE(t_urls[default_index]->suggestions_url.empty());
245   EXPECT_FALSE(t_urls[default_index]->image_url.empty());
246   EXPECT_FALSE(t_urls[default_index]->contextual_search_url.empty());
247   EXPECT_FALSE(t_urls[default_index]->image_url_post_params.empty());
248   EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
249             TemplateURL(*t_urls[default_index]).GetEngineType(
250                 SearchTermsData()));
251 }
252 
253 // Verifies that built-in search providers are processed correctly.
TEST_F(TemplateURLPrepopulateDataTest,ProvidersFromPrepopulated)254 TEST_F(TemplateURLPrepopulateDataTest, ProvidersFromPrepopulated) {
255   // Use United States.
256   prefs_.SetInteger(country_codes::kCountryIDAtInstall, 'U' << 8 | 'S');
257   size_t default_index;
258   std::vector<std::unique_ptr<TemplateURLData>> t_urls =
259       TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_,
260                                                          &default_index);
261 
262   // Ensure all the URLs have the required fields populated.
263   ASSERT_FALSE(t_urls.empty());
264   for (size_t i = 0; i < t_urls.size(); ++i) {
265     ASSERT_FALSE(t_urls[i]->short_name().empty());
266     ASSERT_FALSE(t_urls[i]->keyword().empty());
267     ASSERT_FALSE(t_urls[i]->favicon_url.host().empty());
268     ASSERT_FALSE(GetHostFromTemplateURLData(*t_urls[i]).empty());
269     ASSERT_FALSE(t_urls[i]->input_encodings.empty());
270     EXPECT_GT(t_urls[i]->prepopulate_id, 0);
271     EXPECT_TRUE(t_urls[0]->safe_for_autoreplace);
272     EXPECT_TRUE(t_urls[0]->date_created.is_null());
273     EXPECT_TRUE(t_urls[0]->last_modified.is_null());
274   }
275 
276   // Ensures the default URL is Google and has the optional fields filled.
277   EXPECT_EQ(ASCIIToUTF16("Google"), t_urls[default_index]->short_name());
278   EXPECT_FALSE(t_urls[default_index]->suggestions_url.empty());
279   EXPECT_FALSE(t_urls[default_index]->image_url.empty());
280   EXPECT_FALSE(t_urls[default_index]->contextual_search_url.empty());
281   EXPECT_FALSE(t_urls[default_index]->image_url_post_params.empty());
282   // Expect at least 2 alternate_urls.
283   // This caught a bug with static initialization of arrays, so leave this in.
284   EXPECT_GT(t_urls[default_index]->alternate_urls.size(), 1u);
285   for (size_t i = 0; i < t_urls[default_index]->alternate_urls.size(); ++i)
286     EXPECT_FALSE(t_urls[default_index]->alternate_urls[i].empty());
287   EXPECT_EQ(SEARCH_ENGINE_GOOGLE,
288             TemplateURL(*t_urls[default_index]).GetEngineType(
289                 SearchTermsData()));
290 }
291 
TEST_F(TemplateURLPrepopulateDataTest,GetEngineTypeBasic)292 TEST_F(TemplateURLPrepopulateDataTest, GetEngineTypeBasic) {
293   EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("http://example.com/"));
294   EXPECT_EQ(SEARCH_ENGINE_ASK, GetEngineType("http://www.ask.com/"));
295   EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("http://search.atlas.cz/"));
296   EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType("http://www.google.com/"));
297 }
298 
TEST_F(TemplateURLPrepopulateDataTest,GetEngineTypeAdvanced)299 TEST_F(TemplateURLPrepopulateDataTest, GetEngineTypeAdvanced) {
300   // Google URLs in different forms.
301   const char* kGoogleURLs[] = {
302     // Original with google:baseURL:
303     "{google:baseURL}search?q={searchTerms}&{google:RLZ}"
304     "{google:originalQueryForSuggestion}{google:searchFieldtrialParameter}"
305     "sourceid=chrome&ie={inputEncoding}",
306     // Custom with google.com and reordered query params:
307     "http://google.com/search?{google:RLZ}{google:originalQueryForSuggestion}"
308     "{google:searchFieldtrialParameter}"
309     "sourceid=chrome&ie={inputEncoding}&q={searchTerms}",
310     // Custom with a country TLD and almost no query params:
311     "http://www.google.ru/search?q={searchTerms}"
312   };
313   for (size_t i = 0; i < base::size(kGoogleURLs); ++i) {
314     EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType(kGoogleURLs[i]));
315   }
316 
317   // Non-Google URLs.
318   const char* kYahooURLs[] = {
319       "http://search.yahoo.com/search?"
320       "ei={inputEncoding}&fr=crmas&p={searchTerms}",
321       "http://search.yahoo.com/search?p={searchTerms}",
322       // Aggressively match types by checking just TLD+1.
323       "http://someothersite.yahoo.com/",
324   };
325   for (size_t i = 0; i < base::size(kYahooURLs); ++i) {
326     EXPECT_EQ(SEARCH_ENGINE_YAHOO, GetEngineType(kYahooURLs[i]));
327   }
328 
329   // URLs for engines not present in country-specific lists.
330   EXPECT_EQ(SEARCH_ENGINE_NIGMA,
331             GetEngineType("http://nigma.ru/?s={searchTerms}&arg1=value1"));
332   // Also test matching against alternate URLs (and TLD+1 matching).
333   EXPECT_EQ(SEARCH_ENGINE_SOFTONIC,
334             GetEngineType("http://test.softonic.com.br/?{searchTerms}"));
335 
336   // Search URL for which no prepopulated search provider exists.
337   EXPECT_EQ(SEARCH_ENGINE_OTHER,
338             GetEngineType("http://example.net/search?q={searchTerms}"));
339   EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType("invalid:search:url"));
340 
341   // URL that doesn't look Google-related, but matches a Google base URL
342   // specified on the command line.
343   const std::string foo_url("http://www.foo.com/search?q={searchTerms}");
344   EXPECT_EQ(SEARCH_ENGINE_OTHER, GetEngineType(foo_url));
345   base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
346       switches::kGoogleBaseURL, "http://www.foo.com/");
347   EXPECT_EQ(SEARCH_ENGINE_GOOGLE, GetEngineType(foo_url));
348 }
349 
TEST_F(TemplateURLPrepopulateDataTest,GetEngineTypeForAllPrepopulatedEngines)350 TEST_F(TemplateURLPrepopulateDataTest, GetEngineTypeForAllPrepopulatedEngines) {
351   using PrepopulatedEngine = TemplateURLPrepopulateData::PrepopulatedEngine;
352   const std::vector<const PrepopulatedEngine*> all_engines =
353       TemplateURLPrepopulateData::GetAllPrepopulatedEngines();
354   for (const PrepopulatedEngine* engine : all_engines) {
355     std::unique_ptr<TemplateURLData> data =
356         TemplateURLDataFromPrepopulatedEngine(*engine);
357     EXPECT_EQ(engine->type,
358               TemplateURL(*data).GetEngineType(SearchTermsData()));
359   }
360 }
361 
TEST_F(TemplateURLPrepopulateDataTest,CheckSearchURLDetection)362 TEST_F(TemplateURLPrepopulateDataTest, CheckSearchURLDetection) {
363   using PrepopulatedEngine = TemplateURLPrepopulateData::PrepopulatedEngine;
364   const std::vector<const PrepopulatedEngine*> all_engines =
365       TemplateURLPrepopulateData::GetAllPrepopulatedEngines();
366   for (const PrepopulatedEngine* engine : all_engines) {
367     std::unique_ptr<TemplateURLData> data =
368         TemplateURLDataFromPrepopulatedEngine(*engine);
369     TemplateURL t_url(*data);
370     SearchTermsData search_data;
371     // Test that search term is successfully extracted from generated search
372     // url.
373     GURL search_url = t_url.GenerateSearchURL(search_data);
374     EXPECT_TRUE(t_url.IsSearchURL(search_url, search_data))
375         << "Search url is incorrectly detected for " << search_url;
376   }
377 }
378 
379 namespace {
380 
CheckTemplateUrlRefIsCryptographic(const TemplateURLRef & url_ref)381 void CheckTemplateUrlRefIsCryptographic(const TemplateURLRef& url_ref) {
382   TestingSearchTermsData search_terms_data("https://www.google.com/");
383   if (!url_ref.IsValid(search_terms_data)) {
384     ADD_FAILURE() << url_ref.GetURL();
385     return;
386   }
387 
388   // Double parentheses around the string16 constructor to prevent the compiler
389   // from parsing it as a function declaration.
390   TemplateURLRef::SearchTermsArgs search_term_args((base::string16()));
391   GURL url(url_ref.ReplaceSearchTerms(search_term_args, search_terms_data));
392   EXPECT_TRUE(url.is_empty() || url.SchemeIsCryptographic()) << url;
393 }
394 
395 }  // namespace
396 
TEST_F(TemplateURLPrepopulateDataTest,HttpsUrls)397 TEST_F(TemplateURLPrepopulateDataTest, HttpsUrls) {
398   // Search engines that don't use HTTPS URLs.
399   // Since Chrome and the Internet are trying to transition from HTTP to HTTPS,
400   // please get approval from a PM before entering new HTTP exceptions here.
401   std::set<int> exceptions{
402       4,  6,  16, 17, 21, 27, 35, 36, 43, 44, 45, 50, 54, 55, 56, 60, 61,
403       62, 63, 64, 65, 66, 68, 70, 74, 75, 76, 77, 78, 79, 80, 81, 85, 90,
404   };
405   using PrepopulatedEngine = TemplateURLPrepopulateData::PrepopulatedEngine;
406   const std::vector<const PrepopulatedEngine*> all_engines =
407       TemplateURLPrepopulateData::GetAllPrepopulatedEngines();
408   for (const PrepopulatedEngine* engine : all_engines) {
409     std::unique_ptr<TemplateURLData> data =
410         TemplateURLDataFromPrepopulatedEngine(*engine);
411     if (base::Contains(exceptions, data->prepopulate_id))
412       continue;
413 
414     GURL logo_url = data->logo_url;
415     EXPECT_TRUE(logo_url.is_empty() || logo_url.SchemeIsCryptographic())
416         << logo_url;
417     GURL doodle_url = data->doodle_url;
418     EXPECT_TRUE(doodle_url.is_empty() || doodle_url.SchemeIsCryptographic())
419         << doodle_url;
420     EXPECT_TRUE(logo_url.is_empty() || doodle_url.is_empty())
421         << "Only one of logo_url or doodle_url should be set.";
422 
423     GURL favicon_url = data->favicon_url;
424     EXPECT_TRUE(favicon_url.is_empty() || favicon_url.SchemeIsCryptographic())
425         << favicon_url;
426 
427     TemplateURL template_url(*data);
428 
429     // Intentionally don't check alternate URLs, because those are only used
430     // for matching.
431     CheckTemplateUrlRefIsCryptographic(template_url.url_ref());
432     CheckTemplateUrlRefIsCryptographic(template_url.suggestions_url_ref());
433     CheckTemplateUrlRefIsCryptographic(template_url.image_url_ref());
434     CheckTemplateUrlRefIsCryptographic(template_url.new_tab_url_ref());
435     CheckTemplateUrlRefIsCryptographic(
436         template_url.contextual_search_url_ref());
437   }
438 }
439 
TEST_F(TemplateURLPrepopulateDataTest,FindGoogleIndex)440 TEST_F(TemplateURLPrepopulateDataTest, FindGoogleIndex) {
441   constexpr int kGoogleId = 1;
442   size_t index;
443   std::vector<std::unique_ptr<TemplateURLData>> urls;
444 
445   // Google is first in US, so confirm index 0.
446   prefs_.SetInteger(country_codes::kCountryIDAtInstall, 'U' << 8 | 'S');
447   urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_, &index);
448   EXPECT_EQ(index, size_t{0});
449   EXPECT_EQ(urls[index]->prepopulate_id, kGoogleId);
450 
451   // Google is not first in CN; confirm it is found at index > 0.
452   // If Google ever does reach top in China, this test will need to be adjusted:
453   // check template_url_prepopulate_data.cc reference orders (engines_CN, etc.)
454   // to find a suitable country and index.
455   prefs_.SetInteger(country_codes::kCountryIDAtInstall, 'C' << 8 | 'N');
456   urls = TemplateURLPrepopulateData::GetPrepopulatedEngines(&prefs_, &index);
457   EXPECT_GT(index, size_t{0});
458   EXPECT_LT(index, urls.size());
459   EXPECT_EQ(urls[index]->prepopulate_id, kGoogleId);
460 }
461