chromium/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc

// Copyright 2018 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/web_applications/policy/web_app_policy_manager.h"

#include <memory>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "base/containers/extend.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/web_applications/external_install_options.h"
#include "chrome/browser/web_applications/externally_managed_app_manager.h"
#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/policy/web_app_policy_constants.h"
#include "chrome/browser/web_applications/test/fake_externally_managed_app_manager.h"
#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
#include "chrome/browser/web_applications/test/os_integration_test_override_impl.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_command_manager.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/browser/web_applications/web_app_install_utils.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_registrar_observer.h"
#include "chrome/browser/web_applications/web_app_registry_update.h"
#include "chrome/browser/web_applications/web_app_sync_bridge.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/webapps/browser/install_result_code.h"
#include "components/webapps/common/web_app_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_features.h"
#include "ash/constants/ash_switches.h"
#include "base/test/scoped_command_line.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_manager.h"
#include "chromeos/ash/components/standalone_browser/feature_refs.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_names.h"
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/policy/system_features_disable_list_policy_handler.h"
#include "components/policy/core/common/policy_pref_names.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_WIN)
#include "base/base_paths_win.h"
#include "base/test/scoped_path_override.h"
#endif  // BUILDFLAG(IS_WIN)

namespace web_app {

namespace {

const char kWebAppSettingWithDefaultConfiguration[] =;

const char kDefaultFallbackAppName[] =;

constexpr char kWindowedUrl[] =;
constexpr char kTabbedUrl[] =;
constexpr char kNoContainerUrl[] =;

const char kDefaultCustomAppName[] =;
constexpr char kDefaultCustomIconUrl[] =;
constexpr char kUnsecureIconUrl[] =;
constexpr char kDefaultCustomIconHash[] =;

base::Value::Dict GetWindowedItem() {}

ExternalInstallOptions GetWindowedInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetTabbedItem() {}

ExternalInstallOptions GetTabbedInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetNoContainerItem() {}

ExternalInstallOptions GetNoContainerInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetCreateDesktopShortcutDefaultItem() {}

ExternalInstallOptions GetCreateDesktopShortcutDefaultInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetCreateDesktopShortcutFalseItem() {}

ExternalInstallOptions GetCreateDesktopShortcutFalseInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetCreateDesktopShortcutTrueItem() {}

ExternalInstallOptions GetCreateDesktopShortcutTrueInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

class MockAppRegistrarObserver : public WebAppRegistrarObserver {};

base::Value::Dict GetFallbackAppNameItem() {}

ExternalInstallOptions GetFallbackAppNameInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetCustomAppNameItem(std::string name) {}

ExternalInstallOptions GetCustomAppNameInstallOptions(
    std::string name,
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

base::Value::Dict GetCustomAppIconItem(bool secure = true) {}

ExternalInstallOptions GetCustomAppIconInstallOptions(
    PlaceholderResolutionBehavior placeholder_resolution_behavior =
        PlaceholderResolutionBehavior::kClose) {}

void SetWebAppSettingsListPref(Profile* profile, const std::string_view pref) {}

void SetWebAppInstallForceListPref(Profile* profile,
                                   const std::string_view pref) {}

}  // namespace

class WebAppPolicyManagerTestBase : public ChromeRenderViewHostTestHarness {};

class WebAppPolicyManagerTest : public WebAppPolicyManagerTestBase,
                                public testing::WithParamInterface<bool> {};

TEST_P(WebAppPolicyManagerTest, NoPrefValues) {}

TEST_P(WebAppPolicyManagerTest, NoForceInstalledApps) {}

TEST_P(WebAppPolicyManagerTest, NoWebAppSettings) {}

TEST_P(WebAppPolicyManagerTest, WebAppSettingsInvalidDefaultConfiguration) {}

TEST_P(WebAppPolicyManagerTest,
       WebAppSettingsInvalidDefaultConfigurationWithValidAppPolicy) {}

TEST_P(WebAppPolicyManagerTest, WebAppSettingsNoDefaultConfiguration) {}

TEST_P(WebAppPolicyManagerTest, WebAppSettingsWithDefaultConfiguration) {}

TEST_P(WebAppPolicyManagerTest, TwoForceInstalledApps) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithNoDefaultLaunchContainer) {}

TEST_P(WebAppPolicyManagerTest,
       ForceInstallAppWithDefaultCreateDesktopShortcut) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCreateDesktopShortcut) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithFallbackAppName) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppIcon) {}

// If the custom icon URL is not https, the icon should be ignored.
TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithUnsecureCustomAppIcon) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppName) {}

TEST_P(WebAppPolicyManagerTest, ForceInstallAppWithCustomAppNameRefresh) {}

TEST_P(WebAppPolicyManagerTest, DynamicRefresh) {}

TEST_P(WebAppPolicyManagerTest, UninstallAppInstalledInPreviousSession) {}

// Tests that we correctly uninstall an app that we installed in the same
// session.
TEST_P(WebAppPolicyManagerTest, UninstallAppInstalledInCurrentSession) {}

// Tests that we correctly reinstall a placeholder app.
TEST_P(WebAppPolicyManagerTest, ReinstallPlaceholderAppSuccess) {}

TEST_P(WebAppPolicyManagerTest, DoNotReinstallIfNotPlaceholder) {}

// Tests that we correctly reinstall a placeholder app when the placeholder
// is using a fallback name.
TEST_P(WebAppPolicyManagerTest, ReinstallPlaceholderAppWithFallbackAppName) {}

TEST_P(WebAppPolicyManagerTest, TryToInexistentPlaceholderApp) {}

TEST_P(WebAppPolicyManagerTest, SayRefreshTwoTimesQuickly) {}

TEST_P(WebAppPolicyManagerTest, InstallResultHistogram) {}

TEST_P(WebAppPolicyManagerTest, InvalidUrlParsingSkipped) {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_P(WebAppPolicyManagerTest, DisableSystemWebApps) {
  auto disabled_apps = policy_manager().GetDisabledSystemWebApps();
  EXPECT_TRUE(disabled_apps.empty());

  // Add supported system web apps to system features disable list policy.
  testing_local_state_.Get()->SetUserPref(
      policy::policy_prefs::kSystemFeaturesDisableList,
      base::Value::List()
          .Append(static_cast<int>(policy::SystemFeature::kCamera))
          .Append(static_cast<int>(policy::SystemFeature::kOsSettings))
          .Append(static_cast<int>(policy::SystemFeature::kScanning))
          .Append(static_cast<int>(policy::SystemFeature::kExplore))
          .Append(static_cast<int>(policy::SystemFeature::kCrosh))
          .Append(static_cast<int>(policy::SystemFeature::kTerminal))
          .Append(static_cast<int>(policy::SystemFeature::kGallery))
          .Append(static_cast<int>(policy::SystemFeature::kPrintJobs))
          .Append(static_cast<int>(policy::SystemFeature::kKeyShortcuts))
          .Append(static_cast<int>(policy::SystemFeature::kRecorder)));
  base::RunLoop().RunUntilIdle();

  const std::set<ash::SystemWebAppType> expected_disabled_apps{
      ash::SystemWebAppType::CAMERA,
      ash::SystemWebAppType::SETTINGS,
      ash::SystemWebAppType::SCANNING,
      ash::SystemWebAppType::HELP,
      ash::SystemWebAppType::CROSH,
      ash::SystemWebAppType::TERMINAL,
      ash::SystemWebAppType::MEDIA,
      ash::SystemWebAppType::PRINT_MANAGEMENT,
      ash::SystemWebAppType::SHORTCUT_CUSTOMIZATION,
      ash::SystemWebAppType::RECORDER};

  disabled_apps = policy_manager().GetDisabledSystemWebApps();
  EXPECT_EQ(disabled_apps, expected_disabled_apps);

  // Default disable mode is blocked.
  EXPECT_FALSE(policy_manager().IsDisabledAppsModeHidden());
  // Set disable mode to hidden.
  testing_local_state_.Get()->SetUserPref(
      policy::policy_prefs::kSystemFeaturesDisableMode,
      base::Value(policy::kHiddenDisableMode));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(policy_manager().IsDisabledAppsModeHidden());
}
#endif  // BUILDFLAG(IS_CHROMEOS_ASH)

TEST_P(WebAppPolicyManagerTest, WebAppSettingsDynamicRefresh) {}

TEST_P(WebAppPolicyManagerTest,
       WebAppSettingsApplyToExistingForceInstalledApp) {}

TEST_P(WebAppPolicyManagerTest, WebAppSettingsForceInstallNewApps) {}

INSTANTIATE_TEST_SUITE_P();

class WebAppPolicyManagerPreventCloseTest
    : public WebAppPolicyManagerTestBase,
      public testing::WithParamInterface<
          std::tuple<bool /*prevent_close_enabled*/,
                     bool /*run_on_os_login_enabled*/>> {};

TEST_P(WebAppPolicyManagerPreventCloseTest, WebAppSettingsPreventClose) {}

INSTANTIATE_TEST_SUITE_P();

class WebAppPolicyForceUnregistrationTest : public WebAppTest {};

TEST_F(WebAppPolicyForceUnregistrationTest,
       RefreshPolicyTrueRemovesOsIntegration) {}

TEST_F(WebAppPolicyForceUnregistrationTest,
       RefreshPolicyFalseDoesNotRemovesOsIntegration) {}

TEST_F(WebAppPolicyForceUnregistrationTest,
       OtherPoliciesDoNotAffectOsIntegration) {}

TEST_F(WebAppPolicyForceUnregistrationTest,
       ManifestWildcardDoNotAffectOsIntegration) {}

// Do not call GTEST_SKIP() explicitly here since we do not perform any OS
// integration in this test, and we just verify that the policy itself does not
// work gracefully instead of crashing.
TEST_F(WebAppPolicyForceUnregistrationTest,
       ManifestIdDoesNotExistDoesNotCrash) {}

TEST_F(WebAppPolicyForceUnregistrationTest,
       MultiAppOsIntegrationRemovalBothCorrect) {}

TEST_F(WebAppPolicyForceUnregistrationTest,
       MultiAppOsIntegrationRemovalOneCorrect) {}
}  // namespace web_app