chromium/components/device_signals/core/browser/ash/user_permission_service_ash_unittest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/device_signals/core/browser/ash/user_permission_service_ash.h"

#include "ash/constants/ash_features.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "components/device_signals/core/browser/mock_user_delegate.h"
#include "components/device_signals/core/browser/pref_names.h"
#include "components/device_signals/core/browser/user_delegate.h"
#include "components/device_signals/core/browser/user_permission_service.h"
#include "components/policy/core/common/management/management_service.h"
#include "components/policy/core/common/management/scoped_management_service_override_for_testing.h"
#include "components/prefs/pref_registry.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using policy::EnterpriseManagementAuthority;
using policy::ScopedManagementServiceOverrideForTesting;
using testing::Return;

namespace device_signals {

namespace {

class TestManagementService : public policy::ManagementService {
 public:
  TestManagementService() : ManagementService({}) {}
  explicit TestManagementService(
      std::vector<std::unique_ptr<policy::ManagementStatusProvider>> providers)
      : ManagementService(std::move(providers)) {}
  void SetManagementStatusProviderForTesting(
      std::vector<std::unique_ptr<policy::ManagementStatusProvider>>
          providers) {
    SetManagementStatusProvider(std::move(providers));
  }
};

}  // namespace

class UserPermissionServiceAshTest : public testing::Test {
 protected:
  explicit UserPermissionServiceAshTest(
      bool feature_unmanaged_device_enabled = true)
      : feature_unmanaged_device_enabled_(feature_unmanaged_device_enabled) {
    RegisterProfilePrefs(test_prefs_.registry());

    auto mock_user_delegate =
        std::make_unique<testing::StrictMock<MockUserDelegate>>();
    mock_user_delegate_ = mock_user_delegate.get();

    permission_service_ = std::make_unique<UserPermissionServiceAsh>(
        &management_service_, std::move(mock_user_delegate), &test_prefs_);
  }

  void SetUp() override {
    feature_list_.InitWithFeatureState(
        ash::features::kUnmanagedDeviceDeviceTrustConnectorEnabled,
        feature_unmanaged_device_enabled_);
  }

  void SetDeviceAsCloudManaged(bool is_managed = true) {
    if (is_managed) {
      scoped_override_.emplace(&management_service_,
                               EnterpriseManagementAuthority::CLOUD_DOMAIN);
    }

    EXPECT_EQ(management_service_.HasManagementAuthority(
                  EnterpriseManagementAuthority::CLOUD_DOMAIN),
              is_managed);
  }

  void SetUserAsCloudManaged(bool is_managed = true) {
    if (is_managed) {
      scoped_override_.emplace(&management_service_,
                               EnterpriseManagementAuthority::CLOUD);
    }

    EXPECT_CALL(*mock_user_delegate_, IsManagedUser())
        .WillRepeatedly(Return(is_managed));
  }

  void SetSigninContext(bool is_signin_context = true) {
    EXPECT_CALL(*mock_user_delegate_, IsSigninContext())
        .WillOnce(Return(is_signin_context));
  }

  void SetUserAffiliated(bool is_affiliated = true) {
    EXPECT_CALL(*mock_user_delegate_, IsAffiliated())
        .WillOnce(Return(is_affiliated));
  }

  base::test::TaskEnvironment task_environment_;

  TestManagementService management_service_;
  std::optional<ScopedManagementServiceOverrideForTesting> scoped_override_;
  raw_ptr<testing::StrictMock<MockUserDelegate>, DanglingUntriaged>
      mock_user_delegate_;
  TestingPrefServiceSimple test_prefs_;
  base::test::ScopedFeatureList feature_list_;

  std::unique_ptr<UserPermissionServiceAsh> permission_service_;

  const bool feature_unmanaged_device_enabled_;
};

// Tests that ShouldCollectConsent should always return false on CrOS, as the
// consent flow is not supported yet.
TEST_F(UserPermissionServiceAshTest, ShouldCollectConsent_False) {
  EXPECT_FALSE(permission_service_->ShouldCollectConsent());
}

// Tests that signals can be collected for affiliated users.
TEST_F(UserPermissionServiceAshTest,
       CanCollectSignals_DeviceCloudManaged_AffiliatedUser) {
  SetDeviceAsCloudManaged();
  SetSigninContext(/*is_signin_context=*/false);
  SetUserAffiliated();

  EXPECT_EQ(permission_service_->CanCollectSignals(), UserPermission::kGranted);
}

// Tests that signals can be collected on the signin screen of a managed device.
TEST_F(UserPermissionServiceAshTest,
       CanCollectSignals_DeviceCloudManaged_SigninContext) {
  SetDeviceAsCloudManaged();
  SetSigninContext();

  EXPECT_EQ(permission_service_->CanCollectSignals(), UserPermission::kGranted);
}

// Tests that signals cannot be collected if the device is unmanaged but user is
// deemed as affiliated. The latter can happen since we treat the login profile
// as affiliated.
TEST_F(UserPermissionServiceAshTest,
       CanCollectSignals_DeviceCloudManaged_UnaffiliatedUser) {
  SetDeviceAsCloudManaged();
  SetSigninContext(/*is_signin_context=*/false);
  SetUserAffiliated(/*is_affiliated=*/false);

  EXPECT_EQ(permission_service_->CanCollectSignals(),
            UserPermission::kUnsupported);
}

// Tests that signals cannot be collected on the signin screen if the device is
// unmanaged.
TEST_F(UserPermissionServiceAshTest,
       CanCollectSignals_UnmanagedDevice_UnmanagedUser) {
  SetDeviceAsCloudManaged(/*is_managed=*/false);
  SetUserAsCloudManaged(/*is_managed=*/false);

  EXPECT_EQ(permission_service_->CanCollectSignals(),
            UserPermission::kUnsupported);
}

// Tests that signals can be collected if the device is unmanaged and the user
// is managed.
TEST_F(UserPermissionServiceAshTest,
       CanCollectSignals_UnmanagedDevice_ManagedUser) {
  SetDeviceAsCloudManaged(/*is_managed=*/false);
  SetUserAsCloudManaged();

  EXPECT_EQ(permission_service_->CanCollectSignals(), UserPermission::kGranted);
}

class UserPermissionServiceAshFlagTest
    : public UserPermissionServiceAshTest,
      public ::testing::WithParamInterface<bool> {
 protected:
  UserPermissionServiceAshFlagTest()
      : UserPermissionServiceAshTest(GetParam()) {}
};

TEST_P(UserPermissionServiceAshFlagTest, CanCollectSignals_UnmanagedDevice) {
  SetDeviceAsCloudManaged(/*is_managed=*/false);
  SetUserAsCloudManaged();

  EXPECT_EQ(
      permission_service_->CanCollectSignals(),
      GetParam() ? UserPermission::kGranted : UserPermission::kUnsupported);
}

INSTANTIATE_TEST_SUITE_P(All,
                         UserPermissionServiceAshFlagTest,
                         testing::Bool());

}  // namespace device_signals