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 27using content::BrowserThread; 28 29namespace { 30 31// TestGetInstallState -------------------------------------------------------- 32 33// Test the SearchProviderInstallData::GetInstallState. 34class 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 57TestGetInstallState::TestGetInstallState( 58 SearchProviderInstallData* install_data) 59 : install_data_(install_data) { 60} 61 62void 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 72void 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 102void 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. 119class 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 151SearchProviderInstallDataTest::SearchProviderInstallDataTest() 152 : install_data_(NULL) { 153} 154 155void 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 167void 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 178TemplateURL* 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 190void 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 206TEST_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 228TEST_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 258TEST_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