OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "components/search_engines/template_url_service.h" |
| 6 |
5 #include "base/bind.h" | 7 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
7 #include "base/callback.h" | 9 #include "base/callback.h" |
8 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| 11 #include "base/memory/scoped_ptr.h" |
9 #include "base/memory/scoped_vector.h" | 12 #include "base/memory/scoped_vector.h" |
10 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
11 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
12 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
14 #include "base/task/cancelable_task_tracker.h" | 17 #include "base/task/cancelable_task_tracker.h" |
15 #include "base/test/mock_time_provider.h" | 18 #include "base/test/simple_test_clock.h" |
16 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
17 #include "base/time/time.h" | 20 #include "base/time/time.h" |
18 #include "chrome/browser/history/history_service.h" | 21 #include "chrome/browser/history/history_service.h" |
19 #include "chrome/browser/history/history_service_factory.h" | 22 #include "chrome/browser/history/history_service_factory.h" |
20 #include "chrome/browser/search_engines/template_url_service_test_util.h" | 23 #include "chrome/browser/search_engines/template_url_service_test_util.h" |
21 #include "chrome/test/base/testing_profile.h" | 24 #include "chrome/test/base/testing_profile.h" |
22 #include "components/search_engines/keyword_web_data_service.h" | 25 #include "components/search_engines/keyword_web_data_service.h" |
23 #include "components/search_engines/search_host_to_urls_map.h" | 26 #include "components/search_engines/search_host_to_urls_map.h" |
24 #include "components/search_engines/search_terms_data.h" | 27 #include "components/search_engines/search_terms_data.h" |
25 #include "components/search_engines/template_url.h" | 28 #include "components/search_engines/template_url.h" |
26 #include "components/search_engines/template_url_prepopulate_data.h" | 29 #include "components/search_engines/template_url_prepopulate_data.h" |
27 #include "components/search_engines/template_url_service.h" | |
28 #include "content/public/test/test_browser_thread_bundle.h" | 30 #include "content/public/test/test_browser_thread_bundle.h" |
29 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
30 | 32 |
31 using base::ASCIIToUTF16; | 33 using base::ASCIIToUTF16; |
32 using base::Time; | 34 using base::Time; |
33 using base::TimeDelta; | 35 using base::TimeDelta; |
34 using ::testing::Return; | |
35 using ::testing::StrictMock; | |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 // QueryHistoryCallbackImpl --------------------------------------------------- | 39 // QueryHistoryCallbackImpl --------------------------------------------------- |
40 | 40 |
41 struct QueryHistoryCallbackImpl { | 41 struct QueryHistoryCallbackImpl { |
42 QueryHistoryCallbackImpl() : success(false) {} | 42 QueryHistoryCallbackImpl() : success(false) {} |
43 | 43 |
44 void Callback(bool success, | 44 void Callback(bool success, |
45 const history::URLRow& row, | 45 const history::URLRow& row, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 const std::string& alternate_url, | 143 const std::string& alternate_url, |
144 const std::string& favicon_url, | 144 const std::string& favicon_url, |
145 bool safe_for_autoreplace, | 145 bool safe_for_autoreplace, |
146 const std::string& encodings, | 146 const std::string& encodings, |
147 Time date_created, | 147 Time date_created, |
148 Time last_modified); | 148 Time last_modified); |
149 | 149 |
150 // Verifies the two TemplateURLs are equal. | 150 // Verifies the two TemplateURLs are equal. |
151 void AssertEquals(const TemplateURL& expected, const TemplateURL& actual); | 151 void AssertEquals(const TemplateURL& expected, const TemplateURL& actual); |
152 | 152 |
| 153 // Verifies the two timestamps are equal, within the expected degree of |
| 154 // precision. |
| 155 void AssertTimesEqual(const base::Time& expected, const base::Time& actual); |
| 156 |
153 // Create an URL that appears to have been prepopulated, but won't be in the | 157 // Create an URL that appears to have been prepopulated, but won't be in the |
154 // current data. The caller owns the returned TemplateURL*. | 158 // current data. The caller owns the returned TemplateURL*. |
155 TemplateURL* CreatePreloadedTemplateURL(bool safe_for_autoreplace, | 159 TemplateURL* CreatePreloadedTemplateURL(bool safe_for_autoreplace, |
156 int prepopulate_id); | 160 int prepopulate_id); |
157 | 161 |
158 // Helper methods to make calling TemplateURLServiceTestUtil methods less | 162 // Helper methods to make calling TemplateURLServiceTestUtil methods less |
159 // visually noisy in the test code. | 163 // visually noisy in the test code. |
160 void VerifyObserverCount(int expected_changed_count); | 164 void VerifyObserverCount(int expected_changed_count); |
161 void VerifyObserverFired(); | 165 void VerifyObserverFired(); |
162 TemplateURLServiceTestUtil* test_util() { return test_util_.get(); } | 166 TemplateURLServiceTestUtil* test_util() { return test_util_.get(); } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 ASSERT_EQ(expected.keyword(), actual.keyword()); | 224 ASSERT_EQ(expected.keyword(), actual.keyword()); |
221 ASSERT_EQ(expected.url(), actual.url()); | 225 ASSERT_EQ(expected.url(), actual.url()); |
222 ASSERT_EQ(expected.suggestions_url(), actual.suggestions_url()); | 226 ASSERT_EQ(expected.suggestions_url(), actual.suggestions_url()); |
223 ASSERT_EQ(expected.favicon_url(), actual.favicon_url()); | 227 ASSERT_EQ(expected.favicon_url(), actual.favicon_url()); |
224 ASSERT_EQ(expected.alternate_urls(), actual.alternate_urls()); | 228 ASSERT_EQ(expected.alternate_urls(), actual.alternate_urls()); |
225 ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list()); | 229 ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list()); |
226 ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace()); | 230 ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace()); |
227 ASSERT_EQ(expected.input_encodings(), actual.input_encodings()); | 231 ASSERT_EQ(expected.input_encodings(), actual.input_encodings()); |
228 ASSERT_EQ(expected.id(), actual.id()); | 232 ASSERT_EQ(expected.id(), actual.id()); |
229 ASSERT_EQ(expected.date_created(), actual.date_created()); | 233 ASSERT_EQ(expected.date_created(), actual.date_created()); |
230 ASSERT_EQ(expected.last_modified(), actual.last_modified()); | 234 AssertTimesEqual(expected.last_modified(), actual.last_modified()); |
231 ASSERT_EQ(expected.sync_guid(), actual.sync_guid()); | 235 ASSERT_EQ(expected.sync_guid(), actual.sync_guid()); |
232 ASSERT_EQ(expected.search_terms_replacement_key(), | 236 ASSERT_EQ(expected.search_terms_replacement_key(), |
233 actual.search_terms_replacement_key()); | 237 actual.search_terms_replacement_key()); |
234 } | 238 } |
235 | 239 |
| 240 void TemplateURLServiceTest::AssertTimesEqual(const base::Time& expected, |
| 241 const base::Time& actual) { |
| 242 // Because times are stored with a granularity of one second, there is a loss |
| 243 // of precision when serializing and deserializing the timestamps. Hence, only |
| 244 // expect timestamps to be equal to within one second of one another. |
| 245 ASSERT_LT((expected - actual).magnitude(), base::TimeDelta::FromSeconds(1)); |
| 246 } |
| 247 |
236 TemplateURL* TemplateURLServiceTest::CreatePreloadedTemplateURL( | 248 TemplateURL* TemplateURLServiceTest::CreatePreloadedTemplateURL( |
237 bool safe_for_autoreplace, | 249 bool safe_for_autoreplace, |
238 int prepopulate_id) { | 250 int prepopulate_id) { |
239 TemplateURLData data; | 251 TemplateURLData data; |
240 data.short_name = ASCIIToUTF16("unittest"); | 252 data.short_name = ASCIIToUTF16("unittest"); |
241 data.SetKeyword(ASCIIToUTF16("unittest")); | 253 data.SetKeyword(ASCIIToUTF16("unittest")); |
242 data.SetURL("http://www.unittest.com/{searchTerms}"); | 254 data.SetURL("http://www.unittest.com/{searchTerms}"); |
243 data.favicon_url = GURL("http://favicon.url"); | 255 data.favicon_url = GURL("http://favicon.url"); |
244 data.show_in_default_list = true; | 256 data.show_in_default_list = true; |
245 data.safe_for_autoreplace = safe_for_autoreplace; | 257 data.safe_for_autoreplace = safe_for_autoreplace; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 test_util()->ResetModel(true); | 310 test_util()->ResetModel(true); |
299 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | 311 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); |
300 TemplateURL* loaded_url = | 312 TemplateURL* loaded_url = |
301 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); | 313 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")); |
302 ASSERT_TRUE(loaded_url != NULL); | 314 ASSERT_TRUE(loaded_url != NULL); |
303 AssertEquals(*cloned_url, *loaded_url); | 315 AssertEquals(*cloned_url, *loaded_url); |
304 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), | 316 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), |
305 NULL)); | 317 NULL)); |
306 | 318 |
307 // We expect the last_modified time to be updated to the present time on an | 319 // We expect the last_modified time to be updated to the present time on an |
308 // explicit reset. We have to set up the expectation here because ResetModel | 320 // explicit reset. |
309 // resets the TimeProvider in the TemplateURLService. | 321 base::Time now = base::Time::Now(); |
310 StrictMock<base::MockTimeProvider> mock_time; | 322 scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock); |
311 model()->set_time_provider(&base::MockTimeProvider::StaticNow); | 323 clock->SetNow(now); |
312 EXPECT_CALL(mock_time, Now()).WillOnce(Return(base::Time::FromDoubleT(1337))); | 324 model()->set_clock(clock.Pass()); |
313 | 325 |
314 // Mutate an element and verify it succeeded. | 326 // Mutate an element and verify it succeeded. |
315 model()->ResetTemplateURL(loaded_url, ASCIIToUTF16("a"), ASCIIToUTF16("b"), | 327 model()->ResetTemplateURL(loaded_url, ASCIIToUTF16("a"), ASCIIToUTF16("b"), |
316 "c"); | 328 "c"); |
317 ASSERT_EQ(ASCIIToUTF16("a"), loaded_url->short_name()); | 329 ASSERT_EQ(ASCIIToUTF16("a"), loaded_url->short_name()); |
318 ASSERT_EQ(ASCIIToUTF16("b"), loaded_url->keyword()); | 330 ASSERT_EQ(ASCIIToUTF16("b"), loaded_url->keyword()); |
319 ASSERT_EQ("c", loaded_url->url()); | 331 ASSERT_EQ("c", loaded_url->url()); |
320 ASSERT_FALSE(loaded_url->safe_for_autoreplace()); | 332 ASSERT_FALSE(loaded_url->safe_for_autoreplace()); |
321 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), | 333 ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), |
322 NULL)); | 334 NULL)); |
323 ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("b"), GURL(), NULL)); | 335 ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("b"), GURL(), NULL)); |
324 cloned_url.reset(new TemplateURL(loaded_url->data())); | 336 cloned_url.reset(new TemplateURL(loaded_url->data())); |
325 base::RunLoop().RunUntilIdle(); | 337 base::RunLoop().RunUntilIdle(); |
326 test_util()->ResetModel(true); | 338 test_util()->ResetModel(true); |
327 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | 339 ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); |
328 loaded_url = model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")); | 340 loaded_url = model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")); |
329 ASSERT_TRUE(loaded_url != NULL); | 341 ASSERT_TRUE(loaded_url != NULL); |
330 AssertEquals(*cloned_url, *loaded_url); | 342 AssertEquals(*cloned_url, *loaded_url); |
331 // We changed a TemplateURL in the service, so ensure that the time was | 343 // We changed a TemplateURL in the service, so ensure that the time was |
332 // updated. | 344 // updated. |
333 ASSERT_EQ(base::Time::FromDoubleT(1337), loaded_url->last_modified()); | 345 AssertTimesEqual(now, loaded_url->last_modified()); |
334 | 346 |
335 // Remove an element and verify it succeeded. | 347 // Remove an element and verify it succeeded. |
336 model()->Remove(loaded_url); | 348 model()->Remove(loaded_url); |
337 VerifyObserverCount(1); | 349 VerifyObserverCount(1); |
338 test_util()->ResetModel(true); | 350 test_util()->ResetModel(true); |
339 ASSERT_EQ(initial_count, model()->GetTemplateURLs().size()); | 351 ASSERT_EQ(initial_count, model()->GetTemplateURLs().size()); |
340 EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")) == NULL); | 352 EXPECT_TRUE(model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")) == NULL); |
341 } | 353 } |
342 | 354 |
343 TEST_F(TemplateURLServiceTest, AddSameKeyword) { | 355 TEST_F(TemplateURLServiceTest, AddSameKeyword) { |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 data.SetURL("http://www.google.com/foo/bar"); | 625 data.SetURL("http://www.google.com/foo/bar"); |
614 data.favicon_url = GURL("http://favicon.url"); | 626 data.favicon_url = GURL("http://favicon.url"); |
615 data.date_created = Time::FromTimeT(100); | 627 data.date_created = Time::FromTimeT(100); |
616 data.last_modified = Time::FromTimeT(100); | 628 data.last_modified = Time::FromTimeT(100); |
617 TemplateURL* t_url = new TemplateURL(data); | 629 TemplateURL* t_url = new TemplateURL(data); |
618 model()->Add(t_url); | 630 model()->Add(t_url); |
619 | 631 |
620 VerifyObserverCount(1); | 632 VerifyObserverCount(1); |
621 base::RunLoop().RunUntilIdle(); | 633 base::RunLoop().RunUntilIdle(); |
622 | 634 |
623 StrictMock<base::MockTimeProvider> mock_time; | 635 base::Time now = base::Time::Now(); |
624 model()->set_time_provider(&base::MockTimeProvider::StaticNow); | 636 scoped_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock); |
625 EXPECT_CALL(mock_time, Now()).WillOnce(Return(base::Time::FromDoubleT(1337))); | 637 clock->SetNow(now); |
| 638 model()->set_clock(clock.Pass()); |
626 | 639 |
627 // Reset the short name, keyword, url and make sure it takes. | 640 // Reset the short name, keyword, url and make sure it takes. |
628 const base::string16 new_short_name(ASCIIToUTF16("a")); | 641 const base::string16 new_short_name(ASCIIToUTF16("a")); |
629 const base::string16 new_keyword(ASCIIToUTF16("b")); | 642 const base::string16 new_keyword(ASCIIToUTF16("b")); |
630 const std::string new_url("c"); | 643 const std::string new_url("c"); |
631 model()->ResetTemplateURL(t_url, new_short_name, new_keyword, new_url); | 644 model()->ResetTemplateURL(t_url, new_short_name, new_keyword, new_url); |
632 ASSERT_EQ(new_short_name, t_url->short_name()); | 645 ASSERT_EQ(new_short_name, t_url->short_name()); |
633 ASSERT_EQ(new_keyword, t_url->keyword()); | 646 ASSERT_EQ(new_keyword, t_url->keyword()); |
634 ASSERT_EQ(new_url, t_url->url()); | 647 ASSERT_EQ(new_url, t_url->url()); |
635 | 648 |
636 // Make sure the mappings in the model were updated. | 649 // Make sure the mappings in the model were updated. |
637 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(new_keyword)); | 650 ASSERT_EQ(t_url, model()->GetTemplateURLForKeyword(new_keyword)); |
638 ASSERT_TRUE( | 651 ASSERT_TRUE( |
639 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")) == NULL); | 652 model()->GetTemplateURLForKeyword(ASCIIToUTF16("keyword")) == NULL); |
640 | 653 |
641 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); | 654 scoped_ptr<TemplateURL> cloned_url(new TemplateURL(t_url->data())); |
642 | 655 |
643 // Reload the model from the database and make sure the change took. | 656 // Reload the model from the database and make sure the change took. |
644 test_util()->ResetModel(true); | 657 test_util()->ResetModel(true); |
645 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); | 658 EXPECT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); |
646 const TemplateURL* read_url = model()->GetTemplateURLForKeyword(new_keyword); | 659 const TemplateURL* read_url = model()->GetTemplateURLForKeyword(new_keyword); |
647 ASSERT_TRUE(read_url); | 660 ASSERT_TRUE(read_url); |
648 AssertEquals(*cloned_url, *read_url); | 661 AssertEquals(*cloned_url, *read_url); |
649 ASSERT_EQ(base::Time::FromDoubleT(1337), read_url->last_modified()); | 662 AssertTimesEqual(now, read_url->last_modified()); |
650 } | 663 } |
651 | 664 |
652 TEST_F(TemplateURLServiceTest, DefaultSearchProvider) { | 665 TEST_F(TemplateURLServiceTest, DefaultSearchProvider) { |
653 // Add a new TemplateURL. | 666 // Add a new TemplateURL. |
654 test_util()->VerifyLoad(); | 667 test_util()->VerifyLoad(); |
655 const size_t initial_count = model()->GetTemplateURLs().size(); | 668 const size_t initial_count = model()->GetTemplateURLs().size(); |
656 TemplateURL* t_url = AddKeywordWithDate( | 669 TemplateURL* t_url = AddKeywordWithDate( |
657 "name1", "key1", "http://foo1/{searchTerms}", "http://sugg1", | 670 "name1", "key1", "http://foo1/{searchTerms}", "http://sugg1", |
658 std::string(), "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); | 671 std::string(), "http://icon1", true, "UTF-8;UTF-16", Time(), Time()); |
659 test_util()->ResetObserverCount(); | 672 test_util()->ResetObserverCount(); |
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 scoped_ptr<TemplateURL::AssociatedExtensionInfo> extension_info( | 1491 scoped_ptr<TemplateURL::AssociatedExtensionInfo> extension_info( |
1479 new TemplateURL::AssociatedExtensionInfo( | 1492 new TemplateURL::AssociatedExtensionInfo( |
1480 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext1")); | 1493 TemplateURL::NORMAL_CONTROLLED_BY_EXTENSION, "ext1")); |
1481 extension_info->wants_to_be_default_engine = true; | 1494 extension_info->wants_to_be_default_engine = true; |
1482 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); | 1495 model()->AddExtensionControlledTURL(ext_dse, extension_info.Pass()); |
1483 EXPECT_EQ(ext_dse, model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext1"))); | 1496 EXPECT_EQ(ext_dse, model()->GetTemplateURLForKeyword(ASCIIToUTF16("ext1"))); |
1484 EXPECT_TRUE(model()->is_default_search_managed()); | 1497 EXPECT_TRUE(model()->is_default_search_managed()); |
1485 actual_managed_default = model()->GetDefaultSearchProvider(); | 1498 actual_managed_default = model()->GetDefaultSearchProvider(); |
1486 ExpectSimilar(expected_managed_default.get(), actual_managed_default); | 1499 ExpectSimilar(expected_managed_default.get(), actual_managed_default); |
1487 } | 1500 } |
OLD | NEW |