OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/bind.h" | |
6 #include "base/bind_helpers.h" | |
7 #include "base/callback.h" | |
8 #include "base/memory/ref_counted.h" | |
9 #include "base/memory/scoped_vector.h" | |
10 #include "base/run_loop.h" | |
11 #include "base/strings/string_split.h" | |
12 #include "base/strings/string_util.h" | |
13 #include "base/strings/utf_string_conversions.h" | |
14 #include "base/task/cancelable_task_tracker.h" | |
15 #include "base/test/mock_time_provider.h" | |
16 #include "base/threading/thread.h" | |
17 #include "base/time/time.h" | |
18 #include "chrome/browser/history/history_service.h" | |
19 #include "chrome/browser/history/history_service_factory.h" | |
20 #include "chrome/browser/search_engines/template_url_service_test_util.h" | |
21 #include "chrome/browser/webdata/web_data_service_factory.h" | |
22 #include "chrome/test/base/testing_profile.h" | |
23 #include "components/search_engines/keyword_web_data_service.h" | |
24 #include "components/search_engines/search_host_to_urls_map.h" | |
25 #include "components/search_engines/search_terms_data.h" | |
26 #include "components/search_engines/template_url.h" | |
27 #include "components/search_engines/template_url_prepopulate_data.h" | |
28 #include "components/search_engines/template_url_service.h" | |
29 #include "components/webdata/common/web_database.h" | |
30 #include "testing/gtest/include/gtest/gtest.h" | |
31 | |
32 using base::ASCIIToUTF16; | |
33 using base::Time; | |
34 using base::TimeDelta; | |
35 using ::testing::Return; | |
36 using ::testing::StrictMock; | |
37 | |
38 namespace { | |
39 | |
40 // QueryHistoryCallbackImpl --------------------------------------------------- | |
41 | |
42 struct QueryHistoryCallbackImpl { | |
43 QueryHistoryCallbackImpl() : success(false) {} | |
44 | |
45 void Callback(bool success, | |
46 const history::URLRow& row, | |
47 const history::VisitVector& visits) { | |
48 this->success = success; | |
49 if (success) { | |
50 this->row = row; | |
51 this->visits = visits; | |
52 } | |
53 } | |
54 | |
55 bool success; | |
56 history::URLRow row; | |
57 history::VisitVector visits; | |
58 }; | |
59 | |
60 TemplateURL* CreateKeywordWithDate( | |
61 TemplateURLService* model, | |
62 const std::string& short_name, | |
63 const std::string& keyword, | |
64 const std::string& url, | |
65 const std::string& suggest_url, | |
66 const std::string& alternate_url, | |
67 const std::string& favicon_url, | |
68 bool safe_for_autoreplace, | |
69 bool show_in_default_list, | |
70 const std::string& encodings, | |
71 Time date_created, | |
72 Time last_modified) { | |
73 TemplateURLData data; | |
74 data.short_name = base::UTF8ToUTF16(short_name); | |
75 data.SetKeyword(base::UTF8ToUTF16(keyword)); | |
76 data.SetURL(url); | |
77 data.suggestions_url = suggest_url; | |
78 if (!alternate_url.empty()) | |
79 data.alternate_urls.push_back(alternate_url); | |
80 data.favicon_url = GURL(favicon_url); | |
81 data.safe_for_autoreplace = safe_for_autoreplace; | |
82 data.show_in_default_list = show_in_default_list; | |
83 base::SplitString(encodings, ';', &data.input_encodings); | |
84 data.date_created = date_created; | |
85 data.last_modified = last_modified; | |
86 return new TemplateURL(data); | |
87 } | |
88 | |
89 TemplateURL* AddKeywordWithDate( | |
90 TemplateURLService* model, | |
91 const std::string& short_name, | |
92 const std::string& keyword, | |
93 const std::string& url, | |
94 const std::string& suggest_url, | |
95 const std::string& alternate_url, | |
96 const std::string& favicon_url, | |
97 bool safe_for_autoreplace, | |
98 const std::string& encodings, | |
99 Time date_created, | |
100 Time last_modified) { | |
101 TemplateURL* t_url = CreateKeywordWithDate( | |
102 model, short_name, keyword, url, suggest_url, alternate_url,favicon_url, | |
103 safe_for_autoreplace, false, encodings, date_created, last_modified); | |
104 model->Add(t_url); | |
105 EXPECT_NE(0, t_url->id()); | |
106 return t_url; | |
107 } | |
108 | |
109 // Checks that the two TemplateURLs are similar. It does not check the id, the | |
110 // date_created or the last_modified time. Neither pointer should be NULL. | |
111 void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual) { | |
112 ASSERT_TRUE(expected != NULL); | |
113 ASSERT_TRUE(actual != NULL); | |
114 EXPECT_EQ(expected->short_name(), actual->short_name()); | |
115 EXPECT_EQ(expected->keyword(), actual->keyword()); | |
116 EXPECT_EQ(expected->url(), actual->url()); | |
117 EXPECT_EQ(expected->suggestions_url(), actual->suggestions_url()); | |
118 EXPECT_EQ(expected->favicon_url(), actual->favicon_url()); | |
119 EXPECT_EQ(expected->alternate_urls(), actual->alternate_urls()); | |
120 EXPECT_EQ(expected->show_in_default_list(), actual->show_in_default_list()); | |
121 EXPECT_EQ(expected->safe_for_autoreplace(), actual->safe_for_autoreplace()); | |
122 EXPECT_EQ(expected->input_encodings(), actual->input_encodings()); | |
123 EXPECT_EQ(expected->search_terms_replacement_key(), | |
124 actual->search_terms_replacement_key()); | |
125 } | |
126 | |
127 } // namespace | |
128 | |
129 | |
130 // TemplateURLServiceTest ----------------------------------------------------- | |
131 | |
132 class TemplateURLServiceTest : public testing::Test { | |
133 public: | |
134 TemplateURLServiceTest(); | |
135 | |
136 // testing::Test: | |
137 virtual void SetUp() OVERRIDE; | |
138 virtual void TearDown() OVERRIDE; | |
139 | |
140 TemplateURL* AddKeywordWithDate(const std::string& short_name, | |
141 const std::string& keyword, | |
142 const std::string& url, | |
143 const std::string& suggest_url, | |
144 const std::string& alternate_url, | |
145 const std::string& favicon_url, | |
146 bool safe_for_autoreplace, | |
147 const std::string& encodings, | |
148 Time date_created, | |
149 Time last_modified); | |
150 | |
151 // Verifies the two TemplateURLs are equal. | |
152 void AssertEquals(const TemplateURL& expected, const TemplateURL& actual); | |
153 | |
154 // Create an URL that appears to have been prepopulated, but won't be in the | |
155 // current data. The caller owns the returned TemplateURL*. | |
156 TemplateURL* CreatePreloadedTemplateURL(bool safe_for_autoreplace, | |
157 int prepopulate_id); | |
158 | |
159 // Helper methods to make calling TemplateURLServiceTestUtil methods less | |
160 // visually noisy in the test code. | |
161 void VerifyObserverCount(int expected_changed_count); | |
162 void VerifyObserverFired(); | |
163 TemplateURLService* model() { return test_util_->model(); } | |
164 const SearchTermsData& search_terms_data() { | |
165 return model()->search_terms_data(); | |
166 } | |
167 | |
168 protected: | |
169 scoped_ptr<TemplateURLServiceTestUtil> test_util_; | |
170 | |
171 DISALLOW_COPY_AND_ASSIGN(TemplateURLServiceTest); | |
172 }; | |
173 | |
174 class TemplateURLServiceWithoutFallbackTest : public TemplateURLServiceTest { | |
175 public: | |
176 TemplateURLServiceWithoutFallbackTest() : TemplateURLServiceTest() {} | |
177 | |
178 virtual void SetUp() OVERRIDE { | |
179 DefaultSearchManager::SetFallbackSearchEnginesDisabledForTesting(true); | |
180 TemplateURLServiceTest::SetUp(); | |
181 } | |
182 | |
183 virtual void TearDown() OVERRIDE { | |
184 TemplateURLServiceTest::TearDown(); | |
185 DefaultSearchManager::SetFallbackSearchEnginesDisabledForTesting(false); | |
186 } | |
187 }; | |
188 | |
189 TemplateURLServiceTest::TemplateURLServiceTest() { | |
190 } | |
191 | |
192 void TemplateURLServiceTest::SetUp() { | |
193 test_util_.reset(new TemplateURLServiceTestUtil); | |
194 } | |
195 | |
196 void TemplateURLServiceTest::TearDown() { | |
197 test_util_.reset(); | |
198 } | |
199 | |
200 TemplateURL* TemplateURLServiceTest::AddKeywordWithDate( | |
201 const std::string& short_name, | |
202 const std::string& keyword, | |
203 const std::string& url, | |
204 const std::string& suggest_url, | |
205 const std::string& alternate_url, | |
206 const std::string& favicon_url, | |
207 bool safe_for_autoreplace, | |
208 const std::string& encodings, | |
209 Time date_created, | |
210 Time last_modified) { | |
211 return ::AddKeywordWithDate(model(), short_name, keyword, url, suggest_url, | |
212 alternate_url, favicon_url, safe_for_autoreplace, | |
213 encodings, date_created, last_modified); | |
214 } | |
215 | |
216 void TemplateURLServiceTest::AssertEquals(const TemplateURL& expected, | |
217 const TemplateURL& actual) { | |
218 ASSERT_EQ(expected.short_name(), actual.short_name()); | |
219 ASSERT_EQ(expected.keyword(), actual.keyword()); | |
220 ASSERT_EQ(expected.url(), actual.url()); | |
221 ASSERT_EQ(expected.suggestions_url(), actual.suggestions_url()); | |
222 ASSERT_EQ(expected.favicon_url(), actual.favicon_url()); | |
223 ASSERT_EQ(expected.alternate_urls(), actual.alternate_urls()); | |
224 ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list()); | |
225 ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace()); | |
226 ASSERT_EQ(expected.input_encodings(), actual.input_encodings()); | |
227 ASSERT_EQ(expected.id(), actual.id()); | |
228 ASSERT_EQ(expected.date_created(), actual.date_created()); | |
229 ASSERT_EQ(expected.last_modified(), actual.last_modified()); | |
230 ASSERT_EQ(expected.sync_guid(), actual.sync_guid()); | |
231 ASSERT_EQ(expected.search_terms_replacement_key(), | |
232 actual.search_terms_replacement_key()); | |
233 } | |
234 | |
235 TemplateURL* TemplateURLServiceTest::CreatePreloadedTemplateURL( | |
236 bool safe_for_autoreplace, | |
237 int prepopulate_id) { | |
238 TemplateURLData data; | |
239 data.short_name = ASCIIToUTF16("unittest"); | |
240 data.SetKeyword(ASCIIToUTF16("unittest")); | |
241 data.SetURL("http://www.unittest.com/{searchTerms}"); | |
242 data.favicon_url = GURL("http://favicon.url"); | |
243 data.show_in_default_list = true; | |
244 data.safe_for_autoreplace = safe_for_autoreplace; | |
245 data.input_encodings.push_back("UTF-8"); | |
246 data.date_created = Time::FromTimeT(100); | |
247 data.last_modified = Time::FromTimeT(100); | |
248 data.prepopulate_id = prepopulate_id; | |
249 return new TemplateURL(data); | |
250 } | |
251 | |
252 void TemplateURLServiceTest::VerifyObserverCount(int expected_changed_count) { | |
253 EXPECT_EQ(expected_changed_count, test_util_->GetObserverCount()); | |
254 test_util_->ResetObserverCount(); | |
255 } | |
256 | |
257 void TemplateURLServiceTest::VerifyObserverFired() { | |
258 EXPECT_LE(1, test_util_->GetObserverCount()); | |
259 test_util_->ResetObserverCount(); | |
260 } | |
261 | |
262 | |
263 // Actual tests --------------------------------------------------------------- | |
264 | |
265 TEST_F(TemplateURLServiceTest, Load) { | |
266 test_util_->VerifyLoad(); | |
267 } | |
268 | |
269 TEST_F(TemplateURLServiceTest, AddUpdateRemove) { | |
270 // Add a new TemplateURL. | |
271 test_util_->VerifyLoad(); | |
272 const size_t initial_count = model()->GetTemplateURLs().size(); | |
273 | |
274 TemplateURLData data; | |
275 data.short_name = ASCIIToUTF16("google"); | |
276 data.SetKeyword(ASCIIToUTF16("keyword")); | |
277 data.SetURL("http://www.google.com/foo/bar"); | |
278 data.favicon_url = GURL("http://favicon.url"); | |
279 data.safe_for_autoreplace = true; | |
280 data.date_created = Time::FromTimeT(100); | |
281 data.last_modified = Time::FromTimeT(100); | |
282 data.sync_guid = "00000000-0000-0000-0000-000000000001"; | |
283 TemplateURL* t_url = new TemplateURL(data); | |
284 model()->Add(t_url); | |
285 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), | |
286 NULL)); | |
287 VerifyObserverCount(1); | |
288 base::RunLoop().RunUntilIdle(); | |
289 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
290 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(t_url->keyword())); | |
291 // We need to make a second copy as the model takes ownership of |t_url| and | |
292 // will delete it. We have to do this after calling Add() since that gives | |
293 // |t_url| its ID. | |
294 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
295 | |
296 // Reload the model to verify it was actually saved to the database. | |
297 test_util_->ResetModel(true); | |
298 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
299 TemplateURL* loaded_url = | |
300 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
301 ASSERT_TRUE(loaded_url != NULL); | |
302 AssertEquals(*cloned_url, *loaded_url); | |
303 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), | |
304 NULL)); | |
305 | |
306 // We expect the last_modified time to be updated to the present time on an | |
307 // explicit reset. We have to set up the expectation here because ResetModel | |
308 // resets the TimeProvider in the TemplateURLService. | |
309 StrictMock<base::MockTimeProvider> mock_time; | |
310 model()->set_time_provider(&base::MockTimeProvider::StaticNow); | |
311 EXPECT_CALL(mock_time, Now()).WillOnce(Return(base::Time::FromDoubleT(1337))); | |
312 | |
313 // Mutate an element and verify it succeeded. | |
314 model()->ResetTemplateURL(loaded_url, ASCIIToUTF16("a"), ASCIIToUTF16("b"), | |
315 "c"); | |
316 ASSERT_EQ(ASCIIToUTF16("a"), loaded_url->short_name()); | |
317 ASSERT_EQ(ASCIIToUTF16("b"), loaded_url->keyword()); | |
318 ASSERT_EQ("c", loaded_url->url()); | |
319 ASSERT_FALSE(loaded_url->safe_for_autoreplace()); | |
320 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), | |
321 NULL)); | |
322 ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("b"), GURL(), NULL)); | |
323 cloned_url.reset(new TemplateURL(loaded_url->data())); | |
324 base::RunLoop().RunUntilIdle(); | |
325 test_util_->ResetModel(true); | |
326 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
327 loaded_url = model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")); | |
328 ASSERT_TRUE(loaded_url != NULL); | |
329 AssertEquals(*cloned_url, *loaded_url); | |
330 // We changed a TemplateURL in the service, so ensure that the time was | |
331 // updated. | |
332 ASSERT_EQ(base::Time::FromDoubleT(1337), loaded_url->last_modified()); | |
333 | |
334 // Remove an element and verify it succeeded. | |
335 model()->Remove(loaded_url); | |
336 VerifyObserverCount(1); | |
337 test_util_->ResetModel(true); | |
338 ASSERT_EQ(initial_count, model()->GetTemplateURLs().size()); | |
339 EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")) == NULL); | |
340 } | |
341 | |
342 TEST_F(TemplateURLServiceTest, AddSameKeyword) { | |
343 test_util_->VerifyLoad(); | |
344 | |
345 AddKeywordWithDate( | |
346 "first", "keyword", "http://test1", std::string(), std::string(), | |
347 std::string(), true, "UTF-8", Time(), Time()); | |
348 VerifyObserverCount(1); | |
349 | |
350 // Test what happens when we try to add a TemplateURL with the same keyword as | |
351 // one in the model. | |
352 TemplateURLData data; | |
353 data.short_name = ASCIIToUTF16("second"); | |
354 data.SetKeyword(ASCIIToUTF16("keyword")); | |
355 data.SetURL("http://test2"); | |
356 data.safe_for_autoreplace = false; | |
357 TemplateURL* t_url = new TemplateURL(data); | |
358 model()->Add(t_url); | |
359 | |
360 // Because the old TemplateURL was replaceable and the new one wasn't, the new | |
361 // one should have replaced the old. | |
362 VerifyObserverCount(1); | |
363 EXPECT_EQ(t_url, model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"))); | |
364 EXPECT_EQ(ASCIIToUTF16("second"), t_url->short_name()); | |
365 EXPECT_EQ(ASCIIToUTF16("keyword"), t_url->keyword()); | |
366 EXPECT_FALSE(t_url->safe_for_autoreplace()); | |
367 | |
368 // Now try adding a replaceable TemplateURL. This should just delete the | |
369 // passed-in URL. | |
370 data.short_name = ASCIIToUTF16("third"); | |
371 data.SetURL("http://test3"); | |
372 data.safe_for_autoreplace = true; | |
373 model()->Add(new TemplateURL(data)); | |
374 VerifyObserverCount(0); | |
375 EXPECT_EQ(t_url, model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"))); | |
376 EXPECT_EQ(ASCIIToUTF16("second"), t_url->short_name()); | |
377 EXPECT_EQ(ASCIIToUTF16("keyword"), t_url->keyword()); | |
378 EXPECT_FALSE(t_url->safe_for_autoreplace()); | |
379 | |
380 // Now try adding a non-replaceable TemplateURL again. This should uniquify | |
381 // the existing entry's keyword. | |
382 data.short_name = ASCIIToUTF16("fourth"); | |
383 data.SetURL("http://test4"); | |
384 data.safe_for_autoreplace = false; | |
385 TemplateURL* t_url2 = new TemplateURL(data); | |
386 model()->Add(t_url2); | |
387 VerifyObserverCount(1); | |
388 EXPECT_EQ(t_url2, model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"))); | |
389 EXPECT_EQ(ASCIIToUTF16("fourth"), t_url2->short_name()); | |
390 EXPECT_EQ(ASCIIToUTF16("keyword"), t_url2->keyword()); | |
391 EXPECT_EQ(ASCIIToUTF16("second"), t_url->short_name()); | |
392 EXPECT_EQ(ASCIIToUTF16("test2"), t_url->keyword()); | |
393 } | |
394 | |
395 TEST_F(TemplateURLServiceTest, AddExtensionKeyword) { | |
396 test_util_->VerifyLoad(); | |
397 | |
398 TemplateURL* original1 = AddKeywordWithDate( | |
399 "replaceable", "keyword1", "http://test1", std::string(), std::string(), | |
400 std::string(), true, "UTF-8", Time(), Time()); | |
401 TemplateURL* original2 = AddKeywordWithDate( | |
402 "nonreplaceable", "keyword2", "http://test2", std::string(), | |
403 std::string(), std::string(), false, "UTF-8", Time(), Time()); | |
404 model()->RegisterOmniboxKeyword("test3", "extension", "keyword3", | |
405 "http://test3"); | |
406 TemplateURL* original3 = | |
407 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword3")); | |
408 ASSERT_TRUE(original3); | |
409 | |
410 // Add an extension keyword that conflicts with each of the above three | |
411 // keywords. | |
412 // Both replaceable and non-replaceable keywords should be uniquified. | |
413 model()->RegisterOmniboxKeyword("test4", "test", "keyword1", "http://test4"); | |
414 TemplateURL* extension1 = | |
415 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword1")); | |
416 ASSERT_TRUE(extension1); | |
417 EXPECT_EQ(original1, | |
418 model()->GetTemplateURLForKeyword(ASCIIToUTF16("test1"))); | |
419 | |
420 model()->RegisterOmniboxKeyword("test5", "test", "keyword2", "http://test5"); | |
421 TemplateURL* extension2 = | |
422 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword2")); | |
423 ASSERT_TRUE(extension2); | |
424 EXPECT_EQ(original2, | |
425 model()->GetTemplateURLForKeyword(ASCIIToUTF16("test2"))); | |
426 | |
427 // They should override extension keywords added earlier. | |
428 model()->RegisterOmniboxKeyword("test6", "test", "keyword3", "http://test6"); | |
429 TemplateURL* extension3 = | |
430 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword3")); | |
431 ASSERT_TRUE(extension3); | |
432 EXPECT_EQ(original3, | |
433 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword3_"))); | |
434 } | |
435 | |
436 TEST_F(TemplateURLServiceTest, AddSameKeywordWithExtensionPresent) { | |
437 test_util_->VerifyLoad(); | |
438 | |
439 // Similar to the AddSameKeyword test, but with an extension keyword masking a | |
440 // replaceable TemplateURL. We should still do correct conflict resolution | |
441 // between the non-template URLs. | |
442 model()->RegisterOmniboxKeyword("test2", "extension", "keyword", | |
443 "http://test2"); | |
444 TemplateURL* extension = | |
445 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
446 ASSERT_TRUE(extension); | |
447 // Adding a keyword that matches the extension should cause the extension | |
448 // to uniquify. | |
449 AddKeywordWithDate( | |
450 "replaceable", "keyword", "http://test1", std::string(), std::string(), | |
451 std::string(), true, "UTF-8", Time(), Time()); | |
452 | |
453 // Adding another replaceable keyword should remove the existing one, but | |
454 // leave the extension as is. | |
455 TemplateURLData data; | |
456 data.short_name = ASCIIToUTF16("name1"); | |
457 data.SetKeyword(ASCIIToUTF16("keyword")); | |
458 data.SetURL("http://test3"); | |
459 data.safe_for_autoreplace = true; | |
460 TemplateURL* t_url = new TemplateURL(data); | |
461 model()->Add(t_url); | |
462 EXPECT_EQ(extension, | |
463 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword_"))); | |
464 EXPECT_TRUE(model()->GetTemplateURLForHost("test1") == NULL); | |
465 EXPECT_EQ(t_url, model()->GetTemplateURLForHost("test3")); | |
466 | |
467 // Adding a nonreplaceable keyword should remove the existing replaceable | |
468 // keyword. | |
469 data.short_name = ASCIIToUTF16("name2"); | |
470 data.SetURL("http://test4"); | |
471 data.safe_for_autoreplace = false; | |
472 TemplateURL* t_url2 = new TemplateURL(data); | |
473 model()->Add(t_url2); | |
474 EXPECT_EQ(t_url2, | |
475 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"))); | |
476 EXPECT_TRUE(model()->GetTemplateURLForHost("test3") == NULL); | |
477 EXPECT_EQ(extension, | |
478 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword_"))); | |
479 } | |
480 | |
481 TEST_F(TemplateURLServiceTest, RestoreOmniboxExtensionKeyword) { | |
482 test_util_->VerifyLoad(); | |
483 | |
484 // Register an omnibox keyword. | |
485 model()->RegisterOmniboxKeyword("test", "extension", "keyword", | |
486 "chrome-extension://test"); | |
487 ASSERT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"))); | |
488 | |
489 // Reload the data. | |
490 test_util_->ResetModel(true); | |
491 | |
492 // Ensure the omnibox keyword is restored correctly. | |
493 TemplateURL* t_url = | |
494 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
495 ASSERT_TRUE(t_url); | |
496 ASSERT_EQ(TemplateURL::OMNIBOX_API_EXTENSION, t_url->GetType()); | |
497 EXPECT_EQ("test", t_url->GetExtensionId()); | |
498 } | |
499 | |
500 TEST_F(TemplateURLServiceTest, ClearBrowsingData_Keywords) { | |
501 Time now = Time::Now(); | |
502 TimeDelta one_day = TimeDelta::FromDays(1); | |
503 Time month_ago = now - TimeDelta::FromDays(30); | |
504 | |
505 // Nothing has been added. | |
506 EXPECT_EQ(0U, model()->GetTemplateURLs().size()); | |
507 | |
508 // Create one with a 0 time. | |
509 AddKeywordWithDate("name1", "key1", "http://foo1", "http://suggest1", | |
510 std::string(), "http://icon1", true, "UTF-8;UTF-16", | |
511 Time(), Time()); | |
512 // Create one for now and +/- 1 day. | |
513 AddKeywordWithDate("name2", "key2", "http://foo2", "http://suggest2", | |
514 std::string(), "http://icon2", true, "UTF-8;UTF-16", | |
515 now - one_day, Time()); | |
516 AddKeywordWithDate("name3", "key3", "http://foo3", std::string(), | |
517 std::string(), std::string(), true, std::string(), now, | |
518 Time()); | |
519 AddKeywordWithDate("name4", "key4", "http://foo4", std::string(), | |
520 std::string(), std::string(), true, std::string(), | |
521 now + one_day, Time()); | |
522 // Try the other three states. | |
523 AddKeywordWithDate("name5", "key5", "http://foo5", "http://suggest5", | |
524 std::string(), "http://icon5", false, "UTF-8;UTF-16", now, | |
525 Time()); | |
526 AddKeywordWithDate("name6", "key6", "http://foo6", "http://suggest6", | |
527 std::string(), "http://icon6", false, "UTF-8;UTF-16", | |
528 month_ago, Time()); | |
529 | |
530 // We just added a few items, validate them. | |
531 EXPECT_EQ(6U, model()->GetTemplateURLs().size()); | |
532 | |
533 // Try removing from current timestamp. This should delete the one in the | |
534 // future and one very recent one. | |
535 model()->RemoveAutoGeneratedSince(now); | |
536 EXPECT_EQ(4U, model()->GetTemplateURLs().size()); | |
537 | |
538 // Try removing from two months ago. This should only delete items that are | |
539 // auto-generated. | |
540 model()->RemoveAutoGeneratedBetween(now - TimeDelta::FromDays(60), now); | |
541 EXPECT_EQ(3U, model()->GetTemplateURLs().size()); | |
542 | |
543 // Make sure the right values remain. | |
544 EXPECT_EQ(ASCIIToUTF16("key1"), model()->GetTemplateURLs()[0]->keyword()); | |
545 EXPECT_TRUE(model()->GetTemplateURLs()[0]->safe_for_autoreplace()); | |
546 EXPECT_EQ(0U, | |
547 model()->GetTemplateURLs()[0]->date_created().ToInternalValue()); | |
548 | |
549 EXPECT_EQ(ASCIIToUTF16("key5"), model()->GetTemplateURLs()[1]->keyword()); | |
550 EXPECT_FALSE(model()->GetTemplateURLs()[1]->safe_for_autoreplace()); | |
551 EXPECT_EQ(now.ToInternalValue(), | |
552 model()->GetTemplateURLs()[1]->date_created().ToInternalValue()); | |
553 | |
554 EXPECT_EQ(ASCIIToUTF16("key6"), model()->GetTemplateURLs()[2]->keyword()); | |
555 EXPECT_FALSE(model()->GetTemplateURLs()[2]->safe_for_autoreplace()); | |
556 EXPECT_EQ(month_ago.ToInternalValue(), | |
557 model()->GetTemplateURLs()[2]->date_created().ToInternalValue()); | |
558 | |
559 // Try removing from Time=0. This should delete one more. | |
560 model()->RemoveAutoGeneratedSince(Time()); | |
561 EXPECT_EQ(2U, model()->GetTemplateURLs().size()); | |
562 } | |
563 | |
564 TEST_F(TemplateURLServiceTest, ClearBrowsingData_KeywordsForOrigin) { | |
565 Time now = Time::Now(); | |
566 TimeDelta one_day = TimeDelta::FromDays(1); | |
567 Time month_ago = now - TimeDelta::FromDays(30); | |
568 | |
569 // Nothing has been added. | |
570 EXPECT_EQ(0U, model()->GetTemplateURLs().size()); | |
571 | |
572 // Create one for now and +/- 1 day. | |
573 AddKeywordWithDate("name1", "key1", "http://foo1", "http://suggest1", | |
574 std::string(), "http://icon2", true, "UTF-8;UTF-16", | |
575 now - one_day, Time()); | |
576 AddKeywordWithDate("name2", "key2", "http://foo2", std::string(), | |
577 std::string(), std::string(), true, std::string(), now, | |
578 Time()); | |
579 AddKeywordWithDate("name3", "key3", "http://foo3", std::string(), | |
580 std::string(), std::string(), true, std::string(), | |
581 now + one_day, Time()); | |
582 | |
583 // We just added a few items, validate them. | |
584 EXPECT_EQ(3U, model()->GetTemplateURLs().size()); | |
585 | |
586 // Try removing foo2. This should delete foo2, but leave foo1 and 3 untouched. | |
587 model()->RemoveAutoGeneratedForOriginBetween(GURL("http://foo2"), month_ago, | |
588 now + one_day); | |
589 EXPECT_EQ(2U, model()->GetTemplateURLs().size()); | |
590 EXPECT_EQ(ASCIIToUTF16("key1"), model()->GetTemplateURLs()[0]->keyword()); | |
591 EXPECT_TRUE(model()->GetTemplateURLs()[0]->safe_for_autoreplace()); | |
592 EXPECT_EQ(ASCIIToUTF16("key3"), model()->GetTemplateURLs()[1]->keyword()); | |
593 EXPECT_TRUE(model()->GetTemplateURLs()[1]->safe_for_autoreplace()); | |
594 | |
595 // Try removing foo1, but outside the range in which it was modified. It | |
596 // should remain untouched. | |
597 model()->RemoveAutoGeneratedForOriginBetween(GURL("http://foo1"), now, | |
598 now + one_day); | |
599 EXPECT_EQ(2U, model()->GetTemplateURLs().size()); | |
600 EXPECT_EQ(ASCIIToUTF16("key1"), model()->GetTemplateURLs()[0]->keyword()); | |
601 EXPECT_TRUE(model()->GetTemplateURLs()[0]->safe_for_autoreplace()); | |
602 EXPECT_EQ(ASCIIToUTF16("key3"), model()->GetTemplateURLs()[1]->keyword()); | |
603 EXPECT_TRUE(model()->GetTemplateURLs()[1]->safe_for_autoreplace()); | |
604 | |
605 | |
606 // Try removing foo3. This should delete foo3, but leave foo1 untouched. | |
607 model()->RemoveAutoGeneratedForOriginBetween(GURL("http://foo3"), month_ago, | |
608 now + one_day + one_day); | |
609 EXPECT_EQ(1U, model()->GetTemplateURLs().size()); | |
610 EXPECT_EQ(ASCIIToUTF16("key1"), model()->GetTemplateURLs()[0]->keyword()); | |
611 EXPECT_TRUE(model()->GetTemplateURLs()[0]->safe_for_autoreplace()); | |
612 } | |
613 | |
614 TEST_F(TemplateURLServiceTest, Reset) { | |
615 // Add a new TemplateURL. | |
616 test_util_->VerifyLoad(); | |
617 const size_t initial_count = model()->GetTemplateURLs().size(); | |
618 TemplateURLData data; | |
619 data.short_name = ASCIIToUTF16("google"); | |
620 data.SetKeyword(ASCIIToUTF16("keyword")); | |
621 data.SetURL("http://www.google.com/foo/bar"); | |
622 data.favicon_url = GURL("http://favicon.url"); | |
623 data.date_created = Time::FromTimeT(100); | |
624 data.last_modified = Time::FromTimeT(100); | |
625 TemplateURL* t_url = new TemplateURL(data); | |
626 model()->Add(t_url); | |
627 | |
628 VerifyObserverCount(1); | |
629 base::RunLoop().RunUntilIdle(); | |
630 | |
631 StrictMock<base::MockTimeProvider> mock_time; | |
632 model()->set_time_provider(&base::MockTimeProvider::StaticNow); | |
633 EXPECT_CALL(mock_time, Now()).WillOnce(Return(base::Time::FromDoubleT(1337))); | |
634 | |
635 // Reset the short name, keyword, url and make sure it takes. | |
636 const base::string16 new_short_name(ASCIIToUTF16("a")); | |
637 const base::string16 new_keyword(ASCIIToUTF16("b")); | |
638 const std::string new_url("c"); | |
639 model()->ResetTemplateURL(t_url, new_short_name, new_keyword, new_url); | |
640 ASSERT_EQ(new_short_name, t_url->short_name()); | |
641 ASSERT_EQ(new_keyword, t_url->keyword()); | |
642 ASSERT_EQ(new_url, t_url->url()); | |
643 | |
644 // Make sure the mappings in the model were updated. | |
645 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(new_keyword)); | |
646 ASSERT_TRUE( | |
647 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")) == NULL); | |
648 | |
649 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
650 | |
651 // Reload the model from the database and make sure the change took. | |
652 test_util_->ResetModel(true); | |
653 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
654 const TemplateURL* read_url = model()->GetTemplateURLForKeyword(new_keyword); | |
655 ASSERT_TRUE(read_url); | |
656 AssertEquals(*cloned_url, *read_url); | |
657 ASSERT_EQ(base::Time::FromDoubleT(1337), read_url->last_modified()); | |
658 } | |
659 | |
660 TEST_F(TemplateURLServiceTest, DefaultSearchProvider) { | |
661 // Add a new TemplateURL. | |
662 test_util_->VerifyLoad(); | |
663 const size_t initial_count = model()->GetTemplateURLs().size(); | |
664 TemplateURL* t_url = AddKeywordWithDate( | |
665 "name1", "key1", "http://foo1/{searchTerms}", "http://sugg1", | |
666 std::string(), "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); | |
667 test_util_->ResetObserverCount(); | |
668 | |
669 model()->SetUserSelectedDefaultSearchProvider(t_url); | |
670 ASSERT_EQ(t_url, model()->GetDefaultSearchProvider()); | |
671 ASSERT_TRUE(t_url->safe_for_autoreplace()); | |
672 ASSERT_TRUE(t_url->show_in_default_list()); | |
673 | |
674 // Setting the default search provider should have caused notification. | |
675 VerifyObserverCount(1); | |
676 base::RunLoop().RunUntilIdle(); | |
677 | |
678 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
679 | |
680 // Make sure when we reload we get a default search provider. | |
681 test_util_->ResetModel(true); | |
682 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
683 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
684 AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider()); | |
685 } | |
686 | |
687 TEST_F(TemplateURLServiceTest, CantReplaceWithSameKeyword) { | |
688 test_util_->ChangeModelToLoadState(); | |
689 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), GURL(), NULL)); | |
690 TemplateURL* t_url = AddKeywordWithDate( | |
691 "name1", "foo", "http://foo1", "http://sugg1", std::string(), | |
692 "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); | |
693 | |
694 // Can still replace, newly added template url is marked safe to replace. | |
695 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), | |
696 GURL("http://foo2"), NULL)); | |
697 | |
698 // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should | |
699 // no longer be replaceable. | |
700 model()->ResetTemplateURL(t_url, t_url->short_name(), t_url->keyword(), | |
701 t_url->url()); | |
702 | |
703 ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), | |
704 GURL("http://foo2"), NULL)); | |
705 } | |
706 | |
707 TEST_F(TemplateURLServiceTest, CantReplaceWithSameHosts) { | |
708 test_util_->ChangeModelToLoadState(); | |
709 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), | |
710 GURL("http://foo.com"), NULL)); | |
711 TemplateURL* t_url = AddKeywordWithDate( | |
712 "name1", "foo", "http://foo.com", "http://sugg1", std::string(), | |
713 "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); | |
714 | |
715 // Can still replace, newly added template url is marked safe to replace. | |
716 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("bar"), | |
717 GURL("http://foo.com"), NULL)); | |
718 | |
719 // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should | |
720 // no longer be replaceable. | |
721 model()->ResetTemplateURL(t_url, t_url->short_name(), t_url->keyword(), | |
722 t_url->url()); | |
723 | |
724 ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("bar"), | |
725 GURL("http://foo.com"), NULL)); | |
726 } | |
727 | |
728 TEST_F(TemplateURLServiceTest, HasDefaultSearchProvider) { | |
729 // We should have a default search provider even if we haven't loaded. | |
730 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
731 | |
732 // Now force the model to load and make sure we still have a default. | |
733 test_util_->VerifyLoad(); | |
734 | |
735 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
736 } | |
737 | |
738 TEST_F(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) { | |
739 test_util_->VerifyLoad(); | |
740 | |
741 TemplateURLData data; | |
742 data.short_name = ASCIIToUTF16("a"); | |
743 data.safe_for_autoreplace = true; | |
744 data.SetURL("http://url/{searchTerms}"); | |
745 data.suggestions_url = "http://url2"; | |
746 data.instant_url = "http://instant"; | |
747 data.date_created = Time::FromTimeT(100); | |
748 data.last_modified = Time::FromTimeT(100); | |
749 TemplateURL* t_url = new TemplateURL(data); | |
750 model()->Add(t_url); | |
751 const TemplateURLID id = t_url->id(); | |
752 | |
753 model()->SetUserSelectedDefaultSearchProvider(t_url); | |
754 base::RunLoop().RunUntilIdle(); | |
755 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
756 | |
757 // Reset the model and don't load it. The template url we set as the default | |
758 // should be pulled from prefs now. | |
759 test_util_->ResetModel(false); | |
760 | |
761 // NOTE: This doesn't use AssertEquals as only a subset of the TemplateURLs | |
762 // value are persisted to prefs. | |
763 const TemplateURL* default_turl = model()->GetDefaultSearchProvider(); | |
764 ASSERT_TRUE(default_turl); | |
765 EXPECT_EQ(ASCIIToUTF16("a"), default_turl->short_name()); | |
766 EXPECT_EQ("http://url/{searchTerms}", default_turl->url()); | |
767 EXPECT_EQ("http://url2", default_turl->suggestions_url()); | |
768 EXPECT_EQ("http://instant", default_turl->instant_url()); | |
769 EXPECT_EQ(id, default_turl->id()); | |
770 | |
771 // Now do a load and make sure the default search provider really takes. | |
772 test_util_->VerifyLoad(); | |
773 | |
774 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
775 AssertEquals(*cloned_url, *model()->GetDefaultSearchProvider()); | |
776 } | |
777 | |
778 TEST_F(TemplateURLServiceTest, RepairPrepopulatedSearchEngines) { | |
779 test_util_->VerifyLoad(); | |
780 | |
781 // Edit Google search engine. | |
782 TemplateURL* google = model()->GetTemplateURLForKeyword( | |
783 ASCIIToUTF16("google.com")); | |
784 ASSERT_TRUE(google); | |
785 model()->ResetTemplateURL(google, ASCIIToUTF16("trash"), ASCIIToUTF16("xxx"), | |
786 "http://www.foo.com/s?q={searchTerms}"); | |
787 EXPECT_EQ(ASCIIToUTF16("trash"), google->short_name()); | |
788 EXPECT_EQ(ASCIIToUTF16("xxx"), google->keyword()); | |
789 | |
790 // Add third-party default search engine. | |
791 TemplateURL* user_dse = AddKeywordWithDate( | |
792 "malware", "google.com", "http://www.goo.com/s?q={searchTerms}", | |
793 std::string(), std::string(), std::string(), | |
794 true, "UTF-8", Time(), Time()); | |
795 model()->SetUserSelectedDefaultSearchProvider(user_dse); | |
796 EXPECT_EQ(user_dse, model()->GetDefaultSearchProvider()); | |
797 | |
798 // Remove bing. | |
799 TemplateURL* bing = model()->GetTemplateURLForKeyword( | |
800 ASCIIToUTF16("bing.com")); | |
801 ASSERT_TRUE(bing); | |
802 model()->Remove(bing); | |
803 EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com"))); | |
804 | |
805 // Register an extension with bing keyword. | |
806 model()->RegisterOmniboxKeyword("abcdefg", "extension_name", "bing.com", | |
807 "http://abcdefg"); | |
808 EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com"))); | |
809 | |
810 model()->RepairPrepopulatedSearchEngines(); | |
811 | |
812 // Google is default. | |
813 ASSERT_EQ(google, model()->GetDefaultSearchProvider()); | |
814 // The keyword wasn't reverted. | |
815 EXPECT_EQ(ASCIIToUTF16("trash"), google->short_name()); | |
816 EXPECT_EQ("www.google.com", | |
817 google->GenerateSearchURL(model()->search_terms_data()).host()); | |
818 | |
819 // Bing was repaired. | |
820 bing = model()->GetTemplateURLForKeyword(ASCIIToUTF16("bing.com")); | |
821 ASSERT_TRUE(bing); | |
822 EXPECT_EQ(TemplateURL::NORMAL, bing->GetType()); | |
823 | |
824 // User search engine is preserved. | |
825 EXPECT_EQ(user_dse, model()->GetTemplateURLForHost("www.goo.com")); | |
826 EXPECT_EQ(ASCIIToUTF16("google.com"), user_dse->keyword()); | |
827 } | |
828 | |
829 TEST_F(TemplateURLServiceTest, RepairSearchEnginesWithManagedDefault) { | |
830 // Set a managed preference that establishes a default search provider. | |
831 const char kName[] = "test1"; | |
832 const char kKeyword[] = "test.com"; | |
833 const char kSearchURL[] = "http://test.com/search?t={searchTerms}"; | |
834 const char kIconURL[] = "http://test.com/icon.jpg"; | |
835 const char kEncodings[] = "UTF-16;UTF-32"; | |
836 const char kAlternateURL[] = "http://test.com/search#t={searchTerms}"; | |
837 const char kSearchTermsReplacementKey[] = "espv"; | |
838 test_util_->SetManagedDefaultSearchPreferences(true, kName, kKeyword, | |
839 kSearchURL, std::string(), | |
840 kIconURL, kEncodings, | |
841 kAlternateURL, | |
842 kSearchTermsReplacementKey); | |
843 test_util_->VerifyLoad(); | |
844 // Verify that the default manager we are getting is the managed one. | |
845 TemplateURLData data; | |
846 data.short_name = ASCIIToUTF16(kName); | |
847 data.SetKeyword(ASCIIToUTF16(kKeyword)); | |
848 data.SetURL(kSearchURL); | |
849 data.favicon_url = GURL(kIconURL); | |
850 data.show_in_default_list = true; | |
851 base::SplitString(kEncodings, ';', &data.input_encodings); | |
852 data.alternate_urls.push_back(kAlternateURL); | |
853 data.search_terms_replacement_key = kSearchTermsReplacementKey; | |
854 scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(data)); | |
855 EXPECT_TRUE(model()->is_default_search_managed()); | |
856 const TemplateURL* actual_managed_default = | |
857 model()->GetDefaultSearchProvider(); | |
858 ExpectSimilar(expected_managed_default.get(), actual_managed_default); | |
859 | |
860 // The following call has no effect on the managed search engine. | |
861 model()->RepairPrepopulatedSearchEngines(); | |
862 | |
863 EXPECT_TRUE(model()->is_default_search_managed()); | |
864 actual_managed_default = model()->GetDefaultSearchProvider(); | |
865 ExpectSimilar(expected_managed_default.get(), actual_managed_default); | |
866 } | |
867 | |
868 TEST_F(TemplateURLServiceTest, UpdateKeywordSearchTermsForURL) { | |
869 struct TestData { | |
870 const std::string url; | |
871 const base::string16 term; | |
872 } data[] = { | |
873 { "http://foo/", base::string16() }, | |
874 { "http://foo/foo?q=xx", base::string16() }, | |
875 { "http://x/bar?q=xx", base::string16() }, | |
876 { "http://x/foo?y=xx", base::string16() }, | |
877 { "http://x/foo?q=xx", ASCIIToUTF16("xx") }, | |
878 { "http://x/foo?a=b&q=xx", ASCIIToUTF16("xx") }, | |
879 { "http://x/foo?q=b&q=xx", base::string16() }, | |
880 { "http://x/foo#query=xx", ASCIIToUTF16("xx") }, | |
881 { "http://x/foo?q=b#query=xx", ASCIIToUTF16("xx") }, | |
882 { "http://x/foo?q=b#q=xx", ASCIIToUTF16("b") }, | |
883 { "http://x/foo?query=b#q=xx", base::string16() }, | |
884 }; | |
885 | |
886 test_util_->ChangeModelToLoadState(); | |
887 AddKeywordWithDate("name", "x", "http://x/foo?q={searchTerms}", | |
888 "http://sugg1", "http://x/foo#query={searchTerms}", | |
889 "http://icon1", false, "UTF-8;UTF-16", Time(), Time()); | |
890 | |
891 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { | |
892 TemplateURLService::URLVisitedDetails details = { | |
893 GURL(data[i].url), false | |
894 }; | |
895 model()->UpdateKeywordSearchTermsForURL(details); | |
896 EXPECT_EQ(data[i].term, test_util_->GetAndClearSearchTerm()); | |
897 } | |
898 } | |
899 | |
900 TEST_F(TemplateURLServiceTest, DontUpdateKeywordSearchForNonReplaceable) { | |
901 struct TestData { | |
902 const std::string url; | |
903 } data[] = { | |
904 { "http://foo/" }, | |
905 { "http://x/bar?q=xx" }, | |
906 { "http://x/foo?y=xx" }, | |
907 }; | |
908 | |
909 test_util_->ChangeModelToLoadState(); | |
910 AddKeywordWithDate("name", "x", "http://x/foo", "http://sugg1", std::string(), | |
911 "http://icon1", false, "UTF-8;UTF-16", Time(), Time()); | |
912 | |
913 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { | |
914 TemplateURLService::URLVisitedDetails details = { | |
915 GURL(data[i].url), false | |
916 }; | |
917 model()->UpdateKeywordSearchTermsForURL(details); | |
918 ASSERT_EQ(base::string16(), test_util_->GetAndClearSearchTerm()); | |
919 } | |
920 } | |
921 | |
922 TEST_F(TemplateURLServiceWithoutFallbackTest, ChangeGoogleBaseValue) { | |
923 // NOTE: Do not load the prepopulate data, which also has a {google:baseURL} | |
924 // keyword in it and would confuse this test. | |
925 test_util_->ChangeModelToLoadState(); | |
926 | |
927 test_util_->SetGoogleBaseURL(GURL("http://google.com/")); | |
928 const TemplateURL* t_url = AddKeywordWithDate( | |
929 "name", "google.com", "{google:baseURL}?q={searchTerms}", "http://sugg1", | |
930 std::string(), "http://icon1", false, "UTF-8;UTF-16", Time(), Time()); | |
931 ASSERT_EQ(t_url, model()->GetTemplateURLForHost("google.com")); | |
932 EXPECT_EQ("google.com", t_url->url_ref().GetHost(search_terms_data())); | |
933 EXPECT_EQ(ASCIIToUTF16("google.com"), t_url->keyword()); | |
934 | |
935 // Change the Google base url. | |
936 test_util_->ResetObserverCount(); | |
937 test_util_->SetGoogleBaseURL(GURL("http://google.co.uk/")); | |
938 VerifyObserverCount(1); | |
939 | |
940 // Make sure the host->TemplateURL map was updated appropriately. | |
941 ASSERT_EQ(t_url, model()->GetTemplateURLForHost("google.co.uk")); | |
942 EXPECT_TRUE(model()->GetTemplateURLForHost("google.com") == NULL); | |
943 EXPECT_EQ("google.co.uk", t_url->url_ref().GetHost(search_terms_data())); | |
944 EXPECT_EQ(ASCIIToUTF16("google.co.uk"), t_url->keyword()); | |
945 EXPECT_EQ("http://google.co.uk/?q=x", t_url->url_ref().ReplaceSearchTerms( | |
946 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("x")), search_terms_data())); | |
947 | |
948 // Now add a manual entry and then change the Google base URL such that the | |
949 // autogenerated Google search keyword would conflict. | |
950 TemplateURL* manual = AddKeywordWithDate( | |
951 "manual", "google.de", "http://google.de/search?q={searchTerms}", | |
952 std::string(), std::string(), std::string(), false, "UTF-8", Time(), | |
953 Time()); | |
954 test_util_->SetGoogleBaseURL(GURL("http://google.de")); | |
955 | |
956 // Verify that the manual entry is untouched, and the autogenerated keyword | |
957 // has not changed. | |
958 ASSERT_EQ(manual, | |
959 model()->GetTemplateURLForKeyword(ASCIIToUTF16("google.de"))); | |
960 EXPECT_EQ("google.de", manual->url_ref().GetHost(search_terms_data())); | |
961 ASSERT_EQ(t_url, | |
962 model()->GetTemplateURLForKeyword(ASCIIToUTF16("google.co.uk"))); | |
963 EXPECT_EQ("google.de", t_url->url_ref().GetHost(search_terms_data())); | |
964 EXPECT_EQ(ASCIIToUTF16("google.co.uk"), t_url->keyword()); | |
965 | |
966 // Change the base URL again and verify that the autogenerated keyword follows | |
967 // even though it didn't match the base URL, while the manual entry is still | |
968 // untouched. | |
969 test_util_->SetGoogleBaseURL(GURL("http://google.fr/")); | |
970 ASSERT_EQ(manual, model()->GetTemplateURLForHost("google.de")); | |
971 EXPECT_EQ("google.de", manual->url_ref().GetHost(search_terms_data())); | |
972 EXPECT_EQ(ASCIIToUTF16("google.de"), manual->keyword()); | |
973 ASSERT_EQ(t_url, model()->GetTemplateURLForHost("google.fr")); | |
974 EXPECT_TRUE(model()->GetTemplateURLForHost("google.co.uk") == NULL); | |
975 EXPECT_EQ("google.fr", t_url->url_ref().GetHost(search_terms_data())); | |
976 EXPECT_EQ(ASCIIToUTF16("google.fr"), t_url->keyword()); | |
977 } | |
978 | |
979 // Make sure TemplateURLService generates a KEYWORD_GENERATED visit for | |
980 // KEYWORD visits. | |
981 TEST_F(TemplateURLServiceTest, GenerateVisitOnKeyword) { | |
982 test_util_->VerifyLoad(); | |
983 ASSERT_TRUE(test_util_->profile()->CreateHistoryService(true, false)); | |
984 | |
985 // Create a keyword. | |
986 TemplateURL* t_url = AddKeywordWithDate( | |
987 "keyword", "keyword", "http://foo.com/foo?query={searchTerms}", | |
988 "http://sugg1", std::string(), "http://icon1", true, "UTF-8;UTF-16", | |
989 base::Time::Now(), base::Time::Now()); | |
990 | |
991 // Add a visit that matches the url of the keyword. | |
992 HistoryService* history = | |
993 HistoryServiceFactory::GetForProfile(test_util_->profile(), | |
994 Profile::EXPLICIT_ACCESS); | |
995 history->AddPage( | |
996 GURL(t_url->url_ref().ReplaceSearchTerms( | |
997 TemplateURLRef::SearchTermsArgs(ASCIIToUTF16("blah")), | |
998 search_terms_data())), | |
999 base::Time::Now(), NULL, 0, GURL(), history::RedirectList(), | |
1000 content::PAGE_TRANSITION_KEYWORD, history::SOURCE_BROWSED, false); | |
1001 | |
1002 // Wait for history to finish processing the request. | |
1003 test_util_->profile()->BlockUntilHistoryProcessesPendingRequests(); | |
1004 | |
1005 // Query history for the generated url. | |
1006 base::CancelableTaskTracker tracker; | |
1007 QueryHistoryCallbackImpl callback; | |
1008 history->QueryURL(GURL("http://keyword"), | |
1009 true, | |
1010 base::Bind(&QueryHistoryCallbackImpl::Callback, | |
1011 base::Unretained(&callback)), | |
1012 &tracker); | |
1013 | |
1014 // Wait for the request to be processed. | |
1015 test_util_->profile()->BlockUntilHistoryProcessesPendingRequests(); | |
1016 | |
1017 // And make sure the url and visit were added. | |
1018 EXPECT_TRUE(callback.success); | |
1019 EXPECT_NE(0, callback.row.id()); | |
1020 ASSERT_EQ(1U, callback.visits.size()); | |
1021 EXPECT_EQ(content::PAGE_TRANSITION_KEYWORD_GENERATED, | |
1022 content::PageTransitionStripQualifier(callback.visits[0].transition)); | |
1023 } | |
1024 | |
1025 // Make sure that the load routine deletes prepopulated engines that no longer | |
1026 // exist in the prepopulate data. | |
1027 TEST_F(TemplateURLServiceTest, LoadDeletesUnusedProvider) { | |
1028 // Create a preloaded template url. Add it to a loaded model and wait for the | |
1029 // saves to finish. | |
1030 TemplateURL* t_url = CreatePreloadedTemplateURL(true, 999999); | |
1031 test_util_->ChangeModelToLoadState(); | |
1032 model()->Add(t_url); | |
1033 ASSERT_TRUE( | |
1034 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")) != NULL); | |
1035 base::RunLoop().RunUntilIdle(); | |
1036 | |
1037 // Ensure that merging clears this engine. | |
1038 test_util_->ResetModel(true); | |
1039 ASSERT_TRUE( | |
1040 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")) == NULL); | |
1041 | |
1042 // Wait for any saves to finish. | |
1043 base::RunLoop().RunUntilIdle(); | |
1044 | |
1045 // Reload the model to verify that the database was updated as a result of the | |
1046 // merge. | |
1047 test_util_->ResetModel(true); | |
1048 ASSERT_TRUE( | |
1049 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")) == NULL); | |
1050 } | |
1051 | |
1052 // Make sure that load routine doesn't delete prepopulated engines that no | |
1053 // longer exist in the prepopulate data if it has been modified by the user. | |
1054 TEST_F(TemplateURLServiceTest, LoadRetainsModifiedProvider) { | |
1055 // Create a preloaded template url and add it to a loaded model. | |
1056 TemplateURL* t_url = CreatePreloadedTemplateURL(false, 999999); | |
1057 test_util_->ChangeModelToLoadState(); | |
1058 model()->Add(t_url); | |
1059 | |
1060 // Do the copy after t_url is added so that the id is set. | |
1061 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
1062 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest"))); | |
1063 | |
1064 // Wait for any saves to finish. | |
1065 base::RunLoop().RunUntilIdle(); | |
1066 | |
1067 // Ensure that merging won't clear it if the user has edited it. | |
1068 test_util_->ResetModel(true); | |
1069 const TemplateURL* url_for_unittest = | |
1070 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")); | |
1071 ASSERT_TRUE(url_for_unittest != NULL); | |
1072 AssertEquals(*cloned_url, *url_for_unittest); | |
1073 | |
1074 // Wait for any saves to finish. | |
1075 base::RunLoop().RunUntilIdle(); | |
1076 | |
1077 // Reload the model to verify that save/reload retains the item. | |
1078 test_util_->ResetModel(true); | |
1079 ASSERT_TRUE( | |
1080 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")) != NULL); | |
1081 } | |
1082 | |
1083 // Make sure that load routine doesn't delete | |
1084 // prepopulated engines that no longer exist in the prepopulate data if | |
1085 // it has been modified by the user. | |
1086 TEST_F(TemplateURLServiceTest, LoadSavesPrepopulatedDefaultSearchProvider) { | |
1087 test_util_->VerifyLoad(); | |
1088 // Verify that the default search provider is set to something. | |
1089 TemplateURL* default_search = model()->GetDefaultSearchProvider(); | |
1090 ASSERT_TRUE(default_search != NULL); | |
1091 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(default_search->data())); | |
1092 | |
1093 // Wait for any saves to finish. | |
1094 base::RunLoop().RunUntilIdle(); | |
1095 | |
1096 // Reload the model and check that the default search provider | |
1097 // was properly saved. | |
1098 test_util_->ResetModel(true); | |
1099 default_search = model()->GetDefaultSearchProvider(); | |
1100 ASSERT_TRUE(default_search != NULL); | |
1101 AssertEquals(*cloned_url, *default_search); | |
1102 } | |
1103 | |
1104 // Make sure that the load routine doesn't delete | |
1105 // prepopulated engines that no longer exist in the prepopulate data if | |
1106 // it is the default search provider. | |
1107 TEST_F(TemplateURLServiceTest, LoadRetainsDefaultProvider) { | |
1108 // Set the default search provider to a preloaded template url which | |
1109 // is not in the current set of preloaded template urls and save | |
1110 // the result. | |
1111 TemplateURL* t_url = CreatePreloadedTemplateURL(true, 999999); | |
1112 test_util_->ChangeModelToLoadState(); | |
1113 model()->Add(t_url); | |
1114 model()->SetUserSelectedDefaultSearchProvider(t_url); | |
1115 // Do the copy after t_url is added and set as default so that its | |
1116 // internal state is correct. | |
1117 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | |
1118 | |
1119 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest"))); | |
1120 ASSERT_EQ(t_url, model()->GetDefaultSearchProvider()); | |
1121 base::RunLoop().RunUntilIdle(); | |
1122 | |
1123 // Ensure that merging won't clear the prepopulated template url | |
1124 // which is no longer present if it's the default engine. | |
1125 test_util_->ResetModel(true); | |
1126 { | |
1127 const TemplateURL* keyword_url = | |
1128 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")); | |
1129 ASSERT_TRUE(keyword_url != NULL); | |
1130 AssertEquals(*cloned_url, *keyword_url); | |
1131 ASSERT_EQ(keyword_url, model()->GetDefaultSearchProvider()); | |
1132 } | |
1133 | |
1134 // Wait for any saves to finish. | |
1135 base::RunLoop().RunUntilIdle(); | |
1136 | |
1137 // Reload the model to verify that the update was saved. | |
1138 test_util_->ResetModel(true); | |
1139 { | |
1140 const TemplateURL* keyword_url = | |
1141 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")); | |
1142 ASSERT_TRUE(keyword_url != NULL); | |
1143 AssertEquals(*cloned_url, *keyword_url); | |
1144 ASSERT_EQ(keyword_url, model()->GetDefaultSearchProvider()); | |
1145 } | |
1146 } | |
1147 | |
1148 // Make sure that the load routine sets a default search provider if it was | |
1149 // missing and not managed. | |
1150 TEST_F(TemplateURLServiceTest, LoadEnsuresDefaultSearchProviderExists) { | |
1151 // Force the model to load and make sure we have a default search provider. | |
1152 test_util_->VerifyLoad(); | |
1153 EXPECT_TRUE(model()->GetDefaultSearchProvider()); | |
1154 | |
1155 EXPECT_TRUE(model()->GetDefaultSearchProvider()->SupportsReplacement( | |
1156 search_terms_data())); | |
1157 | |
1158 // Make default search provider unusable (no search terms). | |
1159 model()->ResetTemplateURL(model()->GetDefaultSearchProvider(), | |
1160 ASCIIToUTF16("test"), ASCIIToUTF16("test"), | |
1161 "http://example.com/"); | |
1162 base::RunLoop().RunUntilIdle(); | |
1163 | |
1164 // Reset the model and load it. There should be a usable default search | |
1165 // provider. | |
1166 test_util_->ResetModel(true); | |
1167 | |
1168 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
1169 EXPECT_TRUE(model()->GetDefaultSearchProvider()->SupportsReplacement( | |
1170 search_terms_data())); | |
1171 } | |
1172 | |
1173 // Simulates failing to load the webdb and makes sure the default search | |
1174 // provider is valid. | |
1175 TEST_F(TemplateURLServiceTest, FailedInit) { | |
1176 test_util_->VerifyLoad(); | |
1177 | |
1178 test_util_->ClearModel(); | |
1179 WebDataServiceFactory::GetKeywordWebDataForProfile( | |
1180 test_util_->profile(), Profile::EXPLICIT_ACCESS)->ShutdownDatabase(); | |
1181 | |
1182 test_util_->ResetModel(false); | |
1183 model()->Load(); | |
1184 base::RunLoop().RunUntilIdle(); | |
1185 | |
1186 ASSERT_TRUE(model()->GetDefaultSearchProvider()); | |
1187 } | |
1188 | |
1189 // Verifies that if the default search URL preference is managed, we report | |
1190 // the default search as managed. Also check that we are getting the right | |
1191 // values. | |
1192 TEST_F(TemplateURLServiceTest, TestManagedDefaultSearch) { | |
1193 test_util_->VerifyLoad(); | |
1194 const size_t initial_count = model()->GetTemplateURLs().size(); | |
1195 test_util_->ResetObserverCount(); | |
1196 | |
1197 // Set a regular default search provider. | |
1198 TemplateURL* regular_default = AddKeywordWithDate( | |
1199 "name1", "key1", "http://foo1/{searchTerms}", "http://sugg1", | |
1200 std::string(), "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); | |
1201 VerifyObserverCount(1); | |
1202 model()->SetUserSelectedDefaultSearchProvider(regular_default); | |
1203 // Adding the URL and setting the default search provider should have caused | |
1204 // notifications. | |
1205 VerifyObserverCount(1); | |
1206 EXPECT_FALSE(model()->is_default_search_managed()); | |
1207 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1208 | |
1209 // Set a managed preference that establishes a default search provider. | |
1210 const char kName[] = "test1"; | |
1211 const char kKeyword[] = "test.com"; | |
1212 const char kSearchURL[] = "http://test.com/search?t={searchTerms}"; | |
1213 const char kIconURL[] = "http://test.com/icon.jpg"; | |
1214 const char kEncodings[] = "UTF-16;UTF-32"; | |
1215 const char kAlternateURL[] = "http://test.com/search#t={searchTerms}"; | |
1216 const char kSearchTermsReplacementKey[] = "espv"; | |
1217 test_util_->SetManagedDefaultSearchPreferences(true, kName, kKeyword, | |
1218 kSearchURL, std::string(), kIconURL, kEncodings, kAlternateURL, | |
1219 kSearchTermsReplacementKey); | |
1220 VerifyObserverFired(); | |
1221 EXPECT_TRUE(model()->is_default_search_managed()); | |
1222 EXPECT_EQ(initial_count + 2, model()->GetTemplateURLs().size()); | |
1223 | |
1224 // Verify that the default manager we are getting is the managed one. | |
1225 TemplateURLData data; | |
1226 data.short_name = ASCIIToUTF16(kName); | |
1227 data.SetKeyword(ASCIIToUTF16(kKeyword)); | |
1228 data.SetURL(kSearchURL); | |
1229 data.favicon_url = GURL(kIconURL); | |
1230 data.show_in_default_list = true; | |
1231 base::SplitString(kEncodings, ';', &data.input_encodings); | |
1232 data.alternate_urls.push_back(kAlternateURL); | |
1233 data.search_terms_replacement_key = kSearchTermsReplacementKey; | |
1234 scoped_ptr<TemplateURL> expected_managed_default1(new TemplateURL(data)); | |
1235 const TemplateURL* actual_managed_default = | |
1236 model()->GetDefaultSearchProvider(); | |
1237 ExpectSimilar(expected_managed_default1.get(), actual_managed_default); | |
1238 EXPECT_TRUE(actual_managed_default->show_in_default_list()); | |
1239 | |
1240 // Update the managed preference and check that the model has changed. | |
1241 const char kNewName[] = "test2"; | |
1242 const char kNewKeyword[] = "other.com"; | |
1243 const char kNewSearchURL[] = "http://other.com/search?t={searchTerms}"; | |
1244 const char kNewSuggestURL[] = "http://other.com/suggest?t={searchTerms}"; | |
1245 test_util_->SetManagedDefaultSearchPreferences(true, kNewName, kNewKeyword, | |
1246 kNewSearchURL, kNewSuggestURL, std::string(), std::string(), | |
1247 std::string(), std::string()); | |
1248 VerifyObserverFired(); | |
1249 EXPECT_TRUE(model()->is_default_search_managed()); | |
1250 EXPECT_EQ(initial_count + 2, model()->GetTemplateURLs().size()); | |
1251 | |
1252 // Verify that the default manager we are now getting is the correct one. | |
1253 TemplateURLData data2; | |
1254 data2.short_name = ASCIIToUTF16(kNewName); | |
1255 data2.SetKeyword(ASCIIToUTF16(kNewKeyword)); | |
1256 data2.SetURL(kNewSearchURL); | |
1257 data2.suggestions_url = kNewSuggestURL; | |
1258 data2.show_in_default_list = true; | |
1259 scoped_ptr<TemplateURL> expected_managed_default2(new TemplateURL(data2)); | |
1260 actual_managed_default = model()->GetDefaultSearchProvider(); | |
1261 ExpectSimilar(expected_managed_default2.get(), actual_managed_default); | |
1262 EXPECT_EQ(actual_managed_default->show_in_default_list(), true); | |
1263 | |
1264 // Remove all the managed prefs and check that we are no longer managed. | |
1265 test_util_->RemoveManagedDefaultSearchPreferences(); | |
1266 VerifyObserverFired(); | |
1267 EXPECT_FALSE(model()->is_default_search_managed()); | |
1268 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1269 | |
1270 // The default should now be the user preference. | |
1271 const TemplateURL* actual_final_managed_default = | |
1272 model()->GetDefaultSearchProvider(); | |
1273 ExpectSimilar(regular_default, actual_final_managed_default); | |
1274 EXPECT_EQ(actual_final_managed_default->show_in_default_list(), true); | |
1275 | |
1276 // Disable the default search provider through policy. | |
1277 test_util_->SetManagedDefaultSearchPreferences(false, std::string(), | |
1278 std::string(), std::string(), std::string(), std::string(), | |
1279 std::string(), std::string(), std::string()); | |
1280 VerifyObserverFired(); | |
1281 EXPECT_TRUE(model()->is_default_search_managed()); | |
1282 EXPECT_TRUE(NULL == model()->GetDefaultSearchProvider()); | |
1283 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1284 | |
1285 // Re-enable it. | |
1286 test_util_->SetManagedDefaultSearchPreferences(true, kName, kKeyword, | |
1287 kSearchURL, std::string(), kIconURL, kEncodings, kAlternateURL, | |
1288 kSearchTermsReplacementKey); | |
1289 VerifyObserverFired(); | |
1290 EXPECT_TRUE(model()->is_default_search_managed()); | |
1291 EXPECT_EQ(initial_count + 2, model()->GetTemplateURLs().size()); | |
1292 | |
1293 // Verify that the default manager we are getting is the managed one. | |
1294 actual_managed_default = model()->GetDefaultSearchProvider(); | |
1295 ExpectSimilar(expected_managed_default1.get(), actual_managed_default); | |
1296 EXPECT_EQ(actual_managed_default->show_in_default_list(), true); | |
1297 | |
1298 // Clear the model and disable the default search provider through policy. | |
1299 // Verify that there is no default search provider after loading the model. | |
1300 // This checks against regressions of http://crbug.com/67180 | |
1301 | |
1302 // First, remove the preferences, reset the model, and set a default. | |
1303 test_util_->RemoveManagedDefaultSearchPreferences(); | |
1304 test_util_->ResetModel(true); | |
1305 TemplateURL* new_default = | |
1306 model()->GetTemplateURLForKeyword(ASCIIToUTF16("key1")); | |
1307 ASSERT_FALSE(new_default == NULL); | |
1308 model()->SetUserSelectedDefaultSearchProvider(new_default); | |
1309 EXPECT_EQ(new_default, model()->GetDefaultSearchProvider()); | |
1310 | |
1311 // Now reset the model again but load it after setting the preferences. | |
1312 test_util_->ResetModel(false); | |
1313 test_util_->SetManagedDefaultSearchPreferences(false, std::string(), | |
1314 std::string(), std::string(), std::string(), std::string(), | |
1315 std::string(), std::string(), std::string()); | |
1316 test_util_->VerifyLoad(); | |
1317 EXPECT_TRUE(model()->is_default_search_managed()); | |
1318 EXPECT_TRUE(model()->GetDefaultSearchProvider() == NULL); | |
1319 } | |
1320 | |
1321 // Test that if we load a TemplateURL with an empty GUID, the load process | |
1322 // assigns it a newly generated GUID. | |
1323 TEST_F(TemplateURLServiceTest, PatchEmptySyncGUID) { | |
1324 // Add a new TemplateURL. | |
1325 test_util_->VerifyLoad(); | |
1326 const size_t initial_count = model()->GetTemplateURLs().size(); | |
1327 | |
1328 TemplateURLData data; | |
1329 data.short_name = ASCIIToUTF16("google"); | |
1330 data.SetKeyword(ASCIIToUTF16("keyword")); | |
1331 data.SetURL("http://www.google.com/foo/bar"); | |
1332 data.sync_guid.clear(); | |
1333 TemplateURL* t_url = new TemplateURL(data); | |
1334 model()->Add(t_url); | |
1335 | |
1336 VerifyObserverCount(1); | |
1337 base::RunLoop().RunUntilIdle(); | |
1338 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1339 | |
1340 // Reload the model to verify it was actually saved to the database and | |
1341 // assigned a new GUID when brought back. | |
1342 test_util_->ResetModel(true); | |
1343 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1344 const TemplateURL* loaded_url = | |
1345 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
1346 ASSERT_FALSE(loaded_url == NULL); | |
1347 ASSERT_FALSE(loaded_url->sync_guid().empty()); | |
1348 } | |
1349 | |
1350 // Test that if we load a TemplateURL with duplicate input encodings, the load | |
1351 // process de-dupes them. | |
1352 TEST_F(TemplateURLServiceTest, DuplicateInputEncodings) { | |
1353 // Add a new TemplateURL. | |
1354 test_util_->VerifyLoad(); | |
1355 const size_t initial_count = model()->GetTemplateURLs().size(); | |
1356 | |
1357 TemplateURLData data; | |
1358 data.short_name = ASCIIToUTF16("google"); | |
1359 data.SetKeyword(ASCIIToUTF16("keyword")); | |
1360 data.SetURL("http://www.google.com/foo/bar"); | |
1361 std::vector<std::string> encodings; | |
1362 data.input_encodings.push_back("UTF-8"); | |
1363 data.input_encodings.push_back("UTF-8"); | |
1364 data.input_encodings.push_back("UTF-16"); | |
1365 data.input_encodings.push_back("UTF-8"); | |
1366 data.input_encodings.push_back("Big5"); | |
1367 data.input_encodings.push_back("UTF-16"); | |
1368 data.input_encodings.push_back("Big5"); | |
1369 data.input_encodings.push_back("Windows-1252"); | |
1370 TemplateURL* t_url = new TemplateURL(data); | |
1371 model()->Add(t_url); | |
1372 | |
1373 VerifyObserverCount(1); | |
1374 base::RunLoop().RunUntilIdle(); | |
1375 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1376 const TemplateURL* loaded_url = | |
1377 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
1378 ASSERT_TRUE(loaded_url != NULL); | |
1379 EXPECT_EQ(8U, loaded_url->input_encodings().size()); | |
1380 | |
1381 // Reload the model to verify it was actually saved to the database and the | |
1382 // duplicate encodings were removed. | |
1383 test_util_->ResetModel(true); | |
1384 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | |
1385 loaded_url = model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | |
1386 ASSERT_FALSE(loaded_url == NULL); | |
1387 EXPECT_EQ(4U, loaded_url->input_encodings().size()); | |
1388 } | |
1389 | |
1390 TEST_F(TemplateURLServiceTest, DefaultExtensionEngine) { | |
1391 test_util_->VerifyLoad(); | |
1392 // Add third-party default search engine. | |
1393 TemplateURL* user_dse = AddKeywordWithDate( | |
1394 "user", "user", "http://www.goo.com/s?q={searchTerms}", | |
1395 std::string(), std::string(), std::string(), | |
1396 true, "UTF-8", Time(), Time()); | |
1397 model()->SetUserSelectedDefaultSearchProvider(user_dse); | |
1398 EXPECT_EQ(user_dse, model()->GetDefaultSearchProvider()); | |
1399 | |
1400 TemplateURL* ext_dse = CreateKeywordWithDate( | |
1401 model(), "ext", "ext", "http://www.search.com/s?q={searchTerms}", | |
1402 std::string(), std::string(), std::string(), | |
1403 true, true, "UTF-8", Time(), Time()); | |
1404 scoped_ptr<TemplateURL::AssociatedExtensionInfo> extension_info( | |
1405 new TemplateURL::AssociatedExtensionInfo( | |
1406 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext")); | |
1407 extension_info->wants_to_be_default_engine = true; | |
1408 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); | |
1409 EXPECT_EQ(ext_dse, model()->GetDefaultSearchProvider()); | |
1410 | |
1411 model()->RemoveExtensionControlledTURL( | |
1412 "ext", TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION); | |
1413 ExpectSimilar(user_dse, model()->GetDefaultSearchProvider()); | |
1414 } | |
1415 | |
1416 TEST_F(TemplateURLServiceTest, ExtensionEnginesNotPersist) { | |
1417 test_util_->VerifyLoad(); | |
1418 // Add third-party default search engine. | |
1419 TemplateURL* user_dse = AddKeywordWithDate( | |
1420 "user", "user", "http://www.goo.com/s?q={searchTerms}", | |
1421 std::string(), std::string(), std::string(), | |
1422 true, "UTF-8", Time(), Time()); | |
1423 model()->SetUserSelectedDefaultSearchProvider(user_dse); | |
1424 EXPECT_EQ(user_dse, model()->GetDefaultSearchProvider()); | |
1425 | |
1426 TemplateURL* ext_dse = CreateKeywordWithDate( | |
1427 model(), "ext1", "ext1", "http://www.ext1.com/s?q={searchTerms}", | |
1428 std::string(), std::string(), std::string(), | |
1429 true, false, "UTF-8", Time(), Time()); | |
1430 scoped_ptr<TemplateURL::AssociatedExtensionInfo> extension_info( | |
1431 new TemplateURL::AssociatedExtensionInfo( | |
1432 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext1")); | |
1433 extension_info->wants_to_be_default_engine = false; | |
1434 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); | |
1435 EXPECT_EQ(user_dse, model()->GetDefaultSearchProvider()); | |
1436 | |
1437 ext_dse = CreateKeywordWithDate( | |
1438 model(), "ext2", "ext2", "http://www.ext2.com/s?q={searchTerms}", | |
1439 std::string(), std::string(), std::string(), | |
1440 true, true, "UTF-8", Time(), Time()); | |
1441 extension_info.reset(new TemplateURL::AssociatedExtensionInfo( | |
1442 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext2")); | |
1443 extension_info->wants_to_be_default_engine = true; | |
1444 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); | |
1445 EXPECT_EQ(ext_dse, model()->GetDefaultSearchProvider()); | |
1446 | |
1447 test_util_->ResetModel(true); | |
1448 user_dse = model()->GetTemplateURLForKeyword(ASCIIToUTF16("user")); | |
1449 ExpectSimilar(user_dse, model()->GetDefaultSearchProvider()); | |
1450 EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext1"))); | |
1451 EXPECT_FALSE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext2"))); | |
1452 } | |
1453 | |
1454 TEST_F(TemplateURLServiceTest, ExtensionEngineVsPolicy) { | |
1455 // Set a managed preference that establishes a default search provider. | |
1456 const char kName[] = "test"; | |
1457 const char kKeyword[] = "test.com"; | |
1458 const char kSearchURL[] = "http://test.com/search?t={searchTerms}"; | |
1459 const char kIconURL[] = "http://test.com/icon.jpg"; | |
1460 const char kEncodings[] = "UTF-16;UTF-32"; | |
1461 const char kAlternateURL[] = "http://test.com/search#t={searchTerms}"; | |
1462 const char kSearchTermsReplacementKey[] = "espv"; | |
1463 test_util_->SetManagedDefaultSearchPreferences( | |
1464 true, kName, kKeyword, kSearchURL, std::string(), kIconURL, kEncodings, | |
1465 kAlternateURL, kSearchTermsReplacementKey); | |
1466 test_util_->VerifyLoad(); | |
1467 // Verify that the default manager we are getting is the managed one. | |
1468 TemplateURLData data; | |
1469 data.short_name = ASCIIToUTF16(kName); | |
1470 data.SetKeyword(ASCIIToUTF16(kKeyword)); | |
1471 data.SetURL(kSearchURL); | |
1472 data.favicon_url = GURL(kIconURL); | |
1473 data.show_in_default_list = true; | |
1474 base::SplitString(kEncodings, ';', &data.input_encodings); | |
1475 data.alternate_urls.push_back(kAlternateURL); | |
1476 data.search_terms_replacement_key = kSearchTermsReplacementKey; | |
1477 scoped_ptr<TemplateURL> expected_managed_default(new TemplateURL(data)); | |
1478 EXPECT_TRUE(model()->is_default_search_managed()); | |
1479 const TemplateURL* actual_managed_default = | |
1480 model()->GetDefaultSearchProvider(); | |
1481 ExpectSimilar(expected_managed_default.get(), actual_managed_default); | |
1482 | |
1483 TemplateURL* ext_dse = CreateKeywordWithDate( | |
1484 model(), "ext1", "ext1", "http://www.ext1.com/s?q={searchTerms}", | |
1485 std::string(), std::string(), std::string(), | |
1486 true, true, "UTF-8", Time(), Time()); | |
1487 scoped_ptr<TemplateURL::AssociatedExtensionInfo> extension_info( | |
1488 new TemplateURL::AssociatedExtensionInfo( | |
1489 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext1")); | |
1490 extension_info->wants_to_be_default_engine = true; | |
1491 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); | |
1492 EXPECT_EQ(ext_dse, model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext1"))); | |
1493 EXPECT_TRUE(model()->is_default_search_managed()); | |
1494 actual_managed_default = model()->GetDefaultSearchProvider(); | |
1495 ExpectSimilar(expected_managed_default.get(), actual_managed_default); | |
1496 } | |
OLD | NEW |