OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/callback.h" | 5 #include "base/callback.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
| 8 #include "base/stl_util-inl.h" |
8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
9 #include "base/thread.h" | 10 #include "base/thread.h" |
10 #include "chrome/browser/chrome_thread.h" | 11 #include "chrome/browser/chrome_thread.h" |
11 #include "chrome/browser/history/history.h" | 12 #include "chrome/browser/history/history.h" |
12 #include "chrome/browser/history/history_notifications.h" | 13 #include "chrome/browser/history/history_notifications.h" |
13 #include "chrome/browser/search_engines/template_url_model.h" | 14 #include "chrome/browser/search_engines/template_url_model.h" |
| 15 #include "chrome/browser/search_engines/template_url_prepopulate_data.h" |
14 #include "chrome/browser/webdata/web_database.h" | 16 #include "chrome/browser/webdata/web_database.h" |
15 #include "chrome/test/testing_profile.h" | 17 #include "chrome/test/testing_profile.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
17 | 19 |
18 using base::Time; | 20 using base::Time; |
19 using base::TimeDelta; | 21 using base::TimeDelta; |
20 | 22 |
| 23 // Create an URL that appears to have been prepopulated, but won't be in the |
| 24 // current data. The caller owns the returned TemplateURL*. |
| 25 static TemplateURL* CreatePreloadedTemplateURL() { |
| 26 TemplateURL* t_url = new TemplateURL(); |
| 27 t_url->SetURL("http://www.unittest.com/", 0, 0); |
| 28 t_url->set_keyword(L"unittest"); |
| 29 t_url->set_short_name(L"unittest"); |
| 30 t_url->set_safe_for_autoreplace(true); |
| 31 GURL favicon_url("http://favicon.url"); |
| 32 t_url->SetFavIconURL(favicon_url); |
| 33 t_url->set_date_created(Time::FromTimeT(100)); |
| 34 t_url->set_prepopulate_id(999999); |
| 35 return t_url; |
| 36 } |
| 37 |
21 // A Task used to coordinate when the database has finished processing | 38 // A Task used to coordinate when the database has finished processing |
22 // requests. See note in BlockTillServiceProcessesRequests for details. | 39 // requests. See note in BlockTillServiceProcessesRequests for details. |
23 // | 40 // |
24 // When Run() schedules a QuitTask on the message loop it was created with. | 41 // When Run() schedules a QuitTask on the message loop it was created with. |
25 class QuitTask2 : public Task { | 42 class QuitTask2 : public Task { |
26 public: | 43 public: |
27 QuitTask2() : main_loop_(MessageLoop::current()) {} | 44 QuitTask2() : main_loop_(MessageLoop::current()) {} |
28 | 45 |
29 virtual void Run() { | 46 virtual void Run() { |
30 main_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 47 main_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // which unblocks this. | 183 // which unblocks this. |
167 MessageLoop::current()->Run(); | 184 MessageLoop::current()->Run(); |
168 } | 185 } |
169 | 186 |
170 // Makes sure the load was successful and sent the correct notification. | 187 // Makes sure the load was successful and sent the correct notification. |
171 void VerifyLoad() { | 188 void VerifyLoad() { |
172 ASSERT_FALSE(model_->loaded()); | 189 ASSERT_FALSE(model_->loaded()); |
173 model_->Load(); | 190 model_->Load(); |
174 BlockTillServiceProcessesRequests(); | 191 BlockTillServiceProcessesRequests(); |
175 VerifyObserverCount(1); | 192 VerifyObserverCount(1); |
176 changed_count_ = 0; | 193 } |
| 194 |
| 195 // Makes the model believe it has been loaded (without actually doing the |
| 196 // load). Since this avoids setting the built-in keyword version, the next |
| 197 // load will do a merge from prepopulated data. |
| 198 void ChangeModelToLoadState() { |
| 199 model_->service_ = profile_->GetWebDataService(Profile::EXPLICIT_ACCESS); |
| 200 model_->loaded_ = true; |
177 } | 201 } |
178 | 202 |
179 // Creates a new TemplateURLModel. | 203 // Creates a new TemplateURLModel. |
180 void ResetModel(bool verify_load) { | 204 void ResetModel(bool verify_load) { |
181 model_.reset(new TestingTemplateURLModel(profile_.get())); | 205 model_.reset(new TestingTemplateURLModel(profile_.get())); |
182 model_->AddObserver(this); | 206 model_->AddObserver(this); |
183 changed_count_ = 0; | 207 changed_count_ = 0; |
184 if (verify_load) | 208 if (verify_load) |
185 VerifyLoad(); | 209 VerifyLoad(); |
186 } | 210 } |
(...skipping 12 matching lines...) Expand all Loading... |
199 | 223 |
200 std::wstring GetAndClearSearchTerm() { | 224 std::wstring GetAndClearSearchTerm() { |
201 return model_->GetAndClearSearchTerm(); | 225 return model_->GetAndClearSearchTerm(); |
202 } | 226 } |
203 | 227 |
204 void SetGoogleBaseURL(const std::string& base_url) const { | 228 void SetGoogleBaseURL(const std::string& base_url) const { |
205 delete TemplateURLRef::google_base_url_; | 229 delete TemplateURLRef::google_base_url_; |
206 TemplateURLRef::google_base_url_ = new std::string(base_url); | 230 TemplateURLRef::google_base_url_ = new std::string(base_url); |
207 } | 231 } |
208 | 232 |
| 233 // Verifies the behavior of when a preloaded url later gets changed. |
| 234 // Since the input is the offset from the default, when one passes in |
| 235 // 0, it tests the default. Passing in a number > 0 will verify what |
| 236 // happens when a preloaded url that is not the default gets updated. |
| 237 void TestLoadUpdatingPreloadedUrl(size_t index_offset_from_default); |
| 238 |
209 MessageLoopForUI message_loop_; | 239 MessageLoopForUI message_loop_; |
210 // Needed to make the DeleteOnUIThread trait of WebDataService work | 240 // Needed to make the DeleteOnUIThread trait of WebDataService work |
211 // properly. | 241 // properly. |
212 ChromeThread ui_thread_; | 242 ChromeThread ui_thread_; |
213 scoped_ptr<TemplateURLModelTestingProfile> profile_; | 243 scoped_ptr<TemplateURLModelTestingProfile> profile_; |
214 scoped_ptr<TestingTemplateURLModel> model_; | 244 scoped_ptr<TestingTemplateURLModel> model_; |
215 int changed_count_; | 245 int changed_count_; |
216 }; | 246 }; |
217 | 247 |
| 248 void TemplateURLModelTest::TestLoadUpdatingPreloadedUrl( |
| 249 size_t index_offset_from_default) { |
| 250 // Create a TemplateURL with the same prepopulated id as |
| 251 // a real prepopulated item. |
| 252 TemplateURL* t_url = CreatePreloadedTemplateURL(); |
| 253 t_url->set_safe_for_autoreplace(false); |
| 254 std::vector<TemplateURL*> prepopulated_urls; |
| 255 size_t default_search_provider_index = 0; |
| 256 TemplateURLPrepopulateData::GetPrepopulatedEngines( |
| 257 profile_->GetPrefs(), |
| 258 &prepopulated_urls, |
| 259 &default_search_provider_index); |
| 260 ASSERT_LT(index_offset_from_default, prepopulated_urls.size()); |
| 261 size_t prepopulated_index = |
| 262 (default_search_provider_index + index_offset_from_default) % |
| 263 prepopulated_urls.size(); |
| 264 t_url->set_prepopulate_id( |
| 265 prepopulated_urls[prepopulated_index]->prepopulate_id()); |
| 266 |
| 267 std::wstring original_url = t_url->url()->DisplayURL(); |
| 268 std::wstring prepopulated_url = |
| 269 prepopulated_urls[prepopulated_index]->url()->DisplayURL(); |
| 270 ASSERT_STRNE(prepopulated_url.c_str(), original_url.c_str()); |
| 271 STLDeleteElements(&prepopulated_urls); |
| 272 prepopulated_urls.clear(); |
| 273 |
| 274 // Then add it to the model and save it all. |
| 275 ChangeModelToLoadState(); |
| 276 model_->Add(t_url); |
| 277 const TemplateURL* keyword_url = |
| 278 model_->GetTemplateURLForKeyword(L"unittest"); |
| 279 ASSERT_EQ(t_url, keyword_url); |
| 280 ASSERT_STREQ(original_url.c_str(), keyword_url->url()->DisplayURL().c_str()); |
| 281 BlockTillServiceProcessesRequests(); |
| 282 |
| 283 // Now reload the model and verify that the merge updates the url. |
| 284 ResetModel(true); |
| 285 keyword_url = model_->GetTemplateURLForKeyword(L"unittest"); |
| 286 ASSERT_TRUE(keyword_url != NULL); |
| 287 ASSERT_STREQ(prepopulated_url.c_str(), |
| 288 keyword_url->url()->DisplayURL().c_str()); |
| 289 |
| 290 // Wait for any saves to finish. |
| 291 BlockTillServiceProcessesRequests(); |
| 292 |
| 293 // Reload the model to verify that change was saved correctly. |
| 294 ResetModel(true); |
| 295 keyword_url = model_->GetTemplateURLForKeyword(L"unittest"); |
| 296 ASSERT_TRUE(keyword_url != NULL); |
| 297 ASSERT_STREQ(prepopulated_url.c_str(), |
| 298 keyword_url->url()->DisplayURL().c_str()); |
| 299 } |
| 300 |
218 TEST_F(TemplateURLModelTest, Load) { | 301 TEST_F(TemplateURLModelTest, Load) { |
219 VerifyLoad(); | 302 VerifyLoad(); |
220 } | 303 } |
221 | 304 |
222 TEST_F(TemplateURLModelTest, AddUpdateRemove) { | 305 TEST_F(TemplateURLModelTest, AddUpdateRemove) { |
223 // Add a new TemplateURL. | 306 // Add a new TemplateURL. |
224 VerifyLoad(); | 307 VerifyLoad(); |
225 const size_t initial_count = model_->GetTemplateURLs().size(); | 308 const size_t initial_count = model_->GetTemplateURLs().size(); |
226 | 309 |
227 TemplateURL* t_url = new TemplateURL(); | 310 TemplateURL* t_url = new TemplateURL(); |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 profile_->BlockUntilHistoryProcessesPendingRequests(); | 787 profile_->BlockUntilHistoryProcessesPendingRequests(); |
705 | 788 |
706 // And make sure the url and visit were added. | 789 // And make sure the url and visit were added. |
707 EXPECT_TRUE(callback.success); | 790 EXPECT_TRUE(callback.success); |
708 EXPECT_NE(0, callback.row.id()); | 791 EXPECT_NE(0, callback.row.id()); |
709 ASSERT_EQ(1U, callback.visits.size()); | 792 ASSERT_EQ(1U, callback.visits.size()); |
710 EXPECT_EQ(PageTransition::KEYWORD_GENERATED, | 793 EXPECT_EQ(PageTransition::KEYWORD_GENERATED, |
711 PageTransition::StripQualifier(callback.visits[0].transition)); | 794 PageTransition::StripQualifier(callback.visits[0].transition)); |
712 } | 795 } |
713 | 796 |
714 // Make sure that MergeEnginesFromPrepopulateData() deletes prepopulated engines | 797 // Make sure that the load routine deletes prepopulated engines that no longer |
715 // that no longer exist in the prepopulate data. | 798 // exist in the prepopulate data. |
716 TEST_F(TemplateURLModelTest, MergeDeletesUnusedProviders) { | 799 TEST_F(TemplateURLModelTest, LoadDeletesUnusedProvider) { |
717 VerifyLoad(); | 800 // Create a preloaded template url. Add it to a loaded model and wait for the |
718 | 801 // saves to finish. |
719 // Create an URL that appears to have been prepopulated but won't be in the | 802 TemplateURL* t_url = CreatePreloadedTemplateURL(); |
720 // current data. | 803 ChangeModelToLoadState(); |
721 TemplateURL* t_url = new TemplateURL(); | 804 model_->Add(t_url); |
722 t_url->SetURL("http://www.unittest.com/", 0, 0); | 805 ASSERT_TRUE(model_->GetTemplateURLForKeyword(L"unittest") != NULL); |
723 t_url->set_keyword(L"unittest"); | 806 BlockTillServiceProcessesRequests(); |
724 t_url->set_short_name(L"unittest"); | |
725 t_url->set_safe_for_autoreplace(true); | |
726 GURL favicon_url("http://favicon.url"); | |
727 t_url->SetFavIconURL(favicon_url); | |
728 t_url->set_date_created(Time::FromTimeT(100)); | |
729 t_url->set_prepopulate_id(999999); | |
730 | |
731 // Make a few copies now, since as we add each to the model it takes ownership | |
732 // of them and deletes them when finished. | |
733 TemplateURL* t_url2 = new TemplateURL(*t_url); | |
734 TemplateURL* t_url3 = new TemplateURL(*t_url); | |
735 | 807 |
736 // Ensure that merging clears this engine. | 808 // Ensure that merging clears this engine. |
737 model_->Add(t_url); | 809 ResetModel(true); |
738 EXPECT_EQ(t_url, model_->GetTemplateURLForKeyword(L"unittest")); | |
739 model_->MergeEnginesFromPrepopulateData(); | |
740 ASSERT_TRUE(model_->GetTemplateURLForKeyword(L"unittest") == NULL); | 810 ASSERT_TRUE(model_->GetTemplateURLForKeyword(L"unittest") == NULL); |
741 | 811 |
| 812 // Wait for any saves to finish. |
| 813 BlockTillServiceProcessesRequests(); |
| 814 |
| 815 // Reload the model to verify that the database was updated as a result of the |
| 816 // merge. |
| 817 ResetModel(true); |
| 818 ASSERT_TRUE(model_->GetTemplateURLForKeyword(L"unittest") == NULL); |
| 819 } |
| 820 |
| 821 // Make sure that load routine doesn't delete prepopulated engines that no |
| 822 // longer exist in the prepopulate data if it has been modified by the user. |
| 823 TEST_F(TemplateURLModelTest, LoadRetainsModifiedProvider) { |
| 824 // Create a preloaded template url and add it to a loaded model. |
| 825 TemplateURL* t_url = CreatePreloadedTemplateURL(); |
| 826 t_url->set_safe_for_autoreplace(false); |
| 827 ChangeModelToLoadState(); |
| 828 model_->Add(t_url); |
| 829 |
| 830 // Do the copy after t_url is added so that the id is set. |
| 831 TemplateURL copy_t_url = *t_url; |
| 832 ASSERT_EQ(t_url, model_->GetTemplateURLForKeyword(L"unittest")); |
| 833 |
| 834 // Wait for any saves to finish. |
| 835 BlockTillServiceProcessesRequests(); |
| 836 |
742 // Ensure that merging won't clear it if the user has edited it. | 837 // Ensure that merging won't clear it if the user has edited it. |
743 t_url2->set_safe_for_autoreplace(false); | 838 ResetModel(true); |
744 model_->Add(t_url2); | 839 const TemplateURL* url_for_unittest = |
745 ASSERT_EQ(t_url2, model_->GetTemplateURLForKeyword(L"unittest")); | 840 model_->GetTemplateURLForKeyword(L"unittest"); |
746 model_->MergeEnginesFromPrepopulateData(); | 841 ASSERT_TRUE(url_for_unittest != NULL); |
747 ASSERT_FALSE(model_->GetTemplateURLForKeyword(L"unittest") == NULL); | 842 AssertEquals(copy_t_url, *url_for_unittest); |
748 model_->Remove(t_url2); | |
749 | 843 |
750 // Ensure that merging won't clear it if it's the default engine. | 844 // Wait for any saves to finish. |
751 model_->Add(t_url3); | 845 BlockTillServiceProcessesRequests(); |
752 ASSERT_EQ(t_url3, model_->GetTemplateURLForKeyword(L"unittest")); | 846 |
753 model_->SetDefaultSearchProvider(t_url3); | 847 // Reload the model to verify that save/reload retains the item. |
754 ASSERT_EQ(t_url3, model_->GetDefaultSearchProvider()); | 848 ResetModel(true); |
755 model_->MergeEnginesFromPrepopulateData(); | 849 ASSERT_TRUE(model_->GetTemplateURLForKeyword(L"unittest") != NULL); |
756 ASSERT_EQ(t_url3, model_->GetTemplateURLForKeyword(L"unittest")); | 850 } |
757 ASSERT_EQ(t_url3, model_->GetDefaultSearchProvider()); | 851 |
758 // Don't remove |t_url3|; we'd need to make it non-default first, and why | 852 // Make sure that load routine doesn't delete |
759 // bother when the model shutdown will clean it up for us. | 853 // prepopulated engines that no longer exist in the prepopulate data if |
| 854 // it has been modified by the user. |
| 855 TEST_F(TemplateURLModelTest, LoadSavesPrepopulatedDefaultSearchProvider) { |
| 856 VerifyLoad(); |
| 857 // Verify that the default search provider is set to something. |
| 858 ASSERT_TRUE(model_->GetDefaultSearchProvider() != NULL); |
| 859 TemplateURL default_url = *model_->GetDefaultSearchProvider(); |
| 860 |
| 861 // Wait for any saves to finish. |
| 862 BlockTillServiceProcessesRequests(); |
| 863 |
| 864 // Reload the model and check that the default search provider |
| 865 // was properly saved. |
| 866 ResetModel(true); |
| 867 ASSERT_TRUE(model_->GetDefaultSearchProvider() != NULL); |
| 868 AssertEquals(default_url, *model_->GetDefaultSearchProvider()); |
| 869 } |
| 870 |
| 871 // Make sure that the load routine doesn't delete |
| 872 // prepopulated engines that no longer exist in the prepopulate data if |
| 873 // it is the default search provider. |
| 874 TEST_F(TemplateURLModelTest, LoadRetainsDefaultProvider) { |
| 875 // Set the default search provider to a preloaded template url which |
| 876 // is not in the current set of preloaded template urls and save |
| 877 // the result. |
| 878 TemplateURL* t_url = CreatePreloadedTemplateURL(); |
| 879 ChangeModelToLoadState(); |
| 880 model_->Add(t_url); |
| 881 model_->SetDefaultSearchProvider(t_url); |
| 882 // Do the copy after t_url is added and set as default so that its |
| 883 // internal state is correct. |
| 884 TemplateURL copy_t_url = *t_url; |
| 885 |
| 886 ASSERT_EQ(t_url, model_->GetTemplateURLForKeyword(L"unittest")); |
| 887 ASSERT_EQ(t_url, model_->GetDefaultSearchProvider()); |
| 888 BlockTillServiceProcessesRequests(); |
| 889 |
| 890 // Ensure that merging won't clear the prepopulated template url |
| 891 // which is no longer present if it's the default engine. |
| 892 ResetModel(true); |
| 893 { |
| 894 const TemplateURL* keyword_url = |
| 895 model_->GetTemplateURLForKeyword(L"unittest"); |
| 896 ASSERT_TRUE(keyword_url != NULL); |
| 897 AssertEquals(copy_t_url, *keyword_url); |
| 898 ASSERT_EQ(keyword_url, model_->GetDefaultSearchProvider()); |
| 899 } |
| 900 |
| 901 // Wait for any saves to finish. |
| 902 BlockTillServiceProcessesRequests(); |
| 903 |
| 904 // Reload the model to verify that the update was saved. |
| 905 ResetModel(true); |
| 906 { |
| 907 const TemplateURL* keyword_url = |
| 908 model_->GetTemplateURLForKeyword(L"unittest"); |
| 909 ASSERT_TRUE(keyword_url != NULL); |
| 910 AssertEquals(copy_t_url, *keyword_url); |
| 911 ASSERT_EQ(keyword_url, model_->GetDefaultSearchProvider()); |
| 912 } |
| 913 } |
| 914 |
| 915 // Make sure that the load routine updates the url of a preexisting |
| 916 // default search engine provider and that the result is saved correctly. |
| 917 TEST_F(TemplateURLModelTest, LoadUpdatesDefaultSearchUrl) { |
| 918 TestLoadUpdatingPreloadedUrl(0); |
| 919 } |
| 920 |
| 921 // Make sure that the load routine updates the url of a preexisting |
| 922 // non-default search engine provider and that the result is saved correctly. |
| 923 TEST_F(TemplateURLModelTest, LoadUpdatesSearchUrl) { |
| 924 TestLoadUpdatingPreloadedUrl(1); |
760 } | 925 } |
761 | 926 |
762 // Simulates failing to load the webdb and makes sure the default search | 927 // Simulates failing to load the webdb and makes sure the default search |
763 // provider is valid. | 928 // provider is valid. |
764 TEST_F(TemplateURLModelTest, FailedInit) { | 929 TEST_F(TemplateURLModelTest, FailedInit) { |
765 VerifyLoad(); | 930 VerifyLoad(); |
766 | 931 |
767 model_.reset(NULL); | 932 model_.reset(NULL); |
768 | 933 |
769 profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->UnloadDatabase(); | 934 profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->UnloadDatabase(); |
770 profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->set_failed_init(true); | 935 profile_->GetWebDataService(Profile::EXPLICIT_ACCESS)->set_failed_init(true); |
771 | 936 |
772 ResetModel(false); | 937 ResetModel(false); |
773 model_->Load(); | 938 model_->Load(); |
774 BlockTillServiceProcessesRequests(); | 939 BlockTillServiceProcessesRequests(); |
775 | 940 |
776 ASSERT_TRUE(model_->GetDefaultSearchProvider()); | 941 ASSERT_TRUE(model_->GetDefaultSearchProvider()); |
777 } | 942 } |
OLD | NEW |