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