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

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

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

Powered by Google App Engine
This is Rietveld 408576698