Home | History | Annotate | Download | only in search_engines
      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