Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / components / search_engines / template_url_unittest.cc
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 }