blob: c5451f4d5d32f151aa74d957ee49d653d30746c6 [file] [log] [blame]
// Copyright (c) 2013 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_connect.h"
#include <memory>
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_device_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/login/login_state.h"
#include "chromeos/network/network_connect.h"
#include "chromeos/network/network_connection_handler.h"
#include "chromeos/network/network_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using testing::_;
using testing::AnyNumber;
using testing::NiceMock;
using testing::Return;
namespace chromeos {
namespace {
const char kWiFi1ServicePath[] = "/service/wifi1";
const char kWiFi1Guid[] = "wifi1_guid";
const char kCellular1DevicePath[] = "/device/stub_cellular_device1";
const char kCellular1ServicePath[] = "/service/cellular1";
const char kCellular1Guid[] = "cellular1_guid";
const char kTetherGuid[] = "tether_guid";
class MockDelegate : public NetworkConnect::Delegate {
public:
MockDelegate() = default;
~MockDelegate() override = default;
MOCK_METHOD1(ShowNetworkConfigure, void(const std::string& network_id));
MOCK_METHOD1(ShowNetworkSettings, void(const std::string& network_id));
MOCK_METHOD1(ShowEnrollNetwork, bool(const std::string& network_id));
MOCK_METHOD1(ShowMobileSetupDialog, void(const std::string& network_id));
MOCK_METHOD2(ShowNetworkConnectError,
void(const std::string& error_name,
const std::string& network_id));
MOCK_METHOD1(ShowMobileActivationError, void(const std::string& network_id));
};
class FakeTetherDelegate : public NetworkConnectionHandler::TetherDelegate {
public:
FakeTetherDelegate() = default;
~FakeTetherDelegate() override = default;
std::string last_connected_tether_network_guid() {
return last_connected_tether_network_guid_;
}
// NetworkConnectionHandler::TetherDelegate:
void ConnectToNetwork(
const std::string& tether_network_guid,
const base::Closure& success_callback,
const network_handler::StringResultCallback& error_callback) override {
last_connected_tether_network_guid_ = tether_network_guid;
success_callback.Run();
}
void DisconnectFromNetwork(
const std::string& tether_network_guid,
const base::Closure& success_callback,
const network_handler::StringResultCallback& error_callback) override {}
private:
std::string last_connected_tether_network_guid_;
};
} // namespace
class NetworkConnectTest : public testing::Test {
public:
NetworkConnectTest() = default;
~NetworkConnectTest() override = default;
void SetUp() override {
testing::Test::SetUp();
DBusThreadManager::Initialize();
LoginState::Initialize();
SetupDefaultShillState();
NetworkHandler::Initialize();
base::RunLoop().RunUntilIdle();
mock_delegate_.reset(new MockDelegate());
ON_CALL(*mock_delegate_, ShowEnrollNetwork(_)).WillByDefault(Return(true));
fake_tether_delegate_.reset(new FakeTetherDelegate());
NetworkHandler::Get()->network_connection_handler()->SetTetherDelegate(
fake_tether_delegate_.get());
NetworkConnect::Initialize(mock_delegate_.get());
}
void TearDown() override {
NetworkConnect::Shutdown();
mock_delegate_.reset();
LoginState::Shutdown();
NetworkHandler::Shutdown();
DBusThreadManager::Shutdown();
testing::Test::TearDown();
}
protected:
void SetupDefaultShillState() {
base::RunLoop().RunUntilIdle();
device_test_ =
DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface();
device_test_->ClearDevices();
device_test_->AddDevice("/device/stub_wifi_device1", shill::kTypeWifi,
"stub_wifi_device1");
device_test_->AddDevice(kCellular1DevicePath, shill::kTypeCellular,
"stub_cellular_device1");
device_test_->SetDeviceProperty(
kCellular1DevicePath, shill::kTechnologyFamilyProperty,
base::Value(shill::kNetworkTechnologyGsm), /*notify_changed=*/true);
service_test_ =
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
service_test_->ClearServices();
const bool add_to_visible = true;
// Create a wifi network and set to online.
service_test_->AddService(kWiFi1ServicePath, kWiFi1Guid, "wifi1",
shill::kTypeWifi, shill::kStateIdle,
add_to_visible);
service_test_->SetServiceProperty(kWiFi1ServicePath,
shill::kSecurityClassProperty,
base::Value(shill::kSecurityWep));
service_test_->SetServiceProperty(
kWiFi1ServicePath, shill::kConnectableProperty, base::Value(true));
service_test_->SetServiceProperty(
kWiFi1ServicePath, shill::kPassphraseProperty, base::Value("password"));
// Create a cellular network.
service_test_->AddService(kCellular1ServicePath, kCellular1Guid,
"cellular1", shill::kTypeCellular,
shill::kStateIdle, add_to_visible);
service_test_->SetServiceProperty(
kCellular1ServicePath, shill::kConnectableProperty, base::Value(true));
service_test_->SetServiceProperty(
kCellular1ServicePath, shill::kActivationStateProperty,
base::Value(shill::kActivationStateActivated));
service_test_->SetServiceProperty(kCellular1ServicePath,
shill::kOutOfCreditsProperty,
base::Value(false));
base::RunLoop().RunUntilIdle();
}
void AddTetherNetwork(bool has_connected_to_host) {
NetworkStateHandler* handler =
NetworkHandler::Get()->network_state_handler();
handler->SetTetherTechnologyState(
NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED);
handler->AddTetherNetworkState(kTetherGuid, "TetherName", "TetherCarrier",
100 /* battery_percentage */,
100 /* signal_strength */,
has_connected_to_host);
}
std::unique_ptr<MockDelegate> mock_delegate_;
std::unique_ptr<FakeTetherDelegate> fake_tether_delegate_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
ShillDeviceClient::TestInterface* device_test_;
ShillServiceClient::TestInterface* service_test_;
private:
DISALLOW_COPY_AND_ASSIGN(NetworkConnectTest);
};
TEST_F(NetworkConnectTest, ConnectToNetworkId_NoConfiguration) {
EXPECT_CALL(*mock_delegate_, ShowNetworkConfigure(_)).Times(0);
EXPECT_CALL(*mock_delegate_, ShowNetworkConnectError(_, _)).Times(0);
NetworkConnect::Get()->ConnectToNetworkId("bad guid");
}
TEST_F(NetworkConnectTest, ConfigureAndConnectToNetwork_NoConfiguration) {
EXPECT_CALL(*mock_delegate_,
ShowNetworkConnectError(NetworkConnectionHandler::kErrorNotFound,
"bad guid"));
base::DictionaryValue properties;
NetworkConnect::Get()->ConfigureNetworkIdAndConnect("bad guid", properties,
true);
}
TEST_F(NetworkConnectTest,
ConfigureAndConnectToNetwork_NotSharedButNoProfilePath) {
EXPECT_CALL(*mock_delegate_,
ShowNetworkConnectError(
NetworkConnectionHandler::kErrorConfigureFailed, kWiFi1Guid));
base::DictionaryValue properties;
NetworkConnect::Get()->ConfigureNetworkIdAndConnect(kWiFi1Guid, properties,
false);
}
TEST_F(NetworkConnectTest, ConnectThenDisconnectWiFiNetwork) {
const NetworkState* network =
NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid(
kWiFi1Guid);
NetworkConnect::Get()->ConnectToNetworkId(kWiFi1Guid);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(network->IsConnectedState());
NetworkConnect::Get()->DisconnectFromNetworkId(kWiFi1Guid);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(network->IsConnectedState());
EXPECT_FALSE(network->IsConnectingState());
}
TEST_F(NetworkConnectTest, ConnectToTetherNetwork_HasConnectedToHost) {
EXPECT_CALL(*mock_delegate_, ShowNetworkConfigure(_)).Times(0);
AddTetherNetwork(true /* has_connected_to_host */);
NetworkConnect::Get()->ConnectToNetworkId(kTetherGuid);
EXPECT_EQ(kTetherGuid,
fake_tether_delegate_->last_connected_tether_network_guid());
}
TEST_F(NetworkConnectTest, ConnectToTetherNetwork_HasNotConnectedToHost) {
EXPECT_CALL(*mock_delegate_, ShowNetworkConfigure(_));
AddTetherNetwork(false /* has_connected_to_host */);
NetworkConnect::Get()->ConnectToNetworkId(kTetherGuid);
EXPECT_TRUE(
fake_tether_delegate_->last_connected_tether_network_guid().empty());
}
TEST_F(NetworkConnectTest, ActivateCellular) {
EXPECT_CALL(*mock_delegate_, ShowMobileSetupDialog(kCellular1Guid));
service_test_->SetServiceProperty(
kCellular1ServicePath, shill::kActivationStateProperty,
base::Value(shill::kActivationStateNotActivated));
base::RunLoop().RunUntilIdle();
NetworkConnect::Get()->ConnectToNetworkId(kCellular1Guid);
}
TEST_F(NetworkConnectTest, ActivateCellular_Error) {
EXPECT_CALL(*mock_delegate_, ShowMobileActivationError(kCellular1Guid));
service_test_->SetServiceProperty(
kCellular1ServicePath, shill::kActivationStateProperty,
base::Value(shill::kActivationStateNotActivated));
service_test_->SetServiceProperty(
kCellular1ServicePath, shill::kActivationTypeProperty,
base::Value(shill::kActivationTypeNonCellular));
base::RunLoop().RunUntilIdle();
NetworkConnect::Get()->ConnectToNetworkId(kCellular1Guid);
}
} // namespace chromeos