// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/wifi_service.h"

#include <map>
#include <set>
#include <string>
#include <vector>

#include <base/stringprintf.h>
#include <base/string_number_conversions.h>
#include <base/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/event_dispatcher.h"
#include "shill/manager.h"
#include "shill/metrics.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_certificate_file.h"
#include "shill/mock_control.h"
#include "shill/mock_eap_credentials.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_nss.h"
#include "shill/mock_profile.h"
#include "shill/mock_service.h"
#include "shill/mock_store.h"
#include "shill/mock_wifi.h"
#include "shill/mock_wifi_provider.h"
#include "shill/property_store_unittest.h"
#include "shill/refptr_types.h"
#include "shill/service_property_change_test.h"
#include "shill/wifi_endpoint.h"
#include "shill/wpa_supplicant.h"

using base::FilePath;
using std::map;
using std::set;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::HasSubstr;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrNe;
using ::testing::StrictMock;

namespace shill {

class WiFiServiceTest : public PropertyStoreTest {
 public:
  WiFiServiceTest()
      : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
        wifi_(
            new NiceMock<MockWiFi>(control_interface(),
                                   dispatcher(),
                                   metrics(),
                                   manager(),
                                   "wifi",
                                   fake_mac,
                                   0)),
        simple_ssid_(1, 'a'),
        simple_ssid_string_("a") {}
  virtual ~WiFiServiceTest() {}

 protected:
  static const char fake_mac[];

  MockEapCredentials *SetMockEap(
      const WiFiServiceRefPtr &service) {
    MockEapCredentials *eap = new MockEapCredentials();
    service->eap_.reset(eap);  // Passes ownership.
    return eap;
  }
  bool CheckConnectable(const std::string &security, const char *passphrase,
                        bool is_1x_connectable) {
    Error error;
    WiFiServiceRefPtr service = MakeSimpleService(security);
    if (passphrase)
      service->SetPassphrase(passphrase, &error);
    MockEapCredentials *eap = SetMockEap(service);
    EXPECT_CALL(*eap, IsConnectable())
        .WillRepeatedly(Return(is_1x_connectable));
    const string kKeyManagement8021x(WPASupplicant::kKeyManagementIeee8021X);
    if (security == flimflam::kSecurityWep && is_1x_connectable) {
      EXPECT_CALL(*eap, key_management())
          .WillRepeatedly(ReturnRef(kKeyManagement8021x));
    }
    service->OnEapCredentialsChanged();
    return service->connectable();
  }
  WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
                             uint16 frequency, int16 signal_dbm,
                             bool has_wpa_property, bool has_rsn_property) {
    return WiFiEndpoint::MakeEndpoint(
        NULL, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
        frequency, signal_dbm, has_wpa_property, has_rsn_property);
  }
  WiFiEndpoint *MakeOpenEndpoint(const string &ssid, const string &bssid,
                                 uint16 frequency, int16 signal_dbm) {
    return WiFiEndpoint::MakeOpenEndpoint(
        NULL, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
        frequency, signal_dbm);
  }
  WiFiServiceRefPtr MakeSimpleService(const string &security) {
    return new WiFiService(control_interface(),
                           dispatcher(),
                           metrics(),
                           manager(),
                           &provider_,
                           simple_ssid_,
                           flimflam::kModeManaged,
                           security,
                           false);
  }
  WiFiServiceRefPtr MakeGenericService() {
    return MakeSimpleService(flimflam::kSecurityWep);
  }
  void SetWiFi(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
    service->SetWiFi(wifi);  // Has side-effects.
  }
  void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
    service->wifi_ = wifi;
  }
  WiFiServiceRefPtr MakeServiceWithWiFi(const string &security) {
    WiFiServiceRefPtr service = MakeSimpleService(security);
    SetWiFiForService(service, wifi_);
    return service;
  }
  WiFiServiceRefPtr MakeServiceWithMockManager() {
    return new WiFiService(control_interface(),
                           dispatcher(),
                           metrics(),
                           &mock_manager_,
                           &provider_,
                           simple_ssid_,
                           flimflam::kModeManaged,
                           flimflam::kSecurityWep,
                           false);
  }
  ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
    return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
  }
  Error::Type TestConfigurePassphrase(const string &security,
                                      const char *passphrase) {
    WiFiServiceRefPtr service = MakeSimpleService(security);
    KeyValueStore args;
    if (passphrase) {
      args.SetString(flimflam::kPassphraseProperty, passphrase);
    }
    Error error;
    service->Configure(args, &error);
    return error.type();
  }
  scoped_refptr<MockWiFi> wifi() { return wifi_; }
  MockManager *mock_manager() { return &mock_manager_; }
  MockWiFiProvider *provider() { return &provider_; }
  string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
  const vector<uint8_t> &simple_ssid() { return simple_ssid_; }
  const string &simple_ssid_string() { return simple_ssid_string_; }

 private:
  MockManager mock_manager_;
  scoped_refptr<MockWiFi> wifi_;
  MockWiFiProvider provider_;
  const vector<uint8_t> simple_ssid_;
  const string simple_ssid_string_;
};

// static
const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";

MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
  string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
  return
      arg.ContainsString(WiFiService::kStorageType) &&
      arg.GetString(WiFiService::kStorageType) == flimflam::kTypeWifi &&
      arg.ContainsString(WiFiService::kStorageSSID) &&
      arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
      arg.ContainsString(WiFiService::kStorageMode) &&
      arg.GetString(WiFiService::kStorageMode) == mode &&
      arg.ContainsString(WiFiService::kStorageSecurityClass) &&
      arg.GetString(WiFiService::kStorageSecurityClass) == security;
}

class WiFiServiceSecurityTest : public WiFiServiceTest {
 public:
  bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
                             const string &security) {
    string id = wifi_service->GetStorageIdentifier();
    size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
    EXPECT_NE(mac_pos, string::npos);
    size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
    EXPECT_NE(mode_pos, string::npos);
    return id.find(string(security), mode_pos) != string::npos;
  }

  // Test that a service that is created with security |from_security|
  // gets by default a storage identifier with |to_security| as its
  // security component, and that when saved, it sets the Security
  // property in to |to_security| as well.
  bool TestStorageMapping(const string &from_security,
                          const string &to_security) {
    WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
    NiceMock<MockStore> mock_store;
    EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
    EXPECT_CALL(mock_store,
                SetString(_, WiFiService::kStorageSecurity, from_security))
        .Times(1);
    EXPECT_CALL(mock_store,
                SetString(_, WiFiService::kStorageSecurityClass, to_security))
        .Times(1);
    wifi_service->Save(&mock_store);
    return TestStorageSecurityIs(wifi_service, to_security);
  }

  // Test whether a service of type |service_security| can load from a
  // storage interface containing an entry for |storage_security|.
  // Make sure the result meets |expectation|.  If |expectation| is
  // true, also make sure the service storage identifier changes to
  // match |storage_security|.
  bool TestLoadMapping(const string &service_security,
                       const string &storage_security,
                       bool expectation) {
    WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
    NiceMock<MockStore> mock_store;
    EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
        .WillRepeatedly(Return(set<string>()));
    const string kStorageId = "storage_id";
    EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
        .WillRepeatedly(Return(true));
    set<string> groups;
    groups.insert(kStorageId);
    EXPECT_CALL(mock_store, GetGroupsWithProperties(
        ContainsWiFiProperties(wifi_service->ssid(),
                               flimflam::kModeManaged,
                               storage_security)))
        .WillRepeatedly(Return(groups));
    bool is_loadable = wifi_service->IsLoadableFrom(mock_store);
    EXPECT_EQ(expectation, is_loadable);
    bool is_loaded = wifi_service->Load(&mock_store);
    EXPECT_EQ(expectation, is_loaded);
    const string expected_identifier(expectation ? kStorageId : "");
    EXPECT_EQ(expected_identifier,
              wifi_service->GetLoadableStorageIdentifier(mock_store));

    if (expectation != is_loadable || expectation != is_loaded) {
      return false;
    } else if (!expectation) {
      return true;
    } else {
      return wifi_service->GetStorageIdentifier() == kStorageId;
    }
  }
};

class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
 public:
  WiFiServiceUpdateFromEndpointsTest()
      : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
        kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
        kGoodEndpointStrength(
            WiFiService::SignalToStrength(kGoodEndpointSignal)),
        service(MakeGenericService()),
        adaptor(*GetAdaptor(service)) {
    ok_endpoint = MakeOpenEndpoint(
        simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
        kOkEndpointSignal);
    good_endpoint = MakeOpenEndpoint(
        simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
        kGoodEndpointSignal);
    bad_endpoint = MakeOpenEndpoint(
        simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
        kBadEndpointSignal);
  }

 protected:
  static const uint16 kOkEndpointFrequency = 2422;
  static const uint16 kBadEndpointFrequency = 2417;
  static const uint16 kGoodEndpointFrequency = 2412;
  static const int16 kOkEndpointSignal = -50;
  static const int16 kBadEndpointSignal = -75;
  static const int16 kGoodEndpointSignal = -25;
  static const char *kOkEndpointBssId;
  static const char *kGoodEndpointBssId;
  static const char *kBadEndpointBssId;
  // Can't be both static and const (because initialization requires a
  // function call). So choose to be just const.
  const uint8 kOkEndpointStrength;
  const uint8 kBadEndpointStrength;
  const uint8 kGoodEndpointStrength;
  WiFiEndpointRefPtr ok_endpoint;
  WiFiEndpointRefPtr bad_endpoint;
  WiFiEndpointRefPtr good_endpoint;
  WiFiServiceRefPtr service;
  ServiceMockAdaptor &adaptor;
};

const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
    "00:00:00:00:00:01";
const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
    "00:00:00:00:00:02";
const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
    "00:00:00:00:00:03";

class WiFiServiceFixupStorageTest : public WiFiServiceTest {
 protected:
  void AddGroup(string group_name) {
    groups_.insert(group_name);
  }

  void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
                       bool has_security_class) {
    int index = groups_.size();
    string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
                                   index, index, flimflam::kModeManaged,
                                   flimflam::kSecurityWpa);
    AddGroup(id);
    EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
        .WillOnce(Return(has_type));
    if (!has_type) {
      EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
                                    flimflam::kTypeWifi));
    }
    EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
        .WillOnce(Return(has_mode));
    if (!has_mode) {
      EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
                                    flimflam::kModeManaged));
    }
    EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
        .WillOnce(Return(has_security));
    if (!has_security) {
      EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
                                    flimflam::kSecurityWpa));
    }
    EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
        .WillOnce(Return(has_security_class));
    if (!has_security_class) {
      EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
                                    flimflam::kSecurityPsk));
    }
  }

  bool FixupServiceEntries() {
    EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
    return WiFiService::FixupServiceEntries(&store_);
  }

 private:
  StrictMock<MockStore> store_;
  set<string> groups_;
};

TEST_F(WiFiServiceTest, StorageId) {
  WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
  string id = wifi_service->GetStorageIdentifier();
  for (uint i = 0; i < id.length(); ++i) {
    EXPECT_TRUE(id[i] == '_' ||
                isxdigit(id[i]) ||
                (isalpha(id[i]) && islower(id[i])));
  }
  size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
  EXPECT_NE(mac_pos, string::npos);
  EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
}

// Make sure the passphrase is registered as a write only property
// by reading and comparing all string properties returned on the store.
TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
  WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWpa);
  ReadablePropertyConstIterator<string> it =
      (wifi_service->store()).GetStringPropertiesIter();
  for ( ; !it.AtEnd(); it.Advance())
    EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
}

// Make sure setting the passphrase via D-Bus Service.SetProperty validates
// the passphrase.
TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
  // We only spot check two password cases here to make sure the
  // SetProperty code path does validation.  We're not going to exhaustively
  // test for all types of passwords.
  WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
  Error error;
  EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
                  flimflam::kPassphraseProperty, "0:abcde", &error));
  EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
                   flimflam::kPassphraseProperty, "invalid", &error));
  EXPECT_EQ(Error::kInvalidPassphrase, error.type());
}

TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
  WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
  Error error;
  EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
                   flimflam::kPassphraseProperty, "invalid", &error));
  EXPECT_EQ(Error::kNotSupported, error.type());
}

TEST_F(WiFiServiceTest, NonUTF8SSID) {
  vector<uint8_t> ssid;

  ssid.push_back(0xff);  // not a valid UTF-8 byte-sequence
  WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
                                                   dispatcher(),
                                                   metrics(),
                                                   manager(),
                                                   provider(),
                                                   ssid,
                                                   flimflam::kModeManaged,
                                                   flimflam::kSecurityNone,
                                                   false);
  map<string, ::DBus::Variant> properties;
  // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
  DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
}

MATCHER(PSKSecurityArgs, "") {
  return ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol) &&
      arg.find(WPASupplicant::kPropertySecurityProtocol)->second.
           reader().get_string() == string("WPA RSN") &&
      ContainsKey(arg, WPASupplicant::kPropertyPreSharedKey);
}

MATCHER(WPA80211wSecurityArgs, "") {
  return ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol) &&
      ContainsKey(arg, WPASupplicant::kPropertyPreSharedKey) &&
      ContainsKey(arg, WPASupplicant::kNetworkPropertyIeee80211w);
}

MATCHER(EAPSecurityArgs, "") {
  return ContainsKey(arg, WPASupplicant::kNetworkPropertyEapIdentity) &&
      ContainsKey(arg, WPASupplicant::kNetworkPropertyCaPath);
}

MATCHER_P(FrequencyArg, has_arg, "") {
  return has_arg ==
      ContainsKey(arg, WPASupplicant::kNetworkPropertyFrequency);
}

TEST_F(WiFiServiceTest, ConnectTaskWPA) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWpa);
  EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
  Error error;
  wifi_service->SetPassphrase("0:mumblemumblem", &error);
  wifi_service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectTaskRSN) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
  EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
  Error error;
  wifi_service->SetPassphrase("0:mumblemumblem", &error);
  wifi_service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectConditions) {
  Error error;
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
  scoped_refptr<MockProfile> mock_profile(
      new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
  wifi_service->set_profile(mock_profile);
  // With nothing else going on, the service should attempt to connect.
  EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
  wifi_service->Connect(&error, "in test");
  Mock::VerifyAndClearExpectations(wifi());

  // But if we're already "connecting" or "connected" then we shouldn't attempt
  // again.
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), _)).Times(0);
  wifi_service->SetState(Service::kStateAssociating);
  wifi_service->Connect(&error, "in test");
  wifi_service->SetState(Service::kStateConfiguring);
  wifi_service->Connect(&error, "in test");
  wifi_service->SetState(Service::kStateConnected);
  wifi_service->Connect(&error, "in test");
  wifi_service->SetState(Service::kStatePortal);
  wifi_service->Connect(&error, "in test");
  wifi_service->SetState(Service::kStateOnline);
  wifi_service->Connect(&error, "in test");
  Mock::VerifyAndClearExpectations(wifi());
}

TEST_F(WiFiServiceTest, ConnectTaskPSK) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
  EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
  Error error;
  wifi_service->SetPassphrase("0:mumblemumblem", &error);
  wifi_service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectTask8021x) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
  service->mutable_eap()->set_identity("identity");
  service->mutable_eap()->set_password("mumble");
  service->OnEapCredentialsChanged();
  EXPECT_CALL(*wifi(), ConnectTo(service.get(), EAPSecurityArgs()));
  service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectTask8021xWithMockEap) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
  MockEapCredentials *eap = SetMockEap(service);
  EXPECT_CALL(*eap, IsConnectable()).WillOnce(Return(true));
  service->OnEapCredentialsChanged();
  EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _, _, _));
  // The mocked function does not actually set EAP parameters so we cannot
  // expect them to be set.
  EXPECT_CALL(*wifi(), ConnectTo(service.get(), _));
  service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
  vector<uint8_t> ssid(1, 'a');
  WiFiEndpointRefPtr endpoint_nofreq =
      MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
  WiFiEndpointRefPtr endpoint_freq =
      MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0);

  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
  wifi_service->AddEndpoint(endpoint_freq);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), FrequencyArg(false)));
  wifi_service->Connect(NULL, "in test");

  wifi_service = new WiFiService(control_interface(),
                                 dispatcher(),
                                 metrics(),
                                 manager(),
                                 provider(),
                                 ssid,
                                 flimflam::kModeAdhoc,
                                 flimflam::kSecurityNone,
                                 false);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), FrequencyArg(false)));
  SetWiFiForService(wifi_service, wifi());
  wifi_service->Connect(NULL, "in test");

  wifi_service = new WiFiService(control_interface(),
                                 dispatcher(),
                                 metrics(),
                                 manager(),
                                 provider(),
                                 ssid,
                                 flimflam::kModeAdhoc,
                                 flimflam::kSecurityNone,
                                 false);
  wifi_service->AddEndpoint(endpoint_nofreq);
  SetWiFiForService(wifi_service, wifi());
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), FrequencyArg(false)));
  wifi_service->Connect(NULL, "in test");

  wifi_service = new WiFiService(control_interface(),
                                 dispatcher(),
                                 metrics(),
                                 manager(),
                                 provider(),
                                 ssid,
                                 flimflam::kModeAdhoc,
                                 flimflam::kSecurityNone,
                                 false);
  wifi_service->AddEndpoint(endpoint_freq);
  SetWiFiForService(wifi_service, wifi());
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), FrequencyArg(true)));
  wifi_service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
  endpoint->ieee80211w_required_ = true;
  wifi_service->AddEndpoint(endpoint);
  Error error;
  wifi_service->SetPassphrase("0:mumblemumblem", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
  wifi_service->Connect(NULL, "in test");
}

MATCHER(WEPSecurityArgsKeyIndex0, "") {
  return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("0")) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
      (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
           reader().get_uint32() == 0);
}

MATCHER(WEPSecurityArgsKeyIndex1, "") {
  return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("1")) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
      (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
           reader().get_uint32() == 1);
}

MATCHER(WEPSecurityArgsKeyIndex2, "") {
  return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("2")) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
      (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
           reader().get_uint32() == 2);
}

MATCHER(WEPSecurityArgsKeyIndex3, "") {
  return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("3")) &&
      ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
      (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
           reader().get_uint32() == 3);
}

TEST_F(WiFiServiceTest, ConnectTaskWEP) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
  Error error;
  wifi_service->SetPassphrase("0:abcdefghijklm", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
  wifi_service->Connect(NULL, "in test");

  wifi_service->SetPassphrase("abcdefghijklm", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
  wifi_service->Connect(NULL, "in test");

  wifi_service->SetPassphrase("1:abcdefghijklm", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
  wifi_service->Connect(NULL, "in test");

  wifi_service->SetPassphrase("2:abcdefghijklm", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
  wifi_service->Connect(NULL, "in test");

  wifi_service->SetPassphrase("3:abcdefghijklm", &error);
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
  wifi_service->Connect(NULL, "in test");
}


MATCHER(DynamicWEPArgs, "") {
  return ContainsKey(arg, WPASupplicant::kNetworkPropertyEapIdentity) &&
      ContainsKey(arg, WPASupplicant::kNetworkPropertyCaPath) &&
      !ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol);
}

// Dynamic WEP + 802.1x.
TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);

  wifi_service->mutable_eap()->SetKeyManagement("IEEE8021X", NULL);
  wifi_service->mutable_eap()->set_identity("something");
  wifi_service->mutable_eap()->set_password("mumble");
  wifi_service->OnEapCredentialsChanged();
  EXPECT_CALL(*wifi(),
              ConnectTo(wifi_service.get(), DynamicWEPArgs()));
  wifi_service->Connect(NULL, "in test");
}

TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
  WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);

  const string kPassphrase = "abcdefgh";

  {
    Error error;
    // A changed passphrase should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    wifi_service->SetPassphrase(kPassphrase, &error);
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }

  {
    Error error;
    // An unchanged passphrase should not trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    wifi_service->SetPassphrase(kPassphrase, &error);
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }

  {
    Error error;
    // A modified passphrase should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    wifi_service->SetPassphrase(kPassphrase + "X", &error);
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }

  {
    Error error;
    // A cleared passphrase should also trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    wifi_service->ClearPassphrase(&error);
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }

  {
    Error error;
    // An invalid passphrase should not trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    wifi_service->SetPassphrase("", &error);
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_FALSE(error.IsSuccess());
  }

  {
    // Any change to EAP parameters (including a null one) will trigger cache
    // removal.  This is a lot less granular than the passphrase checks above.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    wifi_service->OnEapCredentialsChanged();
    Mock::VerifyAndClearExpectations(wifi());
  }
}

// This test is somewhat redundant, since:
//
// a) we test that generic property setters return false on a null
//    change (e.g. in PropertyAccessorTest.SignedIntCorrectness)
// b) we test that custom EAP property setters return false on a null
//    change in EapCredentialsTest.CustomSetterNoopChange
// c) we test that the various custom accessors pass through the
//    return value of custom setters
//    (e.g. PropertyAccessorTest.CustomAccessorCorrectness)
// d) we test that PropertyStore skips the change callback when a
//    property setter return false (PropertyStoreTypedTest.SetProperty)
//
// Nonetheless, I think it's worth testing the WiFi+EAP case directly.
TEST_F(WiFiServiceTest, EapAuthPropertyChangeClearsCachedCredentials) {
  WiFiServiceRefPtr wifi_service =
      MakeServiceWithWiFi(flimflam::kSecurity8021x);
  PropertyStore &property_store(*wifi_service->mutable_store());

  // Property with custom accessor.
  const string kPassword = "abcdefgh";
  {
    Error error;
    // A changed passphrase should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    EXPECT_TRUE(property_store.SetStringProperty(
        flimflam::kEapPasswordProperty, kPassword, &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }
  {
    Error error;
    // An unchanged passphrase should not trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    EXPECT_FALSE(property_store.SetStringProperty(
        flimflam::kEapPasswordProperty, kPassword, &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }
  {
    Error error;
    // A modified passphrase should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    EXPECT_TRUE(property_store.SetStringProperty(
        flimflam::kEapPasswordProperty, kPassword + "X", &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }

  // Property with generic accessor.
  const string kCertId = "abcdefgh";
  {
    Error error;
    // A changed cert id should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    EXPECT_TRUE(property_store.SetStringProperty(
        flimflam::kEapCertIdProperty, kCertId, &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }
  {
    Error error;
    // An unchanged cert id should not trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
    EXPECT_FALSE(property_store.SetStringProperty(
        flimflam::kEapCertIdProperty, kCertId, &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }
  {
    Error error;
    // A modified cert id should trigger cache removal.
    EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
    EXPECT_TRUE(property_store.SetStringProperty(
        flimflam::kEapCertIdProperty, kCertId + "X", &error));
    Mock::VerifyAndClearExpectations(wifi());
    EXPECT_TRUE(error.IsSuccess());
  }
}

TEST_F(WiFiServiceTest, LoadHidden) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  ASSERT_FALSE(service->hidden_ssid_);
  NiceMock<MockStore> mock_store;
  const string storage_id = service->GetStorageIdentifier();
  set<string> groups;
  groups.insert(storage_id);
  EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_store, GetGroupsWithProperties(
      ContainsWiFiProperties(
          simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(mock_store, GetBool(_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_store,
              GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
  EXPECT_TRUE(service->Load(&mock_store));
  EXPECT_TRUE(service->hidden_ssid_);
}

TEST_F(WiFiServiceTest, LoadPassphraseForNonPassphraseService) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  NiceMock<MockStore> mock_store;
  const string storage_id = service->GetStorageIdentifier();
  set<string> groups;
  groups.insert(storage_id);
  EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_store, GetGroupsWithProperties(
      ContainsWiFiProperties(
          simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(mock_store,
              GetCryptedString(StrEq(storage_id),
                               StrNe(WiFiService::kStoragePassphrase), _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_store,
              GetCryptedString(StrEq(storage_id),
                               WiFiService::kStoragePassphrase, _))
      .WillOnce(DoAll(SetArgumentPointee<2>(string("password")), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(string()), Return(true)));
  ScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith("Passphrase could not be set: "
                                "org.chromium.flimflam.Error.NotSupported")))
      .Times(1);
  EXPECT_TRUE(service->Load(&mock_store));
  Mock::VerifyAndClearExpectations(&log);
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _, _)).Times(0);
  EXPECT_TRUE(service->Load(&mock_store));
}

TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
  set<string> groups;
  groups.insert("id0");
  groups.insert("id1");
  // Make sure we retain the first matched group in the same way that
  // WiFiService::Load() will.
  string first_group = *groups.begin();

  NiceMock<MockStore> mock_store;
  EXPECT_CALL(mock_store, GetGroupsWithProperties(
      ContainsWiFiProperties(
          simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(mock_store, ContainsGroup(first_group))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
  EXPECT_CALL(mock_store, GetBool(first_group, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
                       EndsWith("choosing the first.")));
  EXPECT_TRUE(service->Load(&mock_store));
}

TEST_F(WiFiServiceSecurityTest, WPAMapping) {
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
                                 flimflam::kSecurityPsk));
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
                                 flimflam::kSecurityPsk));
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
                                 flimflam::kSecurityPsk));
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
                                 flimflam::kSecurityWep));
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
                                 flimflam::kSecurityNone));
  EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
                                 flimflam::kSecurity8021x));
}

TEST_F(WiFiServiceSecurityTest, LoadMapping) {
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
                              flimflam::kSecurityPsk,
                              true));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
                              flimflam::kSecurityRsn,
                              false));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
                              flimflam::kSecurityWpa,
                              false));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
                              flimflam::kSecurityPsk,
                              true));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
                              flimflam::kSecurityWpa,
                              false));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
                              flimflam::kSecurityRsn,
                              false));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
                              flimflam::kSecurityWep,
                              true));
  EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
                              flimflam::kSecurityPsk,
                              false));
}

TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
  NiceMock<MockStore> mock_store;
  const string storage_id = service->GetStorageIdentifier();
  EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
      .WillRepeatedly(Return(true));
  set<string> groups;
  groups.insert(storage_id);
  EXPECT_CALL(mock_store, GetGroupsWithProperties(
      ContainsWiFiProperties(
          simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityPsk)))
      .WillRepeatedly(Return(groups));
  EXPECT_CALL(mock_store, GetBool(_, _, _))
      .WillRepeatedly(Return(false));
  const string passphrase = "passphrase";
  EXPECT_CALL(mock_store,
              GetCryptedString(StrEq(storage_id),
                               WiFiService::kStoragePassphrase, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
  EXPECT_CALL(mock_store,
              GetCryptedString(StrEq(storage_id),
                               StrNe(WiFiService::kStoragePassphrase), _))
      .WillRepeatedly(Return(false));
  EXPECT_TRUE(service->need_passphrase_);
  EXPECT_TRUE(service->Load(&mock_store));
  EXPECT_EQ(passphrase, service->passphrase_);
  EXPECT_TRUE(service->connectable());
  EXPECT_FALSE(service->need_passphrase_);
  service->Unload();
  EXPECT_EQ(string(""), service->passphrase_);
  EXPECT_FALSE(service->connectable());
  EXPECT_TRUE(service->need_passphrase_);
}

TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
  string guid("legit_guid");
  KeyValueStore args;
  args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
  args.SetString(flimflam::kEapPasswordProperty, "legit_password");
  args.SetString(flimflam::kEAPEAPProperty, "PEAP");
  args.SetString(flimflam::kGuidProperty, guid);
  Error error;

  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
  // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
  // our service.  This way, Manager will handle the lookup itself.
  service->SetGuid(guid, NULL);
  manager()->RegisterService(service);
  EXPECT_FALSE(service->connectable());
  EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service->connectable());
}

TEST_F(WiFiServiceTest, ConfigurePassphrase) {
  EXPECT_EQ(Error::kNotSupported,
            TestConfigurePassphrase(flimflam::kSecurityNone, ""));
  EXPECT_EQ(Error::kNotSupported,
            TestConfigurePassphrase(flimflam::kSecurityNone, "foo"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep, NULL));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, ""));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "abcd"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep, "abcde"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep, "abcdefghijklm"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep, "0:abcdefghijklm"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep, "0102030405"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "0x0102030405"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "O102030405"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "1:O102030405"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "1:0xO102030405"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWep, "0xO102030405"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep,
                                    "0102030405060708090a0b0c0d"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep,
                                    "0102030405060708090A0B0C0D"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep,
                                    "0:0102030405060708090a0b0c0d"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWep,
                                    "0:0x0102030405060708090a0b0c0d"));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWpa, NULL));
  EXPECT_EQ(Error::kSuccess,
            TestConfigurePassphrase(flimflam::kSecurityWpa, "secure password"));
  EXPECT_EQ(Error::kInvalidPassphrase,
            TestConfigurePassphrase(flimflam::kSecurityWpa, ""));
  EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
  EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
  // subtle: invalid length for hex key, but valid as ascii passphrase
  EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
  EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAHexLen, '1').c_str()));
  EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
  EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
  EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
      flimflam::kSecurityWpa,
      string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
}

TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  KeyValueStore args;
  args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
  args.SetString(flimflam::kSSIDProperty, simple_ssid_string());
  args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityNone);
  const string kGUID = "aguid";
  args.SetString(flimflam::kGuidProperty, kGUID);

  EXPECT_EQ("", service->guid());
  Error error;
  service->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kGUID, service->guid());
}

TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
  EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
  Error error;
  service->Disconnect(&error);
}

TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
  EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
  Error error;
  service->Disconnect(&error);
  EXPECT_EQ(Error::kOperationFailed, error.type());
}

TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
  EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
  service->SetState(Service::kStateAssociating);
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       HasSubstr("WiFi endpoints do not (yet) exist.")));
  Error error;
  service->Disconnect(&error);
  EXPECT_EQ(Error::kOperationFailed, error.type());
}

TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
  EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
  EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
  service->Unload();
}

TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
  EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
  EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
  service->Unload();
}

TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  const string storage_id = service->GetStorageIdentifier();
  string address;
  string mode;
  string security;
  EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
                                              &security));
  EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
  EXPECT_EQ(flimflam::kModeManaged, mode);
  EXPECT_EQ(flimflam::kSecurityNone, security);
}

TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
  // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
  // which needs to be dealt with specially in the parser.
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
  const string storage_id = service->GetStorageIdentifier();
  string address;
  string mode;
  string security;
  EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
                                              &security));
  EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
  EXPECT_EQ(flimflam::kModeManaged, mode);
  EXPECT_EQ(flimflam::kSecurity8021x, security);
}

TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
  const string kNonWiFiId = "vpn_foo";
  const string kUnparsableWiFiId = "wifi_foo";

  AddGroup(kNonWiFiId);
  AddGroup(kUnparsableWiFiId);
  AddServiceEntry(true, true, true, true);
  AddServiceEntry(false, false, false, false);
  AddServiceEntry(true, true, true, true);
  AddServiceEntry(false, false, false, false);
  EXPECT_TRUE(FixupServiceEntries());
}

TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
  const string kNonWiFiId = "vpn_foo";
  const string kUnparsableWiFiId = "wifi_foo";

  AddGroup(kNonWiFiId);
  AddGroup(kUnparsableWiFiId);
  AddServiceEntry(true, true, true, true);
  EXPECT_FALSE(FixupServiceEntries());
}

TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
  AddServiceEntry(false, true, true, true);
  EXPECT_TRUE(FixupServiceEntries());
}

TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
  AddServiceEntry(true, false, true, true);
  EXPECT_TRUE(FixupServiceEntries());
}

TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
  AddServiceEntry(true, true, false, true);
  EXPECT_TRUE(FixupServiceEntries());
}

TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
  AddServiceEntry(true, true, true, false);
  EXPECT_TRUE(FixupServiceEntries());
}

TEST_F(WiFiServiceTest, Connectable) {
  // Open network should be connectable.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, false));

  // Open network should remain connectable if we try to set a password on it.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", false));

  // WEP network with passphrase set should be connectable.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", false));

  // WEP network without passphrase set should NOT be connectable.
  EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, false));

  // A bad passphrase should not make a WEP network connectable.
  EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", false));

  // Similar to WEP, for WPA.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", false));
  EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, false));
  EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", false));

  // 802.1x without connectable EAP credentials should NOT be connectable.
  EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, false));

  // 802.1x with connectable EAP credentials should be connectable.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, true));

  // Dynamic WEP + 802.1X should be connectable under the same conditions.
  EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, true));
}

TEST_F(WiFiServiceTest, IsAutoConnectable) {
  const char *reason;
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  EXPECT_CALL(*wifi(), IsIdle())
      .WillRepeatedly(Return(true));
  EXPECT_FALSE(service->HasEndpoints());
  EXPECT_FALSE(service->IsAutoConnectable(&reason));
  EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);

  reason = "";
  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
  service->AddEndpoint(endpoint);
  EXPECT_CALL(*wifi(), IsIdle())
      .WillRepeatedly(Return(true));
  EXPECT_TRUE(service->HasEndpoints());
  EXPECT_TRUE(service->IsAutoConnectable(&reason));
  EXPECT_STREQ("", reason);

  // WiFi only supports connecting to one Service at a time. So, to
  // avoid disrupting connectivity, we only allow auto-connection to
  // a WiFiService when the corresponding WiFi is idle.
  EXPECT_CALL(*wifi(), IsIdle())
      .WillRepeatedly(Return(false));
  EXPECT_TRUE(service->HasEndpoints());
  EXPECT_FALSE(service->IsAutoConnectable(&reason));
  EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
}

TEST_F(WiFiServiceTest, AutoConnect) {
  const char *reason;
  WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
  EXPECT_FALSE(service->IsAutoConnectable(&reason));
  EXPECT_CALL(*wifi(), ConnectTo(_, _))
      .Times(0);
  service->AutoConnect();
  dispatcher()->DispatchPendingEvents();

  WiFiEndpointRefPtr endpoint =
      MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
  service->AddEndpoint(endpoint);
  EXPECT_CALL(*wifi(), IsIdle())
      .WillRepeatedly(Return(true));
  EXPECT_TRUE(service->IsAutoConnectable(&reason));
  EXPECT_CALL(*wifi(), ConnectTo(_, _));
  service->AutoConnect();
  dispatcher()->DispatchPendingEvents();

  Error error;
  service->UserInitiatedDisconnect(&error);
  dispatcher()->DispatchPendingEvents();
  EXPECT_FALSE(service->IsAutoConnectable(&reason));
}

TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
  WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);

  EXPECT_EQ("", wifi_service->passphrase_);

  ::DBus::Error error;
  EXPECT_TRUE(DBusAdaptor::SetProperty(
      wifi_service->mutable_store(),
      flimflam::kPassphraseProperty,
      DBusAdaptor::StringToVariant("0:abcde"),
      &error));
  EXPECT_EQ("0:abcde", wifi_service->passphrase_);

  EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
                                         flimflam::kPassphraseProperty,
                                         &error));
  EXPECT_EQ("", wifi_service->passphrase_);
}

TEST_F(WiFiServiceTest, SignalToStrength) {
  // Verify that our mapping is sane, in the sense that it preserves ordering.
  // We break the test into two domains, because we assume that positive
  // values aren't actually in dBm.
  for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
    int16 current_mapped = WiFiService::SignalToStrength(i);
    int16 next_mapped =  WiFiService::SignalToStrength(i+1);
    EXPECT_LE(current_mapped, next_mapped)
        << "(original values " << i << " " << i+1 << ")";
    EXPECT_GE(current_mapped, Service::kStrengthMin);
    EXPECT_LE(current_mapped, Service::kStrengthMax);
  }
  for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
    int16 current_mapped = WiFiService::SignalToStrength(i);
    int16 next_mapped =  WiFiService::SignalToStrength(i+1);
    EXPECT_LE(current_mapped, next_mapped)
        << "(original values " << i << " " << i+1 << ")";
    EXPECT_GE(current_mapped, Service::kStrengthMin);
    EXPECT_LE(current_mapped, Service::kStrengthMax);
  }
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
  // If the chosen signal values don't map to distinct strength
  // values, then we can't expect our other tests to pass. So verify
  // their distinctness.
  EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
  EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
  EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
  // Initial endpoint updates values.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kOkEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kOkEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(
      flimflam::kSignalStrengthProperty, kOkEndpointStrength));
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiPhyMode, Metrics::kWiFiNetworkPhyMode11b));
  service->AddEndpoint(ok_endpoint);
  EXPECT_EQ(1, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Endpoint with stronger signal updates values.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kGoodEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kGoodEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(
      flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
  // However, both endpoints are 11b.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
  service->AddEndpoint(good_endpoint);
  EXPECT_EQ(2, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Endpoint with lower signal does not change values.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
  service->AddEndpoint(bad_endpoint);
  EXPECT_EQ(3, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Removing non-optimal endpoint does not change values.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
  service->RemoveEndpoint(bad_endpoint);
  EXPECT_EQ(2, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Removing optimal endpoint updates values.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kOkEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kOkEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(
      flimflam::kSignalStrengthProperty, kOkEndpointStrength));
  // However, both endpoints are 11b.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
  service->RemoveEndpoint(good_endpoint);
  EXPECT_EQ(1, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Removing last endpoint updates values (and doesn't crash).
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
  EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiPhyMode, Metrics::kWiFiNetworkPhyModeUndef));
  service->RemoveEndpoint(ok_endpoint);
  EXPECT_EQ(0, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
  EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
  service->AddEndpoint(bad_endpoint);
  service->AddEndpoint(ok_endpoint);
  EXPECT_EQ(2, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Setting current endpoint forces adoption of its values, even if it
  // doesn't have the highest signal.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kBadEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kBadEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(
      flimflam::kSignalStrengthProperty, kBadEndpointStrength));
  service->NotifyCurrentEndpoint(bad_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);

  // Adding a better endpoint doesn't matter, when current endpoint is set.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  service->AddEndpoint(good_endpoint);
  EXPECT_EQ(3, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Removing a better endpoint doesn't matter, when current endpoint is set.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  service->RemoveEndpoint(good_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);

  // Removing the current endpoint is safe and sane.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kOkEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kOkEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(
      flimflam::kSignalStrengthProperty, kOkEndpointStrength));
  service->RemoveEndpoint(bad_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);

  // Clearing the current endpoint (without removing it) is also safe and sane.
  service->NotifyCurrentEndpoint(ok_endpoint);
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  service->NotifyCurrentEndpoint(NULL);
  Mock::VerifyAndClearExpectations(&adaptor);
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
  EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
  service->AddEndpoint(ok_endpoint);
  service->AddEndpoint(good_endpoint);
  EXPECT_EQ(2, service->GetEndpointCount());
  Mock::VerifyAndClearExpectations(&adaptor);

  // Updating sub-optimal Endpoint doesn't update Service.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor,
              EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
  ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
  service->NotifyEndpointUpdated(ok_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);

  // Updating optimal Endpoint updates appropriate Service property.
  EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
  EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
  EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
  good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
  service->NotifyEndpointUpdated(good_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);

  // Change in optimal Endpoint updates Service properties.
  EXPECT_CALL(adaptor, EmitUint16Changed(
      flimflam::kWifiFrequency, kOkEndpointFrequency));
  EXPECT_CALL(adaptor, EmitStringChanged(
      flimflam::kWifiBSsid, kOkEndpointBssId));
  EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
  ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
  service->NotifyEndpointUpdated(ok_endpoint);
  Mock::VerifyAndClearExpectations(&adaptor);
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
  EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
  service->AddEndpoint(ok_endpoint);
  EXPECT_FALSE(service->ieee80211w_required());
  good_endpoint->ieee80211w_required_ = true;
  service->AddEndpoint(good_endpoint);
  EXPECT_TRUE(service->ieee80211w_required());
  service->RemoveEndpoint(good_endpoint);
  EXPECT_TRUE(service->ieee80211w_required());
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, PhysicalMode) {
  EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
  EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());

  // No endpoints -> undef.
  EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());

  // Endpoint has unknown physical mode -> undef.
  ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyModeUndef;
  service->AddEndpoint(ok_endpoint);
  EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());

  // New endpoint with 802.11a -> 802.11a.
  good_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
  service->AddEndpoint(good_endpoint);
  EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, service->physical_mode());

  // Remove 802.11a endpoint -> undef.
  service->RemoveEndpoint(good_endpoint);
  EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());

  // Change endpoint -> take endpoint's new value.
  ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11n;
  service->NotifyEndpointUpdated(ok_endpoint);
  EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, service->physical_mode());

  // No endpoints -> undef.
  service->RemoveEndpoint(ok_endpoint);
  EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
}

TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) {
  service->AddEndpoint(ok_endpoint);
  service->SetState(Service::kStateAssociating);
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
                       EndsWith("disconnect due to no remaining endpoints.")));
  service->RemoveEndpoint(ok_endpoint);
}

TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) {
  WiFiServiceRefPtr service(MakeSimpleService(flimflam::kSecurityPsk));
  EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
  WiFiEndpoint *endpoint = MakeOpenEndpoint(
        simple_ssid_string(), "00:00:00:00:00:00", 0, 0);
  service->AddEndpoint(endpoint);
  EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
  service->NotifyCurrentEndpoint(endpoint);
  EXPECT_EQ(flimflam::kSecurityNone, service->GetSecurity(NULL));
  service->NotifyCurrentEndpoint(NULL);
  EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
}

TEST_F(WiFiServiceTest, UpdateSecurity) {
  // Cleartext and pre-shared-key crypto.
  {
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
    EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm());
    EXPECT_FALSE(service->key_rotation());
    EXPECT_FALSE(service->endpoint_auth());
  }
  {
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
    EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
    EXPECT_FALSE(service->key_rotation());
    EXPECT_FALSE(service->endpoint_auth());
  }
  {
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
    EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_FALSE(service->endpoint_auth());
  }
  {
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWpa);
    EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_FALSE(service->endpoint_auth());
  }
  {
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityRsn);
    EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_FALSE(service->endpoint_auth());
  }

  // Crypto with 802.1X key management.
  {
    // WEP
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
    service->SetEAPKeyManagement("IEEE8021X");
    EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_TRUE(service->endpoint_auth());
  }
  {
    // WPA
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false);
    service->AddEndpoint(endpoint);
    EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_TRUE(service->endpoint_auth());
  }
  {
    // RSN
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true);
    service->AddEndpoint(endpoint);
    EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_TRUE(service->endpoint_auth());
  }
  {
    // AP supports both WPA and RSN.
    WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
    WiFiEndpointRefPtr endpoint =
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true);
    service->AddEndpoint(endpoint);
    EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
    EXPECT_TRUE(service->key_rotation());
    EXPECT_TRUE(service->endpoint_auth());
  }
}

TEST_F(WiFiServiceTest, ComputeCipher8021x) {
  // No endpoints.
  {
    const set<WiFiEndpointConstRefPtr> endpoints;
    EXPECT_EQ(Service::kCryptoNone,
              WiFiService::ComputeCipher8021x(endpoints));
  }

  // Single endpoint, various configs.
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
    EXPECT_EQ(Service::kCryptoNone,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
    EXPECT_EQ(Service::kCryptoRc4,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
    EXPECT_EQ(Service::kCryptoAes,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
    EXPECT_EQ(Service::kCryptoAes,
              WiFiService::ComputeCipher8021x(endpoints));
  }

  // Multiple endpoints.
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false));
    EXPECT_EQ(Service::kCryptoNone,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
    EXPECT_EQ(Service::kCryptoNone,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
    EXPECT_EQ(Service::kCryptoRc4,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
    EXPECT_EQ(Service::kCryptoRc4,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
    EXPECT_EQ(Service::kCryptoAes,
              WiFiService::ComputeCipher8021x(endpoints));
  }
  {
    set<WiFiEndpointConstRefPtr> endpoints;
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
    endpoints.insert(
        MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true));
    EXPECT_EQ(Service::kCryptoAes,
              WiFiService::ComputeCipher8021x(endpoints));
  }
}

TEST_F(WiFiServiceTest, Unload) {
  WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
  EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())).
    Times(1);
  service->Unload();
}

TEST_F(WiFiServiceTest, PropertyChanges) {
  WiFiServiceRefPtr service = MakeServiceWithMockManager();
  ServiceMockAdaptor *adaptor = GetAdaptor(service);
  TestCommonPropertyChanges(service, adaptor);
  TestAutoConnectPropertyChange(service, adaptor);

  EXPECT_CALL(*adaptor,
              EmitRpcIdentifierChanged(flimflam::kDeviceProperty, _));
  SetWiFi(service, wifi());
  Mock::VerifyAndClearExpectations(adaptor);

  EXPECT_CALL(*adaptor,
              EmitRpcIdentifierChanged(flimflam::kDeviceProperty, _));
  service->ResetWiFi();
  Mock::VerifyAndClearExpectations(adaptor);
}

// Custom property setters should return false, and make no changes, if
// the new value is the same as the old value.
TEST_F(WiFiServiceTest, CustomSetterNoopChange) {
  WiFiServiceRefPtr service = MakeServiceWithMockManager();
  TestCustomSetterNoopChange(service, mock_manager());
}

}  // namespace shill
