diff options
Diffstat (limited to 'chrome/browser/search_engines')
6 files changed, 83 insertions, 23 deletions
diff --git a/chrome/browser/search_engines/template_url.cc b/chrome/browser/search_engines/template_url.cc index 6a5808b..56db39c 100644 --- a/chrome/browser/search_engines/template_url.cc +++ b/chrome/browser/search_engines/template_url.cc @@ -594,6 +594,7 @@ TemplateURL::TemplateURL() safe_for_autoreplace_(false), id_(0), date_created_(base::Time::Now()), + last_modified_(base::Time::Now()), created_by_policy_(false), usage_count_(0), search_engine_type_(SEARCH_ENGINE_OTHER), diff --git a/chrome/browser/search_engines/template_url.h b/chrome/browser/search_engines/template_url.h index 5fe6a96..fc60674 100644 --- a/chrome/browser/search_engines/template_url.h +++ b/chrome/browser/search_engines/template_url.h @@ -142,6 +142,7 @@ class TemplateURLRef { friend class TemplateURLTest; FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterKnown); FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterUnknown); + FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterReallyUnknown); FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLEmpty); FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoTemplateEnd); FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters); @@ -425,6 +426,12 @@ class TemplateURL { void set_date_created(base::Time time) { date_created_ = time; } base::Time date_created() const { return date_created_; } + // The last time this keyword was modified by a user, since creation. + // + // NOTE: Like date_created above, this may be 0. + void set_last_modified(base::Time time) { last_modified_ = time; } + base::Time last_modified() const { return last_modified_; } + // True if this TemplateURL was automatically created by the administrator via // group policy. void set_created_by_policy(bool created_by_policy) { @@ -510,6 +517,7 @@ class TemplateURL { std::vector<std::string> input_encodings_; TemplateURLID id_; base::Time date_created_; + base::Time last_modified_; bool created_by_policy_; int usage_count_; SearchEngineType search_engine_type_; diff --git a/chrome/browser/search_engines/template_url_prepopulate_data.cc b/chrome/browser/search_engines/template_url_prepopulate_data.cc index 0a8aa90..587d10e 100644 --- a/chrome/browser/search_engines/template_url_prepopulate_data.cc +++ b/chrome/browser/search_engines/template_url_prepopulate_data.cc @@ -3394,6 +3394,7 @@ TemplateURL* MakePrepopulatedTemplateURL(const wchar_t* name, new_turl->set_show_in_default_list(true); new_turl->set_safe_for_autoreplace(true); new_turl->set_date_created(Time()); + new_turl->set_last_modified(Time()); std::vector<std::string> turl_encodings; turl_encodings.push_back(encoding); new_turl->set_input_encodings(turl_encodings); diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc index 3e99e85..b98278c 100644 --- a/chrome/browser/search_engines/template_url_service.cc +++ b/chrome/browser/search_engines/template_url_service.cc @@ -102,7 +102,8 @@ TemplateURLService::TemplateURLService(Profile* profile) load_handle_(0), default_search_provider_(NULL), is_default_search_managed_(false), - next_id_(1) { + next_id_(1), + time_provider_(&base::Time::Now) { DCHECK(profile_); Init(NULL, 0); } @@ -116,7 +117,8 @@ TemplateURLService::TemplateURLService(const Initializer* initializers, service_(NULL), default_search_provider_(NULL), is_default_search_managed_(false), - next_id_(1) { + next_id_(1), + time_provider_(&base::Time::Now) { Init(initializers, count); } @@ -399,6 +401,7 @@ void TemplateURLService::ResetTemplateURL(const TemplateURL* url, new_url.SetURL(search_url, 0, 0); } new_url.set_safe_for_autoreplace(false); + new_url.set_last_modified(time_provider_()); UpdateNoNotify(url, new_url); NotifyObservers(); } diff --git a/chrome/browser/search_engines/template_url_service.h b/chrome/browser/search_engines/template_url_service.h index f5c6264..d029d86 100644 --- a/chrome/browser/search_engines/template_url_service.h +++ b/chrome/browser/search_engines/template_url_service.h @@ -62,6 +62,8 @@ class TemplateURLService : public WebDataServiceConsumer, public: typedef std::map<std::string, std::string> QueryTerms; typedef std::vector<const TemplateURL*> TemplateURLVector; + // Type for a static function pointer that acts as a time source. + typedef base::Time(TimeProvider)(); // Struct used for initializing the data store with fake data. // Each initializer is mapped to a TemplateURL. @@ -240,6 +242,14 @@ class TemplateURLService : public WebDataServiceConsumer, // Registers the preferences used to save a TemplateURL to prefs. static void RegisterUserPrefs(PrefService* prefs); +#if defined(UNIT_TEST) + // Set a different time provider function, such as + // base::MockTimeProvider::StaticNow, when testing calls to base::Time::Now. + void set_time_provider(TimeProvider* time_provider) { + time_provider_ = time_provider; + } +#endif + protected: // Cover method for the method of the same name on the HistoryService. // url is the one that was visited with the given search terms. @@ -440,6 +450,9 @@ class TemplateURLService : public WebDataServiceConsumer, // List of extension IDs waiting for Load to have keywords registered. std::vector<std::string> pending_extension_ids_; + // Function returning current time in base::Time units. + TimeProvider* time_provider_; + DISALLOW_COPY_AND_ASSIGN(TemplateURLService); }; diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc index d62bb5d..16936e8 100644 --- a/chrome/browser/search_engines/template_url_service_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_unittest.cc @@ -5,6 +5,7 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_vector.h" +#include "base/test/mock_time_provider.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/threading/thread.h" @@ -28,6 +29,8 @@ using base::Time; using base::TimeDelta; +using ::testing::Return; +using ::testing::StrictMock; // Test the GenerateSearchURL on a thread or the main thread. class TestGenerateSearchURL @@ -93,6 +96,7 @@ static TemplateURL* CreatePreloadedTemplateURL() { GURL favicon_url("http://favicon.url"); t_url->SetFaviconURL(favicon_url); t_url->set_date_created(Time::FromTimeT(100)); + t_url->set_last_modified(Time::FromTimeT(100)); t_url->set_prepopulate_id(999999); return t_url; } @@ -117,7 +121,8 @@ class TemplateURLServiceTest : public testing::Test { const std::string& encodings, const std::string& short_name, bool safe_for_autoreplace, - Time created_date) { + Time created_date, + Time last_modified) { TemplateURL* template_url = new TemplateURL(); template_url->SetURL(url, 0, 0); template_url->SetSuggestionsURL(suggest_url, 0, 0); @@ -129,6 +134,7 @@ class TemplateURLServiceTest : public testing::Test { base::SplitString(encodings, ';', &encodings_vector); template_url->set_input_encodings(encodings_vector); template_url->set_date_created(created_date); + template_url->set_last_modified(last_modified); template_url->set_safe_for_autoreplace(safe_for_autoreplace); model()->Add(template_url); EXPECT_NE(0, template_url->id()); @@ -158,10 +164,11 @@ class TemplateURLServiceTest : public testing::Test { ASSERT_EQ(expected.safe_for_autoreplace(), actual.safe_for_autoreplace()); ASSERT_EQ(expected.show_in_default_list(), actual.show_in_default_list()); ASSERT_TRUE(expected.date_created() == actual.date_created()); + ASSERT_TRUE(expected.last_modified() == actual.last_modified()); } - // Checks that the two TemplateURLs are similar. It does not check the id - // and the date_created. Neither pointer should be NULL. + // Checks that the two TemplateURLs are similar. It does not check the id, the + // date_created or the last_modified time. Neither pointer should be NULL. void ExpectSimilar(const TemplateURL* expected, const TemplateURL* actual) { ASSERT_TRUE(expected != NULL); ASSERT_TRUE(actual != NULL); @@ -387,6 +394,7 @@ TEST_F(TemplateURLServiceTest, AddUpdateRemove) { GURL favicon_url("http://favicon.url"); t_url->SetFaviconURL(favicon_url); t_url->set_date_created(Time::FromTimeT(100)); + t_url->set_last_modified(Time::FromTimeT(100)); t_url->set_safe_for_autoreplace(true); model()->Add(t_url); ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), @@ -410,6 +418,14 @@ TEST_F(TemplateURLServiceTest, AddUpdateRemove) { ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("keyword"), GURL(), NULL)); + // We expect the last_modified time to be updated to the present time on an + // explicit reset. We have to set up the expectation here because ResetModel + // resets the TimeProvider in the TemplateURLService. + StrictMock<base::MockTimeProvider> mock_time; + model()->set_time_provider(&base::MockTimeProvider::StaticNow); + EXPECT_CALL(mock_time, Now()) + .WillOnce(Return(base::Time::FromDoubleT(1337))); + // Mutate an element and verify it succeeded. model()->ResetTemplateURL(loaded_url, ASCIIToUTF16("a"), ASCIIToUTF16("b"), "c"); @@ -427,6 +443,9 @@ TEST_F(TemplateURLServiceTest, AddUpdateRemove) { loaded_url = model()->GetTemplateURLForKeyword(ASCIIToUTF16("b")); ASSERT_TRUE(loaded_url != NULL); AssertEquals(cloned_url, *loaded_url); + // We changed a TemplateURL in the service, so ensure that the time was + // updated. + ASSERT_EQ(loaded_url->last_modified(), base::Time::FromDoubleT(1337)); // Remove an element and verify it succeeded. model()->Remove(loaded_url); @@ -492,21 +511,23 @@ TEST_F(TemplateURLServiceTest, ClearBrowsingData_Keywords) { // Create one with a 0 time. AddKeywordWithDate("key1", false, "http://foo1", "http://suggest1", - "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), + Time()); // Create one for now and +/- 1 day. AddKeywordWithDate("key2", false, "http://foo2", "http://suggest2", "http://icon2", "UTF-8;UTF-16", "name2", true, - now - one_day); + now - one_day, Time()); AddKeywordWithDate("key3", false, "http://foo3", "", "", "", "name3", - true, now); + true, now, Time()); AddKeywordWithDate("key4", false, "http://foo4", "", "", "", "name4", - true, now + one_day); + true, now + one_day, Time()); // Try the other three states. AddKeywordWithDate("key5", false, "http://foo5", "http://suggest5", - "http://icon5", "UTF-8;UTF-16", "name5", false, now); + "http://icon5", "UTF-8;UTF-16", "name5", false, now, + Time()); AddKeywordWithDate("key6", false, "http://foo6", "http://suggest6", "http://icon6", "UTF-8;UTF-16", "name6", false, - month_ago); + month_ago, Time()); // We just added a few items, validate them. EXPECT_EQ(6U, model()->GetTemplateURLs().size()); @@ -553,11 +574,17 @@ TEST_F(TemplateURLServiceTest, Reset) { GURL favicon_url("http://favicon.url"); t_url->SetFaviconURL(favicon_url); t_url->set_date_created(Time::FromTimeT(100)); + t_url->set_last_modified(Time::FromTimeT(100)); model()->Add(t_url); VerifyObserverCount(1); BlockTillServiceProcessesRequests(); + StrictMock<base::MockTimeProvider> mock_time; + model()->set_time_provider(&base::MockTimeProvider::StaticNow); + EXPECT_CALL(mock_time, Now()) + .WillOnce(Return(base::Time::FromDoubleT(1337))); + // Reset the short name, keyword, url and make sure it takes. const string16 new_short_name(ASCIIToUTF16("a")); const string16 new_keyword(ASCIIToUTF16("b")); @@ -581,6 +608,7 @@ TEST_F(TemplateURLServiceTest, Reset) { const TemplateURL* read_url = model()->GetTemplateURLForKeyword(new_keyword); ASSERT_TRUE(read_url); AssertEquals(last_url, *read_url); + ASSERT_EQ(read_url->last_modified(), base::Time::FromDoubleT(1337)); } TEST_F(TemplateURLServiceTest, DefaultSearchProvider) { @@ -588,7 +616,8 @@ TEST_F(TemplateURLServiceTest, DefaultSearchProvider) { VerifyLoad(); const size_t initial_count = model()->GetTemplateURLs().size(); TemplateURL* t_url = AddKeywordWithDate("key1", false, "http://foo1", - "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), + Time()); test_util_.ResetObserverCount(); model()->SetDefaultSearchProvider(t_url); @@ -620,7 +649,7 @@ TEST_F(TemplateURLServiceTest, TemplateURLWithNoKeyword) { const size_t initial_count = model()->GetTemplateURLs().size(); AddKeywordWithDate("", false, "http://foo1", "http://sugg1", - "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), Time()); // We just added a few items, validate them. ASSERT_EQ(initial_count + 1, model()->GetTemplateURLs().size()); @@ -644,7 +673,8 @@ TEST_F(TemplateURLServiceTest, CantReplaceWithSameKeyword) { ChangeModelToLoadState(); ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), GURL(), NULL)); TemplateURL* t_url = AddKeywordWithDate("foo", false, "http://foo1", - "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), + Time()); // Can still replace, newly added template url is marked safe to replace. ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), @@ -653,7 +683,7 @@ TEST_F(TemplateURLServiceTest, CantReplaceWithSameKeyword) { // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should // no longer be replaceable. model()->ResetTemplateURL(t_url, t_url->short_name(), t_url->keyword(), - t_url->url()->url()); + t_url->url()->url()); ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), GURL("http://foo2"), NULL)); @@ -664,7 +694,8 @@ TEST_F(TemplateURLServiceTest, CantReplaceWithSameHosts) { ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("foo"), GURL("http://foo.com"), NULL)); TemplateURL* t_url = AddKeywordWithDate("foo", false, "http://foo.com", - "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), + Time()); // Can still replace, newly added template url is marked safe to replace. ASSERT_TRUE(model()->CanReplaceKeyword(ASCIIToUTF16("bar"), @@ -673,7 +704,7 @@ TEST_F(TemplateURLServiceTest, CantReplaceWithSameHosts) { // ResetTemplateURL marks the TemplateURL as unsafe to replace, so it should // no longer be replaceable. model()->ResetTemplateURL(t_url, t_url->short_name(), t_url->keyword(), - t_url->url()->url()); + t_url->url()->url()); ASSERT_FALSE(model()->CanReplaceKeyword(ASCIIToUTF16("bar"), GURL("http://foo.com"), NULL)); @@ -699,6 +730,7 @@ TEST_F(TemplateURLServiceTest, DefaultSearchProviderLoadedFromPrefs) { template_url->set_short_name(ASCIIToUTF16("a")); template_url->set_safe_for_autoreplace(true); template_url->set_date_created(Time::FromTimeT(100)); + template_url->set_last_modified(Time::FromTimeT(100)); model()->Add(template_url); @@ -799,7 +831,8 @@ TEST_F(TemplateURLServiceTest, UpdateKeywordSearchTermsForURL) { ChangeModelToLoadState(); AddKeywordWithDate("x", false, "http://x/foo?q={searchTerms}", - "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name", false, Time()); + "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name", false, Time(), + Time()); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { history::URLVisitedDetails details; @@ -821,7 +854,7 @@ TEST_F(TemplateURLServiceTest, DontUpdateKeywordSearchForNonReplaceable) { ChangeModelToLoadState(); AddKeywordWithDate("x", false, "http://x/foo", "http://sugg1", - "http://icon1", "UTF-8;UTF-16", "name", false, Time()); + "http://icon1", "UTF-8;UTF-16", "name", false, Time(), Time()); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { history::URLVisitedDetails details; @@ -840,7 +873,7 @@ TEST_F(TemplateURLServiceTest, ChangeGoogleBaseValue) { SetGoogleBaseURL("http://google.com/"); const TemplateURL* t_url = AddKeywordWithDate("", true, "{google:baseURL}?q={searchTerms}", "http://sugg1", "http://icon1", - "UTF-8;UTF-16", "name", false, Time()); + "UTF-8;UTF-16", "name", false, Time(), Time()); ASSERT_EQ(t_url, model()->GetTemplateURLForHost("google.com")); EXPECT_EQ("google.com", t_url->url()->GetHost()); EXPECT_EQ(ASCIIToUTF16("google.com"), t_url->keyword()); @@ -887,7 +920,7 @@ TEST_F(TemplateURLServiceTest, GenerateVisitOnKeyword) { TemplateURL* t_url = AddKeywordWithDate( "keyword", false, "http://foo.com/foo?query={searchTerms}", "http://sugg1", "http://icon1", "UTF-8;UTF-16", "keyword", - true, base::Time::Now()); + true, base::Time::Now(), base::Time::Now()); // Add a visit that matches the url of the keyword. HistoryService* history = @@ -1102,7 +1135,7 @@ TEST_F(TemplateURLServiceTest, TestManagedDefaultSearch) { // Set a regular default search provider. TemplateURL* regular_default = AddKeywordWithDate("key1", false, "http://foo1", "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", - true, Time()); + true, Time(), Time()); VerifyObserverCount(1); model()->SetDefaultSearchProvider(regular_default); // Adding the URL and setting the default search provider should have caused @@ -1196,7 +1229,8 @@ TEST_F(TemplateURLServiceTest, TestManagedDefaultSearch) { RemoveManagedDefaultSearchPreferences(); ResetModel(true); TemplateURL* t_url = AddKeywordWithDate("key1", false, "http://foo1", - "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time()); + "http://sugg1", "http://icon1", "UTF-8;UTF-16", "name1", true, Time(), + Time()); model()->SetDefaultSearchProvider(t_url); EXPECT_EQ(t_url, model()->GetDefaultSearchProvider()); |