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