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 "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" 17 18 using base::ASCIIToUTF16; 19 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; 25 26 TestingSearchTermsData search_terms_data_; 27 }; 28 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()); 34 } 35 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); 41 } 42 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_)); 48 } 49 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" } 64 }; 65 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 76 } 77 } 78 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()); 89 } 90 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()); 101 } 102 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()); 113 } 114 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()); 125 } 126 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()); 137 } 138 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"; 150 151 TemplateURLData data; 152 data.image_url = KImageSearchURL; 153 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); 165 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_)); 171 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()); 191 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. 229 } 230 break; 231 } 232 } 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); 242 } 243 } 244 } 245 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); 258 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); 266 } 267 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()); 278 } 279 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()); 290 } 291 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/" } 302 }; 303 304 TestingSearchTermsData search_terms_data("http://example.com/e/"); 305 TemplateURLData data; 306 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 316 } 317 } 318 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")}, 338 }; 339 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_UNSAFE(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)); 351 } 352 } 353 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}") }, 367 }; 368 TemplateURLData data; 369 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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_))); 377 } 378 } 379 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" }, 409 }; 410 TemplateURLData data; 411 data.input_encodings.push_back("UTF-8"); 412 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 425 } 426 } 427 428 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"}, 450 }; 451 TemplateURLData data; 452 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 464 } 465 } 466 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"), 490 "", 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&" }, 506 }; 507 TemplateURLData data; 508 data.input_encodings.push_back("UTF-8"); 509 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 521 } 522 } 523 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"), 537 2, 538 "{google:baseURL}?{searchTerms}&{google:cursorPosition}", 539 "http://www.google.com/?foo&cp=2&" }, 540 { ASCIIToUTF16("foo"), 541 15, 542 "{google:baseURL}?{searchTerms}&{google:cursorPosition}", 543 "http://www.google.com/?foo&cp=15&" }, 544 }; 545 TemplateURLData data; 546 data.input_encodings.push_back("UTF-8"); 547 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 558 } 559 } 560 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&" }, 581 }; 582 TemplateURLData data; 583 data.input_encodings.push_back("UTF-8"); 584 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 595 } 596 } 597 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"), 611 "", 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&" }, 618 }; 619 TemplateURLData data; 620 data.input_encodings.push_back("UTF-8"); 621 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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()); 632 } 633 } 634 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, 642 0, 643 "http://bar/foo?q=foobar" }, 644 { true, 645 0, 646 "http://bar/foo?es_sm=0&q=foobar" }, 647 { true, 648 42, 649 "http://bar/foo?es_sm=42&q=foobar" }, 650 }; 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_UNSAFE(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()); 668 } 669 } 670 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" }, 687 }; 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_UNSAFE(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()); 705 } 706 } 707 708 TEST_F(TemplateURLTest, RLZ) { 709 base::string16 rlz_string = search_terms_data_.GetRlzParameterValue(false); 710 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()); 721 } 722 723 TEST_F(TemplateURLTest, RLZFromAppList) { 724 base::string16 rlz_string = search_terms_data_.GetRlzParameterValue(true); 725 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()); 737 } 738 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"}, 747 748 // No query key should result in empty values. 749 { "http://blah/{searchTerms}", "", "", ""}, 750 751 // No term should result in empty values. 752 { "http://blah/", "", "", ""}, 753 754 // Multiple terms should result in empty values. 755 { "http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""}, 756 757 // Term in the host shouldn't match. 758 { "http://{searchTerms}", "", "", ""}, 759 760 { "http://blah/?q={searchTerms}", "blah", "/", "q"}, 761 { "https://blah/?q={searchTerms}", "blah", "/", "q"}, 762 763 // Single term with extra chars in value should match. 764 { "http://blah/?q=stock:{searchTerms}", "blah", "/", "q"}, 765 }; 766 767 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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_)); 775 } 776 } 777 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/", }, 788 }; 789 790 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) 791 CheckSuggestBaseURL(data[i].base_url, data[i].base_suggest_url); 792 } 793 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); 805 } 806 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; 813 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()); 819 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()); 827 } 828 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); 837 } 838 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); 849 } 850 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); 860 } 861 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); 875 } 876 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); 890 } 891 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); 898 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")); 905 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()); 911 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()); 918 } 919 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)); 931 } 932 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)); 944 } 945 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)); 952 } 953 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; 963 964 EXPECT_TRUE(url.ExtractSearchTermsFromURL( 965 GURL("http://google.com/?q=something"), search_terms_data_, &result)); 966 EXPECT_EQ(ASCIIToUTF16("something"), result); 967 968 EXPECT_TRUE(url.ExtractSearchTermsFromURL( 969 GURL("http://google.com/?espv&q=something"), 970 search_terms_data_, &result)); 971 EXPECT_EQ(ASCIIToUTF16("something"), result); 972 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); 977 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); 982 983 EXPECT_TRUE(url.ExtractSearchTermsFromURL( 984 GURL("http://google.com/alt/#q=something"), 985 search_terms_data_, &result)); 986 EXPECT_EQ(ASCIIToUTF16("something"), result); 987 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); 992 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); 997 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); 1002 1003 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1004 GURL("http://google.ca/?q=something"), search_terms_data_, &result)); 1005 EXPECT_EQ(base::string16(), result); 1006 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); 1011 1012 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1013 GURL("http://google.com/foo/?q=foo"), search_terms_data_, &result)); 1014 EXPECT_EQ(base::string16(), result); 1015 1016 EXPECT_TRUE(url.ExtractSearchTermsFromURL( 1017 GURL("https://google.com/?q=foo"), search_terms_data_, &result)); 1018 EXPECT_EQ(ASCIIToUTF16("foo"), result); 1019 1020 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1021 GURL("http://google.com:8080/?q=foo"), search_terms_data_, &result)); 1022 EXPECT_EQ(base::string16(), result); 1023 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); 1027 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); 1032 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); 1037 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); 1042 1043 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1044 GURL("http://google.com/alt/?q="), search_terms_data_, &result)); 1045 EXPECT_EQ(base::string16(), result); 1046 1047 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1048 GURL("http://google.com/alt/?#q="), search_terms_data_, &result)); 1049 EXPECT_EQ(base::string16(), result); 1050 1051 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1052 GURL("http://google.com/alt/?q=#q="), search_terms_data_, &result)); 1053 EXPECT_EQ(base::string16(), result); 1054 1055 EXPECT_FALSE(url.ExtractSearchTermsFromURL( 1056 GURL("http://google.com/alt/?q=123#q="), search_terms_data_, &result)); 1057 EXPECT_EQ(base::string16(), result); 1058 1059 EXPECT_TRUE(url.ExtractSearchTermsFromURL( 1060 GURL("http://google.com/alt/?q=#q=123"), search_terms_data_, &result)); 1061 EXPECT_EQ(ASCIIToUTF16("123"), result); 1062 } 1063 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); 1073 1074 // Test with instant enabled required. 1075 EXPECT_FALSE(url.HasSearchTermsReplacementKey( 1076 GURL("http://google.com/"))); 1077 1078 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1079 GURL("http://google.com/?espv"))); 1080 1081 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1082 GURL("http://google.com/#espv"))); 1083 1084 EXPECT_FALSE(url.HasSearchTermsReplacementKey( 1085 GURL("http://google.com/?q=something"))); 1086 1087 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1088 GURL("http://google.com/?q=something&espv"))); 1089 1090 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1091 GURL("http://google.com/?q=something&espv=1"))); 1092 1093 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1094 GURL("http://google.com/?q=something&espv=0"))); 1095 1096 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1097 GURL("http://google.com/?espv&q=something"))); 1098 1099 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1100 GURL("http://google.com/?espv=1&q=something"))); 1101 1102 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1103 GURL("http://google.com/?espv=0&q=something"))); 1104 1105 EXPECT_FALSE(url.HasSearchTermsReplacementKey( 1106 GURL("http://google.com/alt/#q=something"))); 1107 1108 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1109 GURL("http://google.com/alt/#q=something&espv"))); 1110 1111 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1112 GURL("http://google.com/alt/#q=something&espv=1"))); 1113 1114 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1115 GURL("http://google.com/alt/#q=something&espv=0"))); 1116 1117 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1118 GURL("http://google.com/alt/#espv&q=something"))); 1119 1120 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1121 GURL("http://google.com/alt/#espv=1&q=something"))); 1122 1123 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1124 GURL("http://google.com/alt/#espv=0&q=something"))); 1125 1126 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1127 GURL("http://google.com/?espv#q=something"))); 1128 1129 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1130 GURL("http://google.com/?espv=1#q=something"))); 1131 1132 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1133 GURL("http://google.com/?q=something#espv"))); 1134 1135 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1136 GURL("http://google.com/?q=something#espv=1"))); 1137 1138 // This does not ensure the domain matches. 1139 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1140 GURL("http://bing.com/?espv"))); 1141 1142 EXPECT_TRUE(url.HasSearchTermsReplacementKey( 1143 GURL("http://bing.com/#espv"))); 1144 } 1145 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; 1156 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); 1161 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); 1167 1168 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1169 GURL("http://google.com/foo/?q=foo"), search_terms, 1170 search_terms_data_, &result)); 1171 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); 1176 1177 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1178 GURL("http://google.com:8080/?q=foo"), search_terms, 1179 search_terms_data_, &result)); 1180 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); 1185 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); 1192 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); 1198 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); 1204 1205 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1206 GURL("http://google.com/alt/?q="), search_terms, 1207 search_terms_data_, &result)); 1208 1209 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1210 GURL("http://google.com/alt/?#q="), search_terms, 1211 search_terms_data_, &result)); 1212 1213 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1214 GURL("http://google.com/alt/?q=#q="), search_terms, 1215 search_terms_data_, &result)); 1216 1217 EXPECT_FALSE(url.ReplaceSearchTermsInURL( 1218 GURL("http://google.com/alt/?q=123#q="), search_terms, 1219 search_terms_data_, &result)); 1220 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); 1225 } 1226 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); 1235 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_)); 1242 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_)); 1247 1248 // Add extra_query_params in the mix, and ensure it works. 1249 search_terms.append_extra_query_params = true; 1250 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_)); 1254 } 1255 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); 1264 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_)); 1271 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_)); 1277 1278 // Now append the command-line arg. This should be inserted into the query. 1279 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_)); 1283 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_)); 1288 } 1289 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")); 1299 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); 1303 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); 1308 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); 1314 } 1315 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); 1327 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, }, 1342 }; 1343 1344 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(url_data); ++i) { 1345 EXPECT_EQ(url_data[i].result, 1346 search_provider.IsSearchURL(GURL(url_data[i].url), 1347 search_terms_data_)); 1348 } 1349 } 1350 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")); 1359 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); 1365 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); 1372 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); 1378 } 1379 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"); 1384 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); 1390 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); 1396 } 1397 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"); 1402 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); 1409 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); 1415 } 1416 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}"); 1423 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); 1429 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); 1446 } 1447 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."))); 1460 } 1461 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" } 1472 }; 1473 1474 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(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."; 1481 } 1482 } 1483 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"); 1488 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); 1497 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); 1504 } 1505