• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/string_util.h"
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/rlz/rlz.h"
10 #include "chrome/browser/search_engines/search_terms_data.h"
11 #include "chrome/browser/search_engines/template_url.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 // Simple implementation of SearchTermsData.
15 class TestSearchTermsData : public SearchTermsData {
16  public:
TestSearchTermsData(const char * google_base_url)17   explicit TestSearchTermsData(const char* google_base_url)
18       : google_base_url_(google_base_url)  {
19   }
20 
GoogleBaseURLValue() const21   virtual std::string GoogleBaseURLValue() const {
22     return google_base_url_;
23   }
24 
GetApplicationLocale() const25   virtual std::string GetApplicationLocale() const {
26     return "yy";
27   }
28 
29 #if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD)
30   // Returns the value for the Chrome Omnibox rlz.
GetRlzParameterValue() const31   virtual string16 GetRlzParameterValue() const {
32     return string16();
33   }
34 #endif
35 
36  private:
37   std::string google_base_url_;
38 
39   DISALLOW_COPY_AND_ASSIGN(TestSearchTermsData);
40 };
41 
42 class TemplateURLTest : public testing::Test {
43  public:
TearDown()44   virtual void TearDown() {
45     TemplateURLRef::SetGoogleBaseURL(NULL);
46   }
47 
CheckSuggestBaseURL(const char * base_url,const char * base_suggest_url) const48   void CheckSuggestBaseURL(const char* base_url,
49                            const char* base_suggest_url) const {
50     TestSearchTermsData search_terms_data(base_url);
51     EXPECT_STREQ(base_suggest_url,
52                  search_terms_data.GoogleBaseSuggestURLValue().c_str());
53   }
54 };
55 
TEST_F(TemplateURLTest,Defaults)56 TEST_F(TemplateURLTest, Defaults) {
57   TemplateURL url;
58   ASSERT_FALSE(url.show_in_default_list());
59   ASSERT_FALSE(url.safe_for_autoreplace());
60   ASSERT_EQ(0, url.prepopulate_id());
61 }
62 
TEST_F(TemplateURLTest,TestValidWithComplete)63 TEST_F(TemplateURLTest, TestValidWithComplete) {
64   TemplateURLRef ref("{searchTerms}", 0, 0);
65   ASSERT_TRUE(ref.IsValid());
66 }
67 
TEST_F(TemplateURLTest,URLRefTestSearchTerms)68 TEST_F(TemplateURLTest, URLRefTestSearchTerms) {
69   struct SearchTermsCase {
70     const char* url;
71     const string16 terms;
72     const char* output;
73   } search_term_cases[] = {
74     { "http://foo{searchTerms}", ASCIIToUTF16("sea rch/bar"),
75       "http://foosea%20rch/bar" },
76     { "http://foo{searchTerms}?boo=abc", ASCIIToUTF16("sea rch/bar"),
77       "http://foosea%20rch/bar?boo=abc" },
78     { "http://foo/?boo={searchTerms}", ASCIIToUTF16("sea rch/bar"),
79       "http://foo/?boo=sea+rch%2Fbar" },
80     { "http://en.wikipedia.org/{searchTerms}", ASCIIToUTF16("wiki/?"),
81       "http://en.wikipedia.org/wiki/%3F" }
82   };
83   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(search_term_cases); ++i) {
84     const SearchTermsCase& value = search_term_cases[i];
85     TemplateURL t_url;
86     TemplateURLRef ref(value.url, 0, 0);
87     ASSERT_TRUE(ref.IsValid());
88 
89     ASSERT_TRUE(ref.SupportsReplacement());
90     GURL result = GURL(ref.ReplaceSearchTerms(t_url, value.terms,
91         TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
92     ASSERT_TRUE(result.is_valid());
93     ASSERT_EQ(value.output, result.spec());
94   }
95 }
96 
TEST_F(TemplateURLTest,URLRefTestCount)97 TEST_F(TemplateURLTest, URLRefTestCount) {
98   TemplateURL t_url;
99   TemplateURLRef ref("http://foo{searchTerms}{count?}", 0, 0);
100   ASSERT_TRUE(ref.IsValid());
101   ASSERT_TRUE(ref.SupportsReplacement());
102   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
103       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
104   ASSERT_TRUE(result.is_valid());
105   ASSERT_EQ("http://foox/", result.spec());
106 }
107 
TEST_F(TemplateURLTest,URLRefTestCount2)108 TEST_F(TemplateURLTest, URLRefTestCount2) {
109   TemplateURL t_url;
110   TemplateURLRef ref("http://foo{searchTerms}{count}", 0, 0);
111   ASSERT_TRUE(ref.IsValid());
112   ASSERT_TRUE(ref.SupportsReplacement());
113   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
114       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
115   ASSERT_TRUE(result.is_valid());
116   ASSERT_EQ("http://foox10/", result.spec());
117 }
118 
TEST_F(TemplateURLTest,URLRefTestIndices)119 TEST_F(TemplateURLTest, URLRefTestIndices) {
120   TemplateURL t_url;
121   TemplateURLRef ref("http://foo{searchTerms}x{startIndex?}y{startPage?}",
122                      1, 2);
123   ASSERT_TRUE(ref.IsValid());
124   ASSERT_TRUE(ref.SupportsReplacement());
125   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
126       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
127   ASSERT_TRUE(result.is_valid());
128   ASSERT_EQ("http://fooxxy/", result.spec());
129 }
130 
TEST_F(TemplateURLTest,URLRefTestIndices2)131 TEST_F(TemplateURLTest, URLRefTestIndices2) {
132   TemplateURL t_url;
133   TemplateURLRef ref("http://foo{searchTerms}x{startIndex}y{startPage}", 1, 2);
134   ASSERT_TRUE(ref.IsValid());
135   ASSERT_TRUE(ref.SupportsReplacement());
136   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
137       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
138   ASSERT_TRUE(result.is_valid());
139   ASSERT_EQ("http://fooxx1y2/", result.spec());
140 }
141 
TEST_F(TemplateURLTest,URLRefTestEncoding)142 TEST_F(TemplateURLTest, URLRefTestEncoding) {
143   TemplateURL t_url;
144   TemplateURLRef ref(
145       "http://foo{searchTerms}x{inputEncoding?}y{outputEncoding?}a", 1, 2);
146   ASSERT_TRUE(ref.IsValid());
147   ASSERT_TRUE(ref.SupportsReplacement());
148   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
149       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
150   ASSERT_TRUE(result.is_valid());
151   ASSERT_EQ("http://fooxxutf-8ya/", result.spec());
152 }
153 
TEST_F(TemplateURLTest,InputEncodingBeforeSearchTerm)154 TEST_F(TemplateURLTest, InputEncodingBeforeSearchTerm) {
155   TemplateURL t_url;
156   TemplateURLRef ref(
157       "http://foox{inputEncoding?}a{searchTerms}y{outputEncoding?}b", 1, 2);
158   ASSERT_TRUE(ref.IsValid());
159   ASSERT_TRUE(ref.SupportsReplacement());
160   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
161       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
162   ASSERT_TRUE(result.is_valid());
163   ASSERT_EQ("http://fooxutf-8axyb/", result.spec());
164 }
165 
TEST_F(TemplateURLTest,URLRefTestEncoding2)166 TEST_F(TemplateURLTest, URLRefTestEncoding2) {
167   TemplateURL t_url;
168   TemplateURLRef ref(
169       "http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a", 1, 2);
170   ASSERT_TRUE(ref.IsValid());
171   ASSERT_TRUE(ref.SupportsReplacement());
172   GURL result = GURL(ref.ReplaceSearchTerms(t_url, ASCIIToUTF16("X"),
173       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
174   ASSERT_TRUE(result.is_valid());
175   ASSERT_EQ("http://fooxxutf-8yutf-8a/", result.spec());
176 }
177 
TEST_F(TemplateURLTest,URLRefTestSearchTermsUsingTermsData)178 TEST_F(TemplateURLTest, URLRefTestSearchTermsUsingTermsData) {
179   struct SearchTermsCase {
180     const char* url;
181     const string16 terms;
182     const char* output;
183   } search_term_cases[] = {
184     { "{google:baseURL}{language}{searchTerms}", string16(),
185       "http://example.com/e/yy" },
186     { "{google:baseSuggestURL}{searchTerms}", string16(),
187       "http://clients1.example.com/complete/" }
188   };
189 
190   TestSearchTermsData search_terms_data("http://example.com/e/");
191   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(search_term_cases); ++i) {
192     const SearchTermsCase& value = search_term_cases[i];
193     TemplateURL t_url;
194     TemplateURLRef ref(value.url, 0, 0);
195     ASSERT_TRUE(ref.IsValid());
196 
197     ASSERT_TRUE(ref.SupportsReplacement());
198     GURL result = GURL(ref.ReplaceSearchTermsUsingTermsData(
199         t_url, value.terms,
200         TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16(),
201         search_terms_data));
202     ASSERT_TRUE(result.is_valid());
203     ASSERT_EQ(value.output, result.spec());
204   }
205 }
206 
TEST_F(TemplateURLTest,URLRefTermToWide)207 TEST_F(TemplateURLTest, URLRefTermToWide) {
208   struct ToWideCase {
209     const char* encoded_search_term;
210     const string16 expected_decoded_term;
211   } to_wide_cases[] = {
212     {"hello+world", ASCIIToUTF16("hello world")},
213     // Test some big-5 input.
214     {"%a7A%A6%6e+to+you", WideToUTF16(L"\x4f60\x597d to you")},
215     // Test some UTF-8 input. We should fall back to this when the encoding
216     // doesn't look like big-5. We have a '5' in the middle, which is an invalid
217     // Big-5 trailing byte.
218     {"%e4%bd%a05%e5%a5%bd+to+you", WideToUTF16(L"\x4f60\x35\x597d to you")},
219     // Undecodable input should stay escaped.
220     {"%91%01+abcd", WideToUTF16(L"%91%01 abcd")},
221     // Make sure we convert %2B to +.
222     {"C%2B%2B", ASCIIToUTF16("C++")},
223     // C%2B is escaped as C%252B, make sure we unescape it properly.
224     {"C%252B", ASCIIToUTF16("C%2B")},
225   };
226 
227   TemplateURL t_url;
228 
229   // Set one input encoding: big-5. This is so we can test fallback to UTF-8.
230   std::vector<std::string> encodings;
231   encodings.push_back("big-5");
232   t_url.set_input_encodings(encodings);
233 
234   TemplateURLRef ref("http://foo?q={searchTerms}", 1, 2);
235   ASSERT_TRUE(ref.IsValid());
236   ASSERT_TRUE(ref.SupportsReplacement());
237 
238   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(to_wide_cases); i++) {
239     string16 result = ref.SearchTermToString16(t_url,
240         to_wide_cases[i].encoded_search_term);
241 
242     EXPECT_EQ(to_wide_cases[i].expected_decoded_term, result);
243   }
244 }
245 
TEST_F(TemplateURLTest,SetFavicon)246 TEST_F(TemplateURLTest, SetFavicon) {
247   TemplateURL url;
248   GURL favicon_url("http://favicon.url");
249   url.SetFaviconURL(favicon_url);
250   ASSERT_EQ(1U, url.image_refs().size());
251   ASSERT_TRUE(favicon_url == url.GetFaviconURL());
252 
253   GURL favicon_url2("http://favicon2.url");
254   url.SetFaviconURL(favicon_url2);
255   ASSERT_EQ(1U, url.image_refs().size());
256   ASSERT_TRUE(favicon_url2 == url.GetFaviconURL());
257 }
258 
TEST_F(TemplateURLTest,DisplayURLToURLRef)259 TEST_F(TemplateURLTest, DisplayURLToURLRef) {
260   struct TestData {
261     const std::string url;
262     const string16 expected_result;
263   } data[] = {
264     { "http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a",
265       ASCIIToUTF16("http://foo%sx{inputEncoding}y{outputEncoding}a") },
266     { "http://X",
267       ASCIIToUTF16("http://X") },
268     { "http://foo{searchTerms",
269       ASCIIToUTF16("http://foo{searchTerms") },
270     { "http://foo{searchTerms}{language}",
271       ASCIIToUTF16("http://foo%s{language}") },
272   };
273   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
274     TemplateURLRef ref(data[i].url, 1, 2);
275     EXPECT_EQ(data[i].expected_result, ref.DisplayURL());
276     EXPECT_EQ(data[i].url,
277               TemplateURLRef::DisplayURLToURLRef(ref.DisplayURL()));
278   }
279 }
280 
TEST_F(TemplateURLTest,ReplaceSearchTerms)281 TEST_F(TemplateURLTest, ReplaceSearchTerms) {
282   struct TestData {
283     const std::string url;
284     const std::string expected_result;
285   } data[] = {
286     { "http://foo/{language}{searchTerms}{inputEncoding}",
287       "http://foo/{language}XUTF-8" },
288     { "http://foo/{language}{inputEncoding}{searchTerms}",
289       "http://foo/{language}UTF-8X" },
290     { "http://foo/{searchTerms}{language}{inputEncoding}",
291       "http://foo/X{language}UTF-8" },
292     { "http://foo/{searchTerms}{inputEncoding}{language}",
293       "http://foo/XUTF-8{language}" },
294     { "http://foo/{inputEncoding}{searchTerms}{language}",
295       "http://foo/UTF-8X{language}" },
296     { "http://foo/{inputEncoding}{language}{searchTerms}",
297       "http://foo/UTF-8{language}X" },
298     { "http://foo/{language}a{searchTerms}a{inputEncoding}a",
299       "http://foo/{language}aXaUTF-8a" },
300     { "http://foo/{language}a{inputEncoding}a{searchTerms}a",
301       "http://foo/{language}aUTF-8aXa" },
302     { "http://foo/{searchTerms}a{language}a{inputEncoding}a",
303       "http://foo/Xa{language}aUTF-8a" },
304     { "http://foo/{searchTerms}a{inputEncoding}a{language}a",
305       "http://foo/XaUTF-8a{language}a" },
306     { "http://foo/{inputEncoding}a{searchTerms}a{language}a",
307       "http://foo/UTF-8aXa{language}a" },
308     { "http://foo/{inputEncoding}a{language}a{searchTerms}a",
309       "http://foo/UTF-8a{language}aXa" },
310   };
311   TemplateURL turl;
312   turl.add_input_encoding("UTF-8");
313   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
314     TemplateURLRef ref(data[i].url, 1, 2);
315     EXPECT_TRUE(ref.IsValid());
316     EXPECT_TRUE(ref.SupportsReplacement());
317     std::string expected_result = data[i].expected_result;
318     ReplaceSubstringsAfterOffset(&expected_result, 0, "{language}",
319         g_browser_process->GetApplicationLocale());
320     GURL result = GURL(ref.ReplaceSearchTerms(turl, ASCIIToUTF16("X"),
321         TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
322     EXPECT_TRUE(result.is_valid());
323     EXPECT_EQ(expected_result, result.spec());
324   }
325 }
326 
327 
328 // Tests replacing search terms in various encodings and making sure the
329 // generated URL matches the expected value.
TEST_F(TemplateURLTest,ReplaceArbitrarySearchTerms)330 TEST_F(TemplateURLTest, ReplaceArbitrarySearchTerms) {
331   struct TestData {
332     const std::string encoding;
333     const string16 search_term;
334     const std::string url;
335     const std::string expected_result;
336   } data[] = {
337     { "BIG5",  WideToUTF16(L"\x60BD"),
338       "http://foo/?{searchTerms}{inputEncoding}",
339       "http://foo/?%B1~BIG5" },
340     { "UTF-8", ASCIIToUTF16("blah"),
341       "http://foo/?{searchTerms}{inputEncoding}",
342       "http://foo/?blahUTF-8" },
343   };
344   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
345     TemplateURL turl;
346     turl.add_input_encoding(data[i].encoding);
347     TemplateURLRef ref(data[i].url, 1, 2);
348     GURL result = GURL(ref.ReplaceSearchTerms(turl,
349         data[i].search_term, TemplateURLRef::NO_SUGGESTIONS_AVAILABLE,
350         string16()));
351     EXPECT_TRUE(result.is_valid());
352     EXPECT_EQ(data[i].expected_result, result.spec());
353   }
354 }
355 
TEST_F(TemplateURLTest,Suggestions)356 TEST_F(TemplateURLTest, Suggestions) {
357   struct TestData {
358     const int accepted_suggestion;
359     const string16 original_query_for_suggestion;
360     const std::string expected_result;
361   } data[] = {
362     { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16(),
363       "http://bar/foo?q=foobar" },
364     { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, ASCIIToUTF16("foo"),
365       "http://bar/foo?q=foobar" },
366     { TemplateURLRef::NO_SUGGESTION_CHOSEN, string16(),
367       "http://bar/foo?aq=f&q=foobar" },
368     { TemplateURLRef::NO_SUGGESTION_CHOSEN, ASCIIToUTF16("foo"),
369       "http://bar/foo?aq=f&q=foobar" },
370     { 0, string16(), "http://bar/foo?aq=0&oq=&q=foobar" },
371     { 1, ASCIIToUTF16("foo"), "http://bar/foo?aq=1&oq=foo&q=foobar" },
372   };
373   TemplateURL turl;
374   turl.add_input_encoding("UTF-8");
375   TemplateURLRef ref("http://bar/foo?{google:acceptedSuggestion}"
376       "{google:originalQueryForSuggestion}q={searchTerms}", 1, 2);
377   ASSERT_TRUE(ref.IsValid());
378   ASSERT_TRUE(ref.SupportsReplacement());
379   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
380     GURL result = GURL(ref.ReplaceSearchTerms(turl, ASCIIToUTF16("foobar"),
381         data[i].accepted_suggestion, data[i].original_query_for_suggestion));
382     EXPECT_TRUE(result.is_valid());
383     EXPECT_EQ(data[i].expected_result, result.spec());
384   }
385 }
386 
387 #if defined(OS_WIN)
TEST_F(TemplateURLTest,RLZ)388 TEST_F(TemplateURLTest, RLZ) {
389   string16 rlz_string;
390 #if defined(GOOGLE_CHROME_BUILD)
391   RLZTracker::GetAccessPointRlz(rlz_lib::CHROME_OMNIBOX, &rlz_string);
392 #endif
393 
394   TemplateURL t_url;
395   TemplateURLRef ref("http://bar/?{google:RLZ}{searchTerms}", 1, 2);
396   ASSERT_TRUE(ref.IsValid());
397   ASSERT_TRUE(ref.SupportsReplacement());
398   GURL result(ref.ReplaceSearchTerms(t_url, L"x",
399       TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, string16()));
400   ASSERT_TRUE(result.is_valid());
401   std::string expected_url = "http://bar/?";
402   if (!rlz_string.empty()) {
403     expected_url += "rlz=" + WideToUTF8(rlz_string) + "&";
404   }
405   expected_url += "x";
406   ASSERT_EQ(expected_url, result.spec());
407 }
408 #endif
409 
TEST_F(TemplateURLTest,HostAndSearchTermKey)410 TEST_F(TemplateURLTest, HostAndSearchTermKey) {
411   struct TestData {
412     const std::string url;
413     const std::string host;
414     const std::string path;
415     const std::string search_term_key;
416   } data[] = {
417     { "http://blah/?foo=bar&q={searchTerms}&b=x", "blah", "/", "q"},
418 
419     // No query key should result in empty values.
420     { "http://blah/{searchTerms}", "", "", ""},
421 
422     // No term should result in empty values.
423     { "http://blah/", "", "", ""},
424 
425     // Multiple terms should result in empty values.
426     { "http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""},
427 
428     // Term in the host shouldn't match.
429     { "http://{searchTerms}", "", "", ""},
430 
431     { "http://blah/?q={searchTerms}", "blah", "/", "q"},
432 
433     // Single term with extra chars in value should match.
434     { "http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
435   };
436 
437   TemplateURL t_url;
438   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
439     t_url.SetURL(data[i].url, 0, 0);
440     EXPECT_EQ(data[i].host, t_url.url()->GetHost());
441     EXPECT_EQ(data[i].path, t_url.url()->GetPath());
442     EXPECT_EQ(data[i].search_term_key, t_url.url()->GetSearchTermKey());
443   }
444 }
445 
TEST_F(TemplateURLTest,GoogleBaseSuggestURL)446 TEST_F(TemplateURLTest, GoogleBaseSuggestURL) {
447   static const struct {
448     const char* const base_url;
449     const char* const base_suggest_url;
450   } data[] = {
451     { "http://google.com/", "http://clients1.google.com/complete/", },
452     { "http://www.google.com/", "http://clients1.google.com/complete/", },
453     { "http://www.google.co.uk/", "http://clients1.google.co.uk/complete/", },
454     { "http://www.google.com.by/",
455       "http://clients1.google.com.by/complete/", },
456     { "http://google.com/intl/xx/", "http://clients1.google.com/complete/", },
457   };
458 
459   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i)
460     CheckSuggestBaseURL(data[i].base_url, data[i].base_suggest_url);
461 }
462 
TEST_F(TemplateURLTest,Keyword)463 TEST_F(TemplateURLTest, Keyword) {
464   TemplateURL t_url;
465   t_url.SetURL("http://www.google.com/search", 0, 0);
466   EXPECT_FALSE(t_url.autogenerate_keyword());
467   t_url.set_keyword(ASCIIToUTF16("foo"));
468   EXPECT_EQ(ASCIIToUTF16("foo"), t_url.keyword());
469   t_url.set_autogenerate_keyword(true);
470   EXPECT_TRUE(t_url.autogenerate_keyword());
471   EXPECT_EQ(ASCIIToUTF16("google.com"), t_url.keyword());
472   t_url.set_keyword(ASCIIToUTF16("foo"));
473   EXPECT_FALSE(t_url.autogenerate_keyword());
474   EXPECT_EQ(ASCIIToUTF16("foo"), t_url.keyword());
475 }
476 
TEST_F(TemplateURLTest,ParseParameterKnown)477 TEST_F(TemplateURLTest, ParseParameterKnown) {
478   std::string parsed_url("{searchTerms}");
479   TemplateURLRef url_ref(parsed_url, 0, 0);
480   TemplateURLRef::Replacements replacements;
481   EXPECT_TRUE(url_ref.ParseParameter(0, 12, &parsed_url, &replacements));
482   EXPECT_EQ(std::string(), parsed_url);
483   ASSERT_EQ(1U, replacements.size());
484   EXPECT_EQ(static_cast<size_t>(0), replacements[0].index);
485   EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
486 }
487 
TEST_F(TemplateURLTest,ParseParameterUnknown)488 TEST_F(TemplateURLTest, ParseParameterUnknown) {
489   std::string parsed_url("{}");
490   TemplateURLRef url_ref(parsed_url, 0, 0);
491   TemplateURLRef::Replacements replacements;
492   EXPECT_FALSE(url_ref.ParseParameter(0, 1, &parsed_url, &replacements));
493   EXPECT_EQ("{}", parsed_url);
494   EXPECT_TRUE(replacements.empty());
495 }
496 
TEST_F(TemplateURLTest,ParseURLEmpty)497 TEST_F(TemplateURLTest, ParseURLEmpty) {
498   TemplateURLRef url_ref("", 0, 0);
499   TemplateURLRef::Replacements replacements;
500   bool valid = false;
501   EXPECT_EQ(std::string(), url_ref.ParseURL("", &replacements, &valid));
502   EXPECT_TRUE(replacements.empty());
503   EXPECT_TRUE(valid);
504 }
505 
TEST_F(TemplateURLTest,ParseURLNoTemplateEnd)506 TEST_F(TemplateURLTest, ParseURLNoTemplateEnd) {
507   TemplateURLRef url_ref("{", 0, 0);
508   TemplateURLRef::Replacements replacements;
509   bool valid = false;
510   EXPECT_EQ(std::string(), url_ref.ParseURL("{", &replacements, &valid));
511   EXPECT_TRUE(replacements.empty());
512   EXPECT_FALSE(valid);
513 }
514 
TEST_F(TemplateURLTest,ParseURLNoKnownParameters)515 TEST_F(TemplateURLTest, ParseURLNoKnownParameters) {
516   TemplateURLRef url_ref("{}", 0, 0);
517   TemplateURLRef::Replacements replacements;
518   bool valid = false;
519   EXPECT_EQ("{}", url_ref.ParseURL("{}", &replacements, &valid));
520   EXPECT_TRUE(replacements.empty());
521   EXPECT_TRUE(valid);
522 }
523 
TEST_F(TemplateURLTest,ParseURLTwoParameters)524 TEST_F(TemplateURLTest, ParseURLTwoParameters) {
525   TemplateURLRef url_ref("{}{{%s}}", 0, 0);
526   TemplateURLRef::Replacements replacements;
527   bool valid = false;
528   EXPECT_EQ("{}{}",
529             url_ref.ParseURL("{}{{searchTerms}}", &replacements, &valid));
530   ASSERT_EQ(1U, replacements.size());
531   EXPECT_EQ(static_cast<size_t>(3), replacements[0].index);
532   EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
533   EXPECT_TRUE(valid);
534 }
535 
TEST_F(TemplateURLTest,ParseURLNestedParameter)536 TEST_F(TemplateURLTest, ParseURLNestedParameter) {
537   TemplateURLRef url_ref("{%s", 0, 0);
538   TemplateURLRef::Replacements replacements;
539   bool valid = false;
540   EXPECT_EQ("{", url_ref.ParseURL("{{searchTerms}", &replacements, &valid));
541   ASSERT_EQ(1U, replacements.size());
542   EXPECT_EQ(static_cast<size_t>(1), replacements[0].index);
543   EXPECT_EQ(TemplateURLRef::SEARCH_TERMS, replacements[0].type);
544   EXPECT_TRUE(valid);
545 }
546