blob: 3ea36bdf94870da14195918f1c02b38973ca6401 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "ash/constants/ash_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/browser/policy_pref_mapping_test.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/prefs/pref_service.h"
#include "components/variations/variations_test_utils.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/profiles/profile_helper.h"
#else
#include "components/enterprise/browser/controller/fake_browser_dm_token_storage.h"
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/toolbar_manager_test_helper_android.h"
#endif // BUILDFLAG(IS_ANDROID)
namespace policy {
const size_t kNumChunks = 8;
namespace {
base::FilePath GetTestCasePath() {
base::ScopedAllowBlockingForTesting allow_blocking;
base::FilePath path;
base::PathService::Get(chrome::DIR_TEST_DATA, &path);
return path.Append(FILE_PATH_LITERAL("policy"))
.Append(FILE_PATH_LITERAL("policy_test_cases.json"));
}
size_t GetNumChunks() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
kPolicyToPrefMappingsFilterSwitch)) {
// Run as one chunk when test filter specified.
return 1;
}
return kNumChunks;
}
} // namespace
typedef PlatformBrowserTest PolicyPrefsTestCoverageTest;
IN_PROC_BROWSER_TEST_F(PolicyPrefsTestCoverageTest, AllPoliciesHaveATestCase) {
VerifyAllPoliciesHaveATestCase(GetTestCasePath());
}
// Base class for tests that change policy.
class PolicyPrefsTest : public PlatformBrowserTest {
public:
PolicyPrefsTest() = default;
PolicyPrefsTest(const PolicyPrefsTest&) = delete;
PolicyPrefsTest& operator=(const PolicyPrefsTest&) = delete;
~PolicyPrefsTest() override = default;
protected:
void SetUpInProcessBrowserTestFixture() override {
// Some policies default value might depend on features, enforce use of
// field trial testing config to avoid having unexpected results based on
// new feature flags coming from the server (e.g. on Chrome-branded CI
// bots).
variations::EnableTestingConfig();
GetMockPolicyProvider()->SetDefaultReturns(
true /* is_initialization_complete_return */,
true /* is_first_policy_load_complete_return */);
BrowserPolicyConnector::SetPolicyProviderForTesting(
GetMockPolicyProvider());
}
void TearDownOnMainThread() override { ClearProviderPolicy(); }
void ClearProviderPolicy() {
GetMockPolicyProvider()->UpdateChromePolicy(PolicyMap());
base::RunLoop().RunUntilIdle();
}
MockConfigurationPolicyProvider* GetMockPolicyProvider() {
#if BUILDFLAG(IS_ANDROID)
// Trying to delete the mock provider on Android leads to a cascade of
// crashes due to ChromeBrowserPolicyConnector and ProfileImpl not being
// deleted. Those crashes are caused by checks that ensure that observer
// lists of ConfigurationPolicyProvider are always empty on destruction.
// On Desktop, removal of observers from those lists is triggered by the
// destructors of the classes above, but those same destructors are never
// invoked on Android.
static base::NoDestructor<
testing::NiceMock<MockConfigurationPolicyProvider>>
provider;
return provider.get();
#else
// On non-Android platforms, the mock provider cleanup will be triggered
// by ChromeBrowserPolicyConnector and ProfileImpl destructors. Thus it's
// safe to define a provider object that is deleted on scope destruction.
return &provider_;
#endif // BUILDFLAG(IS_ANDROID)
}
#if !BUILDFLAG(IS_ANDROID)
testing::NiceMock<MockConfigurationPolicyProvider> provider_;
#endif // !BUILDFLAG(IS_ANDROID)
};
// Splits the test cases into `kNumChunks` and the testing parameter determines
// the index of the current chunk. This prevents the test from timing out when
// testing all test cases in a single browser test.
class ChunkedPolicyPrefsTest : public PolicyPrefsTest,
public ::testing::WithParamInterface<size_t> {
public:
ChunkedPolicyPrefsTest();
ChunkedPolicyPrefsTest(const ChunkedPolicyPrefsTest&) = delete;
ChunkedPolicyPrefsTest& operator=(const ChunkedPolicyPrefsTest&) = delete;
~ChunkedPolicyPrefsTest() override = default;
protected:
PrefMappingChunkInfo chunk_info_{GetParam(), GetNumChunks()};
};
ChunkedPolicyPrefsTest::ChunkedPolicyPrefsTest() {
#if BUILDFLAG(IS_ANDROID)
// Skips recreating the Android activity when homepage settings are changed.
// This happens when the feature chrome::android::kStartSurfaceAndroid is
// enabled.
toolbar_manager::setSkipRecreateForTesting(true);
#endif // BUILDFLAG(IS_ANDROID)
}
// Verifies that policies make their corresponding preferences become managed,
// and that the user can't override that setting.
// README SHERIFFs: This test encapsulates a whole suite of individual browser
// tests for performance reasons and therefore has an increased chance of
// failure/flakiness.
// IMPORTANT: Please add hendrich@chromium.org on any related bugs when
// disabling this test.
IN_PROC_BROWSER_TEST_P(ChunkedPolicyPrefsTest, PolicyToPrefsMapping) {
#if !BUILDFLAG(IS_CHROMEOS_ASH)
policy::FakeBrowserDMTokenStorage storage;
policy::BrowserDMTokenStorage::SetForTesting(&storage);
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)
PrefService* local_state = g_browser_process->local_state();
PrefService* user_prefs = ProfileManager::GetLastUsedProfileIfLoaded()
->GetOriginalProfile()
->GetPrefs();
VerifyPolicyToPrefMappings(GetTestCasePath(), local_state, user_prefs,
/* signin_profile_prefs= */ nullptr,
GetMockPolicyProvider(), &chunk_info_);
}
INSTANTIATE_TEST_SUITE_P(Chunked,
ChunkedPolicyPrefsTest,
::testing::Range(/* start= */ static_cast<size_t>(0),
/* end= */ GetNumChunks()));
#if BUILDFLAG(IS_CHROMEOS_ASH)
// Class used to check policy to pref mappings for policies that are mapped into
// the sign-in profile (usually via LoginProfilePolicyProvider).
class SigninPolicyPrefsTest : public PolicyPrefsTest {
public:
SigninPolicyPrefsTest() = default;
SigninPolicyPrefsTest(const SigninPolicyPrefsTest&) = delete;
SigninPolicyPrefsTest& operator=(const SigninPolicyPrefsTest&) = delete;
~SigninPolicyPrefsTest() override = default;
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
PolicyPrefsTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(ash::switches::kLoginManager);
command_line->AppendSwitch(ash::switches::kForceLoginManagerInTests);
}
};
IN_PROC_BROWSER_TEST_F(SigninPolicyPrefsTest, PolicyToPrefsMapping) {
PrefService* signin_profile_prefs =
ash::ProfileHelper::GetSigninProfile()->GetPrefs();
// Only checking signin_profile_prefs here since |local_state| is already
// checked by PolicyPrefsTest.PolicyToPrefsMapping test.
VerifyPolicyToPrefMappings(GetTestCasePath(), /* local_state= */ nullptr,
/* user_prefs= */ nullptr, signin_profile_prefs,
GetMockPolicyProvider());
}
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// For WebUI integration tests, see cr_policy_indicator_tests.js and
// cr_policy_pref_indicator_tests.js.
} // namespace policy