summaryrefslogtreecommitdiffstats
path: root/chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc')
-rw-r--r--chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc1092
1 files changed, 1092 insertions, 0 deletions
diff --git a/chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc b/chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc
new file mode 100644
index 00000000000..cea69022f4e
--- /dev/null
+++ b/chromium/components/policy/core/browser/configuration_policy_handler_unittest.cc
@@ -0,0 +1,1092 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/policy/core/browser/configuration_policy_handler.h"
+
+#include <memory>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/check.h"
+#include "base/json/json_reader.h"
+#include "base/values.h"
+#include "components/policy/core/browser/configuration_policy_handler_parameters.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/core/common/schema.h"
+#include "components/prefs/pref_value_map.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace {
+
+const char kTestPolicy[] = "unit_test.test_policy";
+const char kTestPref[] = "unit_test.test_pref";
+const char kPolicyName[] = "PolicyForTesting";
+
+constexpr char kValidationSchemaJson[] = R"(
+ {
+ "type": "object",
+ "properties": {
+ "PolicyForTesting": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "movie": { "type": "string" },
+ "min_age": { "type": "integer" }
+ }
+ }
+ }
+ }
+ })";
+
+constexpr char kPolicyMapJsonValid[] = R"(
+ {
+ "PolicyForTesting": [
+ "{ \"movie\": \"Talking Animals\", \"min_age\": 0, }",
+ "{ \"movie\": \"Five Cowboys\", \"min_age\": 12, }",
+ "{ \"movie\": \"Scary Horrors\", \"min_age\": 16, }",
+ ]
+ })";
+
+constexpr char kPolicyMapJsonInvalid[] = R"(
+ {
+ "PolicyForTesting": [
+ "{ \"movie\": \"Talking Animals\", \"min_age\": \"G\", }",
+ "{ \"movie\": \"Five Cowboys\", \"min_age\": \"PG\", }",
+ "{ \"movie\": \"Scary Horrors\", \"min_age\": \"R\", }",
+ ]
+ })";
+
+constexpr char kPolicyMapJsonUnparsable[] = R"(
+ {
+ "PolicyForTesting": [
+ "Talking Animals is rated G",
+ "Five Cowboys is rated PG",
+ "Scary Horrors is rated R",
+ ]
+ })";
+
+constexpr char kPolicyMapJsonWrongTypes[] = R"(
+ {
+ "PolicyForTesting": [ 1, 2, 3, ]
+ })";
+
+constexpr char kPolicyMapJsonWrongRootType[] = R"(
+ {
+ "PolicyForTesting": "test",
+ })";
+
+void GetIntegerTypeMap(
+ std::vector<std::unique_ptr<StringMappingListPolicyHandler::MappingEntry>>*
+ result) {
+ result->push_back(
+ std::make_unique<StringMappingListPolicyHandler::MappingEntry>(
+ "one", std::make_unique<base::Value>(1)));
+ result->push_back(
+ std::make_unique<StringMappingListPolicyHandler::MappingEntry>(
+ "two", std::make_unique<base::Value>(2)));
+}
+
+class TestSchemaValidatingPolicyHandler : public SchemaValidatingPolicyHandler {
+ public:
+ TestSchemaValidatingPolicyHandler(const Schema& schema,
+ SchemaOnErrorStrategy strategy)
+ : SchemaValidatingPolicyHandler(kPolicyName, schema, strategy) {}
+ ~TestSchemaValidatingPolicyHandler() override {}
+
+ void ApplyPolicySettings(const policy::PolicyMap&, PrefValueMap*) override {}
+
+ bool CheckAndGetValueForTest(const PolicyMap& policies,
+ std::unique_ptr<base::Value>* value) {
+ return SchemaValidatingPolicyHandler::CheckAndGetValue(policies, nullptr,
+ value);
+ }
+};
+
+// Simple implementation of ListPolicyHandler that assumes a string list and
+// sets the kTestPref pref to the filtered list.
+class StringListPolicyHandler : public ListPolicyHandler {
+ public:
+ StringListPolicyHandler(const char* policy_name, const char* pref_path)
+ : ListPolicyHandler(policy_name, base::Value::Type::STRING) {}
+
+ protected:
+ void ApplyList(base::Value filtered_list, PrefValueMap* prefs) override {
+ DCHECK(filtered_list.is_list());
+ prefs->SetValue(kTestPref, std::move(filtered_list));
+ }
+};
+
+std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler>
+JsonStringHandlerForTesting() {
+ std::string error;
+ Schema validation_schema = Schema::Parse(kValidationSchemaJson, &error);
+ return std::make_unique<SimpleJsonStringSchemaValidatingPolicyHandler>(
+ kPolicyName, kTestPref, validation_schema,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED);
+}
+
+} // namespace
+
+TEST(ListPolicyHandlerTest, CheckPolicySettings) {
+ base::Value list(base::Value::Type::LIST);
+ base::Value dict(base::Value::Type::DICTIONARY);
+ policy::PolicyMap policy_map;
+ policy::PolicyErrorMap errors;
+ StringListPolicyHandler handler(kTestPolicy, kTestPref);
+
+ // No policy set is OK.
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ errors.Clear();
+
+ // Not a list is not OK.
+ policy_map.Set(kTestPolicy, policy::POLICY_LEVEL_MANDATORY,
+ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+ dict.Clone(), nullptr);
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ // Empty list is OK.
+ policy_map.Set(kTestPolicy, policy::POLICY_LEVEL_MANDATORY,
+ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+ list.Clone(), nullptr);
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ errors.Clear();
+
+ // List with an int is OK, but error is added.
+ list.Append(175); // hex af, 255's sake.
+ policy_map.Set(kTestPolicy, policy::POLICY_LEVEL_MANDATORY,
+ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+ list.Clone(), nullptr);
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ list.ClearList();
+ errors.Clear();
+
+ // List with a string is OK.
+ list.Append("any_string");
+ policy_map.Set(kTestPolicy, policy::POLICY_LEVEL_MANDATORY,
+ policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
+ list.Clone(), nullptr);
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ errors.Clear();
+}
+
+TEST(StringListPolicyHandlerTest, ApplyPolicySettings) {
+ base::Value list(base::Value::Type::LIST);
+ base::Value expected(base::Value::Type::LIST);
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ base::Value* value;
+ StringListPolicyHandler handler(kTestPolicy, kTestPref);
+
+ // Empty list applies as empty list.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+
+ // List with any string applies that string.
+ list.Append("any_string");
+ expected.Append("any_string");
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+ list.ClearList();
+ expected.ClearList();
+
+ // List with a string and an integer filters out the integer.
+ list.Append("any_string");
+ list.Append(42);
+ expected.Append("any_string");
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+ list.ClearList();
+ expected.ClearList();
+}
+
+TEST(StringToIntEnumListPolicyHandlerTest, CheckPolicySettings) {
+ base::Value list(base::Value::Type::LIST);
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+ StringMappingListPolicyHandler handler(
+ kTestPolicy, kTestPref, base::BindRepeating(GetIntegerTypeMap));
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ list.Append("one");
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ list.Append("invalid");
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ EXPECT_FALSE(errors.GetErrors(kTestPolicy).empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("no list"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ EXPECT_FALSE(errors.GetErrors(kTestPolicy).empty());
+}
+
+TEST(StringMappingListPolicyHandlerTest, ApplyPolicySettings) {
+ base::Value list(base::Value::Type::LIST);
+ base::Value expected(base::Value::Type::LIST);
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ base::Value* value;
+ StringMappingListPolicyHandler handler(
+ kTestPolicy, kTestPref, base::BindRepeating(GetIntegerTypeMap));
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+
+ list.Append("two");
+ expected.Append(2);
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+
+ list.Append("invalid");
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.Clone(), nullptr);
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(expected, *value);
+}
+
+TEST(IntRangePolicyHandler, CheckPolicySettingsClamp) {
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntRangePolicyHandler handler(kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are not rejected.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ // Check that values lying outside the accepted range are not rejected
+ // (because clamping is enabled) but do yield a warning message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ // Check that an entirely invalid value is rejected and yields an error
+ // message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("invalid"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(IntRangePolicyHandler, CheckPolicySettingsDontClamp) {
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntRangePolicyHandler handler(kTestPolicy, kTestPref, 0, 10, false);
+
+ // Check that values lying in the accepted range are not rejected.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ // Check that values lying outside the accepted range are rejected and yield
+ // an error message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ // Check that an entirely invalid value is rejected and yields an error
+ // message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("invalid"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(IntRangePolicyHandler, ApplyPolicySettingsClamp) {
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ std::unique_ptr<base::Value> expected;
+ const base::Value* value;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntRangePolicyHandler handler(kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are written to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(5);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(10);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ // Check that values lying outside the accepted range are clamped and written
+ // to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(10);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+}
+
+TEST(IntRangePolicyHandler, ApplyPolicySettingsDontClamp) {
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ std::unique_ptr<base::Value> expected;
+ const base::Value* value;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntRangePolicyHandler handler(kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are written to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(5);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(10);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+}
+
+TEST(IntPercentageToDoublePolicyHandler, CheckPolicySettingsClamp) {
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntPercentageToDoublePolicyHandler handler(
+ kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are not rejected.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ // Check that values lying outside the accepted range are not rejected
+ // (because clamping is enabled) but do yield a warning message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ // Check that an entirely invalid value is rejected and yields an error
+ // message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("invalid"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(IntPercentageToDoublePolicyHandler, CheckPolicySettingsDontClamp) {
+ PolicyMap policy_map;
+ PolicyErrorMap errors;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntPercentageToDoublePolicyHandler handler(
+ kTestPolicy, kTestPref, 0, 10, false);
+
+ // Check that values lying in the accepted range are not rejected.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+
+ // Check that values lying outside the accepted range are rejected and yield
+ // an error message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+
+ // Check that an entirely invalid value is rejected and yields an error
+ // message.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("invalid"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(IntPercentageToDoublePolicyHandler, ApplyPolicySettingsClamp) {
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ std::unique_ptr<base::Value> expected;
+ const base::Value* value;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntPercentageToDoublePolicyHandler handler(
+ kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are written to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.05);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.1);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ // Check that values lying outside the accepted range are clamped and written
+ // to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(-5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(15), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.1);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+}
+
+TEST(IntPercentageToDoublePolicyHandler, ApplyPolicySettingsDontClamp) {
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ std::unique_ptr<base::Value> expected;
+ const base::Value* value;
+
+ // This tests needs to modify an int policy. The exact policy used and its
+ // semantics outside the test are irrelevant.
+ IntPercentageToDoublePolicyHandler handler(
+ kTestPolicy, kTestPref, 0, 10, true);
+
+ // Check that values lying in the accepted range are written to the pref.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(0), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.0);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(5), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.05);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(10), nullptr);
+ prefs.Clear();
+ handler.ApplyPolicySettings(policy_map, &prefs);
+ expected = std::make_unique<base::Value>(0.1);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+}
+
+TEST(SchemaValidatingPolicyHandlerTest, CheckAndGetValueInvalid) {
+ std::string error;
+ static const char kSchemaJson[] =
+ "{"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"OneToThree\": {"
+ " \"type\": \"integer\","
+ " \"minimum\": 1,"
+ " \"maximum\": 3"
+ " },"
+ " \"Colors\": {"
+ " \"type\": \"string\","
+ " \"enum\": [ \"Red\", \"Green\", \"Blue\" ]"
+ " }"
+ " }"
+ "}";
+ Schema schema = Schema::Parse(kSchemaJson, &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ static const char kPolicyMapJson[] =
+ "{"
+ " \"PolicyForTesting\": {"
+ " \"OneToThree\": 2,"
+ " \"Colors\": \"White\""
+ " }"
+ "}";
+ base::JSONReader::ValueWithError parsed_json_or_error =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJson, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json_or_error.value) << parsed_json_or_error.error_message;
+
+ base::Value& parsed_json = parsed_json_or_error.value.value();
+ ASSERT_TRUE(parsed_json.is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(&base::Value::AsDictionaryValue(parsed_json),
+ POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD);
+
+ TestSchemaValidatingPolicyHandler handler(schema, SCHEMA_ALLOW_UNKNOWN);
+ std::unique_ptr<base::Value> output_value;
+ EXPECT_FALSE(handler.CheckAndGetValueForTest(policy_map, &output_value));
+}
+
+TEST(SchemaValidatingPolicyHandlerTest, CheckAndGetValueUnknown) {
+ std::string error;
+ static const char kSchemaJson[] =
+ "{"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"OneToThree\": {"
+ " \"type\": \"integer\","
+ " \"minimum\": 1,"
+ " \"maximum\": 3"
+ " },"
+ " \"Colors\": {"
+ " \"type\": \"string\","
+ " \"enum\": [ \"Red\", \"Green\", \"Blue\" ]"
+ " }"
+ " }"
+ "}";
+ Schema schema = Schema::Parse(kSchemaJson, &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ static const char kPolicyMapJson[] =
+ "{"
+ " \"PolicyForTesting\": {"
+ " \"OneToThree\": 2,"
+ " \"Apples\": \"Red\""
+ " }"
+ "}";
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJson, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ TestSchemaValidatingPolicyHandler handler(schema, SCHEMA_ALLOW_UNKNOWN);
+ std::unique_ptr<base::Value> output_value;
+ ASSERT_TRUE(handler.CheckAndGetValueForTest(policy_map, &output_value));
+ ASSERT_TRUE(output_value);
+ ASSERT_TRUE(output_value->is_dict());
+
+ // Test that CheckAndGetValue() actually dropped unknown properties.
+ absl::optional<int> one_two_three = output_value->FindIntKey("OneToThree");
+ ASSERT_TRUE(one_two_three);
+ int int_value = one_two_three.value();
+ EXPECT_EQ(2, int_value);
+ EXPECT_FALSE(output_value->FindKey("Apples"));
+}
+
+TEST(SimpleSchemaValidatingPolicyHandlerTest, CheckAndGetValue) {
+ static const char kSchemaJson[] =
+ "{"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"PolicyForTesting\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"OneToThree\": {"
+ " \"type\": \"integer\","
+ " \"minimum\": 1,"
+ " \"maximum\": 3"
+ " },"
+ " \"Colors\": {"
+ " \"type\": \"string\","
+ " \"enum\": [ \"Red\", \"Green\", \"Blue\" ]"
+ " }"
+ " }"
+ " }"
+ " }"
+ "}";
+ std::string error;
+ Schema schema = Schema::Parse(kSchemaJson, &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ static const char kPolicyMapJson[] =
+ "{"
+ " \"PolicyForTesting\": {"
+ " \"OneToThree\": 2,"
+ " \"Colors\": \"Green\""
+ " }"
+ "}";
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJson, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map_recommended;
+ policy_map_recommended.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_RECOMMENDED, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ PolicyMap policy_map_mandatory;
+ policy_map_mandatory.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ SimpleSchemaValidatingPolicyHandler handler_all(
+ kPolicyName, kTestPref, schema, SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED);
+
+ SimpleSchemaValidatingPolicyHandler handler_recommended(
+ kPolicyName, kTestPref, schema, SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_PROHIBITED);
+
+ SimpleSchemaValidatingPolicyHandler handler_mandatory(
+ kPolicyName, kTestPref, schema, SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED);
+
+ SimpleSchemaValidatingPolicyHandler handler_none(
+ kPolicyName, kTestPref, schema, SCHEMA_STRICT,
+ SimpleSchemaValidatingPolicyHandler::RECOMMENDED_PROHIBITED,
+ SimpleSchemaValidatingPolicyHandler::MANDATORY_PROHIBITED);
+
+ const base::Value* value_expected_in_pref =
+ parsed_json.value->FindPath(kPolicyName);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ EXPECT_TRUE(handler_all.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_all.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+
+ EXPECT_FALSE(
+ handler_recommended.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(
+ handler_mandatory.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_mandatory.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+
+ EXPECT_FALSE(handler_none.CheckPolicySettings(policy_map_mandatory, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(handler_all.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_all.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+
+ EXPECT_FALSE(
+ handler_mandatory.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_FALSE(errors.empty());
+ errors.Clear();
+
+ EXPECT_TRUE(
+ handler_recommended.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler_recommended.ApplyPolicySettings(policy_map_mandatory, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+
+ EXPECT_FALSE(
+ handler_none.CheckPolicySettings(policy_map_recommended, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(SimpleJsonStringSchemaValidatingPolicyHandlerTest, ValidEmbeddedJson) {
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJsonValid, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ const base::Value* value_expected_in_pref =
+ parsed_json.value->FindPath(kPolicyName);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ // This value matches the schema - handler shouldn't record any errors.
+ std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler> handler =
+ JsonStringHandlerForTesting();
+ EXPECT_TRUE(handler->CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ handler->ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+}
+
+TEST(SimpleJsonStringSchemaValidatingPolicyHandlerTest, InvalidEmbeddedJson) {
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJsonInvalid, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ const base::Value* value_expected_in_pref =
+ parsed_json.value->FindPath(kPolicyName);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ // Handler accepts JSON that doesn't match the schema, but records errors.
+ std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler> handler =
+ JsonStringHandlerForTesting();
+ EXPECT_TRUE(handler->CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ handler->ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+}
+
+TEST(SimpleJsonStringSchemaValidatingPolicyHandlerTest, UnparsableJson) {
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJsonUnparsable, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ const base::Value* value_expected_in_pref =
+ parsed_json.value->FindPath(kPolicyName);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ // Handler accepts unparsable JSON, but records errors.
+ std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler> handler =
+ JsonStringHandlerForTesting();
+ EXPECT_TRUE(handler->CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ handler->ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+}
+
+TEST(SimpleJsonStringSchemaValidatingPolicyHandlerTest, WrongType) {
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJsonWrongTypes, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ const base::Value* value_expected_in_pref =
+ parsed_json.value->FindPath(kPolicyName);
+
+ PolicyErrorMap errors;
+ PrefValueMap prefs;
+ base::Value* value_set_in_pref;
+
+ // Handler allows wrong types (not at the root), but records errors.
+ std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler> handler =
+ JsonStringHandlerForTesting();
+ EXPECT_TRUE(handler->CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ handler->ApplyPolicySettings(policy_map, &prefs);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value_set_in_pref));
+ EXPECT_EQ(*value_expected_in_pref, *value_set_in_pref);
+}
+
+TEST(SimpleJsonStringSchemaValidatingPolicyHandlerTest, WrongRootType) {
+ base::JSONReader::ValueWithError parsed_json =
+ base::JSONReader::ReadAndReturnValueWithError(
+ kPolicyMapJsonWrongRootType, base::JSON_ALLOW_TRAILING_COMMAS);
+ ASSERT_TRUE(parsed_json.value) << parsed_json.error_message;
+ ASSERT_TRUE(parsed_json.value->is_dict());
+
+ PolicyMap policy_map;
+ policy_map.LoadFrom(
+ &base::Value::AsDictionaryValue(parsed_json.value.value()),
+ POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD);
+
+ PolicyErrorMap errors;
+
+ // Handler rejects the wrong root type and records errors.
+ std::unique_ptr<SimpleJsonStringSchemaValidatingPolicyHandler> handler =
+ JsonStringHandlerForTesting();
+ EXPECT_FALSE(handler->CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+}
+
+TEST(SimpleDeprecatingPolicyHandlerTest, CheckDeprecatedUsedWhenNoNewValue) {
+ PolicyMap policy_map;
+ PrefValueMap prefs;
+ std::unique_ptr<base::Value> expected;
+ const base::Value* value;
+ PolicyErrorMap errors;
+ PolicyHandlerParameters params;
+ const char kLegacyPolicy[] = "legacy_policy";
+
+ SimpleDeprecatingPolicyHandler handler(
+ std::make_unique<SimplePolicyHandler>(kLegacyPolicy, kTestPref,
+ base::Value::Type::INTEGER),
+ std::make_unique<SimplePolicyHandler>(kTestPolicy, kTestPref,
+ base::Value::Type::INTEGER));
+
+ // Check that legacy value alone is used.
+ policy_map.Set(kLegacyPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(42), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler.ApplyPolicySettingsWithParameters(policy_map, params, &prefs);
+ expected = std::make_unique<base::Value>(42);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ // Set the new value as invalid and verify that the total result is invalid.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value("0"), nullptr);
+ errors.Clear();
+ EXPECT_FALSE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ prefs.Clear();
+
+ // Set the new value and verify that it overrides the legacy.
+ policy_map.Set(kTestPolicy, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, base::Value(1337), nullptr);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_FALSE(errors.empty());
+ prefs.Clear();
+ handler.ApplyPolicySettingsWithParameters(policy_map, params, &prefs);
+ expected = std::make_unique<base::Value>(1337);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+
+ // Erasing the legacy value should have no effect at this point.
+ policy_map.Erase(kLegacyPolicy);
+ errors.Clear();
+ EXPECT_TRUE(handler.CheckPolicySettings(policy_map, &errors));
+ EXPECT_TRUE(errors.empty());
+ prefs.Clear();
+ handler.ApplyPolicySettingsWithParameters(policy_map, params, &prefs);
+ expected = std::make_unique<base::Value>(1337);
+ EXPECT_TRUE(prefs.GetValue(kTestPref, &value));
+ EXPECT_EQ(*expected, *value);
+}
+
+} // namespace policy