OLD | NEW |
| (Empty) |
1 // Copyright (c) 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. | |
4 | |
5 #include "content/browser/geolocation/network_location_provider.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <memory> | |
10 #include <utility> | |
11 | |
12 #include "base/json/json_reader.h" | |
13 #include "base/json/json_writer.h" | |
14 #include "base/macros.h" | |
15 #include "base/run_loop.h" | |
16 #include "base/strings/string_number_conversions.h" | |
17 #include "base/strings/string_util.h" | |
18 #include "base/strings/stringprintf.h" | |
19 #include "base/strings/utf_string_conversions.h" | |
20 #include "base/values.h" | |
21 #include "content/browser/geolocation/fake_access_token_store.h" | |
22 #include "content/browser/geolocation/location_arbitrator_impl.h" | |
23 #include "content/browser/geolocation/wifi_data_provider.h" | |
24 #include "net/base/net_errors.h" | |
25 #include "net/url_request/test_url_fetcher_factory.h" | |
26 #include "net/url_request/url_request_status.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 namespace content { | |
30 | |
31 // Constants used in multiple tests. | |
32 const char kTestServerUrl[] = "https://www.geolocation.test/service"; | |
33 const char kAccessTokenString[] = "accessToken"; | |
34 | |
35 // Using #define so we can easily paste this into various other strings. | |
36 #define REFERENCE_ACCESS_TOKEN "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe" | |
37 | |
38 // Stops the specified (nested) message loop when the listener is called back. | |
39 class MessageLoopQuitListener { | |
40 public: | |
41 MessageLoopQuitListener() | |
42 : client_message_loop_(base::MessageLoop::current()), | |
43 updated_provider_(nullptr) { | |
44 CHECK(client_message_loop_); | |
45 } | |
46 | |
47 void OnLocationUpdate(const LocationProvider* provider, | |
48 const Geoposition& position) { | |
49 EXPECT_EQ(client_message_loop_, base::MessageLoop::current()); | |
50 updated_provider_ = provider; | |
51 client_message_loop_->QuitWhenIdle(); | |
52 } | |
53 | |
54 base::MessageLoop* client_message_loop_; | |
55 const LocationProvider* updated_provider_; | |
56 }; | |
57 | |
58 // A mock implementation of WifiDataProvider for testing. Adapted from | |
59 // http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation_test.cc | |
60 class MockWifiDataProvider : public WifiDataProvider { | |
61 public: | |
62 // Factory method for use with WifiDataProvider::SetFactoryForTesting. | |
63 static WifiDataProvider* GetInstance() { | |
64 CHECK(instance_); | |
65 return instance_; | |
66 } | |
67 | |
68 static MockWifiDataProvider* CreateInstance() { | |
69 CHECK(!instance_); | |
70 instance_ = new MockWifiDataProvider; | |
71 return instance_; | |
72 } | |
73 | |
74 MockWifiDataProvider() : start_calls_(0), stop_calls_(0), got_data_(true) {} | |
75 | |
76 // WifiDataProvider implementation. | |
77 void StartDataProvider() override { ++start_calls_; } | |
78 | |
79 void StopDataProvider() override { ++stop_calls_; } | |
80 | |
81 bool GetData(WifiData* data_out) override { | |
82 CHECK(data_out); | |
83 *data_out = data_; | |
84 return got_data_; | |
85 } | |
86 | |
87 void SetData(const WifiData& new_data) { | |
88 got_data_ = true; | |
89 const bool differs = data_.DiffersSignificantly(new_data); | |
90 data_ = new_data; | |
91 if (differs) | |
92 this->RunCallbacks(); | |
93 } | |
94 | |
95 void set_got_data(bool got_data) { got_data_ = got_data; } | |
96 int start_calls_; | |
97 int stop_calls_; | |
98 | |
99 private: | |
100 ~MockWifiDataProvider() override { | |
101 CHECK(this == instance_); | |
102 instance_ = nullptr; | |
103 } | |
104 | |
105 static MockWifiDataProvider* instance_; | |
106 | |
107 WifiData data_; | |
108 bool got_data_; | |
109 | |
110 DISALLOW_COPY_AND_ASSIGN(MockWifiDataProvider); | |
111 }; | |
112 | |
113 MockWifiDataProvider* MockWifiDataProvider::instance_ = nullptr; | |
114 | |
115 // Main test fixture | |
116 class GeolocationNetworkProviderTest : public testing::Test { | |
117 public: | |
118 void TearDown() override { | |
119 WifiDataProviderManager::ResetFactoryForTesting(); | |
120 } | |
121 | |
122 LocationProvider* CreateProvider(bool set_permission_granted) { | |
123 LocationProvider* provider = NewNetworkLocationProvider( | |
124 access_token_store_, | |
125 nullptr, // No URLContextGetter needed, using test urlfecther factory. | |
126 test_server_url_, | |
127 access_token_store_->access_token_map_[test_server_url_]); | |
128 if (set_permission_granted) | |
129 provider->OnPermissionGranted(); | |
130 return provider; | |
131 } | |
132 | |
133 protected: | |
134 GeolocationNetworkProviderTest() | |
135 : test_server_url_(kTestServerUrl), | |
136 access_token_store_(new FakeAccessTokenStore), | |
137 wifi_data_provider_(MockWifiDataProvider::CreateInstance()) { | |
138 // TODO(joth): Really these should be in SetUp, not here, but they take no | |
139 // effect on Mac OS Release builds if done there. I kid not. Figure out why. | |
140 WifiDataProviderManager::SetFactoryForTesting( | |
141 MockWifiDataProvider::GetInstance); | |
142 } | |
143 | |
144 // Returns the current url fetcher (if any) and advances the id ready for the | |
145 // next test step. | |
146 net::TestURLFetcher* get_url_fetcher_and_advance_id() { | |
147 net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID( | |
148 NetworkLocationRequest::url_fetcher_id_for_tests); | |
149 if (fetcher) | |
150 ++NetworkLocationRequest::url_fetcher_id_for_tests; | |
151 return fetcher; | |
152 } | |
153 | |
154 static int IndexToChannel(int index) { return index + 4; } | |
155 | |
156 // Creates wifi data containing the specified number of access points, with | |
157 // some differentiating charactistics in each. | |
158 static WifiData CreateReferenceWifiScanData(int ap_count) { | |
159 WifiData data; | |
160 for (int i = 0; i < ap_count; ++i) { | |
161 AccessPointData ap; | |
162 ap.mac_address = | |
163 base::ASCIIToUTF16(base::StringPrintf("%02d-34-56-78-54-32", i)); | |
164 ap.radio_signal_strength = ap_count - i; | |
165 ap.channel = IndexToChannel(i); | |
166 ap.signal_to_noise = i + 42; | |
167 ap.ssid = base::ASCIIToUTF16("Some nice+network|name\\"); | |
168 data.access_point_data.insert(ap); | |
169 } | |
170 return data; | |
171 } | |
172 | |
173 static void CreateReferenceWifiScanDataJson( | |
174 int ap_count, int start_index, base::ListValue* wifi_access_point_list) { | |
175 std::vector<std::string> wifi_data; | |
176 for (int i = 0; i < ap_count; ++i) { | |
177 std::unique_ptr<base::DictionaryValue> ap(new base::DictionaryValue()); | |
178 ap->SetString("macAddress", base::StringPrintf("%02d-34-56-78-54-32", i)); | |
179 ap->SetInteger("signalStrength", start_index + ap_count - i); | |
180 ap->SetInteger("age", 0); | |
181 ap->SetInteger("channel", IndexToChannel(i)); | |
182 ap->SetInteger("signalToNoiseRatio", i + 42); | |
183 wifi_access_point_list->Append(std::move(ap)); | |
184 } | |
185 } | |
186 | |
187 static Geoposition CreateReferencePosition(int id) { | |
188 Geoposition pos; | |
189 pos.latitude = id; | |
190 pos.longitude = -(id + 1); | |
191 pos.altitude = 2 * id; | |
192 pos.timestamp = base::Time::Now(); | |
193 return pos; | |
194 } | |
195 | |
196 static std::string PrettyJson(const base::Value& value) { | |
197 std::string pretty; | |
198 base::JSONWriter::WriteWithOptions( | |
199 value, base::JSONWriter::OPTIONS_PRETTY_PRINT, &pretty); | |
200 return pretty; | |
201 } | |
202 | |
203 static testing::AssertionResult JsonGetList( | |
204 const std::string& field, | |
205 const base::DictionaryValue& dict, | |
206 const base::ListValue** output_list) { | |
207 if (!dict.GetList(field, output_list)) | |
208 return testing::AssertionFailure() << "Dictionary " << PrettyJson(dict) | |
209 << " is missing list field " << field; | |
210 return testing::AssertionSuccess(); | |
211 } | |
212 | |
213 static testing::AssertionResult JsonFieldEquals( | |
214 const std::string& field, | |
215 const base::DictionaryValue& expected, | |
216 const base::DictionaryValue& actual) { | |
217 const base::Value* expected_value; | |
218 const base::Value* actual_value; | |
219 if (!expected.Get(field, &expected_value)) | |
220 return testing::AssertionFailure() | |
221 << "Expected dictionary " << PrettyJson(expected) | |
222 << " is missing field " << field; | |
223 if (!expected.Get(field, &actual_value)) | |
224 return testing::AssertionFailure() | |
225 << "Actual dictionary " << PrettyJson(actual) | |
226 << " is missing field " << field; | |
227 if (!expected_value->Equals(actual_value)) | |
228 return testing::AssertionFailure() | |
229 << "Field " << field << " mismatch: " << PrettyJson(*expected_value) | |
230 << " != " << PrettyJson(*actual_value); | |
231 return testing::AssertionSuccess(); | |
232 } | |
233 | |
234 static GURL UrlWithoutQuery(const GURL& url) { | |
235 url::Replacements<char> replacements; | |
236 replacements.ClearQuery(); | |
237 return url.ReplaceComponents(replacements); | |
238 } | |
239 | |
240 testing::AssertionResult IsTestServerUrl(const GURL& request_url) { | |
241 const GURL a(UrlWithoutQuery(test_server_url_)); | |
242 const GURL b(UrlWithoutQuery(request_url)); | |
243 if (a == b) | |
244 return testing::AssertionSuccess(); | |
245 return testing::AssertionFailure() << a << " != " << b; | |
246 } | |
247 | |
248 void CheckRequestIsValid(const net::TestURLFetcher& request, | |
249 int expected_routers, | |
250 int expected_wifi_aps, | |
251 int wifi_start_index, | |
252 const std::string& expected_access_token) { | |
253 const GURL& request_url = request.GetOriginalURL(); | |
254 | |
255 EXPECT_TRUE(IsTestServerUrl(request_url)); | |
256 | |
257 // Check to see that the api key is being appended for the default | |
258 // network provider url. | |
259 bool is_default_url = UrlWithoutQuery(request_url) == | |
260 UrlWithoutQuery(LocationArbitratorImpl::DefaultNetworkProviderURL()); | |
261 EXPECT_EQ(is_default_url, !request_url.query().empty()); | |
262 | |
263 const std::string& upload_data = request.upload_data(); | |
264 ASSERT_FALSE(upload_data.empty()); | |
265 std::string json_parse_error_msg; | |
266 std::unique_ptr<base::Value> parsed_json = | |
267 base::JSONReader::ReadAndReturnError(upload_data, base::JSON_PARSE_RFC, | |
268 nullptr, &json_parse_error_msg); | |
269 EXPECT_TRUE(json_parse_error_msg.empty()); | |
270 ASSERT_TRUE(parsed_json); | |
271 | |
272 const base::DictionaryValue* request_json; | |
273 ASSERT_TRUE(parsed_json->GetAsDictionary(&request_json)); | |
274 | |
275 if (!is_default_url) { | |
276 if (expected_access_token.empty()) | |
277 ASSERT_FALSE(request_json->HasKey(kAccessTokenString)); | |
278 else { | |
279 std::string access_token; | |
280 EXPECT_TRUE(request_json->GetString(kAccessTokenString, &access_token)); | |
281 EXPECT_EQ(expected_access_token, access_token); | |
282 } | |
283 } | |
284 | |
285 if (expected_wifi_aps) { | |
286 base::ListValue expected_wifi_aps_json; | |
287 CreateReferenceWifiScanDataJson( | |
288 expected_wifi_aps, | |
289 wifi_start_index, | |
290 &expected_wifi_aps_json); | |
291 EXPECT_EQ(size_t(expected_wifi_aps), expected_wifi_aps_json.GetSize()); | |
292 | |
293 const base::ListValue* wifi_aps_json; | |
294 ASSERT_TRUE(JsonGetList("wifiAccessPoints", *request_json, | |
295 &wifi_aps_json)); | |
296 for (size_t i = 0; i < expected_wifi_aps_json.GetSize(); ++i ) { | |
297 const base::DictionaryValue* expected_json; | |
298 ASSERT_TRUE(expected_wifi_aps_json.GetDictionary(i, &expected_json)); | |
299 const base::DictionaryValue* actual_json; | |
300 ASSERT_TRUE(wifi_aps_json->GetDictionary(i, &actual_json)); | |
301 ASSERT_TRUE(JsonFieldEquals("macAddress", *expected_json, | |
302 *actual_json)); | |
303 ASSERT_TRUE(JsonFieldEquals("signalStrength", *expected_json, | |
304 *actual_json)); | |
305 ASSERT_TRUE(JsonFieldEquals("channel", *expected_json, *actual_json)); | |
306 ASSERT_TRUE(JsonFieldEquals("signalToNoiseRatio", *expected_json, | |
307 *actual_json)); | |
308 } | |
309 } else { | |
310 ASSERT_FALSE(request_json->HasKey("wifiAccessPoints")); | |
311 } | |
312 EXPECT_TRUE(request_url.is_valid()); | |
313 } | |
314 | |
315 GURL test_server_url_; | |
316 const base::MessageLoop main_message_loop_; | |
317 const scoped_refptr<FakeAccessTokenStore> access_token_store_; | |
318 const net::TestURLFetcherFactory url_fetcher_factory_; | |
319 const scoped_refptr<MockWifiDataProvider> wifi_data_provider_; | |
320 }; | |
321 | |
322 TEST_F(GeolocationNetworkProviderTest, CreateDestroy) { | |
323 // Test fixture members were SetUp correctly. | |
324 EXPECT_EQ(&main_message_loop_, base::MessageLoop::current()); | |
325 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
326 EXPECT_TRUE(provider); | |
327 provider.reset(); | |
328 SUCCEED(); | |
329 } | |
330 | |
331 TEST_F(GeolocationNetworkProviderTest, StartProvider) { | |
332 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
333 EXPECT_TRUE(provider->StartProvider(false)); | |
334 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
335 ASSERT_TRUE(fetcher); | |
336 CheckRequestIsValid(*fetcher, 0, 0, 0, std::string()); | |
337 } | |
338 | |
339 TEST_F(GeolocationNetworkProviderTest, StartProviderDefaultUrl) { | |
340 test_server_url_ = LocationArbitratorImpl::DefaultNetworkProviderURL(); | |
341 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
342 EXPECT_TRUE(provider->StartProvider(false)); | |
343 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
344 ASSERT_TRUE(fetcher); | |
345 CheckRequestIsValid(*fetcher, 0, 0, 0, std::string()); | |
346 } | |
347 | |
348 TEST_F(GeolocationNetworkProviderTest, StartProviderLongRequest) { | |
349 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
350 EXPECT_TRUE(provider->StartProvider(false)); | |
351 const int kFirstScanAps = 20; | |
352 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps)); | |
353 base::RunLoop().RunUntilIdle(); | |
354 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
355 ASSERT_TRUE(fetcher); | |
356 // The request url should have been shortened to less than 2048 characters | |
357 // in length by not including access points with the lowest signal strength | |
358 // in the request. | |
359 EXPECT_LT(fetcher->GetOriginalURL().spec().size(), size_t(2048)); | |
360 CheckRequestIsValid(*fetcher, 0, 16, 4, std::string()); | |
361 } | |
362 | |
363 TEST_F(GeolocationNetworkProviderTest, MultipleWifiScansComplete) { | |
364 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
365 EXPECT_TRUE(provider->StartProvider(false)); | |
366 | |
367 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
368 ASSERT_TRUE(fetcher); | |
369 EXPECT_TRUE(IsTestServerUrl(fetcher->GetOriginalURL())); | |
370 | |
371 // Complete the network request with bad position fix. | |
372 const char* kNoFixNetworkResponse = | |
373 "{" | |
374 " \"status\": \"ZERO_RESULTS\"" | |
375 "}"; | |
376 fetcher->set_url(test_server_url_); | |
377 fetcher->set_status(net::URLRequestStatus()); | |
378 fetcher->set_response_code(200); // OK | |
379 fetcher->SetResponseString(kNoFixNetworkResponse); | |
380 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
381 | |
382 Geoposition position; | |
383 provider->GetPosition(&position); | |
384 EXPECT_FALSE(position.Validate()); | |
385 | |
386 // Now wifi data arrives -- SetData will notify listeners. | |
387 const int kFirstScanAps = 6; | |
388 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps)); | |
389 base::RunLoop().RunUntilIdle(); | |
390 fetcher = get_url_fetcher_and_advance_id(); | |
391 ASSERT_TRUE(fetcher); | |
392 // The request should have the wifi data. | |
393 CheckRequestIsValid(*fetcher, 0, kFirstScanAps, 0, std::string()); | |
394 | |
395 // Send a reply with good position fix. | |
396 const char* kReferenceNetworkResponse = | |
397 "{" | |
398 " \"accessToken\": \"" REFERENCE_ACCESS_TOKEN "\"," | |
399 " \"accuracy\": 1200.4," | |
400 " \"location\": {" | |
401 " \"lat\": 51.0," | |
402 " \"lng\": -0.1" | |
403 " }" | |
404 "}"; | |
405 fetcher->set_url(test_server_url_); | |
406 fetcher->set_status(net::URLRequestStatus()); | |
407 fetcher->set_response_code(200); // OK | |
408 fetcher->SetResponseString(kReferenceNetworkResponse); | |
409 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
410 | |
411 provider->GetPosition(&position); | |
412 EXPECT_EQ(51.0, position.latitude); | |
413 EXPECT_EQ(-0.1, position.longitude); | |
414 EXPECT_EQ(1200.4, position.accuracy); | |
415 EXPECT_FALSE(position.timestamp.is_null()); | |
416 EXPECT_TRUE(position.Validate()); | |
417 | |
418 // Token should be in the store. | |
419 EXPECT_EQ(base::UTF8ToUTF16(REFERENCE_ACCESS_TOKEN), | |
420 access_token_store_->access_token_map_[test_server_url_]); | |
421 | |
422 // Wifi updated again, with one less AP. This is 'close enough' to the | |
423 // previous scan, so no new request made. | |
424 const int kSecondScanAps = kFirstScanAps - 1; | |
425 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kSecondScanAps)); | |
426 base::RunLoop().RunUntilIdle(); | |
427 fetcher = get_url_fetcher_and_advance_id(); | |
428 EXPECT_FALSE(fetcher); | |
429 | |
430 provider->GetPosition(&position); | |
431 EXPECT_EQ(51.0, position.latitude); | |
432 EXPECT_EQ(-0.1, position.longitude); | |
433 EXPECT_TRUE(position.Validate()); | |
434 | |
435 // Now a third scan with more than twice the original amount -> new request. | |
436 const int kThirdScanAps = kFirstScanAps * 2 + 1; | |
437 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kThirdScanAps)); | |
438 base::RunLoop().RunUntilIdle(); | |
439 fetcher = get_url_fetcher_and_advance_id(); | |
440 EXPECT_TRUE(fetcher); | |
441 CheckRequestIsValid(*fetcher, 0, kThirdScanAps, 0, REFERENCE_ACCESS_TOKEN); | |
442 // ...reply with a network error. | |
443 | |
444 fetcher->set_url(test_server_url_); | |
445 fetcher->set_status(net::URLRequestStatus::FromError(net::ERR_FAILED)); | |
446 fetcher->set_response_code(200); // should be ignored | |
447 fetcher->SetResponseString(std::string()); | |
448 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
449 | |
450 // Error means we now no longer have a fix. | |
451 provider->GetPosition(&position); | |
452 EXPECT_FALSE(position.Validate()); | |
453 | |
454 // Wifi scan returns to original set: should be serviced from cache. | |
455 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps)); | |
456 base::RunLoop().RunUntilIdle(); | |
457 EXPECT_FALSE(get_url_fetcher_and_advance_id()); // No new request created. | |
458 | |
459 provider->GetPosition(&position); | |
460 EXPECT_EQ(51.0, position.latitude); | |
461 EXPECT_EQ(-0.1, position.longitude); | |
462 EXPECT_TRUE(position.Validate()); | |
463 } | |
464 | |
465 TEST_F(GeolocationNetworkProviderTest, NoRequestOnStartupUntilWifiData) { | |
466 MessageLoopQuitListener listener; | |
467 wifi_data_provider_->set_got_data(false); | |
468 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
469 EXPECT_TRUE(provider->StartProvider(false)); | |
470 | |
471 provider->SetUpdateCallback(base::Bind( | |
472 &MessageLoopQuitListener::OnLocationUpdate, base::Unretained(&listener))); | |
473 | |
474 base::RunLoop().RunUntilIdle(); | |
475 EXPECT_FALSE(get_url_fetcher_and_advance_id()) | |
476 << "Network request should not be created right away on startup when " | |
477 "wifi data has not yet arrived"; | |
478 | |
479 wifi_data_provider_->SetData(CreateReferenceWifiScanData(1)); | |
480 base::RunLoop().RunUntilIdle(); | |
481 EXPECT_TRUE(get_url_fetcher_and_advance_id()); | |
482 } | |
483 | |
484 TEST_F(GeolocationNetworkProviderTest, NewDataReplacesExistingNetworkRequest) { | |
485 // Send initial request with empty data | |
486 std::unique_ptr<LocationProvider> provider(CreateProvider(true)); | |
487 EXPECT_TRUE(provider->StartProvider(false)); | |
488 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
489 EXPECT_TRUE(fetcher); | |
490 | |
491 // Now wifi data arrives; new request should be sent. | |
492 wifi_data_provider_->SetData(CreateReferenceWifiScanData(4)); | |
493 base::RunLoop().RunUntilIdle(); | |
494 fetcher = get_url_fetcher_and_advance_id(); | |
495 EXPECT_TRUE(fetcher); | |
496 } | |
497 | |
498 TEST_F(GeolocationNetworkProviderTest, NetworkRequestDeferredForPermission) { | |
499 std::unique_ptr<LocationProvider> provider(CreateProvider(false)); | |
500 EXPECT_TRUE(provider->StartProvider(false)); | |
501 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
502 EXPECT_FALSE(fetcher); | |
503 provider->OnPermissionGranted(); | |
504 | |
505 fetcher = get_url_fetcher_and_advance_id(); | |
506 ASSERT_TRUE(fetcher); | |
507 | |
508 EXPECT_TRUE(IsTestServerUrl(fetcher->GetOriginalURL())); | |
509 } | |
510 | |
511 TEST_F(GeolocationNetworkProviderTest, | |
512 NetworkRequestWithWifiDataDeferredForPermission) { | |
513 access_token_store_->access_token_map_[test_server_url_] = | |
514 base::UTF8ToUTF16(REFERENCE_ACCESS_TOKEN); | |
515 std::unique_ptr<LocationProvider> provider(CreateProvider(false)); | |
516 EXPECT_TRUE(provider->StartProvider(false)); | |
517 net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); | |
518 EXPECT_FALSE(fetcher); | |
519 | |
520 static const int kScanCount = 4; | |
521 wifi_data_provider_->SetData(CreateReferenceWifiScanData(kScanCount)); | |
522 base::RunLoop().RunUntilIdle(); | |
523 | |
524 fetcher = get_url_fetcher_and_advance_id(); | |
525 EXPECT_FALSE(fetcher); | |
526 | |
527 provider->OnPermissionGranted(); | |
528 | |
529 fetcher = get_url_fetcher_and_advance_id(); | |
530 ASSERT_TRUE(fetcher); | |
531 | |
532 CheckRequestIsValid(*fetcher, 0, kScanCount, 0, REFERENCE_ACCESS_TOKEN); | |
533 } | |
534 | |
535 TEST_F(GeolocationNetworkProviderTest, NetworkPositionCache) { | |
536 NetworkLocationProvider::PositionCache cache; | |
537 | |
538 const int kCacheSize = NetworkLocationProvider::PositionCache::kMaximumSize; | |
539 for (int i = 1; i < kCacheSize * 2 + 1; ++i) { | |
540 Geoposition pos = CreateReferencePosition(i); | |
541 bool ret = cache.CachePosition(CreateReferenceWifiScanData(i), pos); | |
542 EXPECT_TRUE(ret) << i; | |
543 const Geoposition* item = | |
544 cache.FindPosition(CreateReferenceWifiScanData(i)); | |
545 ASSERT_TRUE(item) << i; | |
546 EXPECT_EQ(pos.latitude, item->latitude) << i; | |
547 EXPECT_EQ(pos.longitude, item->longitude) << i; | |
548 if (i <= kCacheSize) { | |
549 // Nothing should have spilled yet; check oldest item is still there. | |
550 EXPECT_TRUE(cache.FindPosition(CreateReferenceWifiScanData(1))); | |
551 } else { | |
552 const int evicted = i - kCacheSize; | |
553 EXPECT_FALSE(cache.FindPosition(CreateReferenceWifiScanData(evicted))); | |
554 EXPECT_TRUE(cache.FindPosition(CreateReferenceWifiScanData(evicted + 1))); | |
555 } | |
556 } | |
557 } | |
558 | |
559 } // namespace content | |
OLD | NEW |