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. 4 5 #include <string> 6 7 #include "base/basictypes.h" 8 #include "base/bind.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/run_loop.h" 13 #include "base/strings/utf_string_conversions.h" 14 #include "chrome/browser/search_engines/search_provider_install_data.h" 15 #include "chrome/browser/search_engines/template_url_service_test_util.h" 16 #include "chrome/test/base/testing_pref_service_syncable.h" 17 #include "chrome/test/base/testing_profile.h" 18 #include "components/search_engines/search_terms_data.h" 19 #include "components/search_engines/template_url.h" 20 #include "components/search_engines/template_url_prepopulate_data.h" 21 #include "components/search_engines/template_url_service.h" 22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/test/mock_render_process_host.h" 24 #include "content/public/test/test_browser_thread_bundle.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 using content::BrowserThread; 28 29 namespace { 30 31 // TestGetInstallState -------------------------------------------------------- 32 33 // Test the SearchProviderInstallData::GetInstallState. 34 class TestGetInstallState { 35 public: 36 explicit TestGetInstallState(SearchProviderInstallData* install_data); 37 38 // Runs all of the test cases. 39 void RunTests(const std::string& search_provider_host, 40 const std::string& default_search_provider_host); 41 42 private: 43 // Callback for when SearchProviderInstallData is ready to have 44 // GetInstallState called. Runs all of the test cases. 45 void DoInstallStateTests(const std::string& search_provider_host, 46 const std::string& default_search_provider_host); 47 48 // Does a verification for one url and its expected state. 49 void VerifyInstallState(SearchProviderInstallData::State expected_state, 50 const std::string& url); 51 52 SearchProviderInstallData* install_data_; 53 54 DISALLOW_COPY_AND_ASSIGN(TestGetInstallState); 55 }; 56 57 TestGetInstallState::TestGetInstallState( 58 SearchProviderInstallData* install_data) 59 : install_data_(install_data) { 60 } 61 62 void TestGetInstallState::RunTests( 63 const std::string& search_provider_host, 64 const std::string& default_search_provider_host) { 65 install_data_->CallWhenLoaded( 66 base::Bind(&TestGetInstallState::DoInstallStateTests, 67 base::Unretained(this), 68 search_provider_host, default_search_provider_host)); 69 base::RunLoop().RunUntilIdle(); 70 } 71 72 void TestGetInstallState::DoInstallStateTests( 73 const std::string& search_provider_host, 74 const std::string& default_search_provider_host) { 75 SCOPED_TRACE("search provider: " + search_provider_host + 76 ", default search provider: " + default_search_provider_host); 77 // Installed but not default. 78 VerifyInstallState(SearchProviderInstallData::INSTALLED_BUT_NOT_DEFAULT, 79 "http://" + search_provider_host + "/"); 80 VerifyInstallState(SearchProviderInstallData::INSTALLED_BUT_NOT_DEFAULT, 81 "http://" + search_provider_host + ":80/"); 82 83 // Not installed. 84 VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED, 85 "http://" + search_provider_host + ":96/"); 86 87 // Not installed due to different scheme. 88 VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED, 89 "https://" + search_provider_host + "/"); 90 91 // Not installed. 92 VerifyInstallState(SearchProviderInstallData::NOT_INSTALLED, 93 "http://a" + search_provider_host + "/"); 94 95 // Installed as default. 96 if (!default_search_provider_host.empty()) { 97 VerifyInstallState(SearchProviderInstallData::INSTALLED_AS_DEFAULT, 98 "http://" + default_search_provider_host + "/"); 99 } 100 } 101 102 void TestGetInstallState::VerifyInstallState( 103 SearchProviderInstallData::State expected_state, 104 const std::string& url) { 105 106 SearchProviderInstallData::State actual_state = 107 install_data_->GetInstallState(GURL(url)); 108 EXPECT_EQ(expected_state, actual_state) 109 << "GetInstallState for " << url << " failed. Expected " 110 << expected_state << ". Actual " << actual_state << "."; 111 } 112 113 } // namespace 114 115 // SearchProviderInstallDataTest ---------------------------------------------- 116 117 // Provides basic test set-up/tear-down functionality needed by all tests 118 // that use TemplateURLServiceTestUtil. 119 class SearchProviderInstallDataTest : public testing::Test { 120 public: 121 SearchProviderInstallDataTest(); 122 123 virtual void SetUp() OVERRIDE; 124 virtual void TearDown() OVERRIDE; 125 126 TemplateURL* AddNewTemplateURL(const std::string& url, 127 const base::string16& keyword); 128 129 // Sets the Google base URL to |base_url| and runs the IO thread for 130 // |SearchProviderInstallData| to process the update. 131 void SetGoogleBaseURLAndProcessOnIOThread(GURL base_url); 132 133 TemplateURLServiceTestUtil* util() { return &util_; } 134 SearchProviderInstallData* install_data() { return install_data_; } 135 136 private: 137 content::TestBrowserThreadBundle thread_bundle_; // To set up BrowserThreads. 138 TemplateURLServiceTestUtil util_; 139 140 // Provides the search provider install state on the I/O thread. It must be 141 // deleted on the I/O thread, which is why it isn't a scoped_ptr. 142 SearchProviderInstallData* install_data_; 143 144 // A mock RenderProcessHost that the SearchProviderInstallData will scope its 145 // lifetime to. 146 scoped_ptr<content::MockRenderProcessHost> process_; 147 148 DISALLOW_COPY_AND_ASSIGN(SearchProviderInstallDataTest); 149 }; 150 151 SearchProviderInstallDataTest::SearchProviderInstallDataTest() 152 : install_data_(NULL) { 153 } 154 155 void SearchProviderInstallDataTest::SetUp() { 156 testing::Test::SetUp(); 157 #if defined(OS_ANDROID) 158 TemplateURLPrepopulateData::InitCountryCode( 159 std::string() /* unknown country code */); 160 #endif 161 process_.reset(new content::MockRenderProcessHost(util_.profile())); 162 install_data_ = new SearchProviderInstallData( 163 util_.model(), SearchTermsData().GoogleBaseURLValue(), NULL, 164 process_.get()); 165 } 166 167 void SearchProviderInstallDataTest::TearDown() { 168 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, install_data_); 169 install_data_ = NULL; 170 171 // Make sure that the install data class on the UI thread gets cleaned up. 172 // It doesn't matter that this happens after install_data_ is deleted. 173 process_.reset(); 174 175 testing::Test::TearDown(); 176 } 177 178 TemplateURL* SearchProviderInstallDataTest::AddNewTemplateURL( 179 const std::string& url, 180 const base::string16& keyword) { 181 TemplateURLData data; 182 data.short_name = keyword; 183 data.SetKeyword(keyword); 184 data.SetURL(url); 185 TemplateURL* t_url = new TemplateURL(data); 186 util_.model()->Add(t_url); 187 return t_url; 188 } 189 190 void SearchProviderInstallDataTest::SetGoogleBaseURLAndProcessOnIOThread( 191 GURL base_url) { 192 util_.SetGoogleBaseURL(base_url); 193 BrowserThread::PostTask( 194 BrowserThread::IO, 195 FROM_HERE, 196 base::Bind(&SearchProviderInstallData::OnGoogleURLChange, 197 base::Unretained(install_data_), 198 base_url.spec())); 199 200 // Wait for the I/O thread to process the update notification. 201 base::RunLoop().RunUntilIdle(); 202 } 203 204 // Actual tests --------------------------------------------------------------- 205 206 TEST_F(SearchProviderInstallDataTest, GetInstallState) { 207 // Set up the database. 208 util()->ChangeModelToLoadState(); 209 std::string host = "www.unittest.com"; 210 AddNewTemplateURL("http://" + host + "/path", base::ASCIIToUTF16("unittest")); 211 212 // Wait for the changes to be saved. 213 base::RunLoop().RunUntilIdle(); 214 215 // Verify the search providers install state (with no default set). 216 TestGetInstallState test_get_install_state(install_data()); 217 test_get_install_state.RunTests(host, std::string()); 218 219 // Set-up a default and try it all one more time. 220 std::string default_host = "www.mmm.com"; 221 TemplateURL* default_url = 222 AddNewTemplateURL("http://" + default_host + "/", 223 base::ASCIIToUTF16("mmm")); 224 util()->model()->SetUserSelectedDefaultSearchProvider(default_url); 225 test_get_install_state.RunTests(host, default_host); 226 } 227 228 TEST_F(SearchProviderInstallDataTest, ManagedDefaultSearch) { 229 // Set up the database. 230 util()->ChangeModelToLoadState(); 231 std::string host = "www.unittest.com"; 232 AddNewTemplateURL("http://" + host + "/path", base::ASCIIToUTF16("unittest")); 233 234 // Set a managed preference that establishes a default search provider. 235 std::string host2 = "www.managedtest.com"; 236 util()->SetManagedDefaultSearchPreferences( 237 true, 238 "managed", 239 "managed", 240 "http://" + host2 + "/p{searchTerms}", 241 std::string(), 242 std::string(), 243 std::string(), 244 std::string(), 245 std::string()); 246 247 EXPECT_TRUE(util()->model()->is_default_search_managed()); 248 249 // Wait for the changes to be saved. 250 base::RunLoop().RunUntilIdle(); 251 252 // Verify the search providers install state. The default search should be 253 // the managed one we previously set. 254 TestGetInstallState test_get_install_state(install_data()); 255 test_get_install_state.RunTests(host, host2); 256 } 257 258 TEST_F(SearchProviderInstallDataTest, GoogleBaseUrlChange) { 259 TestGetInstallState test_get_install_state(install_data()); 260 261 // Set up the database. 262 util()->ChangeModelToLoadState(); 263 std::string google_host = "w.com"; 264 SetGoogleBaseURLAndProcessOnIOThread(GURL("http://" + google_host + "/")); 265 266 AddNewTemplateURL("{google:baseURL}?q={searchTerms}", 267 base::ASCIIToUTF16("t")); 268 TemplateURL* default_url = 269 AddNewTemplateURL("http://d.com/", base::ASCIIToUTF16("d")); 270 util()->model()->SetUserSelectedDefaultSearchProvider(default_url); 271 272 // Wait for the changes to be saved. 273 base::RunLoop().RunUntilIdle(); 274 275 // Verify the search providers install state (with no default set). 276 test_get_install_state.RunTests(google_host, std::string()); 277 278 // Change the Google base url. 279 google_host = "foo.com"; 280 SetGoogleBaseURLAndProcessOnIOThread(GURL("http://" + google_host + "/")); 281 282 // Verify that the change got picked up. 283 test_get_install_state.RunTests(google_host, std::string()); 284 } 285