1 // Copyright 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.
5 #include "components/google/core/browser/google_url_tracker.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "components/google/core/browser/google_pref_names.h"
15 #include "components/google/core/browser/google_url_tracker_client.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_request_test_util.h"
19 #include "testing/gtest/include/gtest/gtest.h"
23 // TestCallbackListener ---------------------------------------------------
25 class TestCallbackListener
{
27 TestCallbackListener();
28 virtual ~TestCallbackListener();
30 bool HasRegisteredCallback();
31 void RegisterCallback(GoogleURLTracker
* google_url_tracker
);
33 bool notified() const { return notified_
; }
34 void clear_notified() { notified_
= false; }
37 void OnGoogleURLUpdated();
40 scoped_ptr
<GoogleURLTracker::Subscription
> google_url_updated_subscription_
;
43 TestCallbackListener::TestCallbackListener() : notified_(false) {
46 TestCallbackListener::~TestCallbackListener() {
49 void TestCallbackListener::OnGoogleURLUpdated() {
53 bool TestCallbackListener::HasRegisteredCallback() {
54 return google_url_updated_subscription_
.get();
57 void TestCallbackListener::RegisterCallback(
58 GoogleURLTracker
* google_url_tracker
) {
59 google_url_updated_subscription_
=
60 google_url_tracker
->RegisterCallback(base::Bind(
61 &TestCallbackListener::OnGoogleURLUpdated
, base::Unretained(this)));
65 // TestGoogleURLTrackerClient -------------------------------------------------
67 class TestGoogleURLTrackerClient
: public GoogleURLTrackerClient
{
69 explicit TestGoogleURLTrackerClient(PrefService
* prefs_
);
70 ~TestGoogleURLTrackerClient() override
;
72 bool IsBackgroundNetworkingEnabled() override
;
73 PrefService
* GetPrefs() override
;
74 net::URLRequestContextGetter
* GetRequestContext() override
;
78 scoped_refptr
<net::TestURLRequestContextGetter
> request_context_
;
80 DISALLOW_COPY_AND_ASSIGN(TestGoogleURLTrackerClient
);
83 TestGoogleURLTrackerClient::TestGoogleURLTrackerClient(PrefService
* prefs
)
85 request_context_(new net::TestURLRequestContextGetter(
86 base::ThreadTaskRunnerHandle::Get())) {
89 TestGoogleURLTrackerClient::~TestGoogleURLTrackerClient() {
92 bool TestGoogleURLTrackerClient::IsBackgroundNetworkingEnabled() {
96 PrefService
* TestGoogleURLTrackerClient::GetPrefs() {
100 net::URLRequestContextGetter
* TestGoogleURLTrackerClient::GetRequestContext() {
101 return request_context_
.get();
107 // GoogleURLTrackerTest -------------------------------------------------------
109 class GoogleURLTrackerTest
: public testing::Test
{
111 GoogleURLTrackerTest();
112 ~GoogleURLTrackerTest() override
;
115 void SetUp() override
;
116 void TearDown() override
;
118 net::TestURLFetcher
* GetFetcher();
119 void MockSearchDomainCheckResponse(const std::string
& domain
);
120 void RequestServerCheck();
122 void NotifyNetworkChanged();
123 void set_google_url(const GURL
& url
) {
124 google_url_tracker_
->google_url_
= url
;
126 GURL
google_url() const { return google_url_tracker_
->google_url(); }
127 bool listener_notified() const { return listener_
.notified(); }
128 void clear_listener_notified() { listener_
.clear_notified(); }
131 base::MessageLoop message_loop_
;
132 TestingPrefServiceSimple prefs_
;
134 // Creating this allows us to call
135 // net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests().
136 scoped_ptr
<net::NetworkChangeNotifier
> network_change_notifier_
;
137 net::TestURLFetcherFactory fetcher_factory_
;
138 GoogleURLTrackerClient
* client_
;
139 scoped_ptr
<GoogleURLTracker
> google_url_tracker_
;
140 TestCallbackListener listener_
;
143 GoogleURLTrackerTest::GoogleURLTrackerTest() {
144 prefs_
.registry()->RegisterStringPref(
145 prefs::kLastKnownGoogleURL
,
146 GoogleURLTracker::kDefaultGoogleHomepage
);
149 GoogleURLTrackerTest::~GoogleURLTrackerTest() {
152 void GoogleURLTrackerTest::SetUp() {
153 network_change_notifier_
.reset(net::NetworkChangeNotifier::CreateMock());
154 // Ownership is passed to google_url_tracker_, but a weak pointer is kept;
155 // this is safe since GoogleURLTracker keeps the client for its lifetime.
156 client_
= new TestGoogleURLTrackerClient(&prefs_
);
157 scoped_ptr
<GoogleURLTrackerClient
> client(client_
);
158 google_url_tracker_
.reset(new GoogleURLTracker(
159 client
.Pass(), GoogleURLTracker::UNIT_TEST_MODE
));
162 void GoogleURLTrackerTest::TearDown() {
163 google_url_tracker_
->Shutdown();
166 net::TestURLFetcher
* GoogleURLTrackerTest::GetFetcher() {
167 // This will return the last fetcher created. If no fetchers have been
168 // created, we'll pass GetFetcherByID() "-1", and it will return NULL.
169 return fetcher_factory_
.GetFetcherByID(google_url_tracker_
->fetcher_id_
- 1);
172 void GoogleURLTrackerTest::MockSearchDomainCheckResponse(
173 const std::string
& domain
) {
174 net::TestURLFetcher
* fetcher
= GetFetcher();
177 fetcher_factory_
.RemoveFetcherFromMap(fetcher
->id());
178 fetcher
->set_url(GURL(GoogleURLTracker::kSearchDomainCheckURL
));
179 fetcher
->set_response_code(200);
180 fetcher
->SetResponseString(domain
);
181 fetcher
->delegate()->OnURLFetchComplete(fetcher
);
182 // At this point, |fetcher| is deleted.
185 void GoogleURLTrackerTest::RequestServerCheck() {
186 if (!listener_
.HasRegisteredCallback())
187 listener_
.RegisterCallback(google_url_tracker_
.get());
188 google_url_tracker_
->SetNeedToFetch();
191 void GoogleURLTrackerTest::FinishSleep() {
192 google_url_tracker_
->FinishSleep();
195 void GoogleURLTrackerTest::NotifyNetworkChanged() {
196 net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
197 net::NetworkChangeNotifier::CONNECTION_UNKNOWN
);
198 // For thread safety, the NCN queues tasks to do the actual notifications, so
199 // we need to spin the message loop so the tracker will actually be notified.
200 base::MessageLoop::current()->RunUntilIdle();
203 // Tests ----------------------------------------------------------------------
205 TEST_F(GoogleURLTrackerTest
, DontFetchWhenNoOneRequestsCheck
) {
206 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage
), google_url());
208 // No one called RequestServerCheck() so nothing should have happened.
209 EXPECT_FALSE(GetFetcher());
210 MockSearchDomainCheckResponse(".google.co.uk");
211 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage
), google_url());
212 EXPECT_FALSE(listener_notified());
215 TEST_F(GoogleURLTrackerTest
, Update
) {
216 RequestServerCheck();
217 EXPECT_FALSE(GetFetcher());
218 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage
), google_url());
219 EXPECT_FALSE(listener_notified());
222 MockSearchDomainCheckResponse(".google.co.uk");
223 EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url());
224 EXPECT_TRUE(listener_notified());
227 TEST_F(GoogleURLTrackerTest
, DontUpdateWhenUnchanged
) {
228 GURL
original_google_url("https://www.google.co.uk/");
229 set_google_url(original_google_url
);
231 RequestServerCheck();
232 EXPECT_FALSE(GetFetcher());
233 EXPECT_EQ(original_google_url
, google_url());
234 EXPECT_FALSE(listener_notified());
237 MockSearchDomainCheckResponse(".google.co.uk");
238 EXPECT_EQ(original_google_url
, google_url());
239 // No one should be notified, because the new URL matches the old.
240 EXPECT_FALSE(listener_notified());
243 TEST_F(GoogleURLTrackerTest
, DontUpdateOnBadReplies
) {
244 GURL
original_google_url("https://www.google.co.uk/");
245 set_google_url(original_google_url
);
247 RequestServerCheck();
248 EXPECT_FALSE(GetFetcher());
249 EXPECT_EQ(original_google_url
, google_url());
250 EXPECT_FALSE(listener_notified());
252 // Old-style URL string.
254 MockSearchDomainCheckResponse("https://www.google.com/");
255 EXPECT_EQ(original_google_url
, google_url());
256 EXPECT_FALSE(listener_notified());
258 // Not a Google domain.
260 MockSearchDomainCheckResponse(".google.evil.com");
261 EXPECT_EQ(original_google_url
, google_url());
262 EXPECT_FALSE(listener_notified());
264 // Doesn't start with .google.
265 NotifyNetworkChanged();
266 MockSearchDomainCheckResponse(".mail.google.com");
267 EXPECT_EQ(original_google_url
, google_url());
268 EXPECT_FALSE(listener_notified());
271 NotifyNetworkChanged();
272 MockSearchDomainCheckResponse(".google.com/search");
273 EXPECT_EQ(original_google_url
, google_url());
274 EXPECT_FALSE(listener_notified());
277 NotifyNetworkChanged();
278 MockSearchDomainCheckResponse(".google.com/?q=foo");
279 EXPECT_EQ(original_google_url
, google_url());
280 EXPECT_FALSE(listener_notified());
283 NotifyNetworkChanged();
284 MockSearchDomainCheckResponse(".google.com/#anchor");
285 EXPECT_EQ(original_google_url
, google_url());
286 EXPECT_FALSE(listener_notified());
289 NotifyNetworkChanged();
290 MockSearchDomainCheckResponse("HJ)*qF)_*&@f1");
291 EXPECT_EQ(original_google_url
, google_url());
292 EXPECT_FALSE(listener_notified());
295 TEST_F(GoogleURLTrackerTest
, RefetchOnNetworkChange
) {
296 RequestServerCheck();
298 MockSearchDomainCheckResponse(".google.co.uk");
299 EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url());
300 EXPECT_TRUE(listener_notified());
301 clear_listener_notified();
303 NotifyNetworkChanged();
304 MockSearchDomainCheckResponse(".google.co.in");
305 EXPECT_EQ(GURL("https://www.google.co.in/"), google_url());
306 EXPECT_TRUE(listener_notified());
309 TEST_F(GoogleURLTrackerTest
, DontRefetchWhenNoOneRequestsCheck
) {
311 NotifyNetworkChanged();
312 // No one called RequestServerCheck() so nothing should have happened.
313 EXPECT_FALSE(GetFetcher());
314 MockSearchDomainCheckResponse(".google.co.uk");
315 EXPECT_EQ(GURL(GoogleURLTracker::kDefaultGoogleHomepage
), google_url());
316 EXPECT_FALSE(listener_notified());
319 TEST_F(GoogleURLTrackerTest
, FetchOnLateRequest
) {
321 NotifyNetworkChanged();
322 MockSearchDomainCheckResponse(".google.co.jp");
324 RequestServerCheck();
325 // The first request for a check should trigger a fetch if it hasn't happened
327 MockSearchDomainCheckResponse(".google.co.uk");
328 EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url());
329 EXPECT_TRUE(listener_notified());
332 TEST_F(GoogleURLTrackerTest
, DontFetchTwiceOnLateRequests
) {
334 NotifyNetworkChanged();
335 MockSearchDomainCheckResponse(".google.co.jp");
337 RequestServerCheck();
338 // The first request for a check should trigger a fetch if it hasn't happened
340 MockSearchDomainCheckResponse(".google.co.uk");
341 EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url());
342 EXPECT_TRUE(listener_notified());
343 clear_listener_notified();
345 RequestServerCheck();
346 // The second request should be ignored.
347 EXPECT_FALSE(GetFetcher());
348 MockSearchDomainCheckResponse(".google.co.in");
349 EXPECT_EQ(GURL("https://www.google.co.uk/"), google_url());
350 EXPECT_FALSE(listener_notified());