| Index: chrome/browser/geolocation/network_location_provider_unittest.cc
|
| diff --git a/chrome/browser/geolocation/network_location_provider_unittest.cc b/chrome/browser/geolocation/network_location_provider_unittest.cc
|
| index eb3d034177c0a649d6ab5e13c9c78fe8e82013a1..da4edb1e6909de76829d5136b1d2cda8d864b8d9 100644
|
| --- a/chrome/browser/geolocation/network_location_provider_unittest.cc
|
| +++ b/chrome/browser/geolocation/network_location_provider_unittest.cc
|
| @@ -106,6 +106,8 @@ class GeolocationNetworkProviderTest : public testing::Test {
|
| virtual void SetUp() {
|
| URLFetcher::set_factory(&url_fetcher_factory_);
|
| access_token_store_ = new FakeAccessTokenStore;
|
| + gateway_data_provider_ =
|
| + MockDeviceDataProviderImpl<GatewayData>::CreateInstance();
|
| radio_data_provider_ =
|
| MockDeviceDataProviderImpl<RadioData>::CreateInstance();
|
| wifi_data_provider_ =
|
| @@ -133,6 +135,8 @@ class GeolocationNetworkProviderTest : public testing::Test {
|
| GeolocationNetworkProviderTest() : test_server_url_(kTestServerUrl) {
|
| // TODO(joth): Really these should be in SetUp, not here, but they take no
|
| // effect on Mac OS Release builds if done there. I kid not. Figure out why.
|
| + GatewayDataProvider::SetFactory(
|
| + MockDeviceDataProviderImpl<GatewayData>::GetInstance);
|
| RadioDataProvider::SetFactory(
|
| MockDeviceDataProviderImpl<RadioData>::GetInstance);
|
| WifiDataProvider::SetFactory(
|
| @@ -167,10 +171,51 @@ class GeolocationNetworkProviderTest : public testing::Test {
|
| return data;
|
| }
|
|
|
| - static void ParseRequest(const std::string& request_data,
|
| - WifiData* wifi_data_out,
|
| - int* max_age_out,
|
| - std::string* access_token_out) {
|
| + // Creates gateway data containing the specified number of routers, with
|
| + // some differentiating charactistics in each.
|
| + static GatewayData CreateReferenceRouterData(int router_count) {
|
| + GatewayData data;
|
| + for (int i = 0; i < router_count; ++i) {
|
| + RouterData router;
|
| + router.mac_address =
|
| + ASCIIToUTF16(StringPrintf("%02d-34-56-78-54-32", i));
|
| + data.router_data.insert(router);
|
| + }
|
| + return data;
|
| + }
|
| +
|
| + static void ParseGatewayRequest(const std::string& request_data,
|
| + GatewayData* gateway_data_out) {
|
| + scoped_ptr<Value> value(base::JSONReader::Read(request_data, false));
|
| + EXPECT_TRUE(value != NULL);
|
| + EXPECT_EQ(Value::TYPE_DICTIONARY, value->GetType());
|
| + DictionaryValue* dictionary = static_cast<DictionaryValue*>(value.get());
|
| + std::string attr_value;
|
| + EXPECT_TRUE(dictionary->GetString("version", &attr_value));
|
| + EXPECT_EQ(attr_value, "1.1.0");
|
| + EXPECT_TRUE(dictionary->GetString("host", &attr_value));
|
| + EXPECT_EQ(attr_value, kTestHost);
|
| + // Everything else is optional.
|
| + ListValue* gateways;
|
| + if (dictionary->GetList("gateways", &gateways)) {
|
| + int i = 0;
|
| + for (ListValue::const_iterator it = gateways->begin();
|
| + it < gateways->end(); ++it, ++i) {
|
| + EXPECT_EQ(Value::TYPE_DICTIONARY, (*it)->GetType());
|
| + DictionaryValue* gateway = static_cast<DictionaryValue*>(*it);
|
| + RouterData data;
|
| + gateway->GetString("mac_address", &data.mac_address);
|
| + gateway_data_out->router_data.insert(data);
|
| + }
|
| + } else {
|
| + gateway_data_out->router_data.clear();
|
| + }
|
| + }
|
| +
|
| + static void ParseWifiRequest(const std::string& request_data,
|
| + WifiData* wifi_data_out,
|
| + int* max_age_out,
|
| + std::string* access_token_out) {
|
| CHECK(wifi_data_out && max_age_out && access_token_out);
|
| scoped_ptr<Value> value(base::JSONReader::Read(request_data, false));
|
| EXPECT_TRUE(value != NULL);
|
| @@ -213,45 +258,67 @@ class GeolocationNetworkProviderTest : public testing::Test {
|
| WifiData wifi_aps;
|
| std::string access_token;
|
| int max_age;
|
| - ParseRequest(request_data, &wifi_aps, &max_age, &access_token);
|
| + ParseWifiRequest(request_data, &wifi_aps, &max_age, &access_token);
|
| EXPECT_EQ(kint32min, max_age);
|
| EXPECT_EQ(0, static_cast<int>(wifi_aps.access_point_data.size()));
|
| EXPECT_TRUE(access_token.empty());
|
| }
|
|
|
| static void CheckRequestIsValid(const std::string& request_data,
|
| + int expected_routers,
|
| int expected_wifi_aps,
|
| const std::string& expected_access_token) {
|
| WifiData wifi_aps;
|
| std::string access_token;
|
| int max_age;
|
| - ParseRequest(request_data, &wifi_aps, &max_age, &access_token);
|
| - EXPECT_GE(max_age, 0) << "Age must not be negative.";
|
| - EXPECT_LT(max_age, 10 * 1000) << "This test really shouldn't take 10s.";
|
| + ParseWifiRequest(request_data, &wifi_aps, &max_age, &access_token);
|
| EXPECT_EQ(expected_wifi_aps,
|
| static_cast<int>(wifi_aps.access_point_data.size()));
|
| - WifiData expected_data = CreateReferenceWifiScanData(expected_wifi_aps);
|
| - WifiData::AccessPointDataSet::const_iterator expected =
|
| - expected_data.access_point_data.begin();
|
| - WifiData::AccessPointDataSet::const_iterator actual =
|
| - wifi_aps.access_point_data.begin();
|
| - for (int i = 0; i < expected_wifi_aps; ++i) {
|
| + if (expected_wifi_aps > 0) {
|
| + EXPECT_GE(max_age, 0) << "Age must not be negative.";
|
| + EXPECT_LT(max_age, 10 * 1000) << "This test really shouldn't take 10s.";
|
| + WifiData expected_data = CreateReferenceWifiScanData(expected_wifi_aps);
|
| + WifiData::AccessPointDataSet::const_iterator expected =
|
| + expected_data.access_point_data.begin();
|
| + WifiData::AccessPointDataSet::const_iterator actual =
|
| + wifi_aps.access_point_data.begin();
|
| + for (int i = 0; i < expected_wifi_aps; ++i) {
|
| + EXPECT_EQ(expected->mac_address, actual->mac_address) << i;
|
| + EXPECT_EQ(expected->radio_signal_strength,
|
| + actual->radio_signal_strength) << i;
|
| + EXPECT_EQ(expected->channel, actual->channel) << i;
|
| + EXPECT_EQ(expected->signal_to_noise, actual->signal_to_noise) << i;
|
| + EXPECT_EQ(expected->ssid, actual->ssid) << i;
|
| + ++expected;
|
| + ++actual;
|
| + }
|
| + } else {
|
| + EXPECT_EQ(max_age, kint32min);
|
| + }
|
| + EXPECT_EQ(expected_access_token, access_token);
|
| +
|
| + GatewayData gateway_data;
|
| + ParseGatewayRequest(request_data, &gateway_data);
|
| + EXPECT_EQ(expected_routers,
|
| + static_cast<int>(gateway_data.router_data.size()));
|
| + GatewayData expected_data = CreateReferenceRouterData(expected_routers);
|
| + GatewayData::RouterDataSet::const_iterator expected =
|
| + expected_data.router_data.begin();
|
| + GatewayData::RouterDataSet::const_iterator actual =
|
| + gateway_data.router_data.begin();
|
| + for (int i = 0; i < expected_routers; ++i) {
|
| EXPECT_EQ(expected->mac_address, actual->mac_address) << i;
|
| - EXPECT_EQ(expected->radio_signal_strength, actual->radio_signal_strength)
|
| - << i;
|
| - EXPECT_EQ(expected->channel, actual->channel) << i;
|
| - EXPECT_EQ(expected->signal_to_noise, actual->signal_to_noise) << i;
|
| - EXPECT_EQ(expected->ssid, actual->ssid) << i;
|
| ++expected;
|
| ++actual;
|
| }
|
| - EXPECT_EQ(expected_access_token, access_token);
|
| }
|
|
|
| const GURL test_server_url_;
|
| MessageLoop main_message_loop_;
|
| scoped_refptr<FakeAccessTokenStore> access_token_store_;
|
| TestURLFetcherFactory url_fetcher_factory_;
|
| + scoped_refptr<MockDeviceDataProviderImpl<GatewayData> >
|
| + gateway_data_provider_;
|
| scoped_refptr<MockDeviceDataProviderImpl<RadioData> > radio_data_provider_;
|
| scoped_refptr<MockDeviceDataProviderImpl<WifiData> > wifi_data_provider_;
|
| };
|
| @@ -328,7 +395,7 @@ TEST_F(GeolocationNetworkProviderTest, MultipleWifiScansComplete) {
|
| fetcher = get_url_fetcher_and_advance_id();
|
| ASSERT_TRUE(fetcher != NULL);
|
| // The request should have access token (set previously) and the wifi data.
|
| - CheckRequestIsValid(fetcher->upload_data(),
|
| + CheckRequestIsValid(fetcher->upload_data(), 0,
|
| kFirstScanAps,
|
| REFERENCE_ACCESS_TOKEN);
|
|
|
| @@ -402,6 +469,157 @@ TEST_F(GeolocationNetworkProviderTest, MultipleWifiScansComplete) {
|
| EXPECT_TRUE(position.IsValidFix());
|
| }
|
|
|
| +TEST_F(GeolocationNetworkProviderTest, GatewayAndWifiScans) {
|
| + scoped_ptr<LocationProviderBase> provider(CreateProvider(true));
|
| + EXPECT_TRUE(provider->StartProvider(false));
|
| +
|
| + TestURLFetcher* fetcher = get_url_fetcher_and_advance_id();
|
| + ASSERT_TRUE(fetcher != NULL);
|
| + CheckEmptyRequestIsValid(fetcher->upload_data());
|
| + // Complete the network request with bad position fix (using #define so we
|
| + // can paste this into various other strings below)
|
| + #define REFERENCE_ACCESS_TOKEN "2:k7j3G6LaL6u_lafw:4iXOeOpTh1glSXe"
|
| + const char* kNoFixNetworkResponse =
|
| + "{"
|
| + " \"location\": null,"
|
| + " \"access_token\": \"" REFERENCE_ACCESS_TOKEN "\""
|
| + "}";
|
| + fetcher->delegate()->OnURLFetchComplete(
|
| + fetcher, test_server_url_, URLRequestStatus(), 200, // OK
|
| + ResponseCookies(), kNoFixNetworkResponse);
|
| +
|
| + // This should have set the access token anyhow
|
| + EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
|
| + access_token_store_->access_token_set_[test_server_url_]);
|
| +
|
| + Geoposition position;
|
| + provider->GetPosition(&position);
|
| + EXPECT_FALSE(position.IsValidFix());
|
| +
|
| + // Now gateway data arrives -- SetData will notify listeners.
|
| + const int kFirstScanRouters = 1;
|
| + gateway_data_provider_->SetData(
|
| + CreateReferenceRouterData(kFirstScanRouters));
|
| + main_message_loop_.RunAllPending();
|
| + fetcher = get_url_fetcher_and_advance_id();
|
| + ASSERT_TRUE(fetcher != NULL);
|
| + // The request should have access token (set previously) and the
|
| + // gateway data.
|
| + CheckRequestIsValid(fetcher->upload_data(), kFirstScanRouters,
|
| + 0, REFERENCE_ACCESS_TOKEN);
|
| +
|
| + // Send a reply with good position fix.
|
| + const char* kReferenceNetworkResponse_1 =
|
| + "{"
|
| + " \"location\": {"
|
| + " \"latitude\": 51.0,"
|
| + " \"longitude\": -0.1,"
|
| + " \"altitude\": 30.1,"
|
| + " \"accuracy\": 1200.4,"
|
| + " \"altitude_accuracy\": 10.6"
|
| + " }"
|
| + "}";
|
| + fetcher->delegate()->OnURLFetchComplete(
|
| + fetcher, test_server_url_, URLRequestStatus(), 200, // OK
|
| + ResponseCookies(), kReferenceNetworkResponse_1);
|
| +
|
| + provider->GetPosition(&position);
|
| + EXPECT_EQ(51.0, position.latitude);
|
| + EXPECT_EQ(-0.1, position.longitude);
|
| + EXPECT_EQ(30.1, position.altitude);
|
| + EXPECT_EQ(1200.4, position.accuracy);
|
| + EXPECT_EQ(10.6, position.altitude_accuracy);
|
| + EXPECT_TRUE(position.is_valid_timestamp());
|
| + EXPECT_TRUE(position.IsValidFix());
|
| +
|
| + // Token should still be in the store.
|
| + EXPECT_EQ(UTF8ToUTF16(REFERENCE_ACCESS_TOKEN),
|
| + access_token_store_->access_token_set_[test_server_url_]);
|
| +
|
| + // Gateway updated again, with one more router. This is a significant change
|
| + // so a new request is made.
|
| + const int kSecondScanRouters = kFirstScanRouters + 1;
|
| + gateway_data_provider_->SetData(
|
| + CreateReferenceRouterData(kSecondScanRouters));
|
| + main_message_loop_.RunAllPending();
|
| + fetcher = get_url_fetcher_and_advance_id();
|
| + EXPECT_TRUE(fetcher);
|
| +
|
| + CheckRequestIsValid(fetcher->upload_data(), kSecondScanRouters,
|
| + 0, REFERENCE_ACCESS_TOKEN);
|
| +
|
| + // Send a reply with good position fix.
|
| + const char* kReferenceNetworkResponse_2 =
|
| + "{"
|
| + " \"location\": {"
|
| + " \"latitude\": 51.1,"
|
| + " \"longitude\": -0.1,"
|
| + " \"altitude\": 30.2,"
|
| + " \"accuracy\": 1100.4,"
|
| + " \"altitude_accuracy\": 10.6"
|
| + " }"
|
| + "}";
|
| + fetcher->delegate()->OnURLFetchComplete(
|
| + fetcher, test_server_url_, URLRequestStatus(), 200, // OK
|
| + ResponseCookies(), kReferenceNetworkResponse_2);
|
| +
|
| + provider->GetPosition(&position);
|
| + EXPECT_EQ(51.1, position.latitude);
|
| + EXPECT_EQ(-0.1, position.longitude);
|
| + EXPECT_EQ(30.2, position.altitude);
|
| + EXPECT_EQ(1100.4, position.accuracy);
|
| + EXPECT_EQ(10.6, position.altitude_accuracy);
|
| + EXPECT_TRUE(position.is_valid_timestamp());
|
| + EXPECT_TRUE(position.IsValidFix());
|
| +
|
| + // Now add new wifi scan data.
|
| + const int kScanAps = 4;
|
| + wifi_data_provider_->SetData(CreateReferenceWifiScanData(kScanAps));
|
| + main_message_loop_.RunAllPending();
|
| + fetcher = get_url_fetcher_and_advance_id();
|
| + EXPECT_TRUE(fetcher);
|
| + CheckRequestIsValid(fetcher->upload_data(), kSecondScanRouters,
|
| + kScanAps, REFERENCE_ACCESS_TOKEN);
|
| +
|
| + // Send a reply with good position fix.
|
| + const char* kReferenceNetworkResponse_3 =
|
| + "{"
|
| + " \"location\": {"
|
| + " \"latitude\": 51.3,"
|
| + " \"longitude\": -0.1,"
|
| + " \"altitude\": 30.2,"
|
| + " \"accuracy\": 50.4,"
|
| + " \"altitude_accuracy\": 10.6"
|
| + " }"
|
| + "}";
|
| + fetcher->delegate()->OnURLFetchComplete(
|
| + fetcher, test_server_url_, URLRequestStatus(), 200, // OK
|
| + ResponseCookies(), kReferenceNetworkResponse_3);
|
| +
|
| + provider->GetPosition(&position);
|
| + EXPECT_EQ(51.3, position.latitude);
|
| + EXPECT_EQ(-0.1, position.longitude);
|
| + EXPECT_EQ(30.2, position.altitude);
|
| + EXPECT_EQ(50.4, position.accuracy);
|
| + EXPECT_EQ(10.6, position.altitude_accuracy);
|
| + EXPECT_TRUE(position.is_valid_timestamp());
|
| + EXPECT_TRUE(position.IsValidFix());
|
| +
|
| + // Wifi scan returns no access points found: should be serviced from cache.
|
| + wifi_data_provider_->SetData(CreateReferenceWifiScanData(0));
|
| + main_message_loop_.RunAllPending();
|
| + EXPECT_FALSE(get_url_fetcher_and_advance_id()); // No new request created.
|
| +
|
| + provider->GetPosition(&position);
|
| + EXPECT_EQ(51.1, position.latitude);
|
| + EXPECT_EQ(-0.1, position.longitude);
|
| + EXPECT_EQ(30.2, position.altitude);
|
| + EXPECT_EQ(1100.4, position.accuracy);
|
| + EXPECT_EQ(10.6, position.altitude_accuracy);
|
| + EXPECT_TRUE(position.is_valid_timestamp());
|
| + EXPECT_TRUE(position.IsValidFix());
|
| +}
|
| +
|
| TEST_F(GeolocationNetworkProviderTest, NoRequestOnStartupUntilWifiData) {
|
| MessageLoopQuitListener listener;
|
| wifi_data_provider_->set_got_data(false);
|
| @@ -472,6 +690,6 @@ TEST_F(GeolocationNetworkProviderTest,
|
|
|
| EXPECT_EQ(test_server_url_, fetcher->original_url());
|
|
|
| - CheckRequestIsValid(fetcher->upload_data(), kScanCount,
|
| - REFERENCE_ACCESS_TOKEN);
|
| + CheckRequestIsValid(fetcher->upload_data(), 0,
|
| + kScanCount, REFERENCE_ACCESS_TOKEN);
|
| }
|
|
|