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