summaryrefslogtreecommitdiff
path: root/components/policy/core/common/schema_map_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'components/policy/core/common/schema_map_unittest.cc')
-rw-r--r--components/policy/core/common/schema_map_unittest.cc308
1 files changed, 308 insertions, 0 deletions
diff --git a/components/policy/core/common/schema_map_unittest.cc b/components/policy/core/common/schema_map_unittest.cc
new file mode 100644
index 0000000000..96916e5cc1
--- /dev/null
+++ b/components/policy/core/common/schema_map_unittest.cc
@@ -0,0 +1,308 @@
+// Copyright 2013 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/common/schema_map.h"
+#include <memory>
+
+#include "base/memory/weak_ptr.h"
+#include "base/values.h"
+#include "components/policy/core/common/external_data_fetcher.h"
+#include "components/policy/core/common/external_data_manager.h"
+#include "components/policy/core/common/policy_bundle.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 "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace {
+
+const char kTestSchema[] =
+ "{"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"string\": { \"type\": \"string\" },"
+ " \"integer\": { \"type\": \"integer\" },"
+ " \"boolean\": { \"type\": \"boolean\" },"
+ " \"null\": { \"type\": \"null\" },"
+ " \"double\": { \"type\": \"number\" },"
+ " \"list\": {"
+ " \"type\": \"array\","
+ " \"items\": { \"type\": \"string\" }"
+ " },"
+ " \"object\": {"
+ " \"type\": \"object\","
+ " \"properties\": {"
+ " \"a\": { \"type\": \"string\" },"
+ " \"b\": { \"type\": \"integer\" }"
+ " }"
+ " }"
+ " }"
+ "}";
+
+} // namespace
+
+class SchemaMapTest : public testing::Test {
+ protected:
+ Schema CreateTestSchema() {
+ std::string error;
+ Schema schema = Schema::Parse(kTestSchema, &error);
+ if (!schema.valid())
+ ADD_FAILURE() << error;
+ return schema;
+ }
+
+ scoped_refptr<SchemaMap> CreateTestMap() {
+ Schema schema = CreateTestSchema();
+ ComponentMap component_map;
+ component_map["extension-1"] = schema;
+ component_map["extension-2"] = schema;
+ component_map["legacy-extension"] = Schema();
+
+ DomainMap domain_map;
+ domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
+
+ return new SchemaMap(domain_map);
+ }
+};
+
+TEST_F(SchemaMapTest, Empty) {
+ scoped_refptr<SchemaMap> map = new SchemaMap();
+ EXPECT_TRUE(map->GetDomains().empty());
+ EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_CHROME));
+ EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_EXTENSIONS));
+ EXPECT_FALSE(map->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
+ EXPECT_FALSE(map->HasComponents());
+}
+
+TEST_F(SchemaMapTest, HasComponents) {
+ scoped_refptr<SchemaMap> map = new SchemaMap();
+ EXPECT_FALSE(map->HasComponents());
+
+ // The Chrome schema does not count as a component.
+ Schema schema = CreateTestSchema();
+ ComponentMap component_map;
+ component_map[""] = schema;
+ DomainMap domain_map;
+ domain_map[POLICY_DOMAIN_CHROME] = component_map;
+ map = new SchemaMap(domain_map);
+ EXPECT_FALSE(map->HasComponents());
+
+ // An extension schema does.
+ domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
+ map = new SchemaMap(domain_map);
+ EXPECT_TRUE(map->HasComponents());
+}
+
+TEST_F(SchemaMapTest, Lookups) {
+ scoped_refptr<SchemaMap> map = CreateTestMap();
+ ASSERT_TRUE(map.get());
+ EXPECT_TRUE(map->HasComponents());
+
+ EXPECT_FALSE(map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
+ EXPECT_FALSE(map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_CHROME, "extension-1")));
+ EXPECT_FALSE(map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_CHROME, "legacy-extension")));
+ EXPECT_FALSE(map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "")));
+ EXPECT_FALSE(map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-3")));
+
+ const Schema* schema =
+ map->GetSchema(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-1"));
+ ASSERT_TRUE(schema);
+ EXPECT_TRUE(schema->valid());
+
+ schema = map->GetSchema(
+ PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "legacy-extension"));
+ ASSERT_TRUE(schema);
+ EXPECT_FALSE(schema->valid());
+}
+
+TEST_F(SchemaMapTest, FilterBundle) {
+ std::string error;
+ Schema schema = Schema::Parse(kTestSchema, &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ DomainMap domain_map;
+ domain_map[POLICY_DOMAIN_EXTENSIONS]["abc"] = schema;
+ scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
+
+ PolicyBundle bundle;
+ schema_map->FilterBundle(&bundle);
+ const PolicyBundle empty_bundle;
+ EXPECT_TRUE(bundle.Equals(empty_bundle));
+
+ // The Chrome namespace isn't filtered.
+ PolicyBundle expected_bundle;
+ PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
+ expected_bundle.Get(chrome_ns).Set(
+ "ChromePolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value"), nullptr);
+ bundle.CopyFrom(expected_bundle);
+
+ // Unknown components are filtered out.
+ PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
+ bundle.Get(another_extension_ns)
+ .Set("AnotherExtensionPolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value"),
+ nullptr);
+ schema_map->FilterBundle(&bundle);
+ EXPECT_TRUE(bundle.Equals(expected_bundle));
+
+ PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "abc");
+ PolicyMap& map = expected_bundle.Get(extension_ns);
+ base::ListValue list;
+ list.AppendString("a");
+ list.AppendString("b");
+ map.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, list.CreateDeepCopy(), nullptr);
+ map.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true), nullptr);
+ map.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(1), nullptr);
+ map.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(), nullptr);
+ map.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(1.2), nullptr);
+ base::DictionaryValue dict;
+ dict.SetString("a", "b");
+ dict.SetInteger("b", 2);
+ map.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, dict.CreateDeepCopy(), nullptr);
+ map.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value"), nullptr);
+
+ bundle.MergeFrom(expected_bundle);
+ bundle.Get(extension_ns)
+ .Set("Unexpected", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("to-be-removed"),
+ nullptr);
+
+ schema_map->FilterBundle(&bundle);
+ EXPECT_TRUE(bundle.Equals(expected_bundle));
+
+ // Mismatched types are also removed.
+ bundle.Clear();
+ PolicyMap& badmap = bundle.Get(extension_ns);
+ badmap.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false),
+ nullptr);
+ badmap.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(0), nullptr);
+ badmap.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false),
+ nullptr);
+ badmap.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false),
+ nullptr);
+ badmap.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false),
+ nullptr);
+ badmap.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(false),
+ nullptr);
+ badmap.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, nullptr,
+ std::make_unique<ExternalDataFetcher>(nullptr, std::string()));
+
+ schema_map->FilterBundle(&bundle);
+ EXPECT_TRUE(bundle.Equals(empty_bundle));
+}
+
+TEST_F(SchemaMapTest, LegacyComponents) {
+ std::string error;
+ Schema schema = Schema::Parse(
+ "{"
+ " \"type\":\"object\","
+ " \"properties\": {"
+ " \"String\": { \"type\": \"string\" }"
+ " }"
+ "}", &error);
+ ASSERT_TRUE(schema.valid()) << error;
+
+ DomainMap domain_map;
+ domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema;
+ domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema();
+ scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
+
+ // |bundle| contains policies loaded by a policy provider.
+ PolicyBundle bundle;
+
+ // Known components with schemas are filtered.
+ PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema");
+ bundle.Get(extension_ns)
+ .Set("String", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value 1"),
+ nullptr);
+
+ // The Chrome namespace isn't filtered.
+ PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
+ bundle.Get(chrome_ns).Set("ChromePolicy", POLICY_LEVEL_MANDATORY,
+ POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD,
+ std::make_unique<base::Value>("value 3"), nullptr);
+
+ PolicyBundle expected_bundle;
+ expected_bundle.MergeFrom(bundle);
+
+ // Known components without a schema are filtered out completely.
+ PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema");
+ bundle.Get(without_schema_ns)
+ .Set("Schemaless", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value 2"),
+ nullptr);
+
+ // Unknown policies of known components with a schema are removed.
+ bundle.Get(extension_ns)
+ .Set("Surprise", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value 4"),
+ nullptr);
+
+ // Unknown components are removed.
+ PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown");
+ bundle.Get(unknown_ns)
+ .Set("Surprise", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+ POLICY_SOURCE_CLOUD, std::make_unique<base::Value>("value 5"),
+ nullptr);
+
+ schema_map->FilterBundle(&bundle);
+ EXPECT_TRUE(bundle.Equals(expected_bundle));
+}
+
+TEST_F(SchemaMapTest, GetChanges) {
+ DomainMap map;
+ map[POLICY_DOMAIN_CHROME][""] = Schema();
+ scoped_refptr<SchemaMap> older = new SchemaMap(map);
+ map[POLICY_DOMAIN_CHROME][""] = Schema();
+ scoped_refptr<SchemaMap> newer = new SchemaMap(map);
+
+ PolicyNamespaceList removed;
+ PolicyNamespaceList added;
+ newer->GetChanges(older, &removed, &added);
+ EXPECT_TRUE(removed.empty());
+ EXPECT_TRUE(added.empty());
+
+ map[POLICY_DOMAIN_CHROME][""] = Schema();
+ map[POLICY_DOMAIN_EXTENSIONS]["xyz"] = Schema();
+ newer = new SchemaMap(map);
+ newer->GetChanges(older, &removed, &added);
+ EXPECT_TRUE(removed.empty());
+ ASSERT_EQ(1u, added.size());
+ EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), added[0]);
+
+ older = newer;
+ map[POLICY_DOMAIN_EXTENSIONS]["abc"] = Schema();
+ newer = new SchemaMap(map);
+ newer->GetChanges(older, &removed, &added);
+ ASSERT_EQ(2u, removed.size());
+ EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), removed[0]);
+ EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), removed[1]);
+ ASSERT_EQ(1u, added.size());
+ EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), added[0]);
+}
+
+} // namespace policy