blob: 6e684db23607fcff7fc6fc631746e3ae1625697c [file] [log] [blame]
// Copyright 2019 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/services/cellular_setup/ota_activator_impl.h"
#include <memory>
#include <utility>
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "chromeos/network/fake_network_activation_handler.h"
#include "chromeos/network/fake_network_connection_handler.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_state_test_helper.h"
#include "chromeos/services/cellular_setup/public/cpp/fake_activation_delegate.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
namespace chromeos {
namespace cellular_setup {
namespace {
const char kTestCellularDevicePath[] = "/device/wwan0";
const char kTestCellularDeviceName[] = "testDeviceName";
const char kTestCellularDeviceCarrier[] = "testDeviceCarrier";
const char kTestCellularDeviceMeid[] = "testDeviceMeid";
const char kTestCellularDeviceImei[] = "testDeviceImei";
const char kTestCellularDeviceMdn[] = "testDeviceMdn";
const char kTestCellularServicePath[] = "/service/cellular0";
const char kTestCellularServiceGuid[] = "testServiceGuid";
const char kTestCellularServiceName[] = "testServiceName";
const char kTestCellularServicePaymentUrl[] = "testServicePaymentUrl.com";
const char kTestCellularServicePaymentPostData[] = "testServicePostData";
const char kPaymentPortalMethodPost[] = "POST";
} // namespace
class CellularSetupOtaActivatorImplTest : public testing::Test {
protected:
CellularSetupOtaActivatorImplTest()
: test_helper_(false /* use_default_devices_and_services */) {}
~CellularSetupOtaActivatorImplTest() override = default;
// testing::Test:
void SetUp() override {
fake_activation_delegate_ = std::make_unique<FakeActivationDelegate>();
fake_network_connection_handler_ =
std::make_unique<FakeNetworkConnectionHandler>();
fake_network_activation_handler_ =
std::make_unique<FakeNetworkActivationHandler>();
}
void BuildOtaActivator() {
auto test_task_runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
ota_activator_ = OtaActivatorImpl::Factory::Create(
fake_activation_delegate_->GenerateRemote(),
base::BindOnce(&CellularSetupOtaActivatorImplTest::OnFinished,
base::Unretained(this)),
test_helper_.network_state_handler(),
fake_network_connection_handler_.get(),
fake_network_activation_handler_.get(), test_task_runner);
test_task_runner->RunUntilIdle();
carrier_portal_handler_remote_.Bind(ota_activator_->GenerateRemote());
}
void AddCellularDevice(bool has_valid_sim) {
ShillDeviceClient::TestInterface* device_test = test_helper_.device_test();
device_test->AddDevice(kTestCellularDevicePath, shill::kTypeCellular,
kTestCellularDeviceName);
if (has_valid_sim) {
device_test->SetDeviceProperty(
kTestCellularDevicePath, shill::kSIMPresentProperty,
base::Value(true), false /* notify_changed */);
base::DictionaryValue home_provider;
home_provider.SetString(shill::kOperatorNameKey,
kTestCellularDeviceCarrier);
device_test->SetDeviceProperty(kTestCellularDevicePath,
shill::kHomeProviderProperty,
home_provider, false /* notify_changed */);
device_test->SetDeviceProperty(
kTestCellularDevicePath, shill::kMeidProperty,
base::Value(kTestCellularDeviceMeid), false /* notify_changed */);
device_test->SetDeviceProperty(
kTestCellularDevicePath, shill::kImeiProperty,
base::Value(kTestCellularDeviceImei), false /* notify_changed */);
device_test->SetDeviceProperty(
kTestCellularDevicePath, shill::kMdnProperty,
base::Value(kTestCellularDeviceMdn), false /* notify_changed */);
}
base::RunLoop().RunUntilIdle();
}
void RemoveCellularDevice() {
test_helper_.device_test()->RemoveDevice(kTestCellularDevicePath);
base::RunLoop().RunUntilIdle();
}
void AddCellularNetwork(bool has_valid_payment_info,
bool is_connected,
bool is_already_activated) {
ShillServiceClient::TestInterface* service_test =
test_helper_.service_test();
service_test->AddService(
kTestCellularServicePath, kTestCellularServiceGuid,
kTestCellularServiceName, shill::kTypeCellular,
is_connected ? shill::kStateOnline : shill::kStateIdle, true);
service_test->SetServiceProperty(
kTestCellularServicePath, shill::kActivationStateProperty,
is_already_activated
? base::Value(shill::kActivationStateActivated)
: base::Value(shill::kActivationStateNotActivated));
if (has_valid_payment_info) {
base::DictionaryValue payment_portal;
payment_portal.SetString(shill::kPaymentPortalURL,
kTestCellularServicePaymentUrl);
payment_portal.SetString(shill::kPaymentPortalMethod,
kPaymentPortalMethodPost);
payment_portal.SetString(shill::kPaymentPortalPostData,
kTestCellularServicePaymentPostData);
service_test->SetServiceProperty(kTestCellularServicePath,
shill::kPaymentPortalProperty,
payment_portal);
}
base::RunLoop().RunUntilIdle();
}
void RemoveCellularNetwork() {
test_helper_.service_test()->RemoveService(kTestCellularServicePath);
base::RunLoop().RunUntilIdle();
}
void FlushForTesting() {
static_cast<OtaActivatorImpl*>(ota_activator_.get())->FlushForTesting();
}
void VerifyCellularMetadataReceivedByDelegate() {
const std::vector<mojom::CellularMetadataPtr>& cellular_metadata_list =
fake_activation_delegate_->cellular_metadata_list();
ASSERT_EQ(1u, cellular_metadata_list.size());
EXPECT_EQ(GURL(kTestCellularServicePaymentUrl),
cellular_metadata_list[0]->payment_url);
EXPECT_EQ(kTestCellularDeviceCarrier, cellular_metadata_list[0]->carrier);
EXPECT_EQ(kTestCellularDeviceMeid, cellular_metadata_list[0]->meid);
EXPECT_EQ(kTestCellularDeviceImei, cellular_metadata_list[0]->imei);
EXPECT_EQ(kTestCellularDeviceMdn, cellular_metadata_list[0]->mdn);
}
void UpdateCarrierPortalState(
mojom::CarrierPortalStatus carrier_portal_status) {
carrier_portal_handler_remote_->OnCarrierPortalStatusChange(
carrier_portal_status);
carrier_portal_handler_remote_.FlushForTesting();
}
void ConnectCellularNetwork() {
const std::vector<FakeNetworkConnectionHandler::ConnectionParams>&
connect_calls = fake_network_connection_handler_->connect_calls();
ASSERT_LE(1u, connect_calls.size());
// A connection should have been requested by |ota_activator_|.
EXPECT_EQ(kTestCellularServicePath, connect_calls[0].service_path());
// Simulate the connection succeeding.
test_helper_.service_test()->SetServiceProperty(
kTestCellularServicePath, shill::kStateProperty,
base::Value(shill::kStateOnline));
base::RunLoop().RunUntilIdle();
}
void InvokePendingActivationCallback(bool success) {
const std::vector<FakeNetworkActivationHandler::ActivationParams>&
complete_activation_calls =
fake_network_activation_handler_->complete_activation_calls();
ASSERT_EQ(1u, complete_activation_calls.size());
EXPECT_EQ(kTestCellularServicePath,
complete_activation_calls[0].service_path());
if (success) {
complete_activation_calls[0].InvokeSuccessCallback();
} else {
complete_activation_calls[0].InvokeErrorCallback(
"error", nullptr /* error_data */);
}
}
void VerifyActivationFinished(mojom::ActivationResult activation_result) {
const std::vector<mojom::ActivationResult>& activation_results =
fake_activation_delegate_->activation_results();
ASSERT_EQ(1u, activation_results.size());
EXPECT_EQ(activation_result, activation_results[0]);
EXPECT_TRUE(is_finished_);
}
void DisconnectDelegate() {
fake_activation_delegate_->DisconnectReceivers();
}
bool is_finished() { return is_finished_; }
private:
void OnFinished() {
EXPECT_FALSE(is_finished_);
is_finished_ = true;
}
base::test::TaskEnvironment task_environment_;
NetworkStateTestHelper test_helper_;
std::unique_ptr<FakeActivationDelegate> fake_activation_delegate_;
std::unique_ptr<FakeNetworkConnectionHandler>
fake_network_connection_handler_;
std::unique_ptr<FakeNetworkActivationHandler>
fake_network_activation_handler_;
std::unique_ptr<OtaActivator> ota_activator_;
mojo::Remote<mojom::CarrierPortalHandler> carrier_portal_handler_remote_;
bool is_finished_ = false;
DISALLOW_COPY_AND_ASSIGN(CellularSetupOtaActivatorImplTest);
};
TEST_F(CellularSetupOtaActivatorImplTest, Success) {
AddCellularDevice(true /* has_valid_sim */);
AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
false /* is_already_activated */);
BuildOtaActivator();
FlushForTesting();
VerifyCellularMetadataReceivedByDelegate();
UpdateCarrierPortalState(
mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
UpdateCarrierPortalState(
mojom::CarrierPortalStatus::kPortalLoadedAndUserCompletedPayment);
InvokePendingActivationCallback(true /* success */);
FlushForTesting();
VerifyActivationFinished(
mojom::ActivationResult::kSuccessfullyStartedActivation);
}
TEST_F(CellularSetupOtaActivatorImplTest,
SimAndPaymentInfoNotInitiallyPresent_AndNetworkNotConnected) {
AddCellularDevice(false /* has_valid_sim */);
AddCellularNetwork(false /* has_valid_payment_info */,
false /* is_connected */,
false /* is_already_activated */);
BuildOtaActivator();
RemoveCellularDevice();
RemoveCellularNetwork();
AddCellularDevice(true /* has_valid_sim */);
AddCellularNetwork(true /* has_valid_payment_info */,
false /* is_connected */,
false /* is_already_activated */);
ConnectCellularNetwork();
FlushForTesting();
VerifyCellularMetadataReceivedByDelegate();
UpdateCarrierPortalState(
mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
UpdateCarrierPortalState(
mojom::CarrierPortalStatus::kPortalLoadedAndUserCompletedPayment);
InvokePendingActivationCallback(true /* success */);
FlushForTesting();
VerifyActivationFinished(
mojom::ActivationResult::kSuccessfullyStartedActivation);
}
TEST_F(CellularSetupOtaActivatorImplTest, AlreadyActivated) {
AddCellularDevice(true /* has_valid_sim */);
AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
true /* is_already_activated */);
BuildOtaActivator();
FlushForTesting();
VerifyActivationFinished(mojom::ActivationResult::kAlreadyActivated);
}
TEST_F(CellularSetupOtaActivatorImplTest, DelegateBecomesDisconnected) {
AddCellularDevice(true /* has_valid_sim */);
AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
false /* is_already_activated */);
BuildOtaActivator();
DisconnectDelegate();
FlushForTesting();
// Note: Cannot check the ActivationResult received by the delegate because
// the delegate was disconnected and did not receive the result.
EXPECT_TRUE(is_finished());
}
} // namespace cellular_setup
} // namespace chromeos