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);
notified() const36 bool notified() const { return notified_; }
clear_notified()37 void clear_notified() { notified_ = false; }
38
39 private:
40 bool notified_;
41 };
42
TestNotificationObserver()43 TestNotificationObserver::TestNotificationObserver() : notified_(false) {
44 }
45
~TestNotificationObserver()46 TestNotificationObserver::~TestNotificationObserver() {
47 }
48
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)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
google_url_tracker() const63 GoogleURLTracker* google_url_tracker() const { return google_url_tracker_; }
new_google_url() const64 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
TestInfoBarDelegate(GoogleURLTracker * google_url_tracker,const GURL & new_google_url)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
~TestInfoBarDelegate()83 TestInfoBarDelegate::~TestInfoBarDelegate() {
84 }
85
CreateInfoBar()86 InfoBar* TestInfoBarDelegate::CreateInfoBar() {
87 return NULL;
88 }
89
CreateTestInfobar(TabContents * tab_contents,GoogleURLTracker * google_url_tracker,const GURL & new_google_url)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
GoogleURLTrackerTest()142 GoogleURLTrackerTest::GoogleURLTrackerTest()
143 : observer_(new TestNotificationObserver),
144 message_loop_(NULL),
145 io_thread_(NULL) {
146 }
147
~GoogleURLTrackerTest()148 GoogleURLTrackerTest::~GoogleURLTrackerTest() {
149 }
150
SetUp()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
TearDown()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
GetFetcherByID(int expected_id)180 TestURLFetcher* GoogleURLTrackerTest::GetFetcherByID(int expected_id) {
181 return fetcher_factory_.GetFetcherByID(expected_id);
182 }
183
MockSearchDomainCheckResponse(int expected_id,const std::string & domain)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
RequestServerCheck()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
FinishSleep()208 void GoogleURLTrackerTest::FinishSleep() {
209 g_browser_process->google_url_tracker()->FinishSleep();
210 MessageLoop::current()->RunAllPending();
211 }
212
NotifyIPAddressChanged()213 void GoogleURLTrackerTest::NotifyIPAddressChanged() {
214 net::NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
215 MessageLoop::current()->RunAllPending();
216 }
217
GetFetchedGoogleURL()218 GURL GoogleURLTrackerTest::GetFetchedGoogleURL() {
219 return g_browser_process->google_url_tracker()->fetched_google_url_;
220 }
221
SetGoogleURL(const GURL & url)222 void GoogleURLTrackerTest::SetGoogleURL(const GURL& url) {
223 g_browser_process->google_url_tracker()->google_url_ = url;
224 }
225
SetLastPromptedGoogleURL(const GURL & url)226 void GoogleURLTrackerTest::SetLastPromptedGoogleURL(const GURL& url) {
227 g_browser_process->local_state()->SetString(
228 prefs::kLastPromptedGoogleURL, url.spec());
229 }
230
GetLastPromptedGoogleURL()231 GURL GoogleURLTrackerTest::GetLastPromptedGoogleURL() {
232 return GURL(g_browser_process->local_state()->GetString(
233 prefs::kLastPromptedGoogleURL));
234 }
235
SearchCommitted(const GURL & search_url)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
NavEntryCommitted()246 void GoogleURLTrackerTest::NavEntryCommitted() {
247 GoogleURLTracker* google_url_tracker =
248 g_browser_process->google_url_tracker();
249 google_url_tracker->ShowGoogleURLInfoBarIfNecessary(NULL);
250 }
251
InfoBarIsShown()252 bool GoogleURLTrackerTest::InfoBarIsShown() {
253 return (g_browser_process->google_url_tracker()->infobar_ != NULL);
254 }
255
GetInfoBarShowingURL()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
AcceptGoogleURL()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
CancelGoogleURL()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
InfoBarClosed()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
ExpectDefaultURLs()288 void GoogleURLTrackerTest::ExpectDefaultURLs() {
289 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage),
290 GoogleURLTracker::GoogleURL());
291 EXPECT_EQ(GURL(), GetFetchedGoogleURL());
292 }
293
294
295 // Tests ----------------------------------------------------------------------
296
TEST_F(GoogleURLTrackerTest,DontFetchWhenNoOneRequestsCheck)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
TEST_F(GoogleURLTrackerTest,UpdateOnFirstRun)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
TEST_F(GoogleURLTrackerTest,DontUpdateWhenUnchanged)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
TEST_F(GoogleURLTrackerTest,UpdatePromptedURLOnReturnToPreviousLocation)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
TEST_F(GoogleURLTrackerTest,RefetchOnIPAddressChange)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
TEST_F(GoogleURLTrackerTest,DontRefetchWhenNoOneRequestsCheck)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
TEST_F(GoogleURLTrackerTest,FetchOnLateRequest)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
TEST_F(GoogleURLTrackerTest,SearchingDoesNothingIfNoNeedToPrompt)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
TEST_F(GoogleURLTrackerTest,InfobarClosed)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
TEST_F(GoogleURLTrackerTest,InfobarRefused)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
TEST_F(GoogleURLTrackerTest,InfobarAccepted)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