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