blob: 7a44b6cf1802c5980204ea1157acd9a1e8402f0a [file] [log] [blame]
[email protected]d82443b2009-01-15 19:54:561// Copyright (c) 2006-2008 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
[email protected]12bd05872009-03-17 19:25:065#include "base/base_paths.h"
[email protected]d82443b2009-01-15 19:54:566#include "base/string_util.h"
7#include "chrome/browser/browser_process.h"
8#include "chrome/browser/rlz/rlz.h"
[email protected]d54e03a52009-01-16 00:31:049#include "chrome/browser/search_engines/template_url.h"
[email protected]d82443b2009-01-15 19:54:5610#include "testing/gtest/include/gtest/gtest.h"
11
12class TemplateURLTest : public testing::Test {
13 public:
14 virtual void TearDown() {
15 delete TemplateURLRef::google_base_url_;
16 TemplateURLRef::google_base_url_ = NULL;
17 }
18
19 void CheckSuggestBaseURL(const wchar_t* base_url,
20 const wchar_t* base_suggest_url) const {
21 delete TemplateURLRef::google_base_url_;
22 TemplateURLRef::google_base_url_ = new std::wstring(base_url);
23 EXPECT_STREQ(base_suggest_url,
24 TemplateURLRef::GoogleBaseSuggestURLValue().c_str());
25 }
26};
27
28TEST_F(TemplateURLTest, Defaults) {
29 TemplateURL url;
30 ASSERT_FALSE(url.show_in_default_list());
31 ASSERT_FALSE(url.safe_for_autoreplace());
32 ASSERT_EQ(0, url.prepopulate_id());
33}
34
35TEST_F(TemplateURLTest, TestValidWithComplete) {
36 TemplateURLRef ref(L"{searchTerms}", 0, 0);
37 ASSERT_TRUE(ref.IsValid());
38}
39
40TEST_F(TemplateURLTest, URLRefTestSearchTerms) {
41 TemplateURL t_url;
42 TemplateURLRef ref(L"http://foo{searchTerms}", 0, 0);
43 ASSERT_TRUE(ref.IsValid());
44
45 ASSERT_TRUE(ref.SupportsReplacement());
46 GURL result = ref.ReplaceSearchTerms(t_url, L"search",
47 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
48 ASSERT_TRUE(result.is_valid());
49 ASSERT_EQ("http://foosearch/", result.spec());
50}
51
52TEST_F(TemplateURLTest, URLRefTestCount) {
53 TemplateURL t_url;
54 TemplateURLRef ref(L"http://foo{searchTerms}{count?}", 0, 0);
55 ASSERT_TRUE(ref.IsValid());
56 ASSERT_TRUE(ref.SupportsReplacement());
57 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
58 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
59 ASSERT_TRUE(result.is_valid());
60 ASSERT_EQ("http://foox/", result.spec());
61}
62
63TEST_F(TemplateURLTest, URLRefTestCount2) {
64 TemplateURL t_url;
65 TemplateURLRef ref(L"http://foo{searchTerms}{count}", 0, 0);
66 ASSERT_TRUE(ref.IsValid());
67 ASSERT_TRUE(ref.SupportsReplacement());
68 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
69 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
70 ASSERT_TRUE(result.is_valid());
71 ASSERT_EQ("http://foox10/", result.spec());
72}
73
74TEST_F(TemplateURLTest, URLRefTestIndices) {
75 TemplateURL t_url;
76 TemplateURLRef ref(L"http://foo{searchTerms}x{startIndex?}y{startPage?}",
77 1, 2);
78 ASSERT_TRUE(ref.IsValid());
79 ASSERT_TRUE(ref.SupportsReplacement());
80 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
81 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
82 ASSERT_TRUE(result.is_valid());
83 ASSERT_EQ("http://fooxxy/", result.spec());
84}
85
86TEST_F(TemplateURLTest, URLRefTestIndices2) {
87 TemplateURL t_url;
88 TemplateURLRef ref(L"http://foo{searchTerms}x{startIndex}y{startPage}", 1, 2);
89 ASSERT_TRUE(ref.IsValid());
90 ASSERT_TRUE(ref.SupportsReplacement());
91 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
92 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
93 ASSERT_TRUE(result.is_valid());
94 ASSERT_EQ("http://fooxx1y2/", result.spec());
95}
96
97TEST_F(TemplateURLTest, URLRefTestEncoding) {
98 TemplateURL t_url;
99 TemplateURLRef ref(
100 L"http://foo{searchTerms}x{inputEncoding?}y{outputEncoding?}a", 1, 2);
101 ASSERT_TRUE(ref.IsValid());
102 ASSERT_TRUE(ref.SupportsReplacement());
103 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
104 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
105 ASSERT_TRUE(result.is_valid());
106 ASSERT_EQ("http://fooxxutf-8ya/", result.spec());
107}
108
109TEST_F(TemplateURLTest, InputEncodingBeforeSearchTerm) {
110 TemplateURL t_url;
111 TemplateURLRef ref(
112 L"http://foox{inputEncoding?}a{searchTerms}y{outputEncoding?}b", 1, 2);
113 ASSERT_TRUE(ref.IsValid());
114 ASSERT_TRUE(ref.SupportsReplacement());
115 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
116 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
117 ASSERT_TRUE(result.is_valid());
118 ASSERT_EQ("http://fooxutf-8axyb/", result.spec());
119}
120
121TEST_F(TemplateURLTest, URLRefTestEncoding2) {
122 TemplateURL t_url;
123 TemplateURLRef ref(
124 L"http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a", 1, 2);
125 ASSERT_TRUE(ref.IsValid());
126 ASSERT_TRUE(ref.SupportsReplacement());
127 GURL result = ref.ReplaceSearchTerms(t_url, L"X",
128 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
129 ASSERT_TRUE(result.is_valid());
130 ASSERT_EQ("http://fooxxutf-8yutf-8a/", result.spec());
131}
132
133TEST_F(TemplateURLTest, URLRefTermToWide) {
134 struct ToWideCase {
135 const char* encoded_search_term;
136 const wchar_t* expected_decoded_term;
137 } to_wide_cases[] = {
138 {"hello+world", L"hello world"},
139 // Test some big-5 input.
140 {"%a7A%A6%6e+to+you", L"\x4f60\x597d to you"},
141 // Test some UTF-8 input. We should fall back to this when the encoding
142 // doesn't look like big-5. We have a '5' in the middle, which is an invalid
143 // Big-5 trailing byte.
144 {"%e4%bd%a05%e5%a5%bd+to+you", L"\x4f60\x35\x597d to you"},
145 // Undecodable input should stay escaped.
146 {"%91%01+abcd", L"%91%01 abcd"},
147 };
148
149 TemplateURL t_url;
150
151 // Set one input encoding: big-5. This is so we can test fallback to UTF-8.
152 std::vector<std::string> encodings;
153 encodings.push_back("big-5");
154 t_url.set_input_encodings(encodings);
155
156 TemplateURLRef ref(L"http://foo?q={searchTerms}", 1, 2);
157 ASSERT_TRUE(ref.IsValid());
158 ASSERT_TRUE(ref.SupportsReplacement());
159
[email protected]f63ae312009-02-04 17:58:46160 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(to_wide_cases); i++) {
[email protected]d82443b2009-01-15 19:54:56161 std::wstring result = ref.SearchTermToWide(t_url,
162 to_wide_cases[i].encoded_search_term);
163
164 EXPECT_EQ(std::wstring(to_wide_cases[i].expected_decoded_term), result);
165 }
166}
167
168TEST_F(TemplateURLTest, SetFavIcon) {
169 TemplateURL url;
170 GURL favicon_url("http://favicon.url");
171 url.SetFavIconURL(favicon_url);
[email protected]f63ae312009-02-04 17:58:46172 ASSERT_EQ(1U, url.image_refs().size());
[email protected]d82443b2009-01-15 19:54:56173 ASSERT_TRUE(favicon_url == url.GetFavIconURL());
174
175 GURL favicon_url2("http://favicon2.url");
176 url.SetFavIconURL(favicon_url2);
[email protected]f63ae312009-02-04 17:58:46177 ASSERT_EQ(1U, url.image_refs().size());
[email protected]d82443b2009-01-15 19:54:56178 ASSERT_TRUE(favicon_url2 == url.GetFavIconURL());
179}
180
181TEST_F(TemplateURLTest, DisplayURLToURLRef) {
182 struct TestData {
183 const std::wstring url;
184 const std::wstring expected_result;
185 } data[] = {
186 { L"http://foo{searchTerms}x{inputEncoding}y{outputEncoding}a",
187 L"http://foo%sx{inputEncoding}y{outputEncoding}a" },
188 { L"http://X",
189 L"http://X" },
190 { L"http://foo{searchTerms",
191 L"http://foo{searchTerms" },
192 { L"http://foo{searchTerms}{language}",
193 L"http://foo%s{language}" },
194 };
[email protected]f63ae312009-02-04 17:58:46195 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
[email protected]d82443b2009-01-15 19:54:56196 TemplateURLRef ref(data[i].url, 1, 2);
197 EXPECT_EQ(data[i].expected_result, ref.DisplayURL());
198 EXPECT_EQ(data[i].url,
199 TemplateURLRef::DisplayURLToURLRef(ref.DisplayURL()));
200 }
201}
202
203TEST_F(TemplateURLTest, ReplaceSearchTerms) {
204 struct TestData {
205 const std::wstring url;
206 const std::string expected_result;
207 } data[] = {
208 { L"http://foo/{language}{searchTerms}{inputEncoding}",
209 "http://foo/{language}XUTF-8" },
210 { L"http://foo/{language}{inputEncoding}{searchTerms}",
211 "http://foo/{language}UTF-8X" },
212 { L"http://foo/{searchTerms}{language}{inputEncoding}",
213 "http://foo/X{language}UTF-8" },
214 { L"http://foo/{searchTerms}{inputEncoding}{language}",
215 "http://foo/XUTF-8{language}" },
216 { L"http://foo/{inputEncoding}{searchTerms}{language}",
217 "http://foo/UTF-8X{language}" },
218 { L"http://foo/{inputEncoding}{language}{searchTerms}",
219 "http://foo/UTF-8{language}X" },
220 { L"http://foo/{language}a{searchTerms}a{inputEncoding}a",
221 "http://foo/{language}aXaUTF-8a" },
222 { L"http://foo/{language}a{inputEncoding}a{searchTerms}a",
223 "http://foo/{language}aUTF-8aXa" },
224 { L"http://foo/{searchTerms}a{language}a{inputEncoding}a",
225 "http://foo/Xa{language}aUTF-8a" },
226 { L"http://foo/{searchTerms}a{inputEncoding}a{language}a",
227 "http://foo/XaUTF-8a{language}a" },
228 { L"http://foo/{inputEncoding}a{searchTerms}a{language}a",
229 "http://foo/UTF-8aXa{language}a" },
230 { L"http://foo/{inputEncoding}a{language}a{searchTerms}a",
231 "http://foo/UTF-8a{language}aXa" },
232 };
233 TemplateURL turl;
234 turl.add_input_encoding("UTF-8");
[email protected]f63ae312009-02-04 17:58:46235 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
[email protected]d82443b2009-01-15 19:54:56236 TemplateURLRef ref(data[i].url, 1, 2);
237 EXPECT_TRUE(ref.IsValid());
238 EXPECT_TRUE(ref.SupportsReplacement());
239 std::string expected_result = data[i].expected_result;
240 ReplaceSubstringsAfterOffset(&expected_result, 0, "{language}",
241 WideToASCII(g_browser_process->GetApplicationLocale()));
242 GURL result = ref.ReplaceSearchTerms(turl, L"X",
243 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
244 EXPECT_TRUE(result.is_valid());
245 EXPECT_EQ(expected_result, result.spec());
246 }
247}
248
249
250// Tests replacing search terms in various encodings and making sure the
251// generated URL matches the expected value.
252TEST_F(TemplateURLTest, ReplaceArbitrarySearchTerms) {
253 struct TestData {
254 const std::string encoding;
255 const std::wstring search_term;
256 const std::wstring url;
257 const std::string expected_result;
258 } data[] = {
259 { "BIG5", L"\x60BD", L"http://foo/{searchTerms}{inputEncoding}",
260 "http://foo/%B1~BIG5" },
261 { "UTF-8", L"blah", L"http://foo/{searchTerms}{inputEncoding}",
262 "http://foo/blahUTF-8" },
263 };
[email protected]f63ae312009-02-04 17:58:46264 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
[email protected]d82443b2009-01-15 19:54:56265 TemplateURL turl;
266 turl.add_input_encoding(data[i].encoding);
267 TemplateURLRef ref(data[i].url, 1, 2);
268 GURL result = ref.ReplaceSearchTerms(turl, data[i].search_term,
269 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
270 EXPECT_TRUE(result.is_valid());
271 EXPECT_EQ(data[i].expected_result, result.spec());
272 }
273}
274
275TEST_F(TemplateURLTest, Suggestions) {
276 struct TestData {
277 const int accepted_suggestion;
278 const std::wstring original_query_for_suggestion;
279 const std::string expected_result;
280 } data[] = {
281 { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring(),
282 "http://bar/foo?q=foobar" },
283 { TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, L"foo",
284 "http://bar/foo?q=foobar" },
285 { TemplateURLRef::NO_SUGGESTION_CHOSEN, std::wstring(),
286 "http://bar/foo?aq=f&q=foobar" },
287 { TemplateURLRef::NO_SUGGESTION_CHOSEN, L"foo",
288 "http://bar/foo?aq=f&q=foobar" },
289 { 0, std::wstring(), "http://bar/foo?aq=0&oq=&q=foobar" },
290 { 1, L"foo", "http://bar/foo?aq=1&oq=foo&q=foobar" },
291 };
292 TemplateURL turl;
293 turl.add_input_encoding("UTF-8");
294 TemplateURLRef ref(L"http://bar/foo?{google:acceptedSuggestion}"
295 L"{google:originalQueryForSuggestion}q={searchTerms}", 1, 2);
296 ASSERT_TRUE(ref.IsValid());
297 ASSERT_TRUE(ref.SupportsReplacement());
[email protected]f63ae312009-02-04 17:58:46298 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
[email protected]d82443b2009-01-15 19:54:56299 GURL result = ref.ReplaceSearchTerms(turl, L"foobar",
300 data[i].accepted_suggestion, data[i].original_query_for_suggestion);
301 EXPECT_TRUE(result.is_valid());
302 EXPECT_EQ(data[i].expected_result, result.spec());
303 }
304}
305
306TEST_F(TemplateURLTest, RLZ) {
[email protected]12bd05872009-03-17 19:25:06307#if defined(OS_WIN)
308 RLZTracker::InitRlz(base::DIR_EXE);
309#endif
[email protected]d82443b2009-01-15 19:54:56310 std::wstring rlz_string;
311 RLZTracker::GetAccessPointRlz(RLZTracker::CHROME_OMNIBOX, &rlz_string);
312
313 TemplateURL t_url;
[email protected]12bd05872009-03-17 19:25:06314 TemplateURLRef ref(L"http://bar/?{google:RLZ}{searchTerms}", 1, 2);
[email protected]d82443b2009-01-15 19:54:56315 ASSERT_TRUE(ref.IsValid());
316 ASSERT_TRUE(ref.SupportsReplacement());
317 GURL result = ref.ReplaceSearchTerms(t_url, L"x",
318 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring());
319 ASSERT_TRUE(result.is_valid());
[email protected]12bd05872009-03-17 19:25:06320 std::string expected_url = "http://bar/?";
321 if (!rlz_string.empty()) {
322 expected_url += "rlz=" + WideToUTF8(rlz_string) + "&";
323 }
324 expected_url += "x";
325 ASSERT_EQ(expected_url, result.spec());
[email protected]d82443b2009-01-15 19:54:56326}
327
328TEST_F(TemplateURLTest, HostAndSearchTermKey) {
329 struct TestData {
330 const std::wstring url;
331 const std::string host;
332 const std::string path;
333 const std::string search_term_key;
334 } data[] = {
335 { L"http://blah/?foo=bar&q={searchTerms}&b=x", "blah", "/", "q"},
336
337 // No query key should result in empty values.
338 { L"http://blah/{searchTerms}", "", "", ""},
339
340 // No term should result in empty values.
341 { L"http://blah/", "", "", ""},
342
343 // Multiple terms should result in empty values.
344 { L"http://blah/?q={searchTerms}&x={searchTerms}", "", "", ""},
345
346 // Term in the host shouldn't match.
347 { L"http://{searchTerms}", "", "", ""},
348
349 { L"http://blah/?q={searchTerms}", "blah", "/", "q"},
350
351 // Single term with extra chars in value should match.
352 { L"http://blah/?q=stock:{searchTerms}", "blah", "/", "q"},
353
354 };
355
356 TemplateURL t_url;
[email protected]f63ae312009-02-04 17:58:46357 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) {
[email protected]d82443b2009-01-15 19:54:56358 t_url.SetURL(data[i].url, 0, 0);
359 EXPECT_EQ(data[i].host, t_url.url()->GetHost());
360 EXPECT_EQ(data[i].path, t_url.url()->GetPath());
361 EXPECT_EQ(data[i].search_term_key, t_url.url()->GetSearchTermKey());
362 }
363}
364
365TEST_F(TemplateURLTest, GoogleBaseSuggestURL) {
366 static const struct {
367 const wchar_t* const base_url;
368 const wchar_t* const base_suggest_url;
369 } data[] = {
370 { L"http://google.com/", L"http://clients1.google.com/complete/", },
371 { L"http://www.google.com/", L"http://clients1.google.com/complete/", },
372 { L"http://www.google.co.uk/", L"http://clients1.google.co.uk/complete/", },
373 { L"http://www.google.com.by/",
374 L"http://clients1.google.com.by/complete/", },
375 { L"http://google.com/intl/xx/", L"http://clients1.google.com/complete/", },
376 };
377
[email protected]f63ae312009-02-04 17:58:46378 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i)
[email protected]d82443b2009-01-15 19:54:56379 CheckSuggestBaseURL(data[i].base_url, data[i].base_suggest_url);
380}
381
382TEST_F(TemplateURLTest, Keyword) {
383 TemplateURL t_url;
384 t_url.SetURL(L"http://www.google.com/search", 0, 0);
385 EXPECT_FALSE(t_url.autogenerate_keyword());
386 t_url.set_keyword(L"foo");
387 EXPECT_EQ(L"foo", t_url.keyword());
388 t_url.set_autogenerate_keyword(true);
389 EXPECT_TRUE(t_url.autogenerate_keyword());
390 EXPECT_EQ(L"google.com", t_url.keyword());
391 t_url.set_keyword(L"foo");
392 EXPECT_FALSE(t_url.autogenerate_keyword());
393 EXPECT_EQ(L"foo", t_url.keyword());
394}