chromium/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc

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

#include "chromeos/ash/components/standalone_browser/lacros_selection.h"

#include <memory>
#include <optional>

#include "ash/constants/ash_switches.h"
#include "base/test/scoped_command_line.h"
#include "base/values.h"
#include "chromeos/ash/components/standalone_browser/browser_support.h"
#include "components/account_id/account_id.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

// This implementation of RAII for LacrosSelection is to make it easy reset
// the state between runs.
class ScopedLacrosSelectionCache {
 public:
  explicit ScopedLacrosSelectionCache(
      ash::standalone_browser::LacrosSelectionPolicy lacros_selection) {
    SetLacrosSelection(lacros_selection);
  }
  ScopedLacrosSelectionCache(const ScopedLacrosSelectionCache&) = delete;
  ScopedLacrosSelectionCache& operator=(const ScopedLacrosSelectionCache&) =
      delete;
  ~ScopedLacrosSelectionCache() {
    ash::standalone_browser::ClearLacrosSelectionCacheForTest();
  }

 private:
  void SetLacrosSelection(
      ash::standalone_browser::LacrosSelectionPolicy lacros_selection) {
    policy::PolicyMap policy;
    policy.Set(policy::key::kLacrosSelection, policy::POLICY_LEVEL_MANDATORY,
               policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
               base::Value(GetLacrosSelectionPolicyName(lacros_selection)),
               /*external_data_fetcher=*/nullptr);
    ash::standalone_browser::CacheLacrosSelection(policy);
  }
};

class LacrosSelectionTest : public testing::Test {
 public:
  LacrosSelectionTest() = default;
  ~LacrosSelectionTest() override = default;

  void SetUp() override {
    fake_user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>());
  }

  void TearDown() override {
    if (ash::standalone_browser::BrowserSupport::
            IsInitializedForPrimaryUser()) {
      ash::standalone_browser::BrowserSupport::Shutdown();
    }
    fake_user_manager_.Reset();
    ash::standalone_browser::BrowserSupport::SetCpuSupportedForTesting(
        std::nullopt);
  }

  const user_manager::User* AddRegularUser(const std::string& email) {
    AccountId account_id = AccountId::FromUserEmail(email);
    const user_manager::User* user = fake_user_manager_->AddUser(account_id);
    fake_user_manager_->UserLoggedIn(account_id, user->username_hash(),
                                     /*browser_restart=*/false,
                                     /*is_child=*/false);
    ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
        policy::PolicyMap(), false, false);
    return user;
  }

 private:
  user_manager::TypedScopedUserManager<user_manager::FakeUserManager>
      fake_user_manager_;
};

TEST_F(LacrosSelectionTest, LacrosSelection) {
  // Neither policy nor command line have any preference on Lacros selection.
  EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());

  {
    // LacrosSelection policy has precedence over command line.
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
    base::test::ScopedCommandLine cmd_line;
    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
        ash::standalone_browser::kLacrosSelectionSwitch,
        ash::standalone_browser::kLacrosSelectionStateful);
    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
              ash::standalone_browser::LacrosSelection::kRootfs);
  }

  {
    // LacrosSelection allows command line check, but command line is not set.
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
    EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());
  }

  {
    // LacrosSelection allows command line check.
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
    base::test::ScopedCommandLine cmd_line;
    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
        ash::standalone_browser::kLacrosSelectionSwitch,
        ash::standalone_browser::kLacrosSelectionRootfs);
    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
              ash::standalone_browser::LacrosSelection::kRootfs);
  }

  {
    // LacrosSelection allows command line check.
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
    base::test::ScopedCommandLine cmd_line;
    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
        ash::standalone_browser::kLacrosSelectionSwitch,
        ash::standalone_browser::kLacrosSelectionStateful);
    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
              ash::standalone_browser::LacrosSelection::kStateful);
  }
}

// LacrosSelection has no effect on non-googlers.
TEST_F(LacrosSelectionTest, LacrosSelectionPolicyIgnoreNonGoogle) {
  AddRegularUser("[email protected]");

  base::test::ScopedCommandLine cmd_line;
  cmd_line.GetProcessCommandLine()->AppendSwitch(
      ash::switches::kLacrosSelectionPolicyIgnore);

  {
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
    EXPECT_EQ(ash::standalone_browser::GetCachedLacrosSelectionPolicy(),
              ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
              ash::standalone_browser::LacrosSelection::kRootfs);
  }
}

// LacrosSelection has an effect on googlers.
TEST_F(LacrosSelectionTest,
       LacrosSelectionPolicyIgnoreGoogleDisableToUserChoice) {
  AddRegularUser("[email protected]");

  base::test::ScopedCommandLine cmd_line;
  cmd_line.GetProcessCommandLine()->AppendSwitch(
      ash::switches::kLacrosSelectionPolicyIgnore);

  {
    ScopedLacrosSelectionCache cache(
        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
    EXPECT_EQ(ash::standalone_browser::GetCachedLacrosSelectionPolicy(),
              ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
    EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());
  }
}

}  // namespace