| // Copyright 2013 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/sync/service/sync_policy_handler.h" | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "base/test/scoped_feature_list.h" | |
| #include "base/values.h" | |
| #include "components/policy/core/browser/policy_error_map.h" | |
| #include "components/policy/core/common/policy_map.h" | |
| #include "components/policy/core/common/policy_types.h" | |
| #include "components/policy/policy_constants.h" | |
| #include "components/prefs/pref_value_map.h" | |
| #include "components/sync/base/features.h" | |
| #include "components/sync/base/pref_names.h" | |
| #include "testing/gtest/include/gtest/gtest.h" | |
| namespace syncer { | |
| namespace { | |
| TEST(SyncPolicyHandlerTest, Default) { | |
| policy::PolicyMap policy; | |
| SyncPolicyHandler handler; | |
| PrefValueMap prefs; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| EXPECT_FALSE(prefs.GetValue(prefs::internal::kSyncManaged, nullptr)); | |
| } | |
| TEST(SyncPolicyHandlerTest, Enabled) { | |
| policy::PolicyMap policy; | |
| policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, | |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, | |
| base::Value(false), nullptr); | |
| SyncPolicyHandler handler; | |
| PrefValueMap prefs; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Enabling Sync should not set the pref. | |
| EXPECT_FALSE(prefs.GetValue(prefs::internal::kSyncManaged, nullptr)); | |
| } | |
| TEST(SyncPolicyHandlerTest, Disabled) { | |
| policy::PolicyMap policy; | |
| policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, | |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, | |
| base::Value(true), nullptr); | |
| SyncPolicyHandler handler; | |
| PrefValueMap prefs; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Sync should be flagged as managed. | |
| const base::Value* value = nullptr; | |
| EXPECT_TRUE(prefs.GetValue(prefs::internal::kSyncManaged, &value)); | |
| ASSERT_TRUE(value); | |
| EXPECT_TRUE(value->GetBool()); | |
| } | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabled) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncBookmarks, true); | |
| prefs.SetBoolean(prefs::internal::kSyncReadingList, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPreferences, true); | |
| prefs.SetBoolean(prefs::internal::kSyncAutofill, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPayments, true); | |
| prefs.SetBoolean(prefs::internal::kSyncThemes, true); | |
| // Create a policy that disables some types. | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue() | |
| .Append("bookmarks") | |
| .Append("readingList") | |
| .Append("preferences"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Prefs in the policy should be disabled. | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncBookmarks, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncReadingList, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPreferences, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| // Prefs that are not part of the policy are still enabled. | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncAutofill, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPayments, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncThemes, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| } | |
| // Same as SyncTypesListDisabled but tests autofill specifically. | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabledAutofill) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncBookmarks, true); | |
| prefs.SetBoolean(prefs::internal::kSyncReadingList, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPreferences, true); | |
| prefs.SetBoolean(prefs::internal::kSyncAutofill, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPayments, true); | |
| prefs.SetBoolean(prefs::internal::kSyncThemes, true); | |
| // Create a policy that disables autofill. | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue().Append("autofill"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Prefs in the policy should be disabled. | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncAutofill, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPayments, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| // Prefs that are not part of the policy are still enabled. | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncBookmarks, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncReadingList, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPreferences, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncThemes, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| } | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabled_TabsAndSavedTabGroups) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncTabs, true); | |
| prefs.SetBoolean(prefs::internal::kSyncSavedTabGroups, true); | |
| // Create a policy that disables tabs. | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue().Append("tabs"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Both tabs and saved tab groups should be disabled. | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncTabs, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncSavedTabGroups, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| } | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabledInvalidType) { | |
| policy::PolicyMap policy; | |
| policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, | |
| policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, | |
| base::Value(true), nullptr); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, base::Value("string_value"), nullptr); | |
| SyncPolicyHandler handler; | |
| PrefValueMap prefs; | |
| policy::PolicyErrorMap errors; | |
| // An invalid type for SyncTypesListDisabled should produce an error message | |
| // but still return true so the primary SyncDisabled policy is applied. | |
| EXPECT_TRUE(handler.CheckPolicySettings(policy, &errors)); | |
| std::vector<policy::PolicyErrorMap::Data> error_data = | |
| errors.GetErrors(policy::key::kSyncTypesListDisabled); | |
| ASSERT_EQ(error_data.size(), 1u); | |
| EXPECT_EQ(error_data[0].level, policy::PolicyMap::MessageType::kError); | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| bool sync_managed = false; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncManaged, &sync_managed)); | |
| EXPECT_TRUE(sync_managed); | |
| } | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabledInvalidEntry) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncBookmarks, true); | |
| prefs.SetBoolean(prefs::internal::kSyncReadingList, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPreferences, true); | |
| prefs.SetBoolean(prefs::internal::kSyncAutofill, true); | |
| // Create a policy that disables some types, but also contains a non-string | |
| // entry in the list. | |
| policy::PolicyMap policy; | |
| auto disabled_types = | |
| base::ListValue().Append("bookmarks").Append(123).Append("preferences"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| // The invalid value should have produced a warning message. | |
| policy::PolicyErrorMap errors; | |
| handler.CheckPolicySettings(policy, &errors); | |
| std::vector<policy::PolicyErrorMap::Data> error_data = | |
| errors.GetErrors(policy::key::kSyncTypesListDisabled); | |
| ASSERT_EQ(error_data.size(), 1u); | |
| EXPECT_EQ(error_data[0].level, policy::PolicyMap::MessageType::kWarning); | |
| // But the valid entries should still have been applied. | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncBookmarks, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPreferences, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncAutofill, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncReadingList, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| } | |
| TEST(SyncPolicyHandlerTest, SyncTypesListDisabledUnknownEntry) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncBookmarks, true); | |
| prefs.SetBoolean(prefs::internal::kSyncReadingList, true); | |
| prefs.SetBoolean(prefs::internal::kSyncPreferences, true); | |
| prefs.SetBoolean(prefs::internal::kSyncAutofill, true); | |
| // Create a policy that disables some types, but also contains an unrecognized | |
| // value (in practice, this could be a previous data type that was deprecated, | |
| // or a new data type that this version of the browser doesn't know about yet, | |
| // or just a typo in the configuration). | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue() | |
| .Append("bookmarks") | |
| .Append("nonexistent") | |
| .Append("preferences"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| // The invalid value should have produced a warning message. | |
| policy::PolicyErrorMap errors; | |
| handler.CheckPolicySettings(policy, &errors); | |
| std::vector<policy::PolicyErrorMap::Data> error_data = | |
| errors.GetErrors(policy::key::kSyncTypesListDisabled); | |
| ASSERT_EQ(error_data.size(), 1u); | |
| EXPECT_NE(error_data[0].message.find(u"nonexistent"), std::string::npos); | |
| EXPECT_EQ(error_data[0].level, policy::PolicyMap::MessageType::kWarning); | |
| // But the valid entries should still have been applied. | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncBookmarks, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncPreferences, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncAutofill, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncReadingList, &enabled)); | |
| EXPECT_TRUE(enabled); | |
| } | |
| #if BUILDFLAG(IS_CHROMEOS) | |
| TEST(SyncPolicyHandlerOsTest, SyncTypesListDisabled_OsTypes) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncOsApps, true); | |
| prefs.SetBoolean(prefs::internal::kSyncOsPreferences, true); | |
| prefs.SetBoolean(prefs::internal::kSyncWifiConfigurations, true); | |
| // Create a policy that disables the types. | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue() | |
| .Append("osApps") | |
| .Append("osPreferences") | |
| .Append("osWifiConfigurations"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // Prefs in the policy are disabled. | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncOsApps, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncOsPreferences, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE( | |
| prefs.GetBoolean(prefs::internal::kSyncWifiConfigurations, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| } | |
| TEST(SyncPolicyHandlerOsTest, SyncTypesListDisabled_MigratedTypes) { | |
| // Start with prefs enabled so we can sense that they have changed. | |
| PrefValueMap prefs; | |
| prefs.SetBoolean(prefs::internal::kSyncOsApps, true); | |
| prefs.SetBoolean(prefs::internal::kSyncOsPreferences, true); | |
| // Create a policy that disables the types, but using the original browser | |
| // policy names from before the SplitSettingsSync launch. | |
| policy::PolicyMap policy; | |
| auto disabled_types = base::ListValue() | |
| .Append("apps") | |
| .Append("wifiConfigurations") | |
| .Append("preferences"); | |
| policy.Set(policy::key::kSyncTypesListDisabled, | |
| policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, | |
| policy::POLICY_SOURCE_CLOUD, | |
| base::Value(std::move(disabled_types)), nullptr); | |
| SyncPolicyHandler handler; | |
| handler.ApplyPolicySettings(policy, &prefs); | |
| // The equivalent OS types are disabled. | |
| bool enabled; | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncOsApps, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE( | |
| prefs.GetBoolean(prefs::internal::kSyncWifiConfigurations, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| ASSERT_TRUE(prefs.GetBoolean(prefs::internal::kSyncOsPreferences, &enabled)); | |
| EXPECT_FALSE(enabled); | |
| } | |
| #endif // BUILDFLAG(IS_CHROMEOS) | |
| } // namespace | |
| } // namespace syncer |