Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: content/browser/geolocation/network_location_provider_unittest.cc

Issue 6597044: Revert 76228 - Move core pieces of geolocation from chrome to content.This is... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "base/json/json_reader.h"
6 #include "base/scoped_ptr.h"
7 #include "base/utf_string_conversions.h"
8 #include "base/values.h"
9 #include "chrome/common/net/test_url_fetcher_factory.h"
10 #include "content/browser/geolocation/fake_access_token_store.h"
11 #include "content/browser/geolocation/network_location_provider.h"
12 #include "net/url_request/url_request_status.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace {
16
17 // Constants used in multiple tests.
18 const char kTestServerUrl[] = "https://www.geolocation.test/service";
19 const char kTestHost[] = "myclienthost.test";
20 const char kTestHostUrl[] = "http://myclienthost.test/some/path";
21 // Using #define so we can easily paste this into various other strings.
22 #define REFERENCE_ACCESS_TOKEN "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
23
24 // Stops the specified (nested) message loop when the listener is called back.
25 class MessageLoopQuitListener
26 : public LocationProviderBase::ListenerInterface {
27 public:
28 MessageLoopQuitListener()
29 : client_message_loop_(MessageLoop::current()),
30 updated_provider_(NULL),
31 movement_provider_(NULL) {
32 CHECK(client_message_loop_);
33 }
34 // ListenerInterface
35 virtual void LocationUpdateAvailable(LocationProviderBase* provider) {
36 EXPECT_EQ(client_message_loop_, MessageLoop::current());
37 updated_provider_ = provider;
38 client_message_loop_->Quit();
39 }
40 MessageLoop* client_message_loop_;
41 LocationProviderBase* updated_provider_;
42 LocationProviderBase* movement_provider_;
43 };
44
45 // A mock implementation of DeviceDataProviderImplBase for testing. Adapted from
46 // http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation_test.cc
47 template<typename DataType>
48 class MockDeviceDataProviderImpl
49 : public DeviceDataProviderImplBase<DataType> {
50 public:
51 // Factory method for use with DeviceDataProvider::SetFactory.
52 static DeviceDataProviderImplBase<DataType>* GetInstance() {
53 CHECK(instance_);
54 return instance_;
55 }
56
57 static MockDeviceDataProviderImpl<DataType>* CreateInstance() {
58 CHECK(!instance_);
59 instance_ = new MockDeviceDataProviderImpl<DataType>;
60 return instance_;
61 }
62
63 MockDeviceDataProviderImpl()
64 : start_calls_(0),
65 stop_calls_(0),
66 got_data_(true) {
67 }
68
69 virtual ~MockDeviceDataProviderImpl() {
70 CHECK(this == instance_);
71 instance_ = NULL;
72 }
73
74 // DeviceDataProviderImplBase implementation.
75 virtual bool StartDataProvider() {
76 ++start_calls_;
77 return true;
78 }
79 virtual void StopDataProvider() {
80 ++stop_calls_;
81 }
82 virtual bool GetData(DataType* data_out) {
83 CHECK(data_out);
84 *data_out = data_;
85 return got_data_;
86 }
87
88 void SetData(const DataType& new_data) {
89 got_data_ = true;
90 const bool differs = data_.DiffersSignificantly(new_data);
91 data_ = new_data;
92 if (differs)
93 this->NotifyListeners();
94 }
95
96 void set_got_data(bool got_data) { got_data_ = got_data; }
97 int start_calls_;
98 int stop_calls_;
99
100 private:
101 static MockDeviceDataProviderImpl<DataType>* instance_;
102
103 DataType data_;
104 bool got_data_;
105
106 DISALLOW_COPY_AND_ASSIGN(MockDeviceDataProviderImpl);
107 };
108
109 template<typename DataType>
110 MockDeviceDataProviderImpl<DataType>*
111 MockDeviceDataProviderImpl<DataType>::instance_ = NULL;
112
113 // Main test fixture
114 class GeolocationNetworkProviderTest : public testing::Test {
115 public:
116 virtual void SetUp() {
117 URLFetcher::set_factory(&url_fetcher_factory_);
118 access_token_store_ = new FakeAccessTokenStore;
119 gateway_data_provider_ =
120 MockDeviceDataProviderImpl<GatewayData>::CreateInstance();
121 radio_data_provider_ =
122 MockDeviceDataProviderImpl<RadioData>::CreateInstance();
123 wifi_data_provider_ =
124 MockDeviceDataProviderImpl<WifiData>::CreateInstance();
125 }
126
127 virtual void TearDown() {
128 WifiDataProvider::ResetFactory();
129 RadioDataProvider::ResetFactory();
130 GatewayDataProvider::ResetFactory();
131 URLFetcher::set_factory(NULL);
132 }
133
134 LocationProviderBase* CreateProvider(bool set_permission_granted) {
135 LocationProviderBase* provider = NewNetworkLocationProvider(
136 access_token_store_.get(),
137 NULL, // No URLContextGetter needed, as using test urlfecther factory.
138 test_server_url_,
139 access_token_store_->access_token_set_[test_server_url_]);
140 if (set_permission_granted)
141 provider->OnPermissionGranted(GURL(kTestHostUrl));
142 return provider;
143 }
144
145 protected:
146 GeolocationNetworkProviderTest() : test_server_url_(kTestServerUrl) {
147 // TODO(joth): Really these should be in SetUp, not here, but they take no
148 // effect on Mac OS Release builds if done there. I kid not. Figure out why.
149 GatewayDataProvider::SetFactory(
150 MockDeviceDataProviderImpl<GatewayData>::GetInstance);
151 RadioDataProvider::SetFactory(
152 MockDeviceDataProviderImpl<RadioData>::GetInstance);
153 WifiDataProvider::SetFactory(
154 MockDeviceDataProviderImpl<WifiData>::GetInstance);
155 }
156
157 // Returns the current url fetcher (if any) and advances the id ready for the
158 // next test step.
159 TestURLFetcher* get_url_fetcher_and_advance_id() {
160 TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(
161 NetworkLocationRequest::url_fetcher_id_for_tests);
162 if (fetcher)
163 ++NetworkLocationRequest::url_fetcher_id_for_tests;
164 return fetcher;
165 }
166
167 static int IndexToChannal(int index) { return index + 4; }
168
169 // Creates wifi data containing the specified number of access points, with
170 // some differentiating charactistics in each.
171 static WifiData CreateReferenceWifiScanData(int ap_count) {
172 WifiData data;
173 for (int i = 0; i < ap_count; ++i) {
174 AccessPointData ap;
175 ap.mac_address = ASCIIToUTF16(StringPrintf("%02d-34-56-78-54-32", i));
176 ap.radio_signal_strength = i;
177 ap.channel = IndexToChannal(i);
178 ap.signal_to_noise = i + 42;
179 ap.ssid = ASCIIToUTF16("Some nice network");
180 data.access_point_data.insert(ap);
181 }
182 return data;
183 }
184
185 // Creates gateway data containing the specified number of routers, with
186 // some differentiating charactistics in each.
187 static GatewayData CreateReferenceRouterData(int router_count) {
188 GatewayData data;
189 for (int i = 0; i < router_count; ++i) {
190 RouterData router;
191 router.mac_address =
192 ASCIIToUTF16(StringPrintf("%02d-34-56-78-54-32", i));
193 data.router_data.insert(router);
194 }
195 return data;
196 }
197
198 static Geoposition CreateReferencePosition(int id) {
199 Geoposition pos;
200 pos.latitude = id;
201 pos.longitude = -(id + 1);
202 pos.altitude = 2 * id;
203 pos.timestamp = base::Time::Now();
204 return pos;
205 }
206
207 static void ParseGatewayRequest(const std::string& request_data,
208 GatewayData* gateway_data_out) {
209 scoped_ptr<Value> value(base::JSONReader::Read(request_data, false));
210 EXPECT_TRUE(value != NULL);
211 EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType());
212 DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());
213 std::string attr_value;
214 EXPECT_TRUE(dictionary->GetString("version", &attr_value));
215 EXPECT_EQ(attr_value, "1.1.0");
216 EXPECT_TRUE(dictionary->GetString("host", &attr_value));
217 EXPECT_EQ(attr_value, kTestHost);
218 // Everything else is optional.
219 ListValue* gateways;
220 if (dictionary->GetList("gateways", &gateways)) {
221 int i = 0;
222 for (ListValue::const_iterator it = gateways->begin();
223 it < gateways->end(); ++it, ++i) {
224 EXPECT_EQ(Value::TYPE_DICTIONARY, (*it)->GetType());
225 DictionaryValue* gateway = static_cast<DictionaryValue*>(*it);
226 RouterData data;
227 gateway->GetString("mac_address", &data.mac_address);
228 gateway_data_out->router_data.insert(data);
229 }
230 } else {
231 gateway_data_out->router_data.clear();
232 }
233 }
234
235 static void ParseWifiRequest(const std::string& request_data,
236 WifiData* wifi_data_out,
237 int* max_age_out,
238 std::string* access_token_out) {
239 CHECK(wifi_data_out && max_age_out && access_token_out);
240 scoped_ptr<Value> value(base::JSONReader::Read(request_data, false));
241 EXPECT_TRUE(value != NULL);
242 EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType());
243 DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());
244 std::string attr_value;
245 EXPECT_TRUE(dictionary->GetString("version", &attr_value));
246 EXPECT_EQ(attr_value, "1.1.0");
247 EXPECT_TRUE(dictionary->GetString("host", &attr_value));
248 EXPECT_EQ(attr_value, kTestHost);
249 // Everything else is optional.
250 ListValue* wifi_aps;
251 *max_age_out = kint32min;
252 if (dictionary->GetList("wifi_towers", &wifi_aps)) {
253 int i = 0;
254 for (ListValue::const_iterator it = wifi_aps->begin();
255 it < wifi_aps->end(); ++it, ++i) {
256 EXPECT_EQ(Value::TYPE_DICTIONARY, (*it)->GetType());
257 DictionaryValue* ap = static_cast<DictionaryValue*>(*it);
258 AccessPointData data;
259 ap->GetString("mac_address", &data.mac_address);
260 ap->GetInteger("signal_strength", &data.radio_signal_strength);
261 int age = kint32min;
262 ap->GetInteger("age", &age);
263 if (age > *max_age_out)
264 *max_age_out = age;
265 ap->GetInteger("channel", &data.channel);
266 ap->GetInteger("signal_to_noise", &data.signal_to_noise);
267 ap->GetString("ssid", &data.ssid);
268 wifi_data_out->access_point_data.insert(data);
269 }
270 } else {
271 wifi_data_out->access_point_data.clear();
272 }
273 if (!dictionary->GetString("access_token", access_token_out))
274 access_token_out->clear();
275 }
276
277 static void CheckEmptyRequestIsValid(const std::string& request_data) {
278 WifiData wifi_aps;
279 std::string access_token;
280 int max_age;
281 ParseWifiRequest(request_data, &wifi_aps, &max_age, &access_token);
282 EXPECT_EQ(kint32min, max_age);
283 EXPECT_EQ(0, static_cast<int>(wifi_aps.access_point_data.size()));
284 EXPECT_TRUE(access_token.empty());
285 }
286
287 static void CheckRequestIsValid(const std::string& request_data,
288 int expected_routers,
289 int expected_wifi_aps,
290 const std::string& expected_access_token) {
291 WifiData wifi_aps;
292 std::string access_token;
293 int max_age;
294 ParseWifiRequest(request_data, &wifi_aps, &max_age, &access_token);
295 EXPECT_EQ(expected_wifi_aps,
296 static_cast<int>(wifi_aps.access_point_data.size()));
297 if (expected_wifi_aps > 0) {
298 EXPECT_GE(max_age, 0) << "Age must not be negative.";
299 EXPECT_LT(max_age, 10 * 1000) << "This test really shouldn't take 10s.";
300 WifiData expected_data = CreateReferenceWifiScanData(expected_wifi_aps);
301 WifiData::AccessPointDataSet::const_iterator expected =
302 expected_data.access_point_data.begin();
303 WifiData::AccessPointDataSet::const_iterator actual =
304 wifi_aps.access_point_data.begin();
305 for (int i = 0; i < expected_wifi_aps; ++i) {
306 EXPECT_EQ(expected->mac_address, actual->mac_address) << i;
307 EXPECT_EQ(expected->radio_signal_strength,
308 actual->radio_signal_strength) << i;
309 EXPECT_EQ(expected->channel, actual->channel) << i;
310 EXPECT_EQ(expected->signal_to_noise, actual->signal_to_noise) << i;
311 EXPECT_EQ(expected->ssid, actual->ssid) << i;
312 ++expected;
313 ++actual;
314 }
315 } else {
316 EXPECT_EQ(max_age, kint32min);
317 }
318 EXPECT_EQ(expected_access_token, access_token);
319
320 GatewayData gateway_data;
321 ParseGatewayRequest(request_data, &gateway_data);
322 EXPECT_EQ(expected_routers,
323 static_cast<int>(gateway_data.router_data.size()));
324 GatewayData expected_data = CreateReferenceRouterData(expected_routers);
325 GatewayData::RouterDataSet::const_iterator expected =
326 expected_data.router_data.begin();
327 GatewayData::RouterDataSet::const_iterator actual =
328 gateway_data.router_data.begin();
329 for (int i = 0; i < expected_routers; ++i) {
330 EXPECT_EQ(expected->mac_address, actual->mac_address) << i;
331 ++expected;
332 ++actual;
333 }
334 }
335
336 const GURL test_server_url_;
337 MessageLoop main_message_loop_;
338 scoped_refptr<FakeAccessTokenStore> access_token_store_;
339 TestURLFetcherFactory url_fetcher_factory_;
340 scoped_refptr<MockDeviceDataProviderImpl<GatewayData> >
341 gateway_data_provider_;
342 scoped_refptr<MockDeviceDataProviderImpl<RadioData> > radio_data_provider_;
343 scoped_refptr<MockDeviceDataProviderImpl<WifiData> > wifi_data_provider_;
344 };
345
346
347 TEST_F(GeolocationNetworkProviderTest, CreateDestroy) {
348 // Test fixture members were SetUp correctly.
349 EXPECT_EQ(&main_message_loop_, MessageLoop::current());
350 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
351 EXPECT_TRUE(NULL != provider.get());
352 provider.reset();
353 SUCCEED();
354 }
355
356 TEST_F(GeolocationNetworkProviderTest, StartProvider) {
357 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
358 EXPECT_TRUE(provider->StartProvider(false));
359 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
360 ASSERT_TRUE(fetcher != NULL);
361
362 EXPECT_EQ(test_server_url_, fetcher->original_url());
363
364 // No wifi data so expect an empty request.
365 CheckEmptyRequestIsValid(fetcher->upload_data());
366 }
367
368 TEST_F(GeolocationNetworkProviderTest, MultipleStartProvider) {
369 scoped_ptr<LocationProviderBase> provider_1(CreateProvider(true));
370 scoped_ptr<LocationProviderBase> provider_2(CreateProvider(true));
371 ASSERT_TRUE(gateway_data_provider_);
372 ASSERT_TRUE(radio_data_provider_);
373 ASSERT_TRUE(wifi_data_provider_);
374 EXPECT_EQ(0, gateway_data_provider_->start_calls_);
375 EXPECT_EQ(0, radio_data_provider_->start_calls_);
376 EXPECT_EQ(0, wifi_data_provider_->start_calls_);
377 EXPECT_EQ(0, gateway_data_provider_->stop_calls_);
378 EXPECT_EQ(0, radio_data_provider_->stop_calls_);
379 EXPECT_EQ(0, wifi_data_provider_->stop_calls_);
380
381 // Start first provider.
382 EXPECT_TRUE(provider_1->StartProvider(false));
383 EXPECT_EQ(1, gateway_data_provider_->start_calls_);
384 EXPECT_EQ(1, radio_data_provider_->start_calls_);
385 EXPECT_EQ(1, wifi_data_provider_->start_calls_);
386 // Start second provider.
387 EXPECT_TRUE(provider_2->StartProvider(false));
388 EXPECT_EQ(1, gateway_data_provider_->start_calls_);
389 EXPECT_EQ(1, radio_data_provider_->start_calls_);
390 EXPECT_EQ(1, wifi_data_provider_->start_calls_);
391
392 // Stop first provider.
393 provider_1->StopProvider();
394 EXPECT_EQ(0, gateway_data_provider_->stop_calls_);
395 EXPECT_EQ(0, radio_data_provider_->stop_calls_);
396 EXPECT_EQ(0, wifi_data_provider_->stop_calls_);
397 // Stop second provider.
398 provider_2->StopProvider();
399 EXPECT_EQ(1, gateway_data_provider_->stop_calls_);
400 EXPECT_EQ(1, radio_data_provider_->stop_calls_);
401 EXPECT_EQ(1, wifi_data_provider_->stop_calls_);
402 }
403
404 TEST_F(GeolocationNetworkProviderTest, MultiRegistrations) {
405 // TODO(joth): Strictly belongs in a base-class unit test file.
406 MessageLoopQuitListener listener;
407 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
408 EXPECT_FALSE(provider->has_listeners());
409 provider->RegisterListener(&listener);
410 EXPECT_TRUE(provider->has_listeners());
411 provider->RegisterListener(&listener);
412 EXPECT_TRUE(provider->has_listeners());
413
414 provider->UnregisterListener(&listener);
415 EXPECT_TRUE(provider->has_listeners());
416 provider->UnregisterListener(&listener);
417 EXPECT_FALSE(provider->has_listeners());
418 }
419
420 TEST_F(GeolocationNetworkProviderTest, MultipleWifiScansComplete) {
421 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
422 EXPECT_TRUE(provider->StartProvider(false));
423
424 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
425 ASSERT_TRUE(fetcher != NULL);
426 CheckEmptyRequestIsValid(fetcher->upload_data());
427 // Complete the network request with bad position fix.
428 const char* kNoFixNetworkResponse =
429 "{"
430 " \"location\": null,"
431 " \"access_token\": \"" REFERENCE_ACCESS_TOKEN "\""
432 "}";
433 fetcher->delegate()->OnURLFetchComplete(
434 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
435 ResponseCookies(), kNoFixNetworkResponse);
436
437 // This should have set the access token anyhow
438 EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
439 access_token_store_->access_token_set_[test_server_url_]);
440
441 Geoposition position;
442 provider->GetPosition(&position);
443 EXPECT_FALSE(position.IsValidFix());
444
445 // Now wifi data arrives -- SetData will notify listeners.
446 const int kFirstScanAps = 6;
447 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps));
448 main_message_loop_.RunAllPending();
449 fetcher = get_url_fetcher_and_advance_id();
450 ASSERT_TRUE(fetcher != NULL);
451 // The request should have access token (set previously) and the wifi data.
452 CheckRequestIsValid(fetcher->upload_data(), 0,
453 kFirstScanAps,
454 REFERENCE_ACCESS_TOKEN);
455
456 // Send a reply with good position fix.
457 const char* kReferenceNetworkResponse =
458 "{"
459 " \"location\": {"
460 " \"latitude\": 51.0,"
461 " \"longitude\": -0.1,"
462 " \"altitude\": 30.1,"
463 " \"accuracy\": 1200.4,"
464 " \"altitude_accuracy\": 10.6"
465 " }"
466 "}";
467 fetcher->delegate()->OnURLFetchComplete(
468 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
469 ResponseCookies(), kReferenceNetworkResponse);
470
471 provider->GetPosition(&position);
472 EXPECT_EQ(51.0, position.latitude);
473 EXPECT_EQ(-0.1, position.longitude);
474 EXPECT_EQ(30.1, position.altitude);
475 EXPECT_EQ(1200.4, position.accuracy);
476 EXPECT_EQ(10.6, position.altitude_accuracy);
477 EXPECT_TRUE(position.is_valid_timestamp());
478 EXPECT_TRUE(position.IsValidFix());
479
480 // Token should still be in the store.
481 EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
482 access_token_store_->access_token_set_[test_server_url_]);
483
484 // Wifi updated again, with one less AP. This is 'close enough' to the
485 // previous scan, so no new request made.
486 const int kSecondScanAps = kFirstScanAps - 1;
487 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kSecondScanAps));
488 main_message_loop_.RunAllPending();
489 fetcher = get_url_fetcher_and_advance_id();
490 EXPECT_FALSE(fetcher);
491
492 provider->GetPosition(&position);
493 EXPECT_EQ(51.0, position.latitude);
494 EXPECT_EQ(-0.1, position.longitude);
495 EXPECT_TRUE(position.IsValidFix());
496
497 // Now a third scan with more than twice the original amount -> new request.
498 const int kThirdScanAps = kFirstScanAps * 2 + 1;
499 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kThirdScanAps));
500 main_message_loop_.RunAllPending();
501 fetcher = get_url_fetcher_and_advance_id();
502 EXPECT_TRUE(fetcher);
503 // ...reply with a network error.
504 fetcher->delegate()->OnURLFetchComplete(
505 fetcher, test_server_url_,
506 net::URLRequestStatus(net::URLRequestStatus::FAILED, -1),
507 200, // should be ignored
508 ResponseCookies(), "");
509
510 // Error means we now no longer have a fix.
511 provider->GetPosition(&position);
512 EXPECT_FALSE(position.is_valid_latlong());
513 EXPECT_FALSE(position.IsValidFix());
514
515 // Wifi scan returns to original set: should be serviced from cache.
516 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps));
517 main_message_loop_.RunAllPending();
518 EXPECT_FALSE(get_url_fetcher_and_advance_id()); // No new request created.
519
520 provider->GetPosition(&position);
521 EXPECT_EQ(51.0, position.latitude);
522 EXPECT_EQ(-0.1, position.longitude);
523 EXPECT_TRUE(position.IsValidFix());
524 }
525
526 TEST_F(GeolocationNetworkProviderTest, GatewayAndWifiScans) {
527 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
528 EXPECT_TRUE(provider->StartProvider(false));
529
530 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
531 ASSERT_TRUE(fetcher != NULL);
532 CheckEmptyRequestIsValid(fetcher->upload_data());
533 // Complete the network request with bad position fix (using #define so we
534 // can paste this into various other strings below)
535 #define REFERENCE_ACCESS_TOKEN "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
536 const char* kNoFixNetworkResponse =
537 "{"
538 " \"location\": null,"
539 " \"access_token\": \"" REFERENCE_ACCESS_TOKEN "\""
540 "}";
541 fetcher->delegate()->OnURLFetchComplete(
542 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
543 ResponseCookies(), kNoFixNetworkResponse);
544
545 // This should have set the access token anyhow
546 EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
547 access_token_store_->access_token_set_[test_server_url_]);
548
549 Geoposition position;
550 provider->GetPosition(&position);
551 EXPECT_FALSE(position.IsValidFix());
552
553 // Now gateway data arrives -- SetData will notify listeners.
554 const int kFirstScanRouters = 1;
555 gateway_data_provider_->SetData(
556 CreateReferenceRouterData(kFirstScanRouters));
557 main_message_loop_.RunAllPending();
558 fetcher = get_url_fetcher_and_advance_id();
559 ASSERT_TRUE(fetcher != NULL);
560 // The request should have access token (set previously) and the
561 // gateway data.
562 CheckRequestIsValid(fetcher->upload_data(), kFirstScanRouters,
563 0, REFERENCE_ACCESS_TOKEN);
564
565 // Send a reply with good position fix.
566 const char* kReferenceNetworkResponse_1 =
567 "{"
568 " \"location\": {"
569 " \"latitude\": 51.0,"
570 " \"longitude\": -0.1,"
571 " \"altitude\": 30.1,"
572 " \"accuracy\": 1200.4,"
573 " \"altitude_accuracy\": 10.6"
574 " }"
575 "}";
576 fetcher->delegate()->OnURLFetchComplete(
577 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
578 ResponseCookies(), kReferenceNetworkResponse_1);
579
580 provider->GetPosition(&position);
581 EXPECT_EQ(51.0, position.latitude);
582 EXPECT_EQ(-0.1, position.longitude);
583 EXPECT_EQ(30.1, position.altitude);
584 EXPECT_EQ(1200.4, position.accuracy);
585 EXPECT_EQ(10.6, position.altitude_accuracy);
586 EXPECT_TRUE(position.is_valid_timestamp());
587 EXPECT_TRUE(position.IsValidFix());
588
589 // Token should still be in the store.
590 EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
591 access_token_store_->access_token_set_[test_server_url_]);
592
593 // Gateway updated again, with one more router. This is a significant change
594 // so a new request is made.
595 const int kSecondScanRouters = kFirstScanRouters + 1;
596 gateway_data_provider_->SetData(
597 CreateReferenceRouterData(kSecondScanRouters));
598 main_message_loop_.RunAllPending();
599 fetcher = get_url_fetcher_and_advance_id();
600 EXPECT_TRUE(fetcher);
601
602 CheckRequestIsValid(fetcher->upload_data(), kSecondScanRouters,
603 0, REFERENCE_ACCESS_TOKEN);
604
605 // Send a reply with good position fix.
606 const char* kReferenceNetworkResponse_2 =
607 "{"
608 " \"location\": {"
609 " \"latitude\": 51.1,"
610 " \"longitude\": -0.1,"
611 " \"altitude\": 30.2,"
612 " \"accuracy\": 1100.4,"
613 " \"altitude_accuracy\": 10.6"
614 " }"
615 "}";
616 fetcher->delegate()->OnURLFetchComplete(
617 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
618 ResponseCookies(), kReferenceNetworkResponse_2);
619
620 provider->GetPosition(&position);
621 EXPECT_EQ(51.1, position.latitude);
622 EXPECT_EQ(-0.1, position.longitude);
623 EXPECT_EQ(30.2, position.altitude);
624 EXPECT_EQ(1100.4, position.accuracy);
625 EXPECT_EQ(10.6, position.altitude_accuracy);
626 EXPECT_TRUE(position.is_valid_timestamp());
627 EXPECT_TRUE(position.IsValidFix());
628
629 // Now add new wifi scan data.
630 const int kScanAps = 4;
631 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kScanAps));
632 main_message_loop_.RunAllPending();
633 fetcher = get_url_fetcher_and_advance_id();
634 EXPECT_TRUE(fetcher);
635 CheckRequestIsValid(fetcher->upload_data(), kSecondScanRouters,
636 kScanAps, REFERENCE_ACCESS_TOKEN);
637
638 // Send a reply with good position fix.
639 const char* kReferenceNetworkResponse_3 =
640 "{"
641 " \"location\": {"
642 " \"latitude\": 51.3,"
643 " \"longitude\": -0.1,"
644 " \"altitude\": 30.2,"
645 " \"accuracy\": 50.4,"
646 " \"altitude_accuracy\": 10.6"
647 " }"
648 "}";
649 fetcher->delegate()->OnURLFetchComplete(
650 fetcher, test_server_url_, net::URLRequestStatus(), 200, // OK
651 ResponseCookies(), kReferenceNetworkResponse_3);
652
653 provider->GetPosition(&position);
654 EXPECT_EQ(51.3, position.latitude);
655 EXPECT_EQ(-0.1, position.longitude);
656 EXPECT_EQ(30.2, position.altitude);
657 EXPECT_EQ(50.4, position.accuracy);
658 EXPECT_EQ(10.6, position.altitude_accuracy);
659 EXPECT_TRUE(position.is_valid_timestamp());
660 EXPECT_TRUE(position.IsValidFix());
661
662 // Wifi scan returns no access points found: should be serviced from cache.
663 wifi_data_provider_->SetData(CreateReferenceWifiScanData(0));
664 main_message_loop_.RunAllPending();
665 EXPECT_FALSE(get_url_fetcher_and_advance_id()); // No new request created.
666
667 provider->GetPosition(&position);
668 EXPECT_EQ(51.1, position.latitude);
669 EXPECT_EQ(-0.1, position.longitude);
670 EXPECT_EQ(30.2, position.altitude);
671 EXPECT_EQ(1100.4, position.accuracy);
672 EXPECT_EQ(10.6, position.altitude_accuracy);
673 EXPECT_TRUE(position.is_valid_timestamp());
674 EXPECT_TRUE(position.IsValidFix());
675 }
676
677 TEST_F(GeolocationNetworkProviderTest, NoRequestOnStartupUntilWifiData) {
678 MessageLoopQuitListener listener;
679 wifi_data_provider_->set_got_data(false);
680 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
681 EXPECT_TRUE(provider->StartProvider(false));
682 provider->RegisterListener(&listener);
683
684 main_message_loop_.RunAllPending();
685 EXPECT_FALSE(get_url_fetcher_and_advance_id())
686 << "Network request should not be created right away on startup when "
687 "wifi data has not yet arrived";
688
689 wifi_data_provider_->SetData(CreateReferenceWifiScanData(1));
690 main_message_loop_.RunAllPending();
691 EXPECT_TRUE(get_url_fetcher_and_advance_id());
692 }
693
694 TEST_F(GeolocationNetworkProviderTest, NewDataReplacesExistingNetworkRequest) {
695 // Send initial request with empty device data
696 scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
697 EXPECT_TRUE(provider->StartProvider(false));
698 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
699 EXPECT_TRUE(fetcher);
700
701 // Now wifi data arrives; new request should be sent.
702 wifi_data_provider_->SetData(CreateReferenceWifiScanData(4));
703 main_message_loop_.RunAllPending();
704 fetcher = get_url_fetcher_and_advance_id();
705 EXPECT_TRUE(fetcher);
706 }
707
708 TEST_F(GeolocationNetworkProviderTest, NetworkRequestDeferredForPermission) {
709 scoped_ptr<LocationProviderBase> provider(CreateProvider(false));
710 EXPECT_TRUE(provider->StartProvider(false));
711 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
712 EXPECT_FALSE(fetcher);
713 provider->OnPermissionGranted(GURL(kTestHostUrl));
714
715 fetcher = get_url_fetcher_and_advance_id();
716 ASSERT_TRUE(fetcher != NULL);
717
718 EXPECT_EQ(test_server_url_, fetcher->original_url());
719
720 // No wifi data so expect an empty request.
721 CheckEmptyRequestIsValid(fetcher->upload_data());
722 }
723
724 TEST_F(GeolocationNetworkProviderTest,
725 NetworkRequestWithWifiDataDeferredForPermission) {
726 access_token_store_->access_token_set_[test_server_url_] =
727 UTF8ToUTF16(REFERENCE_ACCESS_TOKEN);
728 scoped_ptr<LocationProviderBase> provider(CreateProvider(false));
729 EXPECT_TRUE(provider->StartProvider(false));
730 TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
731 EXPECT_FALSE(fetcher);
732
733 static const int kScanCount = 4;
734 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kScanCount));
735 main_message_loop_.RunAllPending();
736
737 fetcher = get_url_fetcher_and_advance_id();
738 EXPECT_FALSE(fetcher);
739
740 provider->OnPermissionGranted(GURL(kTestHostUrl));
741
742 fetcher = get_url_fetcher_and_advance_id();
743 ASSERT_TRUE(fetcher != NULL);
744
745 EXPECT_EQ(test_server_url_, fetcher->original_url());
746
747 CheckRequestIsValid(fetcher->upload_data(), 0,
748 kScanCount, REFERENCE_ACCESS_TOKEN);
749 }
750
751 TEST_F(GeolocationNetworkProviderTest, NetworkPositionCache) {
752 NetworkLocationProvider::PositionCache cache;
753
754 const int kCacheSize = NetworkLocationProvider::PositionCache::kMaximumSize;
755 for (int i = 0; i < kCacheSize * 2 + 1; ++i) {
756 Geoposition pos = CreateReferencePosition(i);
757 bool ret = cache.CachePosition(CreateReferenceRouterData(2),
758 CreateReferenceWifiScanData(i), pos);
759 EXPECT_TRUE(ret) << i;
760 const Geoposition* item = cache.FindPosition(
761 CreateReferenceRouterData(2),
762 CreateReferenceWifiScanData(i));
763 ASSERT_TRUE(item) << i;
764 EXPECT_EQ(pos.latitude, item->latitude) << i;
765 EXPECT_EQ(pos.longitude, item->longitude) << i;
766 if (i < kCacheSize) {
767 // Nothing should have spilled yet; check oldest item is still there.
768 EXPECT_TRUE(cache.FindPosition(CreateReferenceRouterData(2),
769 CreateReferenceWifiScanData(0)));
770 } else {
771 const int evicted = i - kCacheSize;
772 EXPECT_FALSE(cache.FindPosition(CreateReferenceRouterData(2),
773 CreateReferenceWifiScanData(evicted)));
774 EXPECT_TRUE(cache.FindPosition(CreateReferenceRouterData(2),
775 CreateReferenceWifiScanData(evicted + 1)));
776 }
777 }
778 }
779
780 } // namespace
OLDNEW
« no previous file with comments | « content/browser/geolocation/network_location_provider.cc ('k') | content/browser/geolocation/network_location_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698