// Copyright (c) 2012 The Chromium 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 "chromeos/network/network_state_handler.h"

#include <stddef.h>

#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/values.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_device_client.h"
#include "chromeos/dbus/shill_ipconfig_client.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_profile_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler_observer.h"
#include "chromeos/network/tether_constants.h"
#include "dbus/object_path.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

namespace chromeos {

namespace {

void ErrorCallbackFunction(const std::string& error_name,
                           const std::string& error_message) {
  LOG(ERROR) << "Shill Error: " << error_name << " : " << error_message;
}

const char kShillManagerClientStubWifiDevice[] = "/device/stub_wifi_device1";
const char kShillManagerClientStubCellularDevice[] =
    "/device/stub_cellular_device1";
const char kShillManagerClientStubDefaultService[] = "/service/eth1";
const char kShillManagerClientStubDefaultWifi[] = "/service/wifi1";
const char kShillManagerClientStubWifi2[] = "/service/wifi2";
const char kShillManagerClientStubCellular[] = "/service/cellular1";

const char kWifiGuid1[] = "wifi1";
const char kWifiName1[] = "WiFi 1";

const char kTetherGuid1[] = "tether1";
const char kTetherGuid2[] = "tether2";
const char kTetherName1[] = "Device1";
const char kTetherName2[] = "Device2";
const char kTetherCarrier1[] = "Carrier1";
const char kTetherCarrier2[] = "Carrier2";
const int kTetherBatteryPercentage1 = 85;
const int kTetherBatteryPercentage2 = 90;
const int kTetherSignalStrength1 = 75;
const int kTetherSignalStrength2 = 80;
const bool kTetherHasConnectedToHost1 = true;
const bool kTetherHasConnectedToHost2 = false;

using chromeos::DeviceState;
using chromeos::NetworkState;
using chromeos::NetworkStateHandler;

class TestObserver final : public chromeos::NetworkStateHandlerObserver {
 public:
  explicit TestObserver(NetworkStateHandler* handler)
      : handler_(handler),
        device_list_changed_count_(0),
        device_count_(0),
        network_list_changed_count_(0),
        network_count_(0),
        default_network_change_count_(0),
        scan_requested_count_(0),
        scan_completed_count_(0) {}

  ~TestObserver() override = default;

  void DeviceListChanged() override {
    NetworkStateHandler::DeviceStateList devices;
    handler_->GetDeviceList(&devices);
    device_count_ = devices.size();
    ++device_list_changed_count_;
  }

  void NetworkListChanged() override {
    NetworkStateHandler::NetworkStateList networks;
    handler_->GetNetworkListByType(chromeos::NetworkTypePattern::Default(),
                                   false /* configured_only */,
                                   false /* visible_only */,
                                   0 /* no limit */,
                                   &networks);
    network_count_ = networks.size();
    if (network_count_ == 0) {
      default_network_ = "";
      default_network_connection_state_ = "";
    }
    ++network_list_changed_count_;
  }

  void DefaultNetworkChanged(const NetworkState* network) override {
    EXPECT_TRUE(!network || network->IsConnectedState());
    ++default_network_change_count_;
    default_network_ = network ? network->path() : "";
    default_network_connection_state_ =
        network ? network->connection_state() : "";
    VLOG(1) << "DefaultNetworkChanged: " << default_network_
            << " State: " << default_network_connection_state_;
  }

  void NetworkConnectionStateChanged(const NetworkState* network) override {
    network_connection_state_[network->path()] = network->connection_state();
    connection_state_changes_[network->path()]++;
  }

  void NetworkPropertiesUpdated(const NetworkState* network) override {
    DCHECK(network);
    property_updates_[network->path()]++;
  }

  void DevicePropertiesUpdated(const DeviceState* device) override {
    DCHECK(device);
    device_property_updates_[device->path()]++;
  }

  void ScanRequested() override { scan_requested_count_++; }

  void ScanCompleted(const DeviceState* device) override {
    DCHECK(device);
    scan_completed_count_++;
  }

  size_t device_list_changed_count() { return device_list_changed_count_; }
  size_t device_count() { return device_count_; }
  size_t network_list_changed_count() { return network_list_changed_count_; }
  size_t network_count() { return network_count_; }
  size_t default_network_change_count() {
    return default_network_change_count_;
  }
  size_t scan_requested_count() { return scan_requested_count_; }
  size_t scan_completed_count() { return scan_completed_count_; }
  void reset_change_counts() {
    VLOG(1) << "=== RESET CHANGE COUNTS ===";
    default_network_change_count_ = 0;
    device_list_changed_count_ = 0;
    network_list_changed_count_ = 0;
    scan_requested_count_ = 0;
    scan_completed_count_ = 0;
    connection_state_changes_.clear();
  }
  void reset_updates() {
    property_updates_.clear();
    device_property_updates_.clear();
  }
  std::string default_network() { return default_network_; }
  std::string default_network_connection_state() {
    return default_network_connection_state_;
  }

  int PropertyUpdatesForService(const std::string& service_path) {
    return property_updates_[service_path];
  }

  int PropertyUpdatesForDevice(const std::string& device_path) {
    return device_property_updates_[device_path];
  }

  int ConnectionStateChangesForService(const std::string& service_path) {
    return connection_state_changes_[service_path];
  }

  std::string NetworkConnectionStateForService(
      const std::string& service_path) {
    return network_connection_state_[service_path];
  }

 private:
  NetworkStateHandler* handler_;
  size_t device_list_changed_count_;
  size_t device_count_;
  size_t network_list_changed_count_;
  size_t network_count_;
  size_t default_network_change_count_;
  size_t scan_requested_count_;
  size_t scan_completed_count_;
  std::string default_network_;
  std::string default_network_connection_state_;
  std::map<std::string, int> property_updates_;
  std::map<std::string, int> device_property_updates_;
  std::map<std::string, int> connection_state_changes_;
  std::map<std::string, std::string> network_connection_state_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

class TestTetherSortDelegate : public NetworkStateHandler::TetherSortDelegate {
 public:
  TestTetherSortDelegate() = default;
  ~TestTetherSortDelegate() = default;

  // NetworkStateHandler::TetherSortDelegate:
  void SortTetherNetworkList(
      NetworkStateHandler::ManagedStateList* tether_networks) const override {
    std::sort(tether_networks->begin(), tether_networks->end(),
              [](const std::unique_ptr<ManagedState>& first,
                 const std::unique_ptr<ManagedState>& second) {
                const NetworkState* first_network =
                    static_cast<const NetworkState*>(first.get());
                const NetworkState* second_network =
                    static_cast<const NetworkState*>(second.get());

                // Sort by reverse-alphabetical order of GUIDs.
                return first_network->guid() >= second_network->guid();
              });
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestTetherSortDelegate);
};

}  // namespace

class NetworkStateHandlerTest : public testing::Test {
 public:
  NetworkStateHandlerTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI),
        device_test_(nullptr),
        manager_test_(nullptr),
        profile_test_(nullptr),
        service_test_(nullptr) {}
  ~NetworkStateHandlerTest() override = default;

  void SetUp() override {
    // Initialize DBusThreadManager with a stub implementation.
    DBusThreadManager::Initialize();
    SetupDefaultShillState();
    network_state_handler_.reset(new NetworkStateHandler);
    test_observer_.reset(new TestObserver(network_state_handler_.get()));
    network_state_handler_->AddObserver(test_observer_.get(), FROM_HERE);
    network_state_handler_->InitShillPropertyHandler();
    base::RunLoop().RunUntilIdle();
    test_observer_->reset_change_counts();
  }

  void TearDown() override {
    network_state_handler_->RemoveObserver(test_observer_.get(), FROM_HERE);
    network_state_handler_->Shutdown();
    test_observer_.reset();
    network_state_handler_.reset();
    DBusThreadManager::Shutdown();
  }

 protected:
  void AddService(const std::string& service_path,
                  const std::string& guid,
                  const std::string& name,
                  const std::string& type,
                  const std::string& state) {
    service_test_->AddService(service_path, guid, name, type, state,
                              true /* add_to_visible */);
  }

  void SetupDefaultShillState() {
    base::RunLoop().RunUntilIdle();  // Process any pending updates
    device_test_ =
        DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
    ASSERT_TRUE(device_test_);
    device_test_->ClearDevices();
    device_test_->AddDevice(kShillManagerClientStubWifiDevice,
                            shill::kTypeWifi, "stub_wifi_device1");
    device_test_->AddDevice(kShillManagerClientStubCellularDevice,
                            shill::kTypeCellular, "stub_cellular_device1");

    manager_test_ =
        DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface();
    ASSERT_TRUE(manager_test_);

    profile_test_ =
        DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
    ASSERT_TRUE(profile_test_);
    profile_test_->ClearProfiles();

    service_test_ =
        DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
    ASSERT_TRUE(service_test_);
    service_test_->ClearServices();
    AddService(kShillManagerClientStubDefaultService,
               "eth1_guid",
               "eth1",
               shill::kTypeEthernet,
               shill::kStateOnline);
    AddService(kShillManagerClientStubDefaultWifi,
               "wifi1_guid",
               "wifi1",
               shill::kTypeWifi,
               shill::kStateOnline);
    AddService(kShillManagerClientStubWifi2,
               "wifi2_guid",
               "wifi2",
               shill::kTypeWifi,
               shill::kStateIdle);
    AddService(kShillManagerClientStubCellular,
               "cellular1_guid",
               "cellular1",
               shill::kTypeCellular,
               shill::kStateIdle);
  }

  void UpdateManagerProperties() { base::RunLoop().RunUntilIdle(); }

  void SetServiceProperty(const std::string& service_path,
                          const std::string& key,
                          const base::Value& value) {
    DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
        dbus::ObjectPath(service_path), key, value, base::DoNothing(),
        base::Bind(&ErrorCallbackFunction));
  }

  void GetTetherNetworkList(int limit,
                            NetworkStateHandler::NetworkStateList* list) {
    network_state_handler_->GetNetworkListByType(
        NetworkTypePattern::Tether(), false /* configured_only */,
        false /* visible_only */, limit, list);
  }

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  std::unique_ptr<NetworkStateHandler> network_state_handler_;
  std::unique_ptr<TestObserver> test_observer_;
  ShillDeviceClient::TestInterface* device_test_;
  ShillManagerClient::TestInterface* manager_test_;
  ShillProfileClient::TestInterface* profile_test_;
  ShillServiceClient::TestInterface* service_test_;

 private:
  DISALLOW_COPY_AND_ASSIGN(NetworkStateHandlerTest);
};

TEST_F(NetworkStateHandlerTest, NetworkStateHandlerStub) {
  // Ensure that the device and network list are the expected size.
  const size_t kNumShillManagerClientStubImplDevices = 2;
  EXPECT_EQ(kNumShillManagerClientStubImplDevices,
            test_observer_->device_count());
  const size_t kNumShillManagerClientStubImplServices = 4;
  EXPECT_EQ(kNumShillManagerClientStubImplServices,
            test_observer_->network_count());
  // Ensure that the first stub network is the default network.
  EXPECT_EQ(kShillManagerClientStubDefaultService,
            test_observer_->default_network());
  ASSERT_TRUE(network_state_handler_->DefaultNetwork());
  EXPECT_EQ(kShillManagerClientStubDefaultService,
            network_state_handler_->DefaultNetwork()->path());
  EXPECT_EQ(kShillManagerClientStubDefaultService,
            network_state_handler_->ConnectedNetworkByType(
                NetworkTypePattern::Ethernet())->path());
  EXPECT_EQ(kShillManagerClientStubDefaultWifi,
            network_state_handler_->ConnectedNetworkByType(
                NetworkTypePattern::WiFi())->path());
  EXPECT_EQ(kShillManagerClientStubCellular,
            network_state_handler_->FirstNetworkByType(
                NetworkTypePattern::Mobile())->path());
  EXPECT_EQ(
      kShillManagerClientStubCellular,
      network_state_handler_->FirstNetworkByType(NetworkTypePattern::Cellular())
          ->path());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
}

TEST_F(NetworkStateHandlerTest, GetNetworkList) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // Ensure that the network list is the expected size.
  const size_t kNumShillManagerClientStubImplServices = 4;
  EXPECT_EQ(kNumShillManagerClientStubImplServices,
            test_observer_->network_count());
  // Add a non-visible network to the profile.
  const std::string profile = "/profile/profile1";
  const std::string wifi_favorite_path = "/service/wifi_faviorite";
  service_test_->AddService(wifi_favorite_path,
                            "wifi_faviorite_guid",
                            "wifi_faviorite",
                            shill::kTypeWifi,
                            shill::kStateIdle,
                            false /* add_to_visible */);
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_favorite_path));
  UpdateManagerProperties();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
            test_observer_->network_count());

  // Add two Tether networks.
  const size_t kNumTetherNetworks = 2;
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
      kTetherSignalStrength2, kTetherHasConnectedToHost2);
  EXPECT_EQ(kNumShillManagerClientStubImplServices + 3,
            test_observer_->network_count());

  // Get all networks.
  NetworkStateHandler::NetworkStateList networks;
  network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
                                               false /* configured_only */,
                                               false /* visible_only */,
                                               0 /* no limit */,
                                               &networks);
  EXPECT_EQ(kNumShillManagerClientStubImplServices + kNumTetherNetworks + 1,
            networks.size());
  // Limit number of results, including only Tether networks.
  network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
                                               false /* configured_only */,
                                               false /* visible_only */,
                                               2 /* limit */,
                                               &networks);
  EXPECT_EQ(2u, networks.size());
  // Limit number of results, including more than only Tether networks.
  network_state_handler_->GetNetworkListByType(
      NetworkTypePattern::Default(), false /* configured_only */,
      false /* visible_only */, 4 /* limit */, &networks);
  EXPECT_EQ(4u, networks.size());
  // Get all Tether networks.
  network_state_handler_->GetNetworkListByType(
      NetworkTypePattern::Tether(), false /* configured_only */,
      false /* visible_only */, 0 /* no limit */, &networks);
  EXPECT_EQ(2u, networks.size());
  // Get all wifi networks.
  network_state_handler_->GetNetworkListByType(NetworkTypePattern::WiFi(),
                                               false /* configured_only */,
                                               false /* visible_only */,
                                               0 /* no limit */,
                                               &networks);
  EXPECT_EQ(3u, networks.size());
  // Get visible networks.
  network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
                                               false /* configured_only */,
                                               true /* visible_only */,
                                               0 /* no limit */,
                                               &networks);
  EXPECT_EQ(kNumShillManagerClientStubImplServices + kNumTetherNetworks,
            networks.size());
  network_state_handler_->GetVisibleNetworkList(&networks);
  EXPECT_EQ(kNumShillManagerClientStubImplServices + kNumTetherNetworks,
            networks.size());
  // Get configured (profile) networks.
  network_state_handler_->GetNetworkListByType(NetworkTypePattern::Default(),
                                               true /* configured_only */,
                                               false /* visible_only */,
                                               0 /* no limit */,
                                               &networks);
  EXPECT_EQ(kNumTetherNetworks + 1u, networks.size());
}

TEST_F(NetworkStateHandlerTest, GetTetherNetworkList) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  NetworkStateHandler::NetworkStateList tether_networks;

  GetTetherNetworkList(0 /* no limit */, &tether_networks);
  EXPECT_EQ(0u, tether_networks.size());

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);

  GetTetherNetworkList(0 /* no limit */, &tether_networks);
  EXPECT_EQ(1u, tether_networks.size());

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
      kTetherSignalStrength2, kTetherHasConnectedToHost2);

  GetTetherNetworkList(0 /* no limit */, &tether_networks);
  EXPECT_EQ(2u, tether_networks.size());

  GetTetherNetworkList(1 /* no limit */, &tether_networks);
  EXPECT_EQ(1u, tether_networks.size());
}

TEST_F(NetworkStateHandlerTest, SortTetherNetworkList) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  TestTetherSortDelegate sort_delegate;
  network_state_handler_->set_tether_sort_delegate(&sort_delegate);

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
      kTetherSignalStrength2, kTetherHasConnectedToHost2);

  // Note: GetVisibleNetworkListByType() sorts before outputting networks.
  NetworkStateHandler::NetworkStateList tether_networks;
  network_state_handler_->GetVisibleNetworkListByType(
      NetworkTypePattern::Tether(), &tether_networks);

  // The list should have been reversed due to reverse-alphabetical sorting.
  EXPECT_EQ(2u, tether_networks.size());
  EXPECT_EQ(kTetherGuid2, tether_networks[0]->guid());
  EXPECT_EQ(kTetherGuid1, tether_networks[1]->guid());
}

TEST_F(NetworkStateHandlerTest, SortTetherNetworkList_NoSortingDelegate) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // Do not set a TetherSortDelegate.

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
      kTetherSignalStrength2, kTetherHasConnectedToHost2);

  // Note: GetVisibleNetworkListByType() sorts before outputting networks.
  NetworkStateHandler::NetworkStateList tether_networks;
  network_state_handler_->GetVisibleNetworkListByType(
      NetworkTypePattern::Tether(), &tether_networks);

  // The list should be in the original order.
  EXPECT_EQ(2u, tether_networks.size());
  EXPECT_EQ(kTetherGuid1, tether_networks[0]->guid());
  EXPECT_EQ(kTetherGuid2, tether_networks[1]->guid());
}

TEST_F(NetworkStateHandlerTest,
       GetNetworks_TetherIncluded_ActiveBeforeInactive) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  TestTetherSortDelegate sort_delegate;
  network_state_handler_->set_tether_sort_delegate(&sort_delegate);

  // To start the test, |eth1| and |wifi1| are connected, while |wifi2| and
  // |cellular| are not.
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  const std::string wifi2 = kShillManagerClientStubWifi2;
  const std::string cellular = kShillManagerClientStubCellular;

  // Disconnect |wifi1|, which will serve as the underlying connection
  // for the Tether network under test.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));

  // Connect |cellular| for this test.
  service_test_->SetServiceProperty(cellular, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();

  // Add two Tether networks. Neither is connected yet.
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid2, kTetherName2, kTetherCarrier2, kTetherBatteryPercentage2,
      kTetherSignalStrength2, kTetherHasConnectedToHost2);

  // Connect to the first Tether network (and the underlying Wi-Fi hotspot
  // network, |wifi1|).
  network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
  network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
      kTetherGuid1, "wifi1_guid");
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();
  network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);

  // At this point, |eth1|, |cellular|, and |kTetherGuid1| are connected.
  // |wifi1| is also connected, but it is not considered visible since it is the
  // underlying network for the Tether connection.
  NetworkStateHandler::NetworkStateList list;

  // Get Tether networks. Even though the networks should be sorted according to
  // reverse-alphabetical order, |kTetherGuid1| should be listed first since it
  // is active.
  network_state_handler_->GetVisibleNetworkListByType(
      NetworkTypePattern::Tether(), &list);
  ASSERT_EQ(2u, list.size());
  EXPECT_EQ(kTetherGuid1, list[0]->guid());
  EXPECT_EQ(kTetherGuid2, list[1]->guid());

  // Get Mobile networks. The connected Tether network should be first, followed
  // by the connected Cellular network, followed by the non-connected Tether
  // network.
  network_state_handler_->GetVisibleNetworkListByType(
      NetworkTypePattern::Mobile(), &list);
  ASSERT_EQ(3u, list.size());
  EXPECT_EQ(kTetherGuid1, list[0]->guid());
  EXPECT_EQ(cellular, list[1]->path());
  EXPECT_EQ(kTetherGuid2, list[2]->guid());

  // Get all networks. The connected Ethernet network should be first, followed
  // by the connected Tether network, followed by the connected Cellular
  // network, followed by the non-connected Tether network, followed by the
  // non-connected Wi-Fi network.
  network_state_handler_->GetVisibleNetworkListByType(
      NetworkTypePattern::Default(), &list);
  EXPECT_EQ(5u, list.size());
  EXPECT_EQ(eth1, list[0]->path());
  EXPECT_EQ(kTetherGuid1, list[1]->guid());
  EXPECT_EQ(cellular, list[2]->path());
  EXPECT_EQ(kTetherGuid2, list[3]->guid());
  EXPECT_EQ(wifi2, list[4]->path());
}

TEST_F(NetworkStateHandlerTest, NetworkListChanged) {
  size_t stub_network_count = test_observer_->network_count();
  // Set up two additional visible networks.
  const std::string wifi3 = "/service/wifi3";
  const std::string wifi4 = "/service/wifi4";
  service_test_->SetServiceProperties(
      wifi3, "wifi3_guid", "wifi3",
      shill::kTypeWifi, shill::kStateIdle, true /* visible */);
  service_test_->SetServiceProperties(
      wifi4, "wifi4_guid", "wifi4",
      shill::kTypeWifi, shill::kStateIdle, true /* visible */);
  // Add the services to the Manager. Only notify when the second service is
  // added.
  manager_test_->AddManagerService(wifi3, false);
  manager_test_->AddManagerService(wifi4, true);
  UpdateManagerProperties();
  // Expect two service updates and one list update.
  EXPECT_EQ(stub_network_count + 2, test_observer_->network_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi3));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi4));
  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
}

TEST_F(NetworkStateHandlerTest, GetVisibleNetworks) {
  // Ensure that the network list is the expected size.
  const size_t kNumShillManagerClientStubImplServices = 4;
  EXPECT_EQ(kNumShillManagerClientStubImplServices,
            test_observer_->network_count());
  // Add a non-visible network to the profile.
  const std::string profile = "/profile/profile1";
  const std::string wifi_favorite_path = "/service/wifi_faviorite";
  service_test_->AddService(wifi_favorite_path,
                            "wifi_faviorite_guid",
                            "wifi_faviorite",
                            shill::kTypeWifi,
                            shill::kStateIdle,
                            false /* add_to_visible */);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(kNumShillManagerClientStubImplServices + 1,
            test_observer_->network_count());

  // Get visible networks.
  NetworkStateHandler::NetworkStateList networks;
  network_state_handler_->GetVisibleNetworkList(&networks);
  EXPECT_EQ(kNumShillManagerClientStubImplServices, networks.size());

  // Change the visible state of a network.
  SetServiceProperty(kShillManagerClientStubWifi2, shill::kVisibleProperty,
                     base::Value(false));
  base::RunLoop().RunUntilIdle();
  network_state_handler_->GetVisibleNetworkList(&networks);
  EXPECT_EQ(kNumShillManagerClientStubImplServices - 1, networks.size());
}

TEST_F(NetworkStateHandlerTest, TechnologyChanged) {
  // Disable a technology. Will immediately set the state to AVAILABLE and
  // notify observers.
  network_state_handler_->SetTechnologyEnabled(
      NetworkTypePattern::WiFi(), false, network_handler::ErrorCallback());
  EXPECT_EQ(1u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_AVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi()));

  // Run the message loop. An additional notification will be received when
  // Shill updates the enabled technologies. The state should remain AVAILABLE.
  test_observer_->reset_change_counts();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_AVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi()));

  // Enable a technology. Will immediately set the state to ENABLING and
  // notify observers.
  test_observer_->reset_change_counts();
  network_state_handler_->SetTechnologyEnabled(
      NetworkTypePattern::WiFi(), true, network_handler::ErrorCallback());
  EXPECT_EQ(1u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_ENABLING,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi()));

  // Run the message loop. State should change to ENABLED.
  test_observer_->reset_change_counts();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_ENABLED,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::WiFi()));
}

TEST_F(NetworkStateHandlerTest, TechnologyState) {
  manager_test_->RemoveTechnology(shill::kTypeWimax);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_UNAVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));

  manager_test_->AddTechnology(shill::kTypeWimax, false);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_AVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));

  manager_test_->SetTechnologyInitializing(shill::kTypeWimax, true);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_UNINITIALIZED,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));

  manager_test_->SetTechnologyInitializing(shill::kTypeWimax, false);
  network_state_handler_->SetTechnologyEnabled(
      NetworkTypePattern::Wimax(), true, network_handler::ErrorCallback());
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_ENABLED,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));

  manager_test_->RemoveTechnology(shill::kTypeWimax);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_UNAVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Wimax()));
}

TEST_F(NetworkStateHandlerTest, TetherTechnologyState) {
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_UNAVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether()));
  EXPECT_FALSE(network_state_handler_->GetDeviceState(kTetherDevicePath));
  EXPECT_FALSE(network_state_handler_->GetDeviceStateByType(
      NetworkTypePattern::Tether()));

  // Test SetTetherTechnologyState():
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_AVAILABLE);
  EXPECT_EQ(1u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_AVAILABLE,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether()));
  const DeviceState* tether_device_state =
      network_state_handler_->GetDeviceState(kTetherDevicePath);
  EXPECT_TRUE(tether_device_state);
  EXPECT_EQ(tether_device_state, network_state_handler_->GetDeviceStateByType(
                                     NetworkTypePattern::Tether()));

  // Test SetTechnologyEnabled() with a Tether network:
  network_state_handler_->SetTechnologyEnabled(
      NetworkTypePattern::Tether(), true, network_handler::ErrorCallback());
  EXPECT_EQ(2u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_ENABLED,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether()));
  EXPECT_EQ(tether_device_state,
            network_state_handler_->GetDeviceState(kTetherDevicePath));
  EXPECT_EQ(tether_device_state, network_state_handler_->GetDeviceStateByType(
                                     NetworkTypePattern::Tether()));

  // Test SetProhibitedTechnologies() with a Tether network:
  network_state_handler_->SetProhibitedTechnologies(
      std::vector<std::string>{kTypeTether}, network_handler::ErrorCallback());
  EXPECT_EQ(3u, test_observer_->device_list_changed_count());
  EXPECT_EQ(
      NetworkStateHandler::TECHNOLOGY_PROHIBITED,
      network_state_handler_->GetTechnologyState(NetworkTypePattern::Tether()));
  EXPECT_EQ(tether_device_state,
            network_state_handler_->GetDeviceState(kTetherDevicePath));
  EXPECT_EQ(tether_device_state, network_state_handler_->GetDeviceStateByType(
                                     NetworkTypePattern::Tether()));

  // Set back to TECHNOLOGY_UNAVAILABLE; this should result in nullptr being
  // returned by getters.
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_UNAVAILABLE);
  EXPECT_FALSE(network_state_handler_->GetDeviceState(kTetherDevicePath));
  EXPECT_FALSE(network_state_handler_->GetDeviceStateByType(
      NetworkTypePattern::Tether()));
}

TEST_F(NetworkStateHandlerTest, TetherScanningState) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  const DeviceState* tether_device_state =
      network_state_handler_->GetDeviceStateByType(
          NetworkTypePattern::Tether());
  EXPECT_TRUE(tether_device_state);
  EXPECT_FALSE(tether_device_state->scanning());
  EXPECT_EQ(0u, test_observer_->scan_completed_count());

  network_state_handler_->SetTetherScanState(true /* is_scanning */);
  tether_device_state = network_state_handler_->GetDeviceStateByType(
      NetworkTypePattern::Tether());
  EXPECT_TRUE(tether_device_state);
  EXPECT_TRUE(tether_device_state->scanning());
  EXPECT_EQ(0u, test_observer_->scan_completed_count());

  network_state_handler_->SetTetherScanState(false /* is_scanning */);
  tether_device_state = network_state_handler_->GetDeviceStateByType(
      NetworkTypePattern::Tether());
  EXPECT_TRUE(tether_device_state);
  EXPECT_FALSE(tether_device_state->scanning());
  EXPECT_EQ(1u, test_observer_->scan_completed_count());
}

TEST_F(NetworkStateHandlerTest, ServicePropertyChangedDefaultNetwork) {
  // Set a service property on the default network.
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const NetworkState* ethernet = network_state_handler_->GetNetworkState(eth1);
  ASSERT_TRUE(ethernet);
  EXPECT_EQ("", ethernet->security_class());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(eth1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  base::Value security_class_value("TestSecurityClass");
  SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value);
  base::RunLoop().RunUntilIdle();
  ethernet = network_state_handler_->GetNetworkState(eth1);
  EXPECT_EQ("TestSecurityClass", ethernet->security_class());
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1));
  EXPECT_EQ(1u, test_observer_->default_network_change_count());

  // Changing a service to the existing value should not trigger an update.
  SetServiceProperty(eth1, shill::kSecurityClassProperty, security_class_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(eth1));
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
}

TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingActive) {
  // Set an uninteresting service property on an active network.
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  const NetworkState* wifi = network_state_handler_->GetNetworkState(wifi1);
  ASSERT_TRUE(wifi);
  EXPECT_EQ(1, wifi->signal_strength());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  base::Value signal_strength_value(11);
  SetServiceProperty(wifi1, shill::kSignalStrengthProperty,
                     signal_strength_value);
  base::RunLoop().RunUntilIdle();
  wifi = network_state_handler_->GetNetworkState(wifi1);
  EXPECT_EQ(11, wifi->signal_strength());
  // The change should trigger an additional properties updated event.
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(wifi1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
}

TEST_F(NetworkStateHandlerTest, ServicePropertyChangedNotIneterstingInactive) {
  // Set an uninteresting service property on an inactive network.
  const std::string wifi2 = kShillManagerClientStubWifi2;
  const NetworkState* wifi = network_state_handler_->GetNetworkState(wifi2);
  ASSERT_TRUE(wifi);
  EXPECT_EQ(1, wifi->signal_strength());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi2));
  base::Value signal_strength_value(11);
  SetServiceProperty(wifi2, shill::kSignalStrengthProperty,
                     signal_strength_value);
  base::RunLoop().RunUntilIdle();
  wifi = network_state_handler_->GetNetworkState(wifi2);
  EXPECT_EQ(11, wifi->signal_strength());
  // The change should *not* trigger an additional properties updated event.
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi2));
}

TEST_F(NetworkStateHandlerTest, GetState) {
  const std::string profile = "/profile/profile1";
  const std::string wifi_path = kShillManagerClientStubDefaultWifi;

  // Add a wifi service to a Profile.
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();

  // Ensure that a NetworkState exists.
  const NetworkState* wifi_network =
      network_state_handler_->GetNetworkStateFromServicePath(
          wifi_path, true /* configured_only */);
  ASSERT_TRUE(wifi_network);

  // Test looking up by GUID.
  ASSERT_FALSE(wifi_network->guid().empty());
  const NetworkState* wifi_network_guid =
      network_state_handler_->GetNetworkStateFromGuid(wifi_network->guid());
  EXPECT_EQ(wifi_network, wifi_network_guid);

  // Remove the service, verify that there is no longer a NetworkState for it.
  service_test_->RemoveService(wifi_path);
  UpdateManagerProperties();
  EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path));
}

TEST_F(NetworkStateHandlerTest, TetherNetworkState) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  EXPECT_EQ(0u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, false /* has_connected_to_network */);

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  ASSERT_TRUE(tether_network);
  EXPECT_EQ(kTetherName1, tether_network->name());
  EXPECT_EQ(kTetherGuid1, tether_network->path());
  EXPECT_EQ(kTetherCarrier1, tether_network->carrier());
  EXPECT_EQ(kTetherBatteryPercentage1, tether_network->battery_percentage());
  EXPECT_EQ(kTetherSignalStrength1, tether_network->signal_strength());
  EXPECT_FALSE(tether_network->tether_has_connected_to_host());

  // Update the Tether properties and verify the changes.
  EXPECT_TRUE(network_state_handler_->UpdateTetherNetworkProperties(
      kTetherGuid1, "NewCarrier", 5 /* battery_percentage */,
      10 /* signal_strength */));

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  ASSERT_TRUE(tether_network);
  EXPECT_EQ(kTetherName1, tether_network->name());
  EXPECT_EQ(kTetherGuid1, tether_network->path());
  EXPECT_EQ("NewCarrier", tether_network->carrier());
  EXPECT_EQ(5, tether_network->battery_percentage());
  EXPECT_EQ(10, tether_network->signal_strength());
  EXPECT_FALSE(tether_network->tether_has_connected_to_host());

  // Now, set the HasConnectedToHost property to true.
  EXPECT_TRUE(
      network_state_handler_->SetTetherNetworkHasConnectedToHost(kTetherGuid1));

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Try calling that function again. It should return false and should not
  // trigger a NetworkListChanged() callback for observers.
  EXPECT_FALSE(
      network_state_handler_->SetTetherNetworkHasConnectedToHost(kTetherGuid1));

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  network_state_handler_->RemoveTetherNetworkState(kTetherGuid1);

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  ASSERT_FALSE(network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1));

  // Updating Tether properties should fail since the network was removed.
  EXPECT_FALSE(network_state_handler_->UpdateTetherNetworkProperties(
      kTetherGuid1, "NewNewCarrier", 15 /* battery_percentage */,
      20 /* signal_strength */));
}

TEST_F(NetworkStateHandlerTest, TetherNetworkStateAssociation) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  const std::string profile = "/profile/profile1";
  const std::string wifi_path = "/service/wifi_with_guid";
  AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();
  test_observer_->reset_updates();

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));

  EXPECT_TRUE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));

  const NetworkState* wifi_network =
      network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
  EXPECT_EQ(kTetherGuid1, wifi_network->tether_guid());

  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());

  // Try associating again. The function call should return true since the
  // association was successful, but no new observer updates should occur since
  // no changes happened.
  EXPECT_TRUE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));

  EXPECT_EQ(kTetherGuid1, wifi_network->tether_guid());
  EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));

  network_state_handler_->RemoveTetherNetworkState(kTetherGuid1);

  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));

  wifi_network = network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
  EXPECT_TRUE(wifi_network->tether_guid().empty());
}

TEST_F(NetworkStateHandlerTest, TetherNetworkStateDisassociation) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  const std::string profile = "/profile/profile1";
  const std::string wifi_path = "/service/wifi_with_guid";
  AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();
  test_observer_->reset_updates();

  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));

  EXPECT_TRUE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));

  const NetworkState* wifi_network =
      network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
  EXPECT_EQ(kTetherGuid1, wifi_network->tether_guid());

  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());

  EXPECT_TRUE(
      network_state_handler_->DisassociateTetherNetworkStateFromWifiNetwork(
          kTetherGuid1));

  EXPECT_TRUE(wifi_network->tether_guid().empty());
  EXPECT_TRUE(tether_network->tether_guid().empty());

  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(wifi_path));
}

TEST_F(NetworkStateHandlerTest, TetherNetworkStateAssociationWifiRemoved) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  const std::string profile = "/profile/profile1";
  const std::string wifi_path = "/service/wifi_with_guid";
  AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  EXPECT_TRUE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));

  const NetworkState* wifi_network =
      network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
  EXPECT_EQ(kTetherGuid1, wifi_network->tether_guid());

  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());

  service_test_->RemoveService(wifi_path);
  UpdateManagerProperties();

  tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  ASSERT_TRUE(tether_network->tether_guid().empty());
}

TEST_F(NetworkStateHandlerTest, TetherNetworkStateAssociation_NoWifiNetwork) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);

  EXPECT_FALSE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));
}

TEST_F(NetworkStateHandlerTest, TetherNetworkStateAssociation_NoTetherNetwork) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  const std::string profile = "/profile/profile1";
  const std::string wifi_path = "/service/wifi_with_guid";
  AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  profile_test_->AddProfile(profile, "" /* userhash */);
  EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();

  ASSERT_FALSE(
      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
          kTetherGuid1, kWifiGuid1));
}

TEST_F(NetworkStateHandlerTest,
       SetTetherNetworkStateConnectionState_NoDefaultNetworkToStart) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // Disconnect Ethernet and Wi-Fi so that there is no default network. For the
  // purpose of this test, the default Wi-Fi network will serve as the Tether
  // network's underlying Wi-Fi hotspot.
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(std::string(), test_observer_->default_network());

  // Simulate a host scan, and reset the change counts for the connection flow.
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  test_observer_->reset_change_counts();
  test_observer_->reset_updates();

  // Preconditions.
  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ("", test_observer_->default_network());
  EXPECT_EQ("", test_observer_->default_network_connection_state());
  EXPECT_EQ(nullptr, network_state_handler_->DefaultNetwork());

  // Set the Tether network state to "connecting." This is expected to be called
  // before the connection to the underlying hotspot Wi-Fi network begins.
  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectingState());
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ(tether_network, network_state_handler_->DefaultNetwork());

  // Associate Tether and Wi-Fi networks.
  network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
      kTetherGuid1, "wifi1_guid");
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Connect to the underlying Wi-Fi network. The default network should not
  // change yet.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, test_observer_->default_network_change_count());

  // Now, set the Tether network state to "connected." This should result in a
  // default network change event.
  network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectedState());
  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
  EXPECT_EQ(kTetherGuid1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
  EXPECT_EQ(tether_network, network_state_handler_->DefaultNetwork());

  // Disconnect from the underlying Wi-Fi network. The default network should
  // not change yet.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->default_network_change_count());

  // Now, set the Tether network state to "disconnected." This should result in
  // a default network change event.
  network_state_handler_->SetTetherNetworkStateDisconnected(kTetherGuid1);
  EXPECT_FALSE(tether_network->IsConnectingState());
  EXPECT_FALSE(tether_network->IsConnectedState());
  EXPECT_EQ(3, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(4, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
  EXPECT_EQ("", test_observer_->default_network());
  EXPECT_EQ("", test_observer_->default_network_connection_state());
  EXPECT_EQ(nullptr, network_state_handler_->DefaultNetwork());
}

TEST_F(NetworkStateHandlerTest,
       SetTetherNetworkStateConnectionState_EthernetIsDefaultNetwork) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // The ethernet corresponding to |eth1| will be left connected this entire
  // test. It should be expected to remain the default network during the Tether
  // connection.
  const std::string eth1 = kShillManagerClientStubDefaultService;

  // Disconnect the Wi-Fi network, which will serve as the underlying connection
  // for the Tether network under test.
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(eth1, test_observer_->default_network());

  // Simulate a host scan, and reset the change counts for the connection flow.
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  test_observer_->reset_change_counts();
  test_observer_->reset_updates();

  // Preconditions.
  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());

  // Set the Tether network state to "connecting." This is expected to be called
  // before the connection to the underlying hotspot Wi-Fi network begins.
  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectingState());
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Associate Tether and Wi-Fi networks.
  network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
      kTetherGuid1, "wifi1_guid");
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Connect to the underlying Wi-Fi network.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();

  // Now, set the Tether network state to "connected."
  network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectedState());
  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Disconnect from the underlying Wi-Fi network.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();

  // Now, set the Tether network state to "disconnected."
  network_state_handler_->SetTetherNetworkStateDisconnected(kTetherGuid1);
  EXPECT_FALSE(tether_network->IsConnectingState());
  EXPECT_FALSE(tether_network->IsConnectedState());
  EXPECT_EQ(3, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(4, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // The Ethernet network should still be the default network, and no changes
  // should have occurred during this test.
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
}

TEST_F(NetworkStateHandlerTest,
       EthernetIsDefaultNetwork_ThenTetherConnects_ThenEthernetDisconnects) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // The ethernet corresponding to |eth1| starts out connected, then ends up
  // becoming disconnected.
  const std::string eth1 = kShillManagerClientStubDefaultService;

  // Disconnect the Wi-Fi network, which will serve as the underlying connection
  // for the Tether network under test.
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(eth1, test_observer_->default_network());

  // Simulate a host scan, and reset the change counts for the connection flow.
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  test_observer_->reset_change_counts();
  test_observer_->reset_updates();

  // Preconditions.
  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());

  // Set the Tether network state to "connecting." This is expected to be called
  // before the connection to the underlying hotspot Wi-Fi network begins.
  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectingState());
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Associate Tether and Wi-Fi networks.
  network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
      kTetherGuid1, "wifi1_guid");
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Connect to the underlying Wi-Fi network.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();

  // Now, set the Tether network state to "connected."
  network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectedState());
  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // No default network changes should have occurred, since the Ethernet
  // network should still be considered the default network.
  EXPECT_EQ(0u, test_observer_->default_network_change_count());

  // Disconnect from the Ethernet network.
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();

  // The Tether network should now be the default network. However, there should
  // have been two updates to the default network: one which changed it from
  // |eth1| to null, then one from null to |kTetherGuid1"|.
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
  EXPECT_EQ(kTetherGuid1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
}

TEST_F(NetworkStateHandlerTest,
       SetTetherNetworkStateConnectionState_NoDefaultThenTetherThenEthernet) {
  network_state_handler_->SetTetherTechnologyState(
      NetworkStateHandler::TECHNOLOGY_ENABLED);

  // Disconnect Ethernet and Wi-Fi so that there is no default network. For the
  // purpose of this test, the default Wi-Fi network will serve as the Tether
  // network's underlying Wi-Fi hotspot.
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(std::string(), test_observer_->default_network());

  // Simulate a host scan, and reset the change counts for the connection flow.
  network_state_handler_->AddTetherNetworkState(
      kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
      kTetherSignalStrength1, kTetherHasConnectedToHost1);
  test_observer_->reset_change_counts();
  test_observer_->reset_updates();

  // Preconditions.
  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ("", test_observer_->default_network());
  EXPECT_EQ("", test_observer_->default_network_connection_state());
  EXPECT_EQ(nullptr, network_state_handler_->DefaultNetwork());

  // Set the Tether network state to "connecting." This is expected to be called
  // before the connection to the underlying hotspot Wi-Fi network begins.
  const NetworkState* tether_network =
      network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
  network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectingState());
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  EXPECT_EQ(tether_network, network_state_handler_->DefaultNetwork());

  // Associate Tether and Wi-Fi networks.
  network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
      kTetherGuid1, "wifi1_guid");
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));

  // Connect to the underlying Wi-Fi network. The default network should not
  // change yet.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, test_observer_->default_network_change_count());

  // Now, set the Tether network state to "connected." This should result in a
  // default network change event.
  network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
  EXPECT_TRUE(tether_network->IsConnectedState());
  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
  EXPECT_EQ(kTetherGuid1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
  EXPECT_EQ(tether_network, network_state_handler_->DefaultNetwork());

  // Now, connect the Ethernet network. This should be the new default network.
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    base::Value(shill::kStateOnline));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());

  // Disconnect from the underlying Wi-Fi network. The default network should
  // still be the Ethernet network.
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2u, test_observer_->default_network_change_count());

  // Now, set the Tether network state to "disconnected." The default network
  // should still be the Ethernet network.
  network_state_handler_->SetTetherNetworkStateDisconnected(kTetherGuid1);
  EXPECT_FALSE(tether_network->IsConnectingState());
  EXPECT_FALSE(tether_network->IsConnectedState());
  EXPECT_EQ(3, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
  EXPECT_EQ(4, test_observer_->PropertyUpdatesForService(kTetherGuid1));
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateOnline,
            test_observer_->default_network_connection_state());
}

TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
  const std::string eth1 = kShillManagerClientStubDefaultService;
  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(eth1));

  // Change a network state.
  base::Value connection_state_idle_value(shill::kStateIdle);
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                   connection_state_idle_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kStateIdle,
            test_observer_->NetworkConnectionStateForService(eth1));
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1));
  // Confirm that changing the connection state to the same value does *not*
  // signal the observer.
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                   connection_state_idle_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(eth1));
}

TEST_F(NetworkStateHandlerTest, DefaultServiceDisconnected) {
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;

  EXPECT_EQ(0u, test_observer_->default_network_change_count());
  // Disconnect ethernet.
  base::Value connection_state_idle_value(shill::kStateIdle);
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    connection_state_idle_value);
  base::RunLoop().RunUntilIdle();
  // Expect two changes: first when eth1 becomes disconnected, second when
  // wifi1 becomes the default.
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
  EXPECT_EQ(wifi1, test_observer_->default_network());

  // Disconnect wifi.
  test_observer_->reset_change_counts();
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    connection_state_idle_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
  EXPECT_EQ("", test_observer_->default_network());
}

TEST_F(NetworkStateHandlerTest, DefaultServiceConnected) {
  const std::string eth1 = kShillManagerClientStubDefaultService;
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;

  // Disconnect ethernet and wifi.
  base::Value connection_state_idle_value(shill::kStateIdle);
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    connection_state_idle_value);
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    connection_state_idle_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(std::string(), test_observer_->default_network());

  // Connect ethernet, should become the default network.
  test_observer_->reset_change_counts();
  base::Value connection_state_ready_value(shill::kStateReady);
  service_test_->SetServiceProperty(eth1, shill::kStateProperty,
                                    connection_state_ready_value);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(eth1, test_observer_->default_network());
  EXPECT_EQ(shill::kStateReady,
            test_observer_->default_network_connection_state());
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
}

TEST_F(NetworkStateHandlerTest, DefaultServiceChanged) {
  const std::string eth1 = kShillManagerClientStubDefaultService;
  // The default service should be eth1.
  EXPECT_EQ(eth1, test_observer_->default_network());

  // Change the default network by changing Manager.DefaultService.
  // This should only generate one default network notification when the
  // DefaultService property changes.
  const std::string wifi1 = kShillManagerClientStubDefaultWifi;
  SetServiceProperty(eth1, shill::kStateProperty,
                     base::Value(shill::kStateIdle));
  manager_test_->SetManagerProperty(shill::kDefaultServiceProperty,
                                    base::Value(wifi1));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(wifi1, test_observer_->default_network());
  EXPECT_EQ(1u, test_observer_->default_network_change_count());

  // Change the state of the default network. This should generate a
  // default network notification.
  test_observer_->reset_change_counts();
  service_test_->SetServiceProperty(wifi1, shill::kStateProperty,
                                    base::Value(shill::kStateReady));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(shill::kStateReady,
            test_observer_->default_network_connection_state());
  EXPECT_EQ(1u, test_observer_->default_network_change_count());

  // Updating a property on the default network should also trigger
  // a default network change.
  test_observer_->reset_change_counts();
  SetServiceProperty(wifi1, shill::kSecurityClassProperty,
                     base::Value("TestSecurityClass"));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->default_network_change_count());

  // No default network updates for signal strength changes.
  test_observer_->reset_change_counts();
  SetServiceProperty(wifi1, shill::kSignalStrengthProperty, base::Value(32));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0u, test_observer_->default_network_change_count());

  // Change the default network to a Connecting network, then set the
  // state to Connected. The DefaultNetworkChange notification should only
  // fire once when the network is connected.
  test_observer_->reset_change_counts();
  SetServiceProperty(wifi1, shill::kStateProperty,
                     base::Value(shill::kStateIdle));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
  EXPECT_EQ(std::string(), test_observer_->default_network());

  const std::string wifi2 = kShillManagerClientStubWifi2;
  manager_test_->SetManagerProperty(shill::kDefaultServiceProperty,
                                    base::Value(wifi2));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1u, test_observer_->default_network_change_count());
  // Change the connection state of the default network, observer should fire.
  SetServiceProperty(wifi2, shill::kStateProperty,
                     base::Value(shill::kStateReady));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(wifi2, test_observer_->default_network());
  EXPECT_EQ(2u, test_observer_->default_network_change_count());
}

TEST_F(NetworkStateHandlerTest, RequestUpdate) {
  // Request an update for kShillManagerClientStubDefaultWifi.
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(
      kShillManagerClientStubDefaultWifi));
  network_state_handler_->RequestUpdateForNetwork(
      kShillManagerClientStubDefaultWifi);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(
      kShillManagerClientStubDefaultWifi));
}

TEST_F(NetworkStateHandlerTest, RequestScan) {
  EXPECT_EQ(0u, test_observer_->scan_requested_count());
  network_state_handler_->RequestScan(NetworkTypePattern::WiFi());
  EXPECT_EQ(1u, test_observer_->scan_requested_count());
}

TEST_F(NetworkStateHandlerTest, NetworkGuidInProfile) {
  const std::string profile = "/profile/profile1";
  const std::string wifi_path = "/service/wifi_with_guid";
  const bool is_service_configured = true;

  profile_test_->AddProfile(profile, std::string() /* userhash */);

  // Add a network to the default Profile with a specified GUID.
  AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  ASSERT_TRUE(profile_test_->AddService(profile, wifi_path));
  UpdateManagerProperties();

  // Verify that a NetworkState exists with a matching GUID.
  const NetworkState* network =
      network_state_handler_->GetNetworkStateFromServicePath(
          wifi_path, is_service_configured);
  ASSERT_TRUE(network);
  EXPECT_EQ(kWifiGuid1, network->guid());

  // Remove the service (simulating a network going out of range).
  service_test_->RemoveService(wifi_path);
  UpdateManagerProperties();
  EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path));

  // Add the service (simulating a network coming back in range) and verify that
  // the NetworkState was created with the same GUID.
  AddService(wifi_path, std::string() /* guid */, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  profile_test_->UpdateService(profile, wifi_path);
  UpdateManagerProperties();
  network = network_state_handler_->GetNetworkStateFromServicePath(
      wifi_path, is_service_configured);
  ASSERT_TRUE(network);
  EXPECT_EQ(kWifiGuid1, network->guid());
}

TEST_F(NetworkStateHandlerTest, NetworkGuidNotInProfile) {
  const std::string wifi_path = "/service/wifi_with_guid";
  const bool is_service_configured = false;

  // Add a network without specifying a GUID or adding it to a profile.
  AddService(wifi_path, "" /* guid */, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  UpdateManagerProperties();

  // Verify that a NetworkState exists with an assigned GUID.
  const NetworkState* network =
      network_state_handler_->GetNetworkStateFromServicePath(
          wifi_path, is_service_configured);
  ASSERT_TRUE(network);
  std::string wifi_guid = network->guid();
  EXPECT_FALSE(wifi_guid.empty());

  // Remove the service (simulating a network going out of range).
  service_test_->RemoveService(wifi_path);
  UpdateManagerProperties();
  EXPECT_FALSE(network_state_handler_->GetNetworkState(wifi_path));

  // Add the service (simulating a network coming back in range) and verify that
  // the NetworkState was created with the same GUID.
  AddService(wifi_path, "" /* guid */, kWifiName1, shill::kTypeWifi,
             shill::kStateOnline);
  UpdateManagerProperties();
  network = network_state_handler_->GetNetworkStateFromServicePath(
      wifi_path, is_service_configured);
  ASSERT_TRUE(network);
  EXPECT_EQ(wifi_guid, network->guid());
}

TEST_F(NetworkStateHandlerTest, DeviceListChanged) {
  size_t stub_device_count = test_observer_->device_count();
  // Add an additional device.
  const std::string wifi_device = "/service/stub_wifi_device2";
  device_test_->AddDevice(wifi_device, shill::kTypeWifi, "stub_wifi_device2");
  UpdateManagerProperties();
  // Expect a device list update.
  EXPECT_EQ(stub_device_count + 1, test_observer_->device_count());
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForDevice(wifi_device));
  // Change a device property.
  device_test_->SetDeviceProperty(wifi_device, shill::kScanningProperty,
                                  base::Value(true));
  UpdateManagerProperties();
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForDevice(wifi_device));
}

TEST_F(NetworkStateHandlerTest, IPConfigChanged) {
  test_observer_->reset_updates();
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForDevice(
      kShillManagerClientStubWifiDevice));
  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(
      kShillManagerClientStubDefaultWifi));

  // Change IPConfigs property.
  ShillIPConfigClient::TestInterface* ip_config_test =
      DBusThreadManager::Get()->GetShillIPConfigClient()->GetTestInterface();
  const std::string kIPConfigPath = "test_ip_config";
  base::DictionaryValue ip_config_properties;
  ip_config_test->AddIPConfig(kIPConfigPath, ip_config_properties);
  base::ListValue device_ip_configs;
  device_ip_configs.AppendString(kIPConfigPath);
  device_test_->SetDeviceProperty(
      kShillManagerClientStubWifiDevice, shill::kIPConfigsProperty,
      device_ip_configs);
  service_test_->SetServiceProperty(kShillManagerClientStubDefaultWifi,
                                    shill::kIPConfigProperty,
                                    base::Value(kIPConfigPath));
  UpdateManagerProperties();
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForDevice(
      kShillManagerClientStubWifiDevice));
  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(
      kShillManagerClientStubDefaultWifi));
}

TEST_F(NetworkStateHandlerTest, UpdateGuid) {
  const NetworkState* wifi1 = network_state_handler_->GetNetworkState(
      kShillManagerClientStubDefaultWifi);
  ASSERT_TRUE(wifi1);
  EXPECT_EQ("wifi1_guid", wifi1->guid());
  // Remove the wifi service.
  service_test_->RemoveService(kShillManagerClientStubDefaultWifi);
  base::RunLoop().RunUntilIdle();
  wifi1 = network_state_handler_->GetNetworkState(
      kShillManagerClientStubDefaultWifi);
  EXPECT_FALSE(wifi1);
  // Add the wifi service but do not specify a guid; the same guid should be
  // reused.
  AddService(kShillManagerClientStubDefaultWifi, "", "wifi1", shill::kTypeWifi,
             shill::kStateOnline);
  base::RunLoop().RunUntilIdle();
  wifi1 = network_state_handler_->GetNetworkState(
      kShillManagerClientStubDefaultWifi);
  ASSERT_TRUE(wifi1);
  EXPECT_EQ("wifi1_guid", wifi1->guid());

  const NetworkState* cellular =
      network_state_handler_->GetNetworkState(kShillManagerClientStubCellular);
  ASSERT_TRUE(cellular);
  EXPECT_EQ("cellular1_guid", cellular->guid());
  // Remove the cellular service. This should create a default network with the
  // same GUID.
  service_test_->RemoveService(kShillManagerClientStubCellular);
  base::RunLoop().RunUntilIdle();
  // No service matching kShillManagerClientStubCellular.
  EXPECT_FALSE(
      network_state_handler_->GetNetworkState(kShillManagerClientStubCellular));
  // The default cellular network should have the same guid as before.
  cellular = network_state_handler_->FirstNetworkByType(
      NetworkTypePattern::Cellular());
  ASSERT_TRUE(cellular);
  EXPECT_EQ("cellular1_guid", cellular->guid());
}

TEST_F(NetworkStateHandlerTest, EnsureCellularNetwork) {
  // ClearServices will trigger a kServiceCompleteListProperty property change
  // which will create a default Cellular network.
  service_test_->ClearServices();
  base::RunLoop().RunUntilIdle();
  NetworkStateHandler::NetworkStateList cellular_networks;
  network_state_handler_->GetNetworkListByType(
      NetworkTypePattern::Cellular(), false /* configured_only */,
      false /* visible_only */, 0, &cellular_networks);
  ASSERT_EQ(1u, cellular_networks.size());
  EXPECT_TRUE(cellular_networks[0]->IsDefaultCellular());

  // Add a Cellular service. This should replace the default cellular network.
  AddService(kShillManagerClientStubCellular, "cellular1_guid", "cellular1",
             shill::kTypeCellular, shill::kStateIdle);
  base::RunLoop().RunUntilIdle();
  network_state_handler_->GetNetworkListByType(
      NetworkTypePattern::Cellular(), false /* configured_only */,
      false /* visible_only */, 0, &cellular_networks);
  ASSERT_EQ(1u, cellular_networks.size());
  EXPECT_FALSE(cellular_networks[0]->IsDefaultCellular());
  EXPECT_EQ("/service/cellular1", cellular_networks[0]->path());
}

}  // namespace chromeos
