1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/file_util.h"
8 #include "base/logging.h"
9 #include "base/path_service.h"
10 #include "base/string_util.h"
11 #include "chrome/browser/template_url.h"
12 #include "chrome/browser/template_url_model.h"
13 #include "chrome/common/pref_service.h"
14 #include "chrome/test/testing_profile.h"
15 #include "googleurl/src/gurl.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 // A Task used to coordinate when the database has finished processing
19 // requests. See note in BlockTillServiceProcessesRequests for details.
21 // When Run() schedules a QuitTask on the message loop it was created with.
22 class QuitTask2
: public Task
{
24 QuitTask2() : main_loop_(MessageLoop::current()) {}
27 main_loop_
->PostTask(FROM_HERE
, new MessageLoop::QuitTask());
31 MessageLoop
* main_loop_
;
34 // Subclass the TestingProfile so that it can return a WebDataService.
35 class TemplateURLModelTestingProfile
: public TestingProfile
{
37 TemplateURLModelTestingProfile() : TestingProfile() { }
40 // Name a subdirectory of the temp directory.
41 ASSERT_TRUE(PathService::Get(base::DIR_TEMP
, &test_dir_
));
42 file_util::AppendToPath(&test_dir_
, L
"TemplateURLModelTest");
44 // Create a fresh, empty copy of this directory.
45 file_util::Delete(test_dir_
, true);
46 CreateDirectory(test_dir_
.c_str(), NULL
);
48 std::wstring path
= test_dir_
;
49 file_util::AppendToPath(&path
, L
"TestDataService.db");
50 service_
= new WebDataService
;
51 EXPECT_TRUE(service_
->InitWithPath(path
));
55 // Clean up the test directory.
57 ASSERT_TRUE(file_util::Delete(test_dir_
, true));
58 ASSERT_FALSE(file_util::PathExists(test_dir_
));
61 virtual WebDataService
* GetWebDataService(ServiceAccessType access
) {
62 return service_
.get();
66 scoped_refptr
<WebDataService
> service_
;
67 std::wstring test_dir_
;
70 // Trivial subclass of TemplateURLModel that records the last invocation of
71 // SetKeywordSearchTermsForURL.
72 class TestingTemplateURLModel
: public TemplateURLModel
{
74 explicit TestingTemplateURLModel(Profile
* profile
)
75 : TemplateURLModel(profile
) {
78 std::wstring
GetAndClearSearchTerm() {
79 std::wstring search_term
;
80 search_term
.swap(search_term_
);
85 virtual void SetKeywordSearchTermsForURL(const TemplateURL
* t_url
,
87 const std::wstring
& term
) {
92 std::wstring search_term_
;
94 DISALLOW_EVIL_CONSTRUCTORS(TestingTemplateURLModel
);
97 class TemplateURLModelTest
: public testing::Test
,
98 public TemplateURLModelObserver
{
100 TemplateURLModelTest() : changed_count_(0) {
103 virtual void SetUp() {
104 profile_
.reset(new TemplateURLModelTestingProfile());
106 model_
.reset(new TestingTemplateURLModel(profile_
.get()));
107 model_
->AddObserver(this);
110 virtual void TearDown() {
111 profile_
->TearDown();
112 delete TemplateURLRef::google_base_url_
;
113 TemplateURLRef::google_base_url_
= NULL
;
115 // Flush the message loop to make Purify happy.
116 message_loop_
.RunAllPending();
119 TemplateURL
* AddKeywordWithDate(const std::wstring
& keyword
,
120 bool autogenerate_keyword
,
121 const std::wstring
& url
,
122 const std::wstring
& short_name
,
123 bool safe_for_autoreplace
,
125 TemplateURL
* template_url
= new TemplateURL();
126 template_url
->SetURL(url
, 0, 0);
127 template_url
->set_keyword(keyword
);
128 template_url
->set_autogenerate_keyword(autogenerate_keyword
);
129 template_url
->set_short_name(short_name
);
130 template_url
->set_date_created(created_date
);
131 template_url
->set_safe_for_autoreplace(safe_for_autoreplace
);
132 model_
->Add(template_url
);
133 EXPECT_NE(0, template_url
->id());
137 virtual void OnTemplateURLModelChanged() {
141 void VerifyObserverCount(int expected_changed_count
) {
142 ASSERT_EQ(expected_changed_count
, changed_count_
);
146 // Blocks the caller until the service has finished servicing all pending
148 void BlockTillServiceProcessesRequests() {
149 // Schedule a task on the background thread that is processed after all
150 // pending requests on the background thread.
151 profile_
->GetWebDataService(Profile::EXPLICIT_ACCESS
)->thread()->
152 message_loop()->PostTask(FROM_HERE
, new QuitTask2());
153 // Run the current message loop. QuitTask2, when run, invokes Quit,
154 // which unblocks this.
155 MessageLoop::current()->Run();
158 // Makes sure the load was successful and sent the correct notification.
160 ASSERT_FALSE(model_
->loaded());
162 BlockTillServiceProcessesRequests();
163 VerifyObserverCount(1);
167 // Creates a new TemplateURLModel.
168 void ResetModel(bool verify_load
) {
169 model_
.reset(new TestingTemplateURLModel(profile_
.get()));
170 model_
->AddObserver(this);
176 // Verifies the two TemplateURLs are equal.
177 void AssertEquals(const TemplateURL
& expected
, const TemplateURL
& actual
) {
178 ASSERT_EQ(expected
.url()->url(), actual
.url()->url());
179 ASSERT_EQ(expected
.keyword(), actual
.keyword());
180 ASSERT_EQ(expected
.short_name(), actual
.short_name());
181 ASSERT_TRUE(expected
.GetFavIconURL() == actual
.GetFavIconURL());
182 ASSERT_EQ(expected
.id(), actual
.id());
183 ASSERT_EQ(expected
.safe_for_autoreplace(), actual
.safe_for_autoreplace());
184 ASSERT_EQ(expected
.show_in_default_list(), actual
.show_in_default_list());
185 ASSERT_TRUE(expected
.date_created() == actual
.date_created());
188 std::wstring
GetAndClearSearchTerm() {
189 return model_
->GetAndClearSearchTerm();
192 void SetGoogleBaseURL(const std::wstring
& base_url
) const {
193 delete TemplateURLRef::google_base_url_
;
194 TemplateURLRef::google_base_url_
= new std::wstring(base_url
);
197 MessageLoopForUI message_loop_
;
198 scoped_ptr
<TemplateURLModelTestingProfile
> profile_
;
199 scoped_ptr
<TestingTemplateURLModel
> model_
;
203 TEST_F(TemplateURLModelTest
, Load
) {
207 TEST_F(TemplateURLModelTest
, AddUpdateRemove
) {
208 // Add a new TemplateURL.
210 const size_t initial_count
= model_
->GetTemplateURLs().size();
212 TemplateURL
* t_url
= new TemplateURL();
213 t_url
->SetURL(L
"http://www.google.com/foo/bar", 0, 0);
214 t_url
->set_keyword(L
"keyword");
215 t_url
->set_short_name(L
"google");
216 GURL
favicon_url("http://favicon.url");
217 t_url
->SetFavIconURL(favicon_url
);
218 t_url
->set_date_created(Time::FromTimeT(100));
219 t_url
->set_safe_for_autoreplace(true);
221 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"keyword", std::wstring(), NULL
));
222 VerifyObserverCount(1);
223 BlockTillServiceProcessesRequests();
224 // We need to clone as model takes ownership of TemplateURL and will
226 TemplateURL
cloned_url(*t_url
);
227 ASSERT_EQ(1 + initial_count
, model_
->GetTemplateURLs().size());
228 ASSERT_TRUE(model_
->GetTemplateURLForKeyword(t_url
->keyword()) == t_url
);
229 ASSERT_TRUE(t_url
->date_created() == cloned_url
.date_created());
231 // Reload the model to verify it was actually saved to the database.
233 ASSERT_EQ(1 + initial_count
, model_
->GetTemplateURLs().size());
234 const TemplateURL
* loaded_url
= model_
->GetTemplateURLForKeyword(L
"keyword");
235 ASSERT_TRUE(loaded_url
!= NULL
);
236 AssertEquals(cloned_url
, *loaded_url
);
237 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"keyword", std::wstring(), NULL
));
239 // Mutate an element and verify it succeeded.
240 model_
->ResetTemplateURL(loaded_url
, L
"a", L
"b", L
"c");
241 ASSERT_EQ(L
"a", loaded_url
->short_name());
242 ASSERT_EQ(L
"b", loaded_url
->keyword());
243 ASSERT_EQ(L
"c", loaded_url
->url()->url());
244 ASSERT_FALSE(loaded_url
->safe_for_autoreplace());
245 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"keyword", std::wstring(), NULL
));
246 ASSERT_FALSE(model_
->CanReplaceKeyword(L
"b", std::wstring(), NULL
));
247 cloned_url
= *loaded_url
;
248 BlockTillServiceProcessesRequests();
250 ASSERT_EQ(1 + initial_count
, model_
->GetTemplateURLs().size());
251 loaded_url
= model_
->GetTemplateURLForKeyword(L
"b");
252 ASSERT_TRUE(loaded_url
!= NULL
);
253 AssertEquals(cloned_url
, *loaded_url
);
255 // Remove an element and verify it succeeded.
256 model_
->Remove(loaded_url
);
257 VerifyObserverCount(1);
259 ASSERT_EQ(initial_count
, model_
->GetTemplateURLs().size());
260 EXPECT_TRUE(model_
->GetTemplateURLForKeyword(L
"b") == NULL
);
263 TEST_F(TemplateURLModelTest
, GenerateKeyword
) {
264 ASSERT_EQ(L
"", TemplateURLModel::GenerateKeyword(GURL(), true));
265 // Shouldn't generate keywords for https.
266 ASSERT_EQ(L
"", TemplateURLModel::GenerateKeyword(GURL("https://blah"), true));
267 ASSERT_EQ(L
"foo", TemplateURLModel::GenerateKeyword(GURL("http://foo"),
269 // www. should be stripped.
270 ASSERT_EQ(L
"foo", TemplateURLModel::GenerateKeyword(GURL("http://www.foo"),
272 // Shouldn't generate keywords with paths, if autodetected.
273 ASSERT_EQ(L
"", TemplateURLModel::GenerateKeyword(GURL("http://blah/foo"),
275 ASSERT_EQ(L
"blah", TemplateURLModel::GenerateKeyword(GURL("http://blah/foo"),
277 // FTP shouldn't generate a keyword.
278 ASSERT_EQ(L
"", TemplateURLModel::GenerateKeyword(GURL("ftp://blah/"), true));
279 // Make sure we don't get a trailing /
280 ASSERT_EQ(L
"blah", TemplateURLModel::GenerateKeyword(GURL("http://blah/"),
284 TEST_F(TemplateURLModelTest
, ClearBrowsingData_Keywords
) {
285 Time now
= Time::Now();
286 TimeDelta one_day
= TimeDelta::FromDays(1);
287 Time month_ago
= now
- TimeDelta::FromDays(30);
289 // Nothing has been added.
290 EXPECT_EQ(0, model_
->GetTemplateURLs().size());
292 // Create one with a 0 time.
293 AddKeywordWithDate(L
"key1", false, L
"http://foo1", L
"name1", true, Time());
294 // Create one for now and +/- 1 day.
295 AddKeywordWithDate(L
"key2", false, L
"http://foo2", L
"name2", true,
297 AddKeywordWithDate(L
"key3", false, L
"http://foo3", L
"name3", true, now
);
298 AddKeywordWithDate(L
"key4", false, L
"http://foo4", L
"name4", true,
300 // Try the other three states.
301 AddKeywordWithDate(L
"key5", false, L
"http://foo5", L
"name5", false, now
);
302 AddKeywordWithDate(L
"key6", false, L
"http://foo6", L
"name6", false, month_ago
);
304 // We just added a few items, validate them.
305 EXPECT_EQ(6, model_
->GetTemplateURLs().size());
307 // Try removing from current timestamp. This should delete the one in the
308 // future and one very recent one.
309 model_
->RemoveAutoGeneratedSince(now
);
310 EXPECT_EQ(4, model_
->GetTemplateURLs().size());
312 // Try removing from two months ago. This should only delete items that are
314 model_
->RemoveAutoGeneratedSince(now
- TimeDelta::FromDays(60));
315 EXPECT_EQ(3, model_
->GetTemplateURLs().size());
317 // Make sure the right values remain.
318 EXPECT_EQ(L
"key1", model_
->GetTemplateURLs()[0]->keyword());
319 EXPECT_TRUE(model_
->GetTemplateURLs()[0]->safe_for_autoreplace());
320 EXPECT_EQ(0, model_
->GetTemplateURLs()[0]->date_created().ToInternalValue());
322 EXPECT_EQ(L
"key5", model_
->GetTemplateURLs()[1]->keyword());
323 EXPECT_FALSE(model_
->GetTemplateURLs()[1]->safe_for_autoreplace());
324 EXPECT_EQ(now
.ToInternalValue(),
325 model_
->GetTemplateURLs()[1]->date_created().ToInternalValue());
327 EXPECT_EQ(L
"key6", model_
->GetTemplateURLs()[2]->keyword());
328 EXPECT_FALSE(model_
->GetTemplateURLs()[2]->safe_for_autoreplace());
329 EXPECT_EQ(month_ago
.ToInternalValue(),
330 model_
->GetTemplateURLs()[2]->date_created().ToInternalValue());
332 // Try removing from Time=0. This should delete one more.
333 model_
->RemoveAutoGeneratedSince(Time());
334 EXPECT_EQ(2, model_
->GetTemplateURLs().size());
337 TEST_F(TemplateURLModelTest
, Reset
) {
338 // Add a new TemplateURL.
340 const size_t initial_count
= model_
->GetTemplateURLs().size();
341 TemplateURL
* t_url
= new TemplateURL();
342 t_url
->SetURL(L
"http://www.google.com/foo/bar", 0, 0);
343 t_url
->set_keyword(L
"keyword");
344 t_url
->set_short_name(L
"google");
345 GURL
favicon_url("http://favicon.url");
346 t_url
->SetFavIconURL(favicon_url
);
347 t_url
->set_date_created(Time::FromTimeT(100));
350 VerifyObserverCount(1);
351 BlockTillServiceProcessesRequests();
353 // Reset the short name, keyword, url and make sure it takes.
354 const std::wstring
new_short_name(L
"a");
355 const std::wstring
new_keyword(L
"b");
356 const std::wstring
new_url(L
"c");
357 model_
->ResetTemplateURL(t_url
, new_short_name
, new_keyword
, new_url
);
358 ASSERT_EQ(new_short_name
, t_url
->short_name());
359 ASSERT_EQ(new_keyword
, t_url
->keyword());
360 ASSERT_EQ(new_url
, t_url
->url()->url());
362 // Make sure the mappings in the model were updated.
363 ASSERT_TRUE(model_
->GetTemplateURLForKeyword(new_keyword
) == t_url
);
364 ASSERT_TRUE(model_
->GetTemplateURLForKeyword(L
"keyword") == NULL
);
366 TemplateURL last_url
= *t_url
;
368 // Reload the model from the database and make sure the change took.
371 EXPECT_EQ(initial_count
+ 1, model_
->GetTemplateURLs().size());
372 const TemplateURL
* read_url
= model_
->GetTemplateURLForKeyword(new_keyword
);
373 ASSERT_TRUE(read_url
);
374 AssertEquals(last_url
, *read_url
);
377 TEST_F(TemplateURLModelTest
, DefaultSearchProvider
) {
378 // Add a new TemplateURL.
380 const size_t initial_count
= model_
->GetTemplateURLs().size();
381 TemplateURL
* t_url
= AddKeywordWithDate(L
"key1", false, L
"http://foo1",
382 L
"name1", true, Time());
385 model_
->SetDefaultSearchProvider(t_url
);
387 ASSERT_EQ(t_url
, model_
->GetDefaultSearchProvider());
389 ASSERT_TRUE(t_url
->safe_for_autoreplace());
390 ASSERT_TRUE(t_url
->show_in_default_list());
392 // Setting the default search provider should have caused notification.
393 VerifyObserverCount(1);
395 BlockTillServiceProcessesRequests();
397 TemplateURL cloned_url
= *t_url
;
402 // Make sure when we reload we get a default search provider.
403 EXPECT_EQ(1 + initial_count
, model_
->GetTemplateURLs().size());
404 ASSERT_TRUE(model_
->GetDefaultSearchProvider());
405 AssertEquals(cloned_url
, *model_
->GetDefaultSearchProvider());
408 TEST_F(TemplateURLModelTest
, TemplateURLWithNoKeyword
) {
411 const size_t initial_count
= model_
->GetTemplateURLs().size();
413 AddKeywordWithDate(std::wstring(), false, L
"http://foo1", L
"name1", true,
416 // We just added a few items, validate them.
417 ASSERT_EQ(initial_count
+ 1, model_
->GetTemplateURLs().size());
419 // Reload the model from the database and make sure we get the url back.
422 ASSERT_EQ(1 + initial_count
, model_
->GetTemplateURLs().size());
424 bool found_keyword
= false;
425 for (size_t i
= 0; i
< initial_count
+ 1; ++i
) {
426 if (model_
->GetTemplateURLs()[i
]->keyword().empty()) {
427 found_keyword
= true;
431 ASSERT_TRUE(found_keyword
);
434 TEST_F(TemplateURLModelTest
, CantReplaceWithSameKeyword
) {
435 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"foo", std::wstring(), NULL
));
436 TemplateURL
* t_url
= AddKeywordWithDate(L
"foo", false, L
"http://foo1",
437 L
"name1", true, Time());
439 // Can still replace, newly added template url is marked safe to replace.
440 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"foo", L
"http://foo2", NULL
));
442 // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should
443 // no longer be replaceable.
444 model_
->ResetTemplateURL(t_url
, t_url
->short_name(), t_url
->keyword(),
445 t_url
->url()->url());
447 ASSERT_FALSE(model_
->CanReplaceKeyword(L
"foo", L
"http://foo2", NULL
));
450 TEST_F(TemplateURLModelTest
, CantReplaceWithSameHosts
) {
451 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"foo", L
"http://foo.com", NULL
));
452 TemplateURL
* t_url
= AddKeywordWithDate(L
"foo", false, L
"http://foo.com",
453 L
"name1", true, Time());
455 // Can still replace, newly added template url is marked safe to replace.
456 ASSERT_TRUE(model_
->CanReplaceKeyword(L
"bar", L
"http://foo.com", NULL
));
458 // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should
459 // no longer be replaceable.
460 model_
->ResetTemplateURL(t_url
, t_url
->short_name(), t_url
->keyword(),
461 t_url
->url()->url());
463 ASSERT_FALSE(model_
->CanReplaceKeyword(L
"bar", L
"http://foo.com", NULL
));
466 TEST_F(TemplateURLModelTest
, HasDefaultSearchProvider
) {
467 // We should have a default search provider even if we haven't loaded.
468 ASSERT_TRUE(model_
->GetDefaultSearchProvider());
470 // Now force the model to load and make sure we still have a default.
473 ASSERT_TRUE(model_
->GetDefaultSearchProvider());
476 TEST_F(TemplateURLModelTest
, DefaultSearchProviderLoadedFromPrefs
) {
479 TemplateURL
* template_url
= new TemplateURL();
480 template_url
->SetURL(L
"http://url", 0, 0);
481 template_url
->SetSuggestionsURL(L
"http://url2", 0, 0);
482 template_url
->set_short_name(L
"a");
483 template_url
->set_safe_for_autoreplace(true);
484 template_url
->set_date_created(Time::FromTimeT(100));
486 model_
->Add(template_url
);
488 const TemplateURL::IDType id
= template_url
->id();
490 model_
->SetDefaultSearchProvider(template_url
);
492 BlockTillServiceProcessesRequests();
494 TemplateURL first_default_search_provider
= *template_url
;
498 // Reset the model and don't load it. The template url we set as the default
499 // should be pulled from prefs now.
502 // NOTE: This doesn't use AssertEquals as only a subset of the TemplateURLs
503 // value are persisted to prefs.
504 const TemplateURL
* default_turl
= model_
->GetDefaultSearchProvider();
505 ASSERT_TRUE(default_turl
);
506 ASSERT_TRUE(default_turl
->url());
507 ASSERT_EQ(L
"http://url", default_turl
->url()->url());
508 ASSERT_TRUE(default_turl
->suggestions_url());
509 ASSERT_EQ(L
"http://url2", default_turl
->suggestions_url()->url());
510 ASSERT_EQ(L
"a", default_turl
->short_name());
511 ASSERT_EQ(id
, default_turl
->id());
513 // Now do a load and make sure the default search provider really takes.
516 ASSERT_TRUE(model_
->GetDefaultSearchProvider());
517 AssertEquals(first_default_search_provider
,
518 *model_
->GetDefaultSearchProvider());
521 TEST_F(TemplateURLModelTest
, BuildQueryTerms
) {
523 const std::string url
;
525 // Keys and values are a semicolon separated list of expected values in the
527 const std::string keys
;
528 const std::string values
;
530 // No query should return false.
531 { "http://blah/", false, "", "" },
533 // Query with empty key should return false.
534 { "http://blah/foo?=y", false, "", "" },
536 // Query with key occurring multiple times should return false.
537 { "http://blah/foo?x=y&x=z", false, "", "" },
539 { "http://blah/foo?x=y", true, "x", "y" },
540 { "http://blah/foo?x=y&y=z", true, "x;y", "y;z" },
542 // Key occurring multiple times should get an empty string.
543 { "http://blah/foo?x=y&x=z&y=z", true, "x;y", ";z" },
546 for (size_t i
= 0; i
< arraysize(data
); ++i
) {
547 TemplateURLModel::QueryTerms terms
;
548 ASSERT_EQ(data
[i
].result
,
549 TemplateURLModel::BuildQueryTerms(GURL(data
[i
].url
), &terms
));
550 if (data
[i
].result
) {
551 std::vector
<std::string
> keys
;
552 std::vector
<std::string
> values
;
553 SplitString(data
[i
].keys
, ';', &keys
);
554 SplitString(data
[i
].values
, ';', &values
);
555 ASSERT_TRUE(keys
.size() == values
.size());
556 ASSERT_EQ(keys
.size(), terms
.size());
557 for (size_t j
= 0; j
< keys
.size(); ++j
) {
558 TemplateURLModel::QueryTerms::iterator term_iterator
=
560 ASSERT_TRUE(term_iterator
!= terms
.end());
561 ASSERT_EQ(values
[j
], term_iterator
->second
);
567 TEST_F(TemplateURLModelTest
, UpdateKeywordSearchTermsForURL
) {
569 const std::string url
;
570 const std::wstring term
;
572 { "http://foo/", L
"" },
573 { "http://foo/foo?q=xx", L
"" },
574 { "http://x/bar?q=xx", L
"" },
575 { "http://x/foo?y=xx", L
"" },
576 { "http://x/foo?q=xx", L
"xx" },
577 { "http://x/foo?a=b&q=xx", L
"xx" },
578 { "http://x/foo?q=b&q=xx", L
"" },
581 AddKeywordWithDate(L
"x", false, L
"http://x/foo?q={searchTerms}", L
"name",
584 for (size_t i
= 0; i
< arraysize(data
); ++i
) {
585 model_
->UpdateKeywordSearchTermsForURL(history::URLRow(GURL(data
[i
].url
)));
586 EXPECT_EQ(data
[i
].term
, GetAndClearSearchTerm());
590 TEST_F(TemplateURLModelTest
, DontUpdateKeywordSearchForNonReplaceable
) {
592 const std::string url
;
595 { "http://x/bar?q=xx" },
596 { "http://x/foo?y=xx" },
599 AddKeywordWithDate(L
"x", false, L
"http://x/foo", L
"name", false, Time());
601 for (size_t i
= 0; i
< arraysize(data
); ++i
) {
602 model_
->UpdateKeywordSearchTermsForURL(history::URLRow(GURL(data
[i
].url
)));
603 ASSERT_EQ(std::wstring(), GetAndClearSearchTerm());
607 TEST_F(TemplateURLModelTest
, ChangeGoogleBaseValue
) {
608 // NOTE: Do not do a VerifyLoad() here as it will load the prepopulate data,
609 // which also has a {google:baseURL} keyword in it, which will confuse this
611 SetGoogleBaseURL(L
"http://google.com/");
612 const TemplateURL
* t_url
= AddKeywordWithDate(std::wstring(), true,
613 L
"{google:baseURL}?q={searchTerms}", L
"name", false, Time());
614 ASSERT_EQ(t_url
, model_
->GetTemplateURLForHost("google.com"));
615 EXPECT_EQ("google.com", t_url
->url()->GetHost());
616 EXPECT_EQ(L
"google.com", t_url
->keyword());
618 // Change the Google base url.
619 model_
->loaded_
= true; // Hack to make sure we get notified of the base URL
621 SetGoogleBaseURL(L
"http://foo.com/");
622 model_
->GoogleBaseURLChanged();
623 VerifyObserverCount(1);
625 // Make sure the host->TemplateURL map was updated appropriately.
626 ASSERT_EQ(t_url
, model_
->GetTemplateURLForHost("foo.com"));
627 EXPECT_TRUE(model_
->GetTemplateURLForHost("google.com") == NULL
);
628 EXPECT_EQ("foo.com", t_url
->url()->GetHost());
629 EXPECT_EQ(L
"foo.com", t_url
->keyword());
630 EXPECT_EQ(L
"http://foo.com/?q=x", t_url
->url()->ReplaceSearchTerms(*t_url
,
631 L
"x", TemplateURLRef::NO_SUGGESTIONS_AVAILABLE
, std::wstring()));