Cast: Add an option to turn on non-blocking IO on Windows
[chromium-blink-merge.git] / components / search_engines / template_url_unittest.cc
blobb16e7b42b1a644b055eb0bc9983b934c48f72349
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/base_paths.h"
6 #include "base/command_line.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "components/metrics/proto/omnibox_event.pb.h"
11 #include "components/metrics/proto/omnibox_input_type.pb.h"
12 #include "components/search_engines/search_engines_switches.h"
13 #include "components/search_engines/search_terms_data.h"
14 #include "components/search_engines/template_url.h"
15 #include "components/search_engines/testing_search_terms_data.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using base::ASCIIToUTF16;
20 class TemplateURLTest : public testing::Test {
21 public:
22 TemplateURLTest() : search_terms_data_("http://www.google.com/") {}
23 void CheckSuggestBaseURL(const std::string& base_url,
24 const std::string& base_suggest_url) const;
26 TestingSearchTermsData search_terms_data_;
29 void TemplateURLTest::CheckSuggestBaseURL(
30 const std::string& base_url,
31 const std::string& base_suggest_url) const {
32 TestingSearchTermsData search_terms_data(base_url);
33 EXPECT_EQ(base_suggest_url, search_terms_data.GoogleBaseSuggestURLValue());
36 TEST_F(TemplateURLTest, Defaults) {
37 TemplateURLData data;
38 EXPECT_FALSE(data.show_in_default_list);
39 EXPECT_FALSE(data.safe_for_autoreplace);
40 EXPECT_EQ(0, data.prepopulate_id);
43 TEST_F(TemplateURLTest, TestValidWithComplete) {
44 TemplateURLData data;
45 data.SetURL("{searchTerms}");
46 TemplateURL url(data);
47 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
50 TEST_F(TemplateURLTest, URLRefTestSearchTerms) {
51 struct SearchTermsCase {
52 const char* url;
53 const base::string16 terms;
54 const std::string output;
55 } search_term_cases[] = {
56 { "http://foo{searchTerms}", ASCIIToUTF16("sea rch/bar"),
57 "http://foosea%20rch/bar" },
58 { "http://foo{searchTerms}?boo=abc", ASCIIToUTF16("sea rch/bar"),
59 "http://foosea%20rch/bar?boo=abc" },
60 { "http://foo/?boo={searchTerms}", ASCIIToUTF16("sea rch/bar"),
61 "http://foo/?boo=sea+rch%2Fbar" },
62 { "http://en.wikipedia.org/{searchTerms}", ASCIIToUTF16("wiki/?"),
63 "http://en.wikipedia.org/wiki/%3F" }
65 for (size_t i = 0; i < arraysize(search_term_cases); ++i) {
66 const SearchTermsCase& value = search_term_cases[i];
67 TemplateURLData data;
68 data.SetURL(value.url);
69 TemplateURL url(data);
70 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
71 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
72 GURL result(url.url_ref().ReplaceSearchTerms(
73 TemplateURLRef::SearchTermsArgs(value.terms), search_terms_data_));
74 ASSERT_TRUE(result.is_valid());
75 EXPECT_EQ(value.output, result.spec());
79 TEST_F(TemplateURLTest, URLRefTestCount) {
80 TemplateURLData data;
81 data.SetURL("http://foo{searchTerms}{count?}");
82 TemplateURL url(data);
83 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
84 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
85 GURL result(url.url_ref().ReplaceSearchTerms(
86 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
87 ASSERT_TRUE(result.is_valid());
88 EXPECT_EQ("http://foox/", result.spec());
91 TEST_F(TemplateURLTest, URLRefTestCount2) {
92 TemplateURLData data;
93 data.SetURL("http://foo{searchTerms}{count}");
94 TemplateURL url(data);
95 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
96 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
97 GURL result(url.url_ref().ReplaceSearchTerms(
98 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
99 ASSERT_TRUE(result.is_valid());
100 EXPECT_EQ("http://foox10/", result.spec());
103 TEST_F(TemplateURLTest, URLRefTestIndices) {
104 TemplateURLData data;
105 data.SetURL("http://foo{searchTerms}x{startIndex?}y{startPage?}");
106 TemplateURL url(data);
107 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
108 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
109 GURL result(url.url_ref().ReplaceSearchTerms(
110 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
111 ASSERT_TRUE(result.is_valid());
112 EXPECT_EQ("http://fooxxy/", result.spec());
115 TEST_F(TemplateURLTest, URLRefTestIndices2) {
116 TemplateURLData data;
117 data.SetURL("http://foo{searchTerms}x{startIndex}y{startPage}");
118 TemplateURL url(data);
119 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
120 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
121 GURL result(url.url_ref().ReplaceSearchTerms(
122 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
123 ASSERT_TRUE(result.is_valid());
124 EXPECT_EQ("http://fooxx1y1/", result.spec());
127 TEST_F(TemplateURLTest, URLRefTestEncoding) {
128 TemplateURLData data;
129 data.SetURL("http://foo{searchTerms}x{inputEncoding?}y{outputEncoding?}a");
130 TemplateURL url(data);
131 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
132 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
133 GURL result(url.url_ref().ReplaceSearchTerms(
134 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
135 ASSERT_TRUE(result.is_valid());
136 EXPECT_EQ("http://fooxxutf-8ya/", result.spec());
139 TEST_F(TemplateURLTest, URLRefTestImageURLWithPOST) {
140 const char kInvalidPostParamsString[] =
141 "unknown_template={UnknownTemplate},bad_value=bad{value},"
142 "{google:sbiSource}";
143 // List all accpectable parameter format in valid_post_params_string. it is
144 // expected like: "name0=,name1=value1,name2={template1}"
145 const char kValidPostParamsString[] =
146 "image_content={google:imageThumbnail},image_url={google:imageURL},"
147 "sbisrc={google:imageSearchSource},language={language},empty_param=,"
148 "constant_param=constant,width={google:imageOriginalWidth}";
149 const char KImageSearchURL[] = "http://foo.com/sbi";
151 TemplateURLData data;
152 data.image_url = KImageSearchURL;
154 // Try to parse invalid post parameters.
155 data.image_url_post_params = kInvalidPostParamsString;
156 TemplateURL url_bad(data);
157 ASSERT_FALSE(url_bad.image_url_ref().IsValid(search_terms_data_));
158 const TemplateURLRef::PostParams& bad_post_params =
159 url_bad.image_url_ref().post_params_;
160 ASSERT_EQ(2U, bad_post_params.size());
161 EXPECT_EQ("unknown_template", bad_post_params[0].first);
162 EXPECT_EQ("{UnknownTemplate}", bad_post_params[0].second);
163 EXPECT_EQ("bad_value", bad_post_params[1].first);
164 EXPECT_EQ("bad{value}", bad_post_params[1].second);
166 // Try to parse valid post parameters.
167 data.image_url_post_params = kValidPostParamsString;
168 TemplateURL url(data);
169 ASSERT_TRUE(url.image_url_ref().IsValid(search_terms_data_));
170 ASSERT_FALSE(url.image_url_ref().SupportsReplacement(search_terms_data_));
172 // Check term replacement.
173 TemplateURLRef::SearchTermsArgs search_args(ASCIIToUTF16("X"));
174 search_args.image_thumbnail_content = "dummy-image-thumbnail";
175 search_args.image_url = GURL("http://dummyimage.com/dummy.jpg");
176 search_args.image_original_size = gfx::Size(10, 10);
177 // Replacement operation with no post_data buffer should still return
178 // the parsed URL.
179 TestingSearchTermsData search_terms_data("http://X");
180 GURL result(url.image_url_ref().ReplaceSearchTerms(
181 search_args, search_terms_data));
182 ASSERT_TRUE(result.is_valid());
183 EXPECT_EQ(KImageSearchURL, result.spec());
184 TemplateURLRef::PostContent post_content;
185 result = GURL(url.image_url_ref().ReplaceSearchTerms(
186 search_args, search_terms_data, &post_content));
187 ASSERT_TRUE(result.is_valid());
188 EXPECT_EQ(KImageSearchURL, result.spec());
189 ASSERT_FALSE(post_content.first.empty());
190 ASSERT_FALSE(post_content.second.empty());
192 // Check parsed result of post parameters.
193 const TemplateURLRef::Replacements& replacements =
194 url.image_url_ref().replacements_;
195 const TemplateURLRef::PostParams& post_params =
196 url.image_url_ref().post_params_;
197 EXPECT_EQ(7U, post_params.size());
198 for (TemplateURLRef::PostParams::const_iterator i = post_params.begin();
199 i != post_params.end(); ++i) {
200 TemplateURLRef::Replacements::const_iterator j = replacements.begin();
201 for (; j != replacements.end(); ++j) {
202 if (j->is_post_param && j->index ==
203 static_cast<size_t>(i - post_params.begin())) {
204 switch (j->type) {
205 case TemplateURLRef::GOOGLE_IMAGE_ORIGINAL_WIDTH:
206 EXPECT_EQ("width", i->first);
207 EXPECT_EQ(
208 base::IntToString(search_args.image_original_size.width()),
209 i->second);
210 break;
211 case TemplateURLRef::GOOGLE_IMAGE_SEARCH_SOURCE:
212 EXPECT_EQ("sbisrc", i->first);
213 EXPECT_EQ(search_terms_data.GoogleImageSearchSource(), i->second);
214 break;
215 case TemplateURLRef::GOOGLE_IMAGE_THUMBNAIL:
216 EXPECT_EQ("image_content", i->first);
217 EXPECT_EQ(search_args.image_thumbnail_content, i->second);
218 break;
219 case TemplateURLRef::GOOGLE_IMAGE_URL:
220 EXPECT_EQ("image_url", i->first);
221 EXPECT_EQ(search_args.image_url.spec(), i->second);
222 break;
223 case TemplateURLRef::LANGUAGE:
224 EXPECT_EQ("language", i->first);
225 EXPECT_EQ("en", i->second);
226 break;
227 default:
228 ADD_FAILURE(); // Should never go here.
230 break;
233 if (j != replacements.end())
234 continue;
235 if (i->first == "empty_param") {
236 EXPECT_TRUE(i->second.empty());
237 } else if (i->first == "sbisrc") {
238 EXPECT_FALSE(i->second.empty());
239 } else {
240 EXPECT_EQ("constant_param", i->first);
241 EXPECT_EQ("constant", i->second);
246 // Test that setting the prepopulate ID from TemplateURL causes the stored
247 // TemplateURLRef to handle parsing the URL parameters differently.
248 TEST_F(TemplateURLTest, SetPrepopulatedAndParse) {
249 TemplateURLData data;
250 data.SetURL("http://foo{fhqwhgads}bar");
251 TemplateURL url(data);
252 TemplateURLRef::Replacements replacements;
253 bool valid = false;
254 EXPECT_EQ("http://foo{fhqwhgads}bar", url.url_ref().ParseURL(
255 "http://foo{fhqwhgads}bar", &replacements, NULL, &valid));
256 EXPECT_TRUE(replacements.empty());
257 EXPECT_TRUE(valid);
259 data.prepopulate_id = 123;
260 TemplateURL url2(data);
261 EXPECT_EQ("http://foobar", url2.url_ref().ParseURL("http://foo{fhqwhgads}bar",
262 &replacements, NULL,
263 &valid));
264 EXPECT_TRUE(replacements.empty());
265 EXPECT_TRUE(valid);
268 TEST_F(TemplateURLTest, InputEncodingBeforeSearchTerm) {
269 TemplateURLData data;
270 data.SetURL("http://foox{inputEncoding?}a{searchTerms}y{outputEncoding?}b");
271 TemplateURL url(data);
272 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
273 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
274 GURL result(url.url_ref().ReplaceSearchTerms(
275 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
276 ASSERT_TRUE(result.is_valid());
277 EXPECT_EQ("http://fooxutf-8axyb/", result.spec());
280 TEST_F(TemplateURLTest, URLRefTestEncoding2) {
281 TemplateURLData data;
282 data.SetURL("http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a");
283 TemplateURL url(data);
284 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
285 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
286 GURL result(url.url_ref().ReplaceSearchTerms(
287 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")), search_terms_data_));
288 ASSERT_TRUE(result.is_valid());
289 EXPECT_EQ("http://fooxxutf-8yutf-8a/", result.spec());
292 TEST_F(TemplateURLTest, URLRefTestSearchTermsUsingTermsData) {
293 struct SearchTermsCase {
294 const char* url;
295 const base::string16 terms;
296 const char* output;
297 } search_term_cases[] = {
298 { "{google:baseURL}{language}{searchTerms}", base::string16(),
299 "http://example.com/e/en" },
300 { "{google:baseSuggestURL}{searchTerms}", base::string16(),
301 "http://example.com/complete/" }
304 TestingSearchTermsData search_terms_data("http://example.com/e/");
305 TemplateURLData data;
306 for (size_t i = 0; i < arraysize(search_term_cases); ++i) {
307 const SearchTermsCase& value = search_term_cases[i];
308 data.SetURL(value.url);
309 TemplateURL url(data);
310 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data));
311 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data));
312 GURL result(url.url_ref().ReplaceSearchTerms(
313 TemplateURLRef::SearchTermsArgs(value.terms), search_terms_data, NULL));
314 ASSERT_TRUE(result.is_valid());
315 EXPECT_EQ(value.output, result.spec());
319 TEST_F(TemplateURLTest, URLRefTermToWide) {
320 struct ToWideCase {
321 const char* encoded_search_term;
322 const base::string16 expected_decoded_term;
323 } to_wide_cases[] = {
324 {"hello+world", ASCIIToUTF16("hello world")},
325 // Test some big-5 input.
326 {"%a7A%A6%6e+to+you", base::WideToUTF16(L"\x4f60\x597d to you")},
327 // Test some UTF-8 input. We should fall back to this when the encoding
328 // doesn't look like big-5. We have a '5' in the middle, which is an invalid
329 // Big-5 trailing byte.
330 {"%e4%bd%a05%e5%a5%bd+to+you",
331 base::WideToUTF16(L"\x4f60\x35\x597d to you")},
332 // Undecodable input should stay escaped.
333 {"%91%01+abcd", base::WideToUTF16(L"%91%01 abcd")},
334 // Make sure we convert %2B to +.
335 {"C%2B%2B", ASCIIToUTF16("C++")},
336 // C%2B is escaped as C%252B, make sure we unescape it properly.
337 {"C%252B", ASCIIToUTF16("C%2B")},
340 // Set one input encoding: big-5. This is so we can test fallback to UTF-8.
341 TemplateURLData data;
342 data.SetURL("http://foo?q={searchTerms}");
343 data.input_encodings.push_back("big-5");
344 TemplateURL url(data);
345 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
346 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
347 for (size_t i = 0; i < arraysize(to_wide_cases); i++) {
348 EXPECT_EQ(to_wide_cases[i].expected_decoded_term,
349 url.url_ref().SearchTermToString16(
350 to_wide_cases[i].encoded_search_term));
354 TEST_F(TemplateURLTest, DisplayURLToURLRef) {
355 struct TestData {
356 const std::string url;
357 const base::string16 expected_result;
358 } test_data[] = {
359 { "http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a",
360 ASCIIToUTF16("http://foo%sx{inputEncoding}y{outputEncoding}a") },
361 { "http://X",
362 ASCIIToUTF16("http://X") },
363 { "http://foo{searchTerms",
364 ASCIIToUTF16("http://foo{searchTerms") },
365 { "http://foo{searchTerms}{language}",
366 ASCIIToUTF16("http://foo%s{language}") },
368 TemplateURLData data;
369 for (size_t i = 0; i < arraysize(test_data); ++i) {
370 data.SetURL(test_data[i].url);
371 TemplateURL url(data);
372 EXPECT_EQ(test_data[i].expected_result,
373 url.url_ref().DisplayURL(search_terms_data_));
374 EXPECT_EQ(test_data[i].url,
375 TemplateURLRef::DisplayURLToURLRef(
376 url.url_ref().DisplayURL(search_terms_data_)));
380 TEST_F(TemplateURLTest, ReplaceSearchTerms) {
381 struct TestData {
382 const std::string url;
383 const std::string expected_result;
384 } test_data[] = {
385 { "http://foo/{language}{searchTerms}{inputEncoding}",
386 "http://foo/{language}XUTF-8" },
387 { "http://foo/{language}{inputEncoding}{searchTerms}",
388 "http://foo/{language}UTF-8X" },
389 { "http://foo/{searchTerms}{language}{inputEncoding}",
390 "http://foo/X{language}UTF-8" },
391 { "http://foo/{searchTerms}{inputEncoding}{language}",
392 "http://foo/XUTF-8{language}" },
393 { "http://foo/{inputEncoding}{searchTerms}{language}",
394 "http://foo/UTF-8X{language}" },
395 { "http://foo/{inputEncoding}{language}{searchTerms}",
396 "http://foo/UTF-8{language}X" },
397 { "http://foo/{language}a{searchTerms}a{inputEncoding}a",
398 "http://foo/{language}aXaUTF-8a" },
399 { "http://foo/{language}a{inputEncoding}a{searchTerms}a",
400 "http://foo/{language}aUTF-8aXa" },
401 { "http://foo/{searchTerms}a{language}a{inputEncoding}a",
402 "http://foo/Xa{language}aUTF-8a" },
403 { "http://foo/{searchTerms}a{inputEncoding}a{language}a",
404 "http://foo/XaUTF-8a{language}a" },
405 { "http://foo/{inputEncoding}a{searchTerms}a{language}a",
406 "http://foo/UTF-8aXa{language}a" },
407 { "http://foo/{inputEncoding}a{language}a{searchTerms}a",
408 "http://foo/UTF-8a{language}aXa" },
410 TemplateURLData data;
411 data.input_encodings.push_back("UTF-8");
412 for (size_t i = 0; i < arraysize(test_data); ++i) {
413 data.SetURL(test_data[i].url);
414 TemplateURL url(data);
415 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
416 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
417 std::string expected_result = test_data[i].expected_result;
418 ReplaceSubstringsAfterOffset(&expected_result, 0, "{language}",
419 search_terms_data_.GetApplicationLocale());
420 GURL result(url.url_ref().ReplaceSearchTerms(
421 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("X")),
422 search_terms_data_));
423 ASSERT_TRUE(result.is_valid());
424 EXPECT_EQ(expected_result, result.spec());
429 // Tests replacing search terms in various encodings and making sure the
430 // generated URL matches the expected value.
431 TEST_F(TemplateURLTest, ReplaceArbitrarySearchTerms) {
432 struct TestData {
433 const std::string encoding;
434 const base::string16 search_term;
435 const std::string url;
436 const std::string expected_result;
437 } test_data[] = {
438 { "BIG5", base::WideToUTF16(L"\x60BD"),
439 "http://foo/?{searchTerms}{inputEncoding}",
440 "http://foo/?%B1~BIG5" },
441 { "UTF-8", ASCIIToUTF16("blah"),
442 "http://foo/?{searchTerms}{inputEncoding}",
443 "http://foo/?blahUTF-8" },
444 { "Shift_JIS", base::UTF8ToUTF16("\xe3\x81\x82"),
445 "http://foo/{searchTerms}/bar",
446 "http://foo/%82%A0/bar"},
447 { "Shift_JIS", base::UTF8ToUTF16("\xe3\x81\x82 \xe3\x81\x84"),
448 "http://foo/{searchTerms}/bar",
449 "http://foo/%82%A0%20%82%A2/bar"},
451 TemplateURLData data;
452 for (size_t i = 0; i < arraysize(test_data); ++i) {
453 data.SetURL(test_data[i].url);
454 data.input_encodings.clear();
455 data.input_encodings.push_back(test_data[i].encoding);
456 TemplateURL url(data);
457 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
458 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
459 GURL result(url.url_ref().ReplaceSearchTerms(
460 TemplateURLRef::SearchTermsArgs(test_data[i].search_term),
461 search_terms_data_));
462 ASSERT_TRUE(result.is_valid());
463 EXPECT_EQ(test_data[i].expected_result, result.spec());
467 // Tests replacing assisted query stats (AQS) in various scenarios.
468 TEST_F(TemplateURLTest, ReplaceAssistedQueryStats) {
469 struct TestData {
470 const base::string16 search_term;
471 const std::string aqs;
472 const std::string base_url;
473 const std::string url;
474 const std::string expected_result;
475 } test_data[] = {
476 // No HTTPS, no AQS.
477 { ASCIIToUTF16("foo"),
478 "chrome.0.0l6",
479 "http://foo/",
480 "{google:baseURL}?{searchTerms}{google:assistedQueryStats}",
481 "http://foo/?foo" },
482 // HTTPS available, AQS should be replaced.
483 { ASCIIToUTF16("foo"),
484 "chrome.0.0l6",
485 "https://foo/",
486 "{google:baseURL}?{searchTerms}{google:assistedQueryStats}",
487 "https://foo/?fooaqs=chrome.0.0l6&" },
488 // HTTPS available, however AQS is empty.
489 { ASCIIToUTF16("foo"),
491 "https://foo/",
492 "{google:baseURL}?{searchTerms}{google:assistedQueryStats}",
493 "https://foo/?foo" },
494 // No {google:baseURL} and protocol is HTTP, we must not substitute AQS.
495 { ASCIIToUTF16("foo"),
496 "chrome.0.0l6",
497 "http://www.google.com",
498 "http://foo?{searchTerms}{google:assistedQueryStats}",
499 "http://foo/?foo" },
500 // A non-Google search provider with HTTPS should allow AQS.
501 { ASCIIToUTF16("foo"),
502 "chrome.0.0l6",
503 "https://www.google.com",
504 "https://foo?{searchTerms}{google:assistedQueryStats}",
505 "https://foo/?fooaqs=chrome.0.0l6&" },
507 TemplateURLData data;
508 data.input_encodings.push_back("UTF-8");
509 for (size_t i = 0; i < arraysize(test_data); ++i) {
510 data.SetURL(test_data[i].url);
511 TemplateURL url(data);
512 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
513 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
514 TemplateURLRef::SearchTermsArgs search_terms_args(test_data[i].search_term);
515 search_terms_args.assisted_query_stats = test_data[i].aqs;
516 search_terms_data_.set_google_base_url(test_data[i].base_url);
517 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
518 search_terms_data_));
519 ASSERT_TRUE(result.is_valid());
520 EXPECT_EQ(test_data[i].expected_result, result.spec());
524 // Tests replacing cursor position.
525 TEST_F(TemplateURLTest, ReplaceCursorPosition) {
526 struct TestData {
527 const base::string16 search_term;
528 size_t cursor_position;
529 const std::string url;
530 const std::string expected_result;
531 } test_data[] = {
532 { ASCIIToUTF16("foo"),
533 base::string16::npos,
534 "{google:baseURL}?{searchTerms}&{google:cursorPosition}",
535 "http://www.google.com/?foo&" },
536 { ASCIIToUTF16("foo"),
538 "{google:baseURL}?{searchTerms}&{google:cursorPosition}",
539 "http://www.google.com/?foo&cp=2&" },
540 { ASCIIToUTF16("foo"),
542 "{google:baseURL}?{searchTerms}&{google:cursorPosition}",
543 "http://www.google.com/?foo&cp=15&" },
545 TemplateURLData data;
546 data.input_encodings.push_back("UTF-8");
547 for (size_t i = 0; i < arraysize(test_data); ++i) {
548 data.SetURL(test_data[i].url);
549 TemplateURL url(data);
550 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
551 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
552 TemplateURLRef::SearchTermsArgs search_terms_args(test_data[i].search_term);
553 search_terms_args.cursor_position = test_data[i].cursor_position;
554 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
555 search_terms_data_));
556 ASSERT_TRUE(result.is_valid());
557 EXPECT_EQ(test_data[i].expected_result, result.spec());
561 // Tests replacing input type (&oit=).
562 TEST_F(TemplateURLTest, ReplaceInputType) {
563 struct TestData {
564 const base::string16 search_term;
565 metrics::OmniboxInputType::Type input_type;
566 const std::string url;
567 const std::string expected_result;
568 } test_data[] = {
569 { ASCIIToUTF16("foo"),
570 metrics::OmniboxInputType::UNKNOWN,
571 "{google:baseURL}?{searchTerms}&{google:inputType}",
572 "http://www.google.com/?foo&oit=1&" },
573 { ASCIIToUTF16("foo"),
574 metrics::OmniboxInputType::URL,
575 "{google:baseURL}?{searchTerms}&{google:inputType}",
576 "http://www.google.com/?foo&oit=3&" },
577 { ASCIIToUTF16("foo"),
578 metrics::OmniboxInputType::FORCED_QUERY,
579 "{google:baseURL}?{searchTerms}&{google:inputType}",
580 "http://www.google.com/?foo&oit=5&" },
582 TemplateURLData data;
583 data.input_encodings.push_back("UTF-8");
584 for (size_t i = 0; i < arraysize(test_data); ++i) {
585 data.SetURL(test_data[i].url);
586 TemplateURL url(data);
587 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
588 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
589 TemplateURLRef::SearchTermsArgs search_terms_args(test_data[i].search_term);
590 search_terms_args.input_type = test_data[i].input_type;
591 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
592 search_terms_data_));
593 ASSERT_TRUE(result.is_valid());
594 EXPECT_EQ(test_data[i].expected_result, result.spec());
598 // Tests replacing currentPageUrl.
599 TEST_F(TemplateURLTest, ReplaceCurrentPageUrl) {
600 struct TestData {
601 const base::string16 search_term;
602 const std::string current_page_url;
603 const std::string url;
604 const std::string expected_result;
605 } test_data[] = {
606 { ASCIIToUTF16("foo"),
607 "http://www.google.com/",
608 "{google:baseURL}?{searchTerms}&{google:currentPageUrl}",
609 "http://www.google.com/?foo&url=http%3A%2F%2Fwww.google.com%2F&" },
610 { ASCIIToUTF16("foo"),
612 "{google:baseURL}?{searchTerms}&{google:currentPageUrl}",
613 "http://www.google.com/?foo&" },
614 { ASCIIToUTF16("foo"),
615 "http://g.com/+-/*&=",
616 "{google:baseURL}?{searchTerms}&{google:currentPageUrl}",
617 "http://www.google.com/?foo&url=http%3A%2F%2Fg.com%2F%2B-%2F*%26%3D&" },
619 TemplateURLData data;
620 data.input_encodings.push_back("UTF-8");
621 for (size_t i = 0; i < arraysize(test_data); ++i) {
622 data.SetURL(test_data[i].url);
623 TemplateURL url(data);
624 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
625 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
626 TemplateURLRef::SearchTermsArgs search_terms_args(test_data[i].search_term);
627 search_terms_args.current_page_url = test_data[i].current_page_url;
628 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
629 search_terms_data_));
630 ASSERT_TRUE(result.is_valid());
631 EXPECT_EQ(test_data[i].expected_result, result.spec());
635 TEST_F(TemplateURLTest, OmniboxStartmargin) {
636 struct TestData {
637 const bool enable_omnibox_start_margin;
638 const int omnibox_start_margin;
639 const std::string expected_result;
640 } test_data[] = {
641 { false,
643 "http://bar/foo?q=foobar" },
644 { true,
646 "http://bar/foo?es_sm=0&q=foobar" },
647 { true,
649 "http://bar/foo?es_sm=42&q=foobar" },
651 TemplateURLData data;
652 data.SetURL("http://bar/foo?{google:omniboxStartMarginParameter}"
653 "q={searchTerms}");
654 data.input_encodings.push_back("UTF-8");
655 TemplateURL url(data);
656 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
657 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
658 for (size_t i = 0; i < arraysize(test_data); ++i) {
659 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foobar"));
660 search_terms_args.enable_omnibox_start_margin =
661 test_data[i].enable_omnibox_start_margin;
662 search_terms_data_.set_omnibox_start_margin(
663 test_data[i].omnibox_start_margin);
664 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
665 search_terms_data_));
666 ASSERT_TRUE(result.is_valid());
667 EXPECT_EQ(test_data[i].expected_result, result.spec());
671 TEST_F(TemplateURLTest, Suggestions) {
672 struct TestData {
673 const int accepted_suggestion;
674 const base::string16 original_query_for_suggestion;
675 const std::string expected_result;
676 } test_data[] = {
677 { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, base::string16(),
678 "http://bar/foo?q=foobar" },
679 { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, ASCIIToUTF16("foo"),
680 "http://bar/foo?q=foobar" },
681 { TemplateURLRef::NO_SUGGESTION_CHOSEN, base::string16(),
682 "http://bar/foo?q=foobar" },
683 { TemplateURLRef::NO_SUGGESTION_CHOSEN, ASCIIToUTF16("foo"),
684 "http://bar/foo?q=foobar" },
685 { 0, base::string16(), "http://bar/foo?oq=&q=foobar" },
686 { 1, ASCIIToUTF16("foo"), "http://bar/foo?oq=foo&q=foobar" },
688 TemplateURLData data;
689 data.SetURL("http://bar/foo?{google:originalQueryForSuggestion}"
690 "q={searchTerms}");
691 data.input_encodings.push_back("UTF-8");
692 TemplateURL url(data);
693 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
694 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
695 for (size_t i = 0; i < arraysize(test_data); ++i) {
696 TemplateURLRef::SearchTermsArgs search_terms_args(
697 ASCIIToUTF16("foobar"));
698 search_terms_args.accepted_suggestion = test_data[i].accepted_suggestion;
699 search_terms_args.original_query =
700 test_data[i].original_query_for_suggestion;
701 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
702 search_terms_data_));
703 ASSERT_TRUE(result.is_valid());
704 EXPECT_EQ(test_data[i].expected_result, result.spec());
708 TEST_F(TemplateURLTest, RLZ) {
709 base::string16 rlz_string = search_terms_data_.GetRlzParameterValue(false);
711 TemplateURLData data;
712 data.SetURL("http://bar/?{google:RLZ}{searchTerms}");
713 TemplateURL url(data);
714 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
715 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
716 GURL result(url.url_ref().ReplaceSearchTerms(
717 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("x")), search_terms_data_));
718 ASSERT_TRUE(result.is_valid());
719 EXPECT_EQ("http://bar/?rlz=" + base::UTF16ToUTF8(rlz_string) + "&x",
720 result.spec());
723 TEST_F(TemplateURLTest, RLZFromAppList) {
724 base::string16 rlz_string = search_terms_data_.GetRlzParameterValue(true);
726 TemplateURLData data;
727 data.SetURL("http://bar/?{google:RLZ}{searchTerms}");
728 TemplateURL url(data);
729 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
730 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
731 TemplateURLRef::SearchTermsArgs args(ASCIIToUTF16("x"));
732 args.from_app_list = true;
733 GURL result(url.url_ref().ReplaceSearchTerms(args, search_terms_data_));
734 ASSERT_TRUE(result.is_valid());
735 EXPECT_EQ("http://bar/?rlz=" + base::UTF16ToUTF8(rlz_string) + "&x",
736 result.spec());
739 TEST_F(TemplateURLTest, HostAndSearchTermKey) {
740 struct TestData {
741 const std::string url;
742 const std::string host;
743 const std::string path;
744 const std::string search_term_key;
745 } test_data[] = {
746 { "http://blah/?foo=bar&q={searchTerms}&b=x", "blah", "/", "q"},
748 // No query key should result in empty values.
749 { "http://blah/{searchTerms}", "", "", ""},
751 // No term should result in empty values.
752 { "http://blah/", "", "", ""},
754 // Multiple terms should result in empty values.
755 { "http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""},
757 // Term in the host shouldn't match.
758 { "http://{searchTerms}", "", "", ""},
760 { "http://blah/?q={searchTerms}", "blah", "/", "q"},
761 { "https://blah/?q={searchTerms}", "blah", "/", "q"},
763 // Single term with extra chars in value should match.
764 { "http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
767 for (size_t i = 0; i < arraysize(test_data); ++i) {
768 TemplateURLData data;
769 data.SetURL(test_data[i].url);
770 TemplateURL url(data);
771 EXPECT_EQ(test_data[i].host, url.url_ref().GetHost(search_terms_data_));
772 EXPECT_EQ(test_data[i].path, url.url_ref().GetPath(search_terms_data_));
773 EXPECT_EQ(test_data[i].search_term_key,
774 url.url_ref().GetSearchTermKey(search_terms_data_));
778 TEST_F(TemplateURLTest, GoogleBaseSuggestURL) {
779 static const struct {
780 const char* const base_url;
781 const char* const base_suggest_url;
782 } data[] = {
783 { "http://google.com/", "http://google.com/complete/", },
784 { "http://www.google.com/", "http://www.google.com/complete/", },
785 { "http://www.google.co.uk/", "http://www.google.co.uk/complete/", },
786 { "http://www.google.com.by/", "http://www.google.com.by/complete/", },
787 { "http://google.com/intl/xx/", "http://google.com/complete/", },
790 for (size_t i = 0; i < arraysize(data); ++i)
791 CheckSuggestBaseURL(data[i].base_url, data[i].base_suggest_url);
794 TEST_F(TemplateURLTest, ParseParameterKnown) {
795 std::string parsed_url("{searchTerms}");
796 TemplateURLData data;
797 data.SetURL(parsed_url);
798 TemplateURL url(data);
799 TemplateURLRef::Replacements replacements;
800 EXPECT_TRUE(url.url_ref().ParseParameter(0, 12, &parsed_url, &replacements));
801 EXPECT_EQ(std::string(), parsed_url);
802 ASSERT_EQ(1U, replacements.size());
803 EXPECT_EQ(0U, replacements[0].index);
804 EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
807 TEST_F(TemplateURLTest, ParseParameterUnknown) {
808 std::string parsed_url("{fhqwhgads}abc");
809 TemplateURLData data;
810 data.SetURL(parsed_url);
811 TemplateURL url(data);
812 TemplateURLRef::Replacements replacements;
814 // By default, TemplateURLRef should not consider itself prepopulated.
815 // Therefore we should not replace the unknown parameter.
816 EXPECT_FALSE(url.url_ref().ParseParameter(0, 10, &parsed_url, &replacements));
817 EXPECT_EQ("{fhqwhgads}abc", parsed_url);
818 EXPECT_TRUE(replacements.empty());
820 // If the TemplateURLRef is prepopulated, we should remove unknown parameters.
821 parsed_url = "{fhqwhgads}abc";
822 data.prepopulate_id = 1;
823 TemplateURL url2(data);
824 EXPECT_TRUE(url2.url_ref().ParseParameter(0, 10, &parsed_url, &replacements));
825 EXPECT_EQ("abc", parsed_url);
826 EXPECT_TRUE(replacements.empty());
829 TEST_F(TemplateURLTest, ParseURLEmpty) {
830 TemplateURL url((TemplateURLData()));
831 TemplateURLRef::Replacements replacements;
832 bool valid = false;
833 EXPECT_EQ(std::string(),
834 url.url_ref().ParseURL(std::string(), &replacements, NULL, &valid));
835 EXPECT_TRUE(replacements.empty());
836 EXPECT_TRUE(valid);
839 TEST_F(TemplateURLTest, ParseURLNoTemplateEnd) {
840 TemplateURLData data;
841 data.SetURL("{");
842 TemplateURL url(data);
843 TemplateURLRef::Replacements replacements;
844 bool valid = false;
845 EXPECT_EQ(std::string(), url.url_ref().ParseURL("{", &replacements, NULL,
846 &valid));
847 EXPECT_TRUE(replacements.empty());
848 EXPECT_FALSE(valid);
851 TEST_F(TemplateURLTest, ParseURLNoKnownParameters) {
852 TemplateURLData data;
853 data.SetURL("{}");
854 TemplateURL url(data);
855 TemplateURLRef::Replacements replacements;
856 bool valid = false;
857 EXPECT_EQ("{}", url.url_ref().ParseURL("{}", &replacements, NULL, &valid));
858 EXPECT_TRUE(replacements.empty());
859 EXPECT_TRUE(valid);
862 TEST_F(TemplateURLTest, ParseURLTwoParameters) {
863 TemplateURLData data;
864 data.SetURL("{}{{%s}}");
865 TemplateURL url(data);
866 TemplateURLRef::Replacements replacements;
867 bool valid = false;
868 EXPECT_EQ("{}{}",
869 url.url_ref().ParseURL("{}{{searchTerms}}", &replacements, NULL,
870 &valid));
871 ASSERT_EQ(1U, replacements.size());
872 EXPECT_EQ(3U, replacements[0].index);
873 EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
874 EXPECT_TRUE(valid);
877 TEST_F(TemplateURLTest, ParseURLNestedParameter) {
878 TemplateURLData data;
879 data.SetURL("{%s");
880 TemplateURL url(data);
881 TemplateURLRef::Replacements replacements;
882 bool valid = false;
883 EXPECT_EQ("{",
884 url.url_ref().ParseURL("{{searchTerms}", &replacements, NULL,
885 &valid));
886 ASSERT_EQ(1U, replacements.size());
887 EXPECT_EQ(1U, replacements[0].index);
888 EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
889 EXPECT_TRUE(valid);
892 TEST_F(TemplateURLTest, SearchClient) {
893 const std::string base_url_str("http://google.com/?");
894 const std::string terms_str("{searchTerms}&{google:searchClient}");
895 const std::string full_url_str = base_url_str + terms_str;
896 const base::string16 terms(ASCIIToUTF16(terms_str));
897 search_terms_data_.set_google_base_url(base_url_str);
899 TemplateURLData data;
900 data.SetURL(full_url_str);
901 TemplateURL url(data);
902 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
903 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
904 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foobar"));
906 // Check that the URL is correct when a client is not present.
907 GURL result(url.url_ref().ReplaceSearchTerms(search_terms_args,
908 search_terms_data_));
909 ASSERT_TRUE(result.is_valid());
910 EXPECT_EQ("http://google.com/?foobar&", result.spec());
912 // Check that the URL is correct when a client is present.
913 search_terms_data_.set_search_client("search_client");
914 GURL result_2(url.url_ref().ReplaceSearchTerms(search_terms_args,
915 search_terms_data_));
916 ASSERT_TRUE(result_2.is_valid());
917 EXPECT_EQ("http://google.com/?foobar&client=search_client&", result_2.spec());
920 TEST_F(TemplateURLTest, GetURLNoInstantURL) {
921 TemplateURLData data;
922 data.SetURL("http://google.com/?q={searchTerms}");
923 data.suggestions_url = "http://google.com/suggest?q={searchTerms}";
924 data.alternate_urls.push_back("http://google.com/alt?q={searchTerms}");
925 data.alternate_urls.push_back("{google:baseURL}/alt/#q={searchTerms}");
926 TemplateURL url(data);
927 ASSERT_EQ(3U, url.URLCount());
928 EXPECT_EQ("http://google.com/alt?q={searchTerms}", url.GetURL(0));
929 EXPECT_EQ("{google:baseURL}/alt/#q={searchTerms}", url.GetURL(1));
930 EXPECT_EQ("http://google.com/?q={searchTerms}", url.GetURL(2));
933 TEST_F(TemplateURLTest, GetURLNoSuggestionsURL) {
934 TemplateURLData data;
935 data.SetURL("http://google.com/?q={searchTerms}");
936 data.instant_url = "http://google.com/instant#q={searchTerms}";
937 data.alternate_urls.push_back("http://google.com/alt?q={searchTerms}");
938 data.alternate_urls.push_back("{google:baseURL}/alt/#q={searchTerms}");
939 TemplateURL url(data);
940 ASSERT_EQ(3U, url.URLCount());
941 EXPECT_EQ("http://google.com/alt?q={searchTerms}", url.GetURL(0));
942 EXPECT_EQ("{google:baseURL}/alt/#q={searchTerms}", url.GetURL(1));
943 EXPECT_EQ("http://google.com/?q={searchTerms}", url.GetURL(2));
946 TEST_F(TemplateURLTest, GetURLOnlyOneURL) {
947 TemplateURLData data;
948 data.SetURL("http://www.google.co.uk/");
949 TemplateURL url(data);
950 ASSERT_EQ(1U, url.URLCount());
951 EXPECT_EQ("http://www.google.co.uk/", url.GetURL(0));
954 TEST_F(TemplateURLTest, ExtractSearchTermsFromURL) {
955 TemplateURLData data;
956 data.SetURL("http://google.com/?q={searchTerms}");
957 data.instant_url = "http://google.com/instant#q={searchTerms}";
958 data.alternate_urls.push_back("http://google.com/alt/#q={searchTerms}");
959 data.alternate_urls.push_back(
960 "http://google.com/alt/?ext=foo&q={searchTerms}#ref=bar");
961 TemplateURL url(data);
962 base::string16 result;
964 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
965 GURL("http://google.com/?q=something"), search_terms_data_, &result));
966 EXPECT_EQ(ASCIIToUTF16("something"), result);
968 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
969 GURL("http://google.com/?espv&q=something"),
970 search_terms_data_, &result));
971 EXPECT_EQ(ASCIIToUTF16("something"), result);
973 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
974 GURL("http://google.com/?espv=1&q=something"),
975 search_terms_data_, &result));
976 EXPECT_EQ(ASCIIToUTF16("something"), result);
978 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
979 GURL("http://google.com/?espv=0&q=something"),
980 search_terms_data_, &result));
981 EXPECT_EQ(ASCIIToUTF16("something"), result);
983 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
984 GURL("http://google.com/alt/#q=something"),
985 search_terms_data_, &result));
986 EXPECT_EQ(ASCIIToUTF16("something"), result);
988 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
989 GURL("http://google.com/alt/#espv&q=something"),
990 search_terms_data_, &result));
991 EXPECT_EQ(ASCIIToUTF16("something"), result);
993 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
994 GURL("http://google.com/alt/#espv=1&q=something"),
995 search_terms_data_, &result));
996 EXPECT_EQ(ASCIIToUTF16("something"), result);
998 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
999 GURL("http://google.com/alt/#espv=0&q=something"),
1000 search_terms_data_, &result));
1001 EXPECT_EQ(ASCIIToUTF16("something"), result);
1003 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1004 GURL("http://google.ca/?q=something"), search_terms_data_, &result));
1005 EXPECT_EQ(base::string16(), result);
1007 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1008 GURL("http://google.ca/?q=something&q=anything"),
1009 search_terms_data_, &result));
1010 EXPECT_EQ(base::string16(), result);
1012 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1013 GURL("http://google.com/foo/?q=foo"), search_terms_data_, &result));
1014 EXPECT_EQ(base::string16(), result);
1016 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
1017 GURL("https://google.com/?q=foo"), search_terms_data_, &result));
1018 EXPECT_EQ(ASCIIToUTF16("foo"), result);
1020 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1021 GURL("http://google.com:8080/?q=foo"), search_terms_data_, &result));
1022 EXPECT_EQ(base::string16(), result);
1024 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
1025 GURL("http://google.com/?q=1+2+3&b=456"), search_terms_data_, &result));
1026 EXPECT_EQ(ASCIIToUTF16("1 2 3"), result);
1028 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
1029 GURL("http://google.com/alt/?q=123#q=456"),
1030 search_terms_data_, &result));
1031 EXPECT_EQ(ASCIIToUTF16("456"), result);
1033 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
1034 GURL("http://google.com/alt/?a=012&q=123&b=456#f=789"),
1035 search_terms_data_, &result));
1036 EXPECT_EQ(ASCIIToUTF16("123"), result);
1038 EXPECT_TRUE(url.ExtractSearchTermsFromURL(GURL(
1039 "http://google.com/alt/?a=012&q=123&b=456#j=abc&q=789&h=def9"),
1040 search_terms_data_, &result));
1041 EXPECT_EQ(ASCIIToUTF16("789"), result);
1043 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1044 GURL("http://google.com/alt/?q="), search_terms_data_, &result));
1045 EXPECT_EQ(base::string16(), result);
1047 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1048 GURL("http://google.com/alt/?#q="), search_terms_data_, &result));
1049 EXPECT_EQ(base::string16(), result);
1051 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1052 GURL("http://google.com/alt/?q=#q="), search_terms_data_, &result));
1053 EXPECT_EQ(base::string16(), result);
1055 EXPECT_FALSE(url.ExtractSearchTermsFromURL(
1056 GURL("http://google.com/alt/?q=123#q="), search_terms_data_, &result));
1057 EXPECT_EQ(base::string16(), result);
1059 EXPECT_TRUE(url.ExtractSearchTermsFromURL(
1060 GURL("http://google.com/alt/?q=#q=123"), search_terms_data_, &result));
1061 EXPECT_EQ(ASCIIToUTF16("123"), result);
1064 TEST_F(TemplateURLTest, HasSearchTermsReplacementKey) {
1065 TemplateURLData data;
1066 data.SetURL("http://google.com/?q={searchTerms}");
1067 data.instant_url = "http://google.com/instant#q={searchTerms}";
1068 data.alternate_urls.push_back("http://google.com/alt/#q={searchTerms}");
1069 data.alternate_urls.push_back(
1070 "http://google.com/alt/?ext=foo&q={searchTerms}#ref=bar");
1071 data.search_terms_replacement_key = "espv";
1072 TemplateURL url(data);
1074 // Test with instant enabled required.
1075 EXPECT_FALSE(url.HasSearchTermsReplacementKey(
1076 GURL("http://google.com/")));
1078 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1079 GURL("http://google.com/?espv")));
1081 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1082 GURL("http://google.com/#espv")));
1084 EXPECT_FALSE(url.HasSearchTermsReplacementKey(
1085 GURL("http://google.com/?q=something")));
1087 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1088 GURL("http://google.com/?q=something&espv")));
1090 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1091 GURL("http://google.com/?q=something&espv=1")));
1093 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1094 GURL("http://google.com/?q=something&espv=0")));
1096 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1097 GURL("http://google.com/?espv&q=something")));
1099 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1100 GURL("http://google.com/?espv=1&q=something")));
1102 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1103 GURL("http://google.com/?espv=0&q=something")));
1105 EXPECT_FALSE(url.HasSearchTermsReplacementKey(
1106 GURL("http://google.com/alt/#q=something")));
1108 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1109 GURL("http://google.com/alt/#q=something&espv")));
1111 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1112 GURL("http://google.com/alt/#q=something&espv=1")));
1114 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1115 GURL("http://google.com/alt/#q=something&espv=0")));
1117 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1118 GURL("http://google.com/alt/#espv&q=something")));
1120 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1121 GURL("http://google.com/alt/#espv=1&q=something")));
1123 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1124 GURL("http://google.com/alt/#espv=0&q=something")));
1126 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1127 GURL("http://google.com/?espv#q=something")));
1129 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1130 GURL("http://google.com/?espv=1#q=something")));
1132 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1133 GURL("http://google.com/?q=something#espv")));
1135 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1136 GURL("http://google.com/?q=something#espv=1")));
1138 // This does not ensure the domain matches.
1139 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1140 GURL("http://bing.com/?espv")));
1142 EXPECT_TRUE(url.HasSearchTermsReplacementKey(
1143 GURL("http://bing.com/#espv")));
1146 TEST_F(TemplateURLTest, ReplaceSearchTermsInURL) {
1147 TemplateURLData data;
1148 data.SetURL("http://google.com/?q={searchTerms}");
1149 data.instant_url = "http://google.com/instant#q={searchTerms}";
1150 data.alternate_urls.push_back("http://google.com/alt/#q={searchTerms}");
1151 data.alternate_urls.push_back(
1152 "http://google.com/alt/?ext=foo&q={searchTerms}#ref=bar");
1153 TemplateURL url(data);
1154 TemplateURLRef::SearchTermsArgs search_terms(ASCIIToUTF16("Bob Morane"));
1155 GURL result;
1157 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1158 GURL("http://google.com/?q=something"), search_terms,
1159 search_terms_data_, &result));
1160 EXPECT_EQ(GURL("http://google.com/?q=Bob%20Morane"), result);
1162 result = GURL("http://should.not.change.com");
1163 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1164 GURL("http://google.ca/?q=something"), search_terms,
1165 search_terms_data_, &result));
1166 EXPECT_EQ(GURL("http://should.not.change.com"), result);
1168 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1169 GURL("http://google.com/foo/?q=foo"), search_terms,
1170 search_terms_data_, &result));
1172 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1173 GURL("https://google.com/?q=foo"), search_terms,
1174 search_terms_data_, &result));
1175 EXPECT_EQ(GURL("https://google.com/?q=Bob%20Morane"), result);
1177 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1178 GURL("http://google.com:8080/?q=foo"), search_terms,
1179 search_terms_data_, &result));
1181 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1182 GURL("http://google.com/?q=1+2+3&b=456"), search_terms,
1183 search_terms_data_, &result));
1184 EXPECT_EQ(GURL("http://google.com/?q=Bob%20Morane&b=456"), result);
1186 // Note: Spaces in REF parameters are not escaped. See TryEncoding() in
1187 // template_url.cc for details.
1188 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1189 GURL("http://google.com/alt/?q=123#q=456"), search_terms,
1190 search_terms_data_, &result));
1191 EXPECT_EQ(GURL("http://google.com/alt/?q=123#q=Bob Morane"), result);
1193 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1194 GURL("http://google.com/alt/?a=012&q=123&b=456#f=789"), search_terms,
1195 search_terms_data_, &result));
1196 EXPECT_EQ(GURL("http://google.com/alt/?a=012&q=Bob%20Morane&b=456#f=789"),
1197 result);
1199 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1200 GURL("http://google.com/alt/?a=012&q=123&b=456#j=abc&q=789&h=def9"),
1201 search_terms, search_terms_data_, &result));
1202 EXPECT_EQ(GURL("http://google.com/alt/?a=012&q=123&b=456"
1203 "#j=abc&q=Bob Morane&h=def9"), result);
1205 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1206 GURL("http://google.com/alt/?q="), search_terms,
1207 search_terms_data_, &result));
1209 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1210 GURL("http://google.com/alt/?#q="), search_terms,
1211 search_terms_data_, &result));
1213 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1214 GURL("http://google.com/alt/?q=#q="), search_terms,
1215 search_terms_data_, &result));
1217 EXPECT_FALSE(url.ReplaceSearchTermsInURL(
1218 GURL("http://google.com/alt/?q=123#q="), search_terms,
1219 search_terms_data_, &result));
1221 EXPECT_TRUE(url.ReplaceSearchTermsInURL(
1222 GURL("http://google.com/alt/?q=#q=123"), search_terms,
1223 search_terms_data_, &result));
1224 EXPECT_EQ(GURL("http://google.com/alt/?q=#q=Bob Morane"), result);
1227 // Test the |suggest_query_params| field of SearchTermsArgs.
1228 TEST_F(TemplateURLTest, SuggestQueryParams) {
1229 TemplateURLData data;
1230 // Pick a URL with replacements before, during, and after the query, to ensure
1231 // we don't goof up any of them.
1232 data.SetURL("{google:baseURL}search?q={searchTerms}"
1233 "#{google:originalQueryForSuggestion}x");
1234 TemplateURL url(data);
1236 // Baseline: no |suggest_query_params| field.
1237 TemplateURLRef::SearchTermsArgs search_terms(ASCIIToUTF16("abc"));
1238 search_terms.original_query = ASCIIToUTF16("def");
1239 search_terms.accepted_suggestion = 0;
1240 EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x",
1241 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1243 // Set the suggest_query_params.
1244 search_terms.suggest_query_params = "pq=xyz";
1245 EXPECT_EQ("http://www.google.com/search?pq=xyz&q=abc#oq=def&x",
1246 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1248 // Add extra_query_params in the mix, and ensure it works.
1249 search_terms.append_extra_query_params = true;
1250 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1251 switches::kExtraSearchQueryParams, "a=b");
1252 EXPECT_EQ("http://www.google.com/search?a=b&pq=xyz&q=abc#oq=def&x",
1253 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1256 // Test the |append_extra_query_params| field of SearchTermsArgs.
1257 TEST_F(TemplateURLTest, ExtraQueryParams) {
1258 TemplateURLData data;
1259 // Pick a URL with replacements before, during, and after the query, to ensure
1260 // we don't goof up any of them.
1261 data.SetURL("{google:baseURL}search?q={searchTerms}"
1262 "#{google:originalQueryForSuggestion}x");
1263 TemplateURL url(data);
1265 // Baseline: no command-line args, no |append_extra_query_params| flag.
1266 TemplateURLRef::SearchTermsArgs search_terms(ASCIIToUTF16("abc"));
1267 search_terms.original_query = ASCIIToUTF16("def");
1268 search_terms.accepted_suggestion = 0;
1269 EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x",
1270 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1272 // Set the flag. Since there are no command-line args, this should have no
1273 // effect.
1274 search_terms.append_extra_query_params = true;
1275 EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x",
1276 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1278 // Now append the command-line arg. This should be inserted into the query.
1279 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1280 switches::kExtraSearchQueryParams, "a=b");
1281 EXPECT_EQ("http://www.google.com/search?a=b&q=abc#oq=def&x",
1282 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1284 // Turn off the flag. Now the command-line arg should be ignored again.
1285 search_terms.append_extra_query_params = false;
1286 EXPECT_EQ("http://www.google.com/search?q=abc#oq=def&x",
1287 url.url_ref().ReplaceSearchTerms(search_terms, search_terms_data_));
1290 // Tests replacing pageClassification.
1291 TEST_F(TemplateURLTest, ReplacePageClassification) {
1292 TemplateURLData data;
1293 data.input_encodings.push_back("UTF-8");
1294 data.SetURL("{google:baseURL}?{google:pageClassification}q={searchTerms}");
1295 TemplateURL url(data);
1296 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
1297 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
1298 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1300 std::string result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1301 search_terms_data_);
1302 EXPECT_EQ("http://www.google.com/?q=foo", result);
1304 search_terms_args.page_classification = metrics::OmniboxEventProto::NTP;
1305 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1306 search_terms_data_);
1307 EXPECT_EQ("http://www.google.com/?pgcl=1&q=foo", result);
1309 search_terms_args.page_classification =
1310 metrics::OmniboxEventProto::HOME_PAGE;
1311 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1312 search_terms_data_);
1313 EXPECT_EQ("http://www.google.com/?pgcl=3&q=foo", result);
1316 // Test the IsSearchResults function.
1317 TEST_F(TemplateURLTest, IsSearchResults) {
1318 TemplateURLData data;
1319 data.SetURL("http://bar/search?q={searchTerms}");
1320 data.instant_url = "http://bar/instant#q={searchTerms}";
1321 data.new_tab_url = "http://bar/newtab";
1322 data.alternate_urls.push_back("http://bar/?q={searchTerms}");
1323 data.alternate_urls.push_back("http://bar/#q={searchTerms}");
1324 data.alternate_urls.push_back("http://bar/search#q{searchTerms}");
1325 data.alternate_urls.push_back("http://bar/webhp#q={searchTerms}");
1326 TemplateURL search_provider(data);
1328 const struct {
1329 const char* const url;
1330 bool result;
1331 } url_data[] = {
1332 { "http://bar/search?q=foo&oq=foo", true, },
1333 { "http://bar/?q=foo&oq=foo", true, },
1334 { "http://bar/#output=search&q=foo&oq=foo", true, },
1335 { "http://bar/webhp#q=foo&oq=foo", true, },
1336 { "http://bar/#q=foo&oq=foo", true, },
1337 { "http://bar/?ext=foo&q=foo#ref=bar", true, },
1338 { "http://bar/url?url=http://www.foo.com/&q=foo#ref=bar", false, },
1339 { "http://bar/", false, },
1340 { "http://foo/", false, },
1341 { "http://bar/newtab", false, },
1344 for (size_t i = 0; i < arraysize(url_data); ++i) {
1345 EXPECT_EQ(url_data[i].result,
1346 search_provider.IsSearchURL(GURL(url_data[i].url),
1347 search_terms_data_));
1351 TEST_F(TemplateURLTest, ReflectsBookmarkBarPinned) {
1352 TemplateURLData data;
1353 data.input_encodings.push_back("UTF-8");
1354 data.SetURL("{google:baseURL}?{google:bookmarkBarPinned}q={searchTerms}");
1355 TemplateURL url(data);
1356 EXPECT_TRUE(url.url_ref().IsValid(search_terms_data_));
1357 ASSERT_TRUE(url.url_ref().SupportsReplacement(search_terms_data_));
1358 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1360 // Do not add the param when InstantExtended is suppressed on SRPs.
1361 search_terms_data_.set_is_showing_search_terms_on_search_results_pages(false);
1362 std::string result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1363 search_terms_data_);
1364 EXPECT_EQ("http://www.google.com/?q=foo", result);
1366 // Add the param when InstantExtended is not suppressed on SRPs.
1367 search_terms_data_.set_is_showing_search_terms_on_search_results_pages(true);
1368 search_terms_args.bookmark_bar_pinned = false;
1369 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1370 search_terms_data_);
1371 EXPECT_EQ("http://www.google.com/?bmbp=0&q=foo", result);
1373 search_terms_data_.set_is_showing_search_terms_on_search_results_pages(true);
1374 search_terms_args.bookmark_bar_pinned = true;
1375 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1376 search_terms_data_);
1377 EXPECT_EQ("http://www.google.com/?bmbp=1&q=foo", result);
1380 TEST_F(TemplateURLTest, AnswersHasVersion) {
1381 TemplateURLData data;
1382 search_terms_data_.set_google_base_url("http://bar/");
1383 data.SetURL("http://bar/search?q={searchTerms}&{google:searchVersion}xssi=t");
1385 TemplateURL url(data);
1386 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1387 std::string result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1388 search_terms_data_);
1389 EXPECT_EQ("http://bar/search?q=foo&xssi=t", result);
1391 search_terms_data_.set_enable_answers_in_suggest(true);
1392 TemplateURL url2(data);
1393 result = url2.url_ref().ReplaceSearchTerms(search_terms_args,
1394 search_terms_data_);
1395 EXPECT_EQ("http://bar/search?q=foo&gs_rn=42&xssi=t", result);
1398 TEST_F(TemplateURLTest, SessionToken) {
1399 TemplateURLData data;
1400 search_terms_data_.set_google_base_url("http://bar/");
1401 data.SetURL("http://bar/search?q={searchTerms}&{google:sessionToken}xssi=t");
1403 TemplateURL url(data);
1404 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1405 search_terms_args.session_token = "SESSIONTOKENGOESHERE";
1406 std::string result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1407 search_terms_data_);
1408 EXPECT_EQ("http://bar/search?q=foo&psi=SESSIONTOKENGOESHERE&xssi=t", result);
1410 TemplateURL url2(data);
1411 search_terms_args.session_token = "";
1412 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1413 search_terms_data_);
1414 EXPECT_EQ("http://bar/search?q=foo&xssi=t", result);
1417 TEST_F(TemplateURLTest, ContextualSearchParameters) {
1418 TemplateURLData data;
1419 search_terms_data_.set_google_base_url("http://bar/");
1420 data.SetURL("http://bar/_/contextualsearch?"
1421 "{google:contextualSearchVersion}"
1422 "{google:contextualSearchContextData}");
1424 TemplateURL url(data);
1425 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1426 std::string result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1427 search_terms_data_);
1428 EXPECT_EQ("http://bar/_/contextualsearch?ctxsl_resolve=1", result);
1430 TemplateURLRef::SearchTermsArgs::ContextualSearchParams params(
1431 1, 6, 11, "allen", "woody+allen+movies", "www.wikipedia.org",
1432 "utf-8", true);
1433 search_terms_args.contextual_search_params = params;
1434 result = url.url_ref().ReplaceSearchTerms(search_terms_args,
1435 search_terms_data_);
1436 EXPECT_EQ("http://bar/_/contextualsearch?"
1437 "ctxs=1&"
1438 "ctxs_start=6&"
1439 "ctxs_end=11&"
1440 "q=allen&"
1441 "ctxs_content=woody+allen+movies&"
1442 "ctxsl_url=www.wikipedia.org&"
1443 "ctxs_encoding=utf-8&"
1444 "ctxsl_resolve=1",
1445 result);
1448 TEST_F(TemplateURLTest, GenerateKeyword) {
1449 ASSERT_EQ(ASCIIToUTF16("foo"),
1450 TemplateURL::GenerateKeyword(GURL("http://foo")));
1451 // www. should be stripped.
1452 ASSERT_EQ(ASCIIToUTF16("foo"),
1453 TemplateURL::GenerateKeyword(GURL("http://www.foo")));
1454 // Make sure we don't get a trailing '/'.
1455 ASSERT_EQ(ASCIIToUTF16("blah"),
1456 TemplateURL::GenerateKeyword(GURL("http://blah/")));
1457 // Don't generate the empty string.
1458 ASSERT_EQ(ASCIIToUTF16("www"),
1459 TemplateURL::GenerateKeyword(GURL("http://www.")));
1462 TEST_F(TemplateURLTest, GenerateSearchURL) {
1463 struct GenerateSearchURLCase {
1464 const char* test_name;
1465 const char* url;
1466 const char* expected;
1467 } generate_url_cases[] = {
1468 { "invalid URL", "foo{searchTerms}", "" },
1469 { "URL with no replacements", "http://foo/", "http://foo/" },
1470 { "basic functionality", "http://foo/{searchTerms}",
1471 "http://foo/blah.blah.blah.blah.blah" }
1474 for (size_t i = 0; i < arraysize(generate_url_cases); ++i) {
1475 TemplateURLData data;
1476 data.SetURL(generate_url_cases[i].url);
1477 TemplateURL t_url(data);
1478 EXPECT_EQ(t_url.GenerateSearchURL(search_terms_data_).spec(),
1479 generate_url_cases[i].expected)
1480 << generate_url_cases[i].test_name << " failed.";
1484 TEST_F(TemplateURLTest, PrefetchQueryParameters) {
1485 TemplateURLData data;
1486 search_terms_data_.set_google_base_url("http://bar/");
1487 data.SetURL("http://bar/search?q={searchTerms}&{google:prefetchQuery}xssi=t");
1489 TemplateURL url(data);
1490 TemplateURLRef::SearchTermsArgs search_terms_args(ASCIIToUTF16("foo"));
1491 search_terms_args.prefetch_query = "full query text";
1492 search_terms_args.prefetch_query_type = "2338";
1493 std::string result =
1494 url.url_ref().ReplaceSearchTerms(search_terms_args, search_terms_data_);
1495 EXPECT_EQ("http://bar/search?q=foo&pfq=full%20query%20text&qha=2338&xssi=t",
1496 result);
1498 TemplateURL url2(data);
1499 search_terms_args.prefetch_query.clear();
1500 search_terms_args.prefetch_query_type.clear();
1501 result =
1502 url2.url_ref().ReplaceSearchTerms(search_terms_args, search_terms_data_);
1503 EXPECT_EQ("http://bar/search?q=foo&xssi=t", result);