chromium/chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_unittest.cc

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

#include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager.h"

#include "ash/components/arc/arc_features.h"
#include "ash/components/arc/test/arc_util_test_support.h"
#include "ash/constants/ash_features.h"
#include "ash/webui/settings/public/constants/routes.mojom.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/metrics/histogram_base.h"
#include "base/test/metrics/histogram_enum_reader.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/ash/app_list/arc/arc_app_list_prefs_factory.h"
#include "chrome/browser/ash/arc/arc_util.h"
#include "chrome/browser/ash/eche_app/eche_app_manager_factory.h"
#include "chrome/browser/ash/kerberos/kerberos_credentials_manager_factory.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/multidevice_setup/multidevice_setup_client_factory.h"
#include "chrome/browser/ash/phonehub/phone_hub_manager_factory.h"
#include "chrome/browser/ash/printing/cups_printers_manager_factory.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/webui/ash/settings/constants/constants_util.h"
#include "chrome/browser/ui/webui/ash/settings/pages/os_settings_sections.h"
#include "chrome/browser/ui/webui/ash/settings/search/hierarchy.h"
#include "chrome/browser/ui/webui/ash/settings/services/settings_manager/os_settings_manager_factory.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h"
#include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h"
#include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy_factory.h"
#include "chromeos/ash/components/local_search_service/search_metrics_reporter.h"
#include "chromeos/ash/components/system/fake_statistics_provider.h"
#include "chromeos/ash/components/system/statistics_provider.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_manager.h"
#include "components/user_manager/user_names.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/ash/mock_input_method_manager.h"

namespace ash::settings {

namespace mojom {
using ::chromeos::settings::mojom::Section;
using ::chromeos::settings::mojom::Subpage;
}  // namespace mojom

// Verifies the OsSettingsManager initialization flow. Behavioral functionality
// is tested via unit tests on the sub-elements owned by OsSettingsManager.
class OsSettingsManagerTest : public testing::Test {
 protected:
  OsSettingsManagerTest()
      : fake_user_manager_(std::make_unique<ash::FakeChromeUserManager>()),
        profile_manager_(TestingBrowserProcess::GetGlobal()) {}
  ~OsSettingsManagerTest() override = default;

  // testing::Test:
  void SetUp() override {
    scoped_feature_list_.InitWithFeatures(
        {ash::features::kInputDeviceSettingsSplit,
         ash::features::kOsSettingsRevampWayfinding,
         ash::features::kPeripheralCustomization, arc::kPerAppLanguage},
        {});
    ASSERT_TRUE(profile_manager_.SetUp());
    Profile* profile = profile_manager_.CreateTestingProfile(
        TestingProfile::kDefaultProfileUserName);
    // Log in user to ensure ARC PlayStore can be enabled.
    const AccountId account_id(
        AccountId::FromUserEmailGaiaId(profile->GetProfileUserName(), "1234"));
    fake_user_manager_->AddUser(account_id);
    fake_user_manager_->LoginUser(account_id);

    // Enables ARC for test profile.
    arc::SetArcAvailableCommandLineForTesting(
        base::CommandLine::ForCurrentProcess());
    arc::SetArcPlayStoreEnabledForProfile(profile, true);

    NearbySharingServiceFactory::
        SetIsNearbyShareSupportedForBrowserContextForTesting(false);
    local_search_service::SearchMetricsReporter::RegisterLocalStatePrefs(
        pref_service_.registry());
    local_search_service::LocalSearchServiceProxyFactory::GetInstance()
        ->SetLocalState(&pref_service_);
    input_method::MockInputMethodManager::Initialize(
        new input_method::MockInputMethodManager);
    statistics_provider_.SetMachineStatistic(ash::system::kRegionKey, "us");

    UserDataAuthClient::InitializeFake();

    manager_ = std::make_unique<OsSettingsManager>(
        profile, local_search_service_proxy_.get(),
        multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(
            profile),
        phonehub::PhoneHubManagerFactory::GetForProfile(profile),
        KerberosCredentialsManagerFactory::Get(profile),
        ArcAppListPrefsFactory::GetForBrowserContext(profile),
        IdentityManagerFactory::GetForProfile(profile),
        CupsPrintersManagerFactory::GetForBrowserContext(profile),
        apps::AppServiceProxyFactory::GetForProfile(profile),
        eche_app::EcheAppManagerFactory::GetForProfile(profile));
  }

  user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
      fake_user_manager_;
  content::BrowserTaskEnvironment task_environment_;
  TestingPrefServiceSimple pref_service_;
  TestingProfileManager profile_manager_;
  std::unique_ptr<local_search_service::LocalSearchServiceProxy>
      local_search_service_proxy_ =
          std::make_unique<local_search_service::LocalSearchServiceProxy>(
              /*for_testing=*/true);
  std::unique_ptr<OsSettingsManager> manager_;
  base::test::ScopedFeatureList scoped_feature_list_;
  ash::system::ScopedFakeStatisticsProvider statistics_provider_;
};

TEST_F(OsSettingsManagerTest, Initialization) {
  std::optional<base::HistogramEnumEntryMap> sections_enum_entry_map =
      base::ReadEnumFromEnumsXml("OsSettingsSection", "chromeos_settings");
  ASSERT_TRUE(sections_enum_entry_map);
  for (const auto& section : AllSections()) {
    // For each mojom::Section value, there should be an associated
    // OsSettingsSection class registered.
    EXPECT_TRUE(manager_->sections_->GetSection(section))
        << "No OsSettingsSection instance created for " << section << ".";

    // Each mojom::Section should be registered in the hierarchy.
    manager_->hierarchy_->GetSectionMetadata(section);

    EXPECT_TRUE(
        base::Contains(*sections_enum_entry_map, static_cast<int32_t>(section)))
        << "Missing OsSettingsSection enums.xml entry for " << section;
  }

  std::optional<base::HistogramEnumEntryMap> subpages_enum_entry_map =
      base::ReadEnumFromEnumsXml("OsSettingsSubpage", "chromeos_settings");
  ASSERT_TRUE(subpages_enum_entry_map);
  for (const auto& subpage : AllSubpages()) {
    // Each mojom::Subpage should be registered in the hierarchy. Note that
    // GetSubpageMetadata() internally CHECK()s that the metadata exists before
    // returning it.
    manager_->hierarchy_->GetSubpageMetadata(subpage);

    EXPECT_TRUE(
        base::Contains(*subpages_enum_entry_map, static_cast<int32_t>(subpage)))
        << "Missing OsSettingsSubpage enums.xml entry for " << subpage;
  }

  std::optional<base::HistogramEnumEntryMap> settings_enum_entry_map =
      base::ReadEnumFromEnumsXml("OsSetting", "chromeos_settings");
  ASSERT_TRUE(settings_enum_entry_map);
  for (const auto& setting : AllSettings()) {
    // Each mojom::Setting should be registered in the hierarchy. Note that
    // GetSettingMetadata() internally CHECK()s that the metadata exists before
    // returning it.
    manager_->hierarchy_->GetSettingMetadata(setting);

    EXPECT_TRUE(
        base::Contains(*settings_enum_entry_map, static_cast<int32_t>(setting)))
        << "Missing OsSetting enums.xml entry for " << setting;
  }
}

}  // namespace ash::settings