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