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"
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
;
35 using base::TimeDelta
;
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
;
50 this->visits
= visits
;
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
,
73 data
.SetShortName(base::UTF8ToUTF16(short_name
));
74 data
.SetKeyword(base::UTF8ToUTF16(keyword
));
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
,
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
);
105 EXPECT_NE(0, t_url
->id());
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());
130 // TemplateURLServiceTest -----------------------------------------------------
132 class TemplateURLServiceTest
: public testing::Test
{
134 TemplateURLServiceTest();
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
,
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
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
,
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();
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
{
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() {
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
,
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
);
299 ASSERT_TRUE(model()->CanAddAutogeneratedKeyword(ASCIIToUTF16("keyword"),
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
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"),
320 // We expect the last_modified time to be updated to the present time on an
322 base::Time now
= base::Time::Now();
323 scoped_ptr
<base::SimpleTestClock
> clock(new base::SimpleTestClock
);
325 model()->set_clock(clock
.Pass());
327 // Mutate an element and verify it succeeded.
328 model()->ResetTemplateURL(loaded_url
, ASCIIToUTF16("a"), ASCIIToUTF16("b"),
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"),
336 ASSERT_FALSE(model()->CanAddAutogeneratedKeyword(ASCIIToUTF16("b"), GURL(),
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
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();
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
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
);
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
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();
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",
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
);
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",
458 TemplateURL
* extension
=
459 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword"));
460 ASSERT_TRUE(extension
);
461 // Adding a keyword that matches the extension.
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
);
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
);
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")));
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",
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
,
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
,
532 AddKeywordWithDate("name6", "key6", "http://foo6", "http://suggest6",
533 std::string(), "http://icon6", false, "UTF-8;UTF-16",
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
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());
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
,
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
,
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
,
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
);
634 VerifyObserverCount(1);
635 base::RunLoop().RunUntilIdle();
637 base::Time now
= base::Time::Now();
638 scoped_ptr
<base::SimpleTestClock
> clock(new base::SimpleTestClock
);
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
));
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(),
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(),
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(),
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
);
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"));
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());
807 TemplateURL
* bing
= model()->GetTemplateURLForKeyword(
808 ASCIIToUTF16("bing.com"));
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",
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"));
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
,
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
) {
879 const std::string url
;
880 const base::string16 term
;
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
) {
911 const std::string url
;
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(),
963 test_util()->SetGoogleBaseURL(GURL("http://google.de"));
965 // Verify that the manual entry is untouched, and the autogenerated keyword
968 model()->GetTemplateURLForKeyword(ASCIIToUTF16("google.de")));
969 EXPECT_EQ("google.de", manual
->url_ref().GetHost(search_terms_data()));
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
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
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);
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
);
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"),
1019 base::Bind(&QueryHistoryCallbackImpl::Callback
,
1020 base::Unretained(&callback
)),
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
1039 TemplateURL
* t_url
= CreatePreloadedTemplateURL(true, 999999);
1040 test_util()->ChangeModelToLoadState();
1041 model()->Add(t_url
);
1043 model()->GetTemplateURLForKeyword(ASCIIToUTF16("unittest")) != NULL
);
1044 base::RunLoop().RunUntilIdle();
1046 // Ensure that merging clears this engine.
1047 test_util()->ResetModel(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
1056 test_util()->ResetModel(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);
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
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
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);
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
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
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());
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
);