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