| // Copyright 2018 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/multidevice_setup/host_status_provider_impl.h" |
| |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "chromeos/components/multidevice/remote_device_test_util.h" |
| #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h" |
| #include "chromeos/services/multidevice_setup/fake_eligible_host_devices_provider.h" |
| #include "chromeos/services/multidevice_setup/fake_host_backend_delegate.h" |
| #include "chromeos/services/multidevice_setup/fake_host_status_provider.h" |
| #include "chromeos/services/multidevice_setup/fake_host_verifier.h" |
| #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace chromeos { |
| |
| namespace multidevice_setup { |
| |
| namespace { |
| |
| const size_t kNumTestDevices = 5; |
| |
| } // namespace |
| |
| class MultiDeviceSetupHostStatusProviderImplTest : public testing::Test { |
| protected: |
| MultiDeviceSetupHostStatusProviderImplTest() |
| : test_devices_( |
| multidevice::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {} |
| ~MultiDeviceSetupHostStatusProviderImplTest() override = default; |
| |
| // testing::Test: |
| void SetUp() override { |
| fake_eligible_host_devices_provider_ = |
| std::make_unique<FakeEligibleHostDevicesProvider>(); |
| fake_host_backend_delegate_ = std::make_unique<FakeHostBackendDelegate>(); |
| fake_host_verifier_ = std::make_unique<FakeHostVerifier>(); |
| fake_device_sync_client_ = |
| std::make_unique<device_sync::FakeDeviceSyncClient>(); |
| fake_device_sync_client_->set_synced_devices(test_devices_); |
| |
| host_status_provider_ = |
| HostStatusProviderImpl::Factory::Get()->BuildInstance( |
| fake_eligible_host_devices_provider_.get(), |
| fake_host_backend_delegate_.get(), fake_host_verifier_.get(), |
| fake_device_sync_client_.get()); |
| |
| fake_observer_ = std::make_unique<FakeHostStatusProviderObserver>(); |
| host_status_provider_->AddObserver(fake_observer_.get()); |
| } |
| |
| void TearDown() override { |
| host_status_provider_->RemoveObserver(fake_observer_.get()); |
| } |
| |
| void MakeDevicesEligibleHosts() { |
| fake_eligible_host_devices_provider_->set_eligible_host_devices( |
| test_devices_); |
| fake_device_sync_client_->NotifyNewDevicesSynced(); |
| } |
| |
| // Verifies the current status and, if |expected_observer_index| is non-null, |
| // verifies that the observer received that update at the specified index. |
| void VerifyCurrentStatus( |
| mojom::HostStatus host_status, |
| const base::Optional<multidevice::RemoteDeviceRef>& host_device, |
| const base::Optional<size_t>& expected_observer_index) { |
| HostStatusProvider::HostStatusWithDevice status_with_device(host_status, |
| host_device); |
| EXPECT_EQ(status_with_device, host_status_provider_->GetHostWithStatus()); |
| |
| if (!expected_observer_index) |
| return; |
| EXPECT_EQ(status_with_device, |
| fake_observer_->host_status_updates()[*expected_observer_index]); |
| } |
| |
| size_t GetNumChangeEvents() { |
| return fake_observer_->host_status_updates().size(); |
| } |
| |
| const multidevice::RemoteDeviceRefList& test_devices() const { |
| return test_devices_; |
| } |
| |
| FakeHostBackendDelegate* fake_host_backend_delegate() { |
| return fake_host_backend_delegate_.get(); |
| } |
| |
| FakeHostVerifier* fake_host_verifier() { return fake_host_verifier_.get(); } |
| |
| private: |
| multidevice::RemoteDeviceRefList test_devices_; |
| |
| std::unique_ptr<FakeEligibleHostDevicesProvider> |
| fake_eligible_host_devices_provider_; |
| std::unique_ptr<FakeHostBackendDelegate> fake_host_backend_delegate_; |
| std::unique_ptr<FakeHostVerifier> fake_host_verifier_; |
| std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_; |
| std::unique_ptr<FakeHostStatusProviderObserver> fake_observer_; |
| |
| std::unique_ptr<HostStatusProvider> host_status_provider_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupHostStatusProviderImplTest); |
| }; |
| |
| TEST_F(MultiDeviceSetupHostStatusProviderImplTest, |
| IncreaseHostState_ThenDecrease) { |
| VerifyCurrentStatus(mojom::HostStatus::kNoEligibleHosts, |
| base::nullopt /* host_device */, |
| base::nullopt /* expected_observer_index */); |
| |
| // Add eligible hosts to the account and verify that the status has been |
| // updated accordingly. |
| MakeDevicesEligibleHosts(); |
| EXPECT_EQ(1u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet, |
| base::nullopt /* host_device */, |
| 0u /* expected_observer_index */); |
| |
| // Make a request to set the host, but do not complete it yet. |
| fake_host_backend_delegate()->AttemptToSetMultiDeviceHostOnBackend( |
| test_devices()[0]); |
| EXPECT_EQ(2u, GetNumChangeEvents()); |
| VerifyCurrentStatus( |
| mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation, |
| test_devices()[0] /* host_device */, 1u /* expected_observer_index */); |
| |
| // Successfully set the host on the back-end. |
| fake_host_backend_delegate()->NotifyHostChangedOnBackend(test_devices()[0]); |
| EXPECT_EQ(3u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kHostSetButNotYetVerified, |
| test_devices()[0] /* host_device */, |
| 2u /* expected_observer_index */); |
| |
| // Verify the device. |
| fake_host_verifier()->set_is_host_verified(true); |
| fake_host_verifier()->NotifyHostVerified(); |
| EXPECT_EQ(4u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kHostVerified, |
| test_devices()[0] /* host_device */, |
| 3u /* expected_observer_index */); |
| } |
| |
| TEST_F(MultiDeviceSetupHostStatusProviderImplTest, SetHostThenForget) { |
| MakeDevicesEligibleHosts(); |
| EXPECT_EQ(1u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet, |
| base::nullopt /* host_device */, |
| 0u /* expected_observer_index */); |
| |
| // Without first attempting to set the host on the back-end, set the device. |
| // This simulates the case where the host is set by another device (e.g., if |
| // another Chromebook completes the setup flow). |
| fake_host_backend_delegate()->NotifyHostChangedOnBackend(test_devices()[0]); |
| EXPECT_EQ(2u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kHostSetButNotYetVerified, |
| test_devices()[0] /* host_device */, |
| 1u /* expected_observer_index */); |
| |
| // Now, start an attempt to remove the device on the back-end. This simulates |
| // the user clicking "forget device" in settings. |
| fake_host_backend_delegate()->AttemptToSetMultiDeviceHostOnBackend( |
| base::nullopt /* host_device */); |
| EXPECT_EQ(3u, GetNumChangeEvents()); |
| VerifyCurrentStatus(mojom::HostStatus::kEligibleHostExistsButNoHostSet, |
| base::nullopt /* host_device */, |
| 2u /* expected_observer_index */); |
| |
| // Complete the pending back-end request. In this case, the status should stay |
| // the same, so the observer should not have received an additional event. |
| fake_host_backend_delegate()->NotifyHostChangedOnBackend( |
| base::nullopt /* host_device_on_backend */); |
| EXPECT_EQ(3u, GetNumChangeEvents()); |
| } |
| |
| } // namespace multidevice_setup |
| |
| } // namespace chromeos |