| // Copyright 2017 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/components/tether/tether_disconnector_impl.h" |
| |
| #include <memory> |
| |
| #include "chromeos/components/tether/device_id_tether_network_guid_map.h" |
| #include "chromeos/components/tether/fake_active_host.h" |
| #include "chromeos/components/tether/fake_disconnect_tethering_request_sender.h" |
| #include "chromeos/components/tether/fake_tether_connector.h" |
| #include "chromeos/components/tether/fake_tether_session_completion_logger.h" |
| #include "chromeos/components/tether/fake_wifi_hotspot_disconnector.h" |
| #include "chromeos/components/tether/tether_session_completion_logger.h" |
| #include "components/cryptauth/remote_device_ref.h" |
| #include "components/cryptauth/remote_device_test_util.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace chromeos { |
| |
| namespace tether { |
| |
| namespace { |
| |
| const char kSuccessResult[] = "success"; |
| const char kWifiNetworkGuid[] = "wifiNetworkGuid"; |
| |
| } // namespace |
| |
| class TetherDisconnectorImplTest : public testing::Test { |
| public: |
| TetherDisconnectorImplTest() |
| : test_devices_(cryptauth::CreateRemoteDeviceRefListForTest(2u)) {} |
| ~TetherDisconnectorImplTest() override = default; |
| |
| void SetUp() override { |
| fake_active_host_ = std::make_unique<FakeActiveHost>(); |
| fake_wifi_hotspot_disconnector_ = |
| std::make_unique<FakeWifiHotspotDisconnector>(); |
| fake_disconnect_tethering_request_sender_ = |
| std::make_unique<FakeDisconnectTetheringRequestSender>(); |
| fake_tether_connector_ = std::make_unique<FakeTetherConnector>(); |
| device_id_tether_network_guid_map_ = |
| std::make_unique<DeviceIdTetherNetworkGuidMap>(); |
| fake_tether_session_completion_logger_ = |
| std::make_unique<FakeTetherSessionCompletionLogger>(); |
| |
| tether_disconnector_ = std::make_unique<TetherDisconnectorImpl>( |
| fake_active_host_.get(), fake_wifi_hotspot_disconnector_.get(), |
| fake_disconnect_tethering_request_sender_.get(), |
| fake_tether_connector_.get(), device_id_tether_network_guid_map_.get(), |
| fake_tether_session_completion_logger_.get()); |
| } |
| |
| std::string GetTetherNetworkGuid(const std::string& device_id) { |
| return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( |
| device_id); |
| } |
| |
| void SuccessCallback() { disconnection_result_ = kSuccessResult; } |
| |
| void ErrorCallback(const std::string& error_name) { |
| disconnection_result_ = error_name; |
| } |
| |
| void CallDisconnect( |
| const std::string& tether_network_guid, |
| const TetherSessionCompletionLogger::SessionCompletionReason& |
| session_completion_reason) { |
| tether_disconnector_->DisconnectFromNetwork( |
| tether_network_guid, |
| base::Bind(&TetherDisconnectorImplTest::SuccessCallback, |
| base::Unretained(this)), |
| base::Bind(&TetherDisconnectorImplTest::ErrorCallback, |
| base::Unretained(this)), |
| session_completion_reason); |
| } |
| |
| std::string GetResultAndReset() { |
| std::string result; |
| result.swap(disconnection_result_); |
| return result; |
| } |
| |
| // Verifies that no Wi-Fi disconnection was requested and that no |
| // DisconnectTetheringRequest message was sent. |
| void VerifyNoDisconnectionOccurred() { |
| EXPECT_TRUE( |
| fake_wifi_hotspot_disconnector_->last_disconnected_wifi_network_guid() |
| .empty()); |
| EXPECT_TRUE( |
| fake_disconnect_tethering_request_sender_->device_ids_sent_requests() |
| .empty()); |
| } |
| |
| void VerifySessionCompletionReasonRecorded( |
| TetherSessionCompletionLogger::SessionCompletionReason |
| expected_session_completion_reason) { |
| EXPECT_EQ(expected_session_completion_reason, |
| *fake_tether_session_completion_logger_ |
| ->last_session_completion_reason()); |
| } |
| |
| void VerifySessionCompletionReasonNotRecorded() { |
| EXPECT_FALSE(fake_tether_session_completion_logger_ |
| ->last_session_completion_reason()); |
| } |
| |
| const cryptauth::RemoteDeviceRefList test_devices_; |
| |
| std::unique_ptr<FakeActiveHost> fake_active_host_; |
| std::unique_ptr<FakeWifiHotspotDisconnector> fake_wifi_hotspot_disconnector_; |
| std::unique_ptr<FakeDisconnectTetheringRequestSender> |
| fake_disconnect_tethering_request_sender_; |
| std::unique_ptr<FakeTetherConnector> fake_tether_connector_; |
| // TODO(hansberry): Use a fake for this when a real mapping scheme is created. |
| std::unique_ptr<DeviceIdTetherNetworkGuidMap> |
| device_id_tether_network_guid_map_; |
| std::unique_ptr<FakeTetherSessionCompletionLogger> |
| fake_tether_session_completion_logger_; |
| |
| std::string disconnection_result_; |
| |
| std::unique_ptr<TetherDisconnectorImpl> tether_disconnector_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorImplTest); |
| }; |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenAlreadyDisconnected) { |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); |
| |
| VerifyNoDisconnectionOccurred(); |
| VerifySessionCompletionReasonNotRecorded(); |
| |
| // Should still be disconnected. |
| EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| fake_active_host_->GetActiveHostStatus()); |
| } |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenOtherDeviceConnected) { |
| // Set device 1 as connected. |
| fake_active_host_->SetActiveHostConnected( |
| test_devices_[1].GetDeviceId(), |
| GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), |
| "someWifiNetworkGuid"); |
| |
| // Try to disconnect device 0; this should fail since the device is not |
| // connected. |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); |
| |
| VerifyNoDisconnectionOccurred(); |
| VerifySessionCompletionReasonNotRecorded(); |
| |
| // Should still be connected to the other host. |
| EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED, |
| fake_active_host_->GetActiveHostStatus()); |
| EXPECT_EQ(test_devices_[1].GetDeviceId(), |
| fake_active_host_->GetActiveHostDeviceId()); |
| } |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnecting_CancelFails) { |
| fake_active_host_->SetActiveHostConnecting( |
| test_devices_[0].GetDeviceId(), |
| GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| fake_tether_connector_->set_should_cancel_successfully(false); |
| |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed, |
| GetResultAndReset()); |
| EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| fake_tether_connector_->last_canceled_tether_network_guid()); |
| |
| VerifyNoDisconnectionOccurred(); |
| VerifySessionCompletionReasonNotRecorded(); |
| |
| // Note: This test does not check the active host's status because it will be |
| // changed by TetherConnector. |
| } |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnecting_CancelSucceeds) { |
| fake_active_host_->SetActiveHostConnecting( |
| test_devices_[0].GetDeviceId(), |
| GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| fake_tether_connector_->set_should_cancel_successfully(true); |
| |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| fake_tether_connector_->last_canceled_tether_network_guid()); |
| |
| VerifyNoDisconnectionOccurred(); |
| VerifySessionCompletionReasonNotRecorded(); |
| |
| // Note: This test does not check the active host's status because it will be |
| // changed by TetherConnector. |
| } |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnected_Failure) { |
| fake_active_host_->SetActiveHostConnected( |
| test_devices_[0].GetDeviceId(), |
| GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| fake_wifi_hotspot_disconnector_->set_disconnection_error_name("failureName"); |
| |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ("failureName", GetResultAndReset()); |
| |
| EXPECT_EQ( |
| kWifiNetworkGuid, |
| fake_wifi_hotspot_disconnector_->last_disconnected_wifi_network_guid()); |
| EXPECT_EQ( |
| std::vector<std::string>{test_devices_[0].GetDeviceId()}, |
| fake_disconnect_tethering_request_sender_->device_ids_sent_requests()); |
| EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| fake_active_host_->GetActiveHostStatus()); |
| |
| VerifySessionCompletionReasonRecorded( |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| } |
| |
| TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnected_Success) { |
| fake_active_host_->SetActiveHostConnected( |
| test_devices_[0].GetDeviceId(), |
| GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid); |
| |
| CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| |
| EXPECT_EQ( |
| kWifiNetworkGuid, |
| fake_wifi_hotspot_disconnector_->last_disconnected_wifi_network_guid()); |
| EXPECT_EQ( |
| std::vector<std::string>{test_devices_[0].GetDeviceId()}, |
| fake_disconnect_tethering_request_sender_->device_ids_sent_requests()); |
| EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| fake_active_host_->GetActiveHostStatus()); |
| |
| VerifySessionCompletionReasonRecorded( |
| TetherSessionCompletionLogger::SessionCompletionReason:: |
| USER_DISCONNECTED); |
| } |
| |
| } // namespace tether |
| |
| } // namespace chromeos |