1 // Copyright (c) 2011 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 "chrome/browser/google/google_url_tracker.h" 6 7 #include "base/command_line.h" 8 #include "base/message_loop.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/prefs/browser_prefs.h" 11 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 12 #include "chrome/common/net/test_url_fetcher_factory.h" 13 #include "chrome/common/net/url_fetcher.h" 14 #include "chrome/common/pref_names.h" 15 #include "chrome/test/testing_browser_process.h" 16 #include "chrome/test/testing_pref_service.h" 17 #include "content/browser/browser_thread.h" 18 #include "content/common/notification_service.h" 19 #include "net/url_request/url_request.h" 20 #include "net/url_request/url_request_context_getter.h" 21 #include "net/url_request/url_request_test_util.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 // TestNotificationObserver --------------------------------------------------- 25 26 namespace { 27 28 class TestNotificationObserver : public NotificationObserver { 29 public: 30 TestNotificationObserver(); 31 virtual ~TestNotificationObserver(); 32 33 virtual void Observe(NotificationType type, 34 const NotificationSource& source, 35 const NotificationDetails& details); 36 bool notified() const { return notified_; } 37 void clear_notified() { notified_ = false; } 38 39 private: 40 bool notified_; 41 }; 42 43 TestNotificationObserver::TestNotificationObserver() : notified_(false) { 44 } 45 46 TestNotificationObserver::~TestNotificationObserver() { 47 } 48 49 void TestNotificationObserver::Observe(NotificationType type, 50 const NotificationSource& source, 51 const NotificationDetails& details) { 52 notified_ = true; 53 } 54 55 56 // TestInfoBarDelegate -------------------------------------------------------- 57 58 class TestInfoBarDelegate : public InfoBarDelegate { 59 public: 60 TestInfoBarDelegate(GoogleURLTracker* google_url_tracker, 61 const GURL& new_google_url); 62 63 GoogleURLTracker* google_url_tracker() const { return google_url_tracker_; } 64 GURL new_google_url() const { return new_google_url_; } 65 66 private: 67 virtual ~TestInfoBarDelegate(); 68 69 // InfoBarDelegate: 70 virtual InfoBar* CreateInfoBar(); 71 72 GoogleURLTracker* google_url_tracker_; 73 GURL new_google_url_; 74 }; 75 76 TestInfoBarDelegate::TestInfoBarDelegate(GoogleURLTracker* google_url_tracker, 77 const GURL& new_google_url) 78 : InfoBarDelegate(NULL), 79 google_url_tracker_(google_url_tracker), 80 new_google_url_(new_google_url) { 81 } 82 83 TestInfoBarDelegate::~TestInfoBarDelegate() { 84 } 85 86 InfoBar* TestInfoBarDelegate::CreateInfoBar() { 87 return NULL; 88 } 89 90 InfoBarDelegate* CreateTestInfobar( 91 TabContents* tab_contents, 92 GoogleURLTracker* google_url_tracker, 93 const GURL& new_google_url) { 94 return new TestInfoBarDelegate(google_url_tracker, new_google_url); 95 } 96 97 } // namespace 98 99 100 // GoogleURLTrackerTest ------------------------------------------------------- 101 102 class GoogleURLTrackerTest : public testing::Test { 103 protected: 104 GoogleURLTrackerTest(); 105 virtual ~GoogleURLTrackerTest(); 106 107 // testing::Test 108 virtual void SetUp(); 109 virtual void TearDown(); 110 111 TestURLFetcher* GetFetcherByID(int expected_id); 112 void MockSearchDomainCheckResponse(int expected_id, 113 const std::string& domain); 114 void RequestServerCheck(); 115 void FinishSleep(); 116 void NotifyIPAddressChanged(); 117 GURL GetFetchedGoogleURL(); 118 void SetGoogleURL(const GURL& url); 119 void SetLastPromptedGoogleURL(const GURL& url); 120 GURL GetLastPromptedGoogleURL(); 121 void SearchCommitted(const GURL& search_url); 122 void NavEntryCommitted(); 123 bool InfoBarIsShown(); 124 GURL GetInfoBarShowingURL(); 125 void AcceptGoogleURL(); 126 void CancelGoogleURL(); 127 void InfoBarClosed(); 128 void ExpectDefaultURLs(); 129 130 scoped_ptr<TestNotificationObserver> observer_; 131 132 private: 133 MessageLoop* message_loop_; 134 BrowserThread* io_thread_; 135 scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; 136 TestingPrefService local_state_; 137 138 TestURLFetcherFactory fetcher_factory_; 139 NotificationRegistrar registrar_; 140 }; 141 142 GoogleURLTrackerTest::GoogleURLTrackerTest() 143 : observer_(new TestNotificationObserver), 144 message_loop_(NULL), 145 io_thread_(NULL) { 146 } 147 148 GoogleURLTrackerTest::~GoogleURLTrackerTest() { 149 } 150 151 void GoogleURLTrackerTest::SetUp() { 152 message_loop_ = new MessageLoop(MessageLoop::TYPE_IO); 153 io_thread_ = new BrowserThread(BrowserThread::IO, message_loop_); 154 network_change_notifier_.reset(net::NetworkChangeNotifier::CreateMock()); 155 browser::RegisterLocalState(&local_state_); 156 TestingBrowserProcess* testing_browser_process = 157 static_cast<TestingBrowserProcess*>(g_browser_process); 158 testing_browser_process->SetPrefService(&local_state_); 159 GoogleURLTracker* tracker = new GoogleURLTracker; 160 tracker->queue_wakeup_task_ = false; 161 MessageLoop::current()->RunAllPending(); 162 testing_browser_process->SetGoogleURLTracker(tracker); 163 164 URLFetcher::set_factory(&fetcher_factory_); 165 g_browser_process->google_url_tracker()->infobar_creator_ = 166 &CreateTestInfobar; 167 } 168 169 void GoogleURLTrackerTest::TearDown() { 170 URLFetcher::set_factory(NULL); 171 TestingBrowserProcess* testing_browser_process = 172 static_cast<TestingBrowserProcess*>(g_browser_process); 173 testing_browser_process->SetGoogleURLTracker(NULL); 174 testing_browser_process->SetPrefService(NULL); 175 network_change_notifier_.reset(); 176 delete io_thread_; 177 delete message_loop_; 178 } 179 180 TestURLFetcher* GoogleURLTrackerTest::GetFetcherByID(int expected_id) { 181 return fetcher_factory_.GetFetcherByID(expected_id); 182 } 183 184 void GoogleURLTrackerTest::MockSearchDomainCheckResponse( 185 int expected_id, 186 const std::string& domain) { 187 TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(expected_id); 188 if (!fetcher) 189 return; 190 fetcher->delegate()->OnURLFetchComplete(fetcher, 191 GURL(GoogleURLTracker::kSearchDomainCheckURL), net::URLRequestStatus(), 192 200, ResponseCookies(), domain); 193 // At this point, |fetcher| is deleted. 194 MessageLoop::current()->RunAllPending(); 195 } 196 197 void GoogleURLTrackerTest::RequestServerCheck() { 198 if (!registrar_.IsRegistered(observer_.get(), 199 NotificationType::GOOGLE_URL_UPDATED, 200 NotificationService::AllSources())) { 201 registrar_.Add(observer_.get(), NotificationType::GOOGLE_URL_UPDATED, 202 NotificationService::AllSources()); 203 } 204 GoogleURLTracker::RequestServerCheck(); 205 MessageLoop::current()->RunAllPending(); 206 } 207 208 void GoogleURLTrackerTest::FinishSleep() { 209 g_browser_process->google_url_tracker()->FinishSleep(); 210 MessageLoop::current()->RunAllPending(); 211 } 212 213 void GoogleURLTrackerTest::NotifyIPAddressChanged() { 214 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 215 MessageLoop::current()->RunAllPending(); 216 } 217 218 GURL GoogleURLTrackerTest::GetFetchedGoogleURL() { 219 return g_browser_process->google_url_tracker()->fetched_google_url_; 220 } 221 222 void GoogleURLTrackerTest::SetGoogleURL(const GURL& url) { 223 g_browser_process->google_url_tracker()->google_url_ = url; 224 } 225 226 void GoogleURLTrackerTest::SetLastPromptedGoogleURL(const GURL& url) { 227 g_browser_process->local_state()->SetString( 228 prefs::kLastPromptedGoogleURL, url.spec()); 229 } 230 231 GURL GoogleURLTrackerTest::GetLastPromptedGoogleURL() { 232 return GURL(g_browser_process->local_state()->GetString( 233 prefs::kLastPromptedGoogleURL)); 234 } 235 236 void GoogleURLTrackerTest::SearchCommitted(const GURL& search_url) { 237 GoogleURLTracker* google_url_tracker = 238 g_browser_process->google_url_tracker(); 239 google_url_tracker->SearchCommitted(); 240 if (google_url_tracker->registrar_.IsRegistered(google_url_tracker, 241 NotificationType::NAV_ENTRY_PENDING, 242 NotificationService::AllSources())) 243 google_url_tracker->search_url_ = search_url; 244 } 245 246 void GoogleURLTrackerTest::NavEntryCommitted() { 247 GoogleURLTracker* google_url_tracker = 248 g_browser_process->google_url_tracker(); 249 google_url_tracker->ShowGoogleURLInfoBarIfNecessary(NULL); 250 } 251 252 bool GoogleURLTrackerTest::InfoBarIsShown() { 253 return (g_browser_process->google_url_tracker()->infobar_ != NULL); 254 } 255 256 GURL GoogleURLTrackerTest::GetInfoBarShowingURL() { 257 TestInfoBarDelegate* infobar = static_cast<TestInfoBarDelegate*>( 258 g_browser_process->google_url_tracker()->infobar_); 259 return infobar->new_google_url(); 260 } 261 262 void GoogleURLTrackerTest::AcceptGoogleURL() { 263 TestInfoBarDelegate* infobar = static_cast<TestInfoBarDelegate*>( 264 g_browser_process->google_url_tracker()->infobar_); 265 ASSERT_TRUE(infobar); 266 ASSERT_TRUE(infobar->google_url_tracker()); 267 infobar->google_url_tracker()->AcceptGoogleURL(infobar->new_google_url()); 268 } 269 270 void GoogleURLTrackerTest::CancelGoogleURL() { 271 TestInfoBarDelegate* infobar = static_cast<TestInfoBarDelegate*>( 272 g_browser_process->google_url_tracker()->infobar_); 273 ASSERT_TRUE(infobar); 274 ASSERT_TRUE(infobar->google_url_tracker()); 275 infobar->google_url_tracker()->CancelGoogleURL(infobar->new_google_url()); 276 } 277 278 void GoogleURLTrackerTest::InfoBarClosed() { 279 InfoBarDelegate* infobar = g_browser_process->google_url_tracker()->infobar_; 280 ASSERT_TRUE(infobar); 281 GoogleURLTracker* url_tracker = 282 static_cast<TestInfoBarDelegate*>(infobar)->google_url_tracker(); 283 ASSERT_TRUE(url_tracker); 284 url_tracker->InfoBarClosed(); 285 delete infobar; 286 } 287 288 void GoogleURLTrackerTest::ExpectDefaultURLs() { 289 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), 290 GoogleURLTracker::GoogleURL()); 291 EXPECT_EQ(GURL(), GetFetchedGoogleURL()); 292 } 293 294 295 // Tests ---------------------------------------------------------------------- 296 297 TEST_F(GoogleURLTrackerTest, DontFetchWhenNoOneRequestsCheck) { 298 ExpectDefaultURLs(); 299 FinishSleep(); 300 // No one called RequestServerCheck() so nothing should have happened. 301 EXPECT_FALSE(GetFetcherByID(0)); 302 ExpectDefaultURLs(); 303 EXPECT_FALSE(observer_->notified()); 304 } 305 306 TEST_F(GoogleURLTrackerTest, UpdateOnFirstRun) { 307 RequestServerCheck(); 308 EXPECT_FALSE(GetFetcherByID(0)); 309 ExpectDefaultURLs(); 310 EXPECT_FALSE(observer_->notified()); 311 312 FinishSleep(); 313 MockSearchDomainCheckResponse(0, ".google.co.uk"); 314 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 315 // GoogleURL should be updated, becase there was no last prompted URL. 316 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 317 EXPECT_TRUE(observer_->notified()); 318 } 319 320 TEST_F(GoogleURLTrackerTest, DontUpdateWhenUnchanged) { 321 SetLastPromptedGoogleURL(GURL("http://www.google.co.uk/")); 322 323 RequestServerCheck(); 324 EXPECT_FALSE(GetFetcherByID(0)); 325 ExpectDefaultURLs(); 326 EXPECT_FALSE(observer_->notified()); 327 328 FinishSleep(); 329 MockSearchDomainCheckResponse(0, ".google.co.uk"); 330 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 331 // GoogleURL should not be updated, because the fetched and prompted URLs 332 // match. 333 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), 334 GoogleURLTracker::GoogleURL()); 335 EXPECT_FALSE(observer_->notified()); 336 } 337 338 TEST_F(GoogleURLTrackerTest, UpdatePromptedURLOnReturnToPreviousLocation) { 339 SetLastPromptedGoogleURL(GURL("http://www.google.co.jp/")); 340 SetGoogleURL(GURL("http://www.google.co.uk/")); 341 RequestServerCheck(); 342 FinishSleep(); 343 MockSearchDomainCheckResponse(0, ".google.co.uk"); 344 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 345 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 346 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL()); 347 EXPECT_FALSE(observer_->notified()); 348 } 349 350 TEST_F(GoogleURLTrackerTest, RefetchOnIPAddressChange) { 351 RequestServerCheck(); 352 FinishSleep(); 353 MockSearchDomainCheckResponse(0, ".google.co.uk"); 354 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 355 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 356 EXPECT_TRUE(observer_->notified()); 357 observer_->clear_notified(); 358 359 NotifyIPAddressChanged(); 360 MockSearchDomainCheckResponse(1, ".google.co.in"); 361 EXPECT_EQ(GURL("http://www.google.co.in/"), GetFetchedGoogleURL()); 362 // Just fetching a new URL shouldn't reset things without a prompt. 363 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 364 EXPECT_FALSE(observer_->notified()); 365 } 366 367 TEST_F(GoogleURLTrackerTest, DontRefetchWhenNoOneRequestsCheck) { 368 FinishSleep(); 369 NotifyIPAddressChanged(); 370 // No one called RequestServerCheck() so nothing should have happened. 371 EXPECT_FALSE(GetFetcherByID(0)); 372 ExpectDefaultURLs(); 373 EXPECT_FALSE(observer_->notified()); 374 } 375 376 TEST_F(GoogleURLTrackerTest, FetchOnLateRequest) { 377 FinishSleep(); 378 NotifyIPAddressChanged(); 379 380 RequestServerCheck(); 381 // The first request for a check should trigger a fetch if it hasn't happened 382 // already. 383 MockSearchDomainCheckResponse(0, ".google.co.uk"); 384 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 385 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 386 EXPECT_TRUE(observer_->notified()); 387 } 388 389 TEST_F(GoogleURLTrackerTest, SearchingDoesNothingIfNoNeedToPrompt) { 390 RequestServerCheck(); 391 FinishSleep(); 392 MockSearchDomainCheckResponse(0, ".google.co.uk"); 393 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 394 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 395 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL()); 396 EXPECT_TRUE(observer_->notified()); 397 observer_->clear_notified(); 398 399 SearchCommitted(GURL("http://www.google.co.uk/search?q=test")); 400 NavEntryCommitted(); 401 EXPECT_FALSE(InfoBarIsShown()); 402 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetFetchedGoogleURL()); 403 EXPECT_EQ(GURL("http://www.google.co.uk/"), GoogleURLTracker::GoogleURL()); 404 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL()); 405 EXPECT_FALSE(observer_->notified()); 406 } 407 408 TEST_F(GoogleURLTrackerTest, InfobarClosed) { 409 SetLastPromptedGoogleURL(GURL("http://www.google.co.uk/")); 410 RequestServerCheck(); 411 FinishSleep(); 412 MockSearchDomainCheckResponse(0, ".google.co.jp"); 413 414 SearchCommitted(GURL("http://www.google.co.uk/search?q=test")); 415 NavEntryCommitted(); 416 EXPECT_TRUE(InfoBarIsShown()); 417 418 InfoBarClosed(); 419 EXPECT_FALSE(InfoBarIsShown()); 420 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), 421 GoogleURLTracker::GoogleURL()); 422 EXPECT_EQ(GURL("http://www.google.co.uk/"), GetLastPromptedGoogleURL()); 423 EXPECT_FALSE(observer_->notified()); 424 } 425 426 TEST_F(GoogleURLTrackerTest, InfobarRefused) { 427 SetLastPromptedGoogleURL(GURL("http://www.google.co.uk/")); 428 RequestServerCheck(); 429 FinishSleep(); 430 MockSearchDomainCheckResponse(0, ".google.co.jp"); 431 432 SearchCommitted(GURL("http://www.google.co.uk/search?q=test")); 433 NavEntryCommitted(); 434 EXPECT_TRUE(InfoBarIsShown()); 435 436 CancelGoogleURL(); 437 InfoBarClosed(); 438 EXPECT_FALSE(InfoBarIsShown()); 439 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage), 440 GoogleURLTracker::GoogleURL()); 441 EXPECT_EQ(GURL("http://www.google.co.jp/"), GetLastPromptedGoogleURL()); 442 EXPECT_FALSE(observer_->notified()); 443 } 444 445 TEST_F(GoogleURLTrackerTest, InfobarAccepted) { 446 SetLastPromptedGoogleURL(GURL("http://www.google.co.uk/")); 447 RequestServerCheck(); 448 FinishSleep(); 449 MockSearchDomainCheckResponse(0, ".google.co.jp"); 450 451 SearchCommitted(GURL("http://www.google.co.uk/search?q=test")); 452 NavEntryCommitted(); 453 EXPECT_TRUE(InfoBarIsShown()); 454 455 AcceptGoogleURL(); 456 InfoBarClosed(); 457 EXPECT_FALSE(InfoBarIsShown()); 458 EXPECT_EQ(GURL("http://www.google.co.jp/"), GoogleURLTracker::GoogleURL()); 459 EXPECT_EQ(GURL("http://www.google.co.jp/"), GetLastPromptedGoogleURL()); 460 EXPECT_TRUE(observer_->notified()); 461 } 462