1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema_map.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/weak_ptr.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_manager.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_bundle.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/schema.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace policy {
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestSchema[] =
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "{"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"type\": \"object\","
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  \"properties\": {"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"string\": { \"type\": \"string\" },"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"integer\": { \"type\": \"integer\" },"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"boolean\": { \"type\": \"boolean\" },"
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"null\": { \"type\": \"null\" },"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"double\": { \"type\": \"number\" },"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"list\": {"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      \"type\": \"array\","
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      \"items\": { \"type\": \"string\" }"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    },"
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    \"object\": {"
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      \"type\": \"object\","
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      \"properties\": {"
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "        \"a\": { \"type\": \"string\" },"
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "        \"b\": { \"type\": \"integer\" }"
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "      }"
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "    }"
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "  }"
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "}";
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SchemaMapTest : public testing::Test {
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema CreateTestSchema() {
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string error;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Schema schema = Schema::Parse(kTestSchema, &error);
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!schema.valid())
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      ADD_FAILURE() << error;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return schema;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> CreateTestMap() {
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Schema schema = CreateTestSchema();
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ComponentMap component_map;
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    component_map["extension-1"] = schema;
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    component_map["extension-2"] = schema;
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    component_map["legacy-extension"] = Schema();
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DomainMap domain_map;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return new SchemaMap(domain_map);
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, Empty) {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> map = new SchemaMap();
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(map->GetDomains().empty());
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_CHROME));
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_EXTENSIONS));
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->HasComponents());
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, HasComponents) {
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> map = new SchemaMap();
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->HasComponents());
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The Chrome schema does not count as a component.
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema schema = CreateTestSchema();
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ComponentMap component_map;
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  component_map[""] = schema;
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DomainMap domain_map;
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  domain_map[POLICY_DOMAIN_CHROME] = component_map;
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map = new SchemaMap(domain_map);
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->HasComponents());
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // An extension schema does.
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map = new SchemaMap(domain_map);
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(map->HasComponents());
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, Lookups) {
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> map = CreateTestMap();
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(map.get());
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(map->HasComponents());
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_CHROME, "extension-1")));
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_CHROME, "legacy-extension")));
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "")));
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(map->GetSchema(
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-3")));
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Schema* schema =
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      map->GetSchema(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-1"));
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(schema);
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(schema->valid());
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema = map->GetSchema(
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "legacy-extension"));
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(schema);
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(schema->valid());
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, FilterBundle) {
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string error;
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema schema = Schema::Parse(kTestSchema, &error);
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(schema.valid()) << error;
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DomainMap domain_map;
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  domain_map[POLICY_DOMAIN_EXTENSIONS]["abc"] = schema;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle bundle;
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema_map->FilterBundle(&bundle);
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const PolicyBundle empty_bundle;
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(bundle.Equals(empty_bundle));
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The Chrome namespace isn't filtered.
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle expected_bundle;
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  expected_bundle.Get(chrome_ns).Set("ChromePolicy",
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     POLICY_LEVEL_MANDATORY,
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     POLICY_SCOPE_USER,
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     new base::StringValue("value"),
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     NULL);
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.CopyFrom(expected_bundle);
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Unknown components are filtered out.
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bundle.Get(another_extension_ns).Set("AnotherExtensionPolicy",
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       POLICY_LEVEL_MANDATORY,
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       POLICY_SCOPE_USER,
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       new base::StringValue("value"),
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       NULL);
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema_map->FilterBundle(&bundle);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(bundle.Equals(expected_bundle));
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "abc");
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyMap& map = expected_bundle.Get(extension_ns);
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ListValue list;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  list.AppendString("a");
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  list.AppendString("b");
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          list.DeepCopy(), NULL);
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  map.Set("boolean",
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          POLICY_LEVEL_MANDATORY,
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          POLICY_SCOPE_USER,
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          new base::FundamentalValue(true),
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          NULL);
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  map.Set("integer",
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          POLICY_LEVEL_MANDATORY,
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          POLICY_SCOPE_USER,
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          new base::FundamentalValue(1),
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          NULL);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          base::Value::CreateNullValue(), NULL);
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  map.Set("double",
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          POLICY_LEVEL_MANDATORY,
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          POLICY_SCOPE_USER,
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new base::FundamentalValue(1.2),
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          NULL);
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::DictionaryValue dict;
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dict.SetString("a", "b");
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  dict.SetInteger("b", 2);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          dict.DeepCopy(), NULL);
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  map.Set("string",
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          POLICY_LEVEL_MANDATORY,
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          POLICY_SCOPE_USER,
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          new base::StringValue("value"),
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          NULL);
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.MergeFrom(expected_bundle);
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Get(extension_ns).Set("Unexpected",
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_LEVEL_MANDATORY,
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_SCOPE_USER,
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               new base::StringValue("to-be-removed"),
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               NULL);
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema_map->FilterBundle(&bundle);
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(bundle.Equals(expected_bundle));
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Mismatched types are also removed.
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Clear();
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyMap& badmap = bundle.Get(extension_ns);
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("list",
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(false),
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("boolean",
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(0),
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("integer",
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(false),
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("null",
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(false),
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("double",
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(false),
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  badmap.Set("object",
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_LEVEL_MANDATORY,
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             POLICY_SCOPE_USER,
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             new base::FundamentalValue(false),
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch             NULL);
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  badmap.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             NULL,
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)             new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(),
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     std::string()));
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema_map->FilterBundle(&bundle);
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(bundle.Equals(empty_bundle));
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, LegacyComponents) {
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string error;
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Schema schema = Schema::Parse(
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "{"
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"type\":\"object\","
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  \"properties\": {"
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "    \"String\": { \"type\": \"string\" }"
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "  }"
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "}", &error);
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(schema.valid()) << error;
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DomainMap domain_map;
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema;
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema();
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // |bundle| contains policies loaded by a policy provider.
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle bundle;
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Known components with schemas are filtered.
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema");
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Get(extension_ns).Set("String",
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_LEVEL_MANDATORY,
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_SCOPE_USER,
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               new base::StringValue("value 1"),
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               NULL);
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The Chrome namespace isn't filtered.
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Get(chrome_ns).Set("ChromePolicy",
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            POLICY_LEVEL_MANDATORY,
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            POLICY_SCOPE_USER,
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                            new base::StringValue("value 3"),
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            NULL);
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyBundle expected_bundle;
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  expected_bundle.MergeFrom(bundle);
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Known components without a schema are filtered out completely.
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema");
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bundle.Get(without_schema_ns).Set("Schemaless",
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    POLICY_LEVEL_MANDATORY,
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    POLICY_SCOPE_USER,
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    new base::StringValue("value 2"),
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    NULL);
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Unknown policies of known components with a schema are removed.
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Get(extension_ns).Set("Surprise",
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_LEVEL_MANDATORY,
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               POLICY_SCOPE_USER,
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               new base::StringValue("value 4"),
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               NULL);
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Unknown components are removed.
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown");
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bundle.Get(unknown_ns).Set("Surprise",
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             POLICY_LEVEL_MANDATORY,
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             POLICY_SCOPE_USER,
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                             new base::StringValue("value 5"),
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             NULL);
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  schema_map->FilterBundle(&bundle);
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(bundle.Equals(expected_bundle));
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(SchemaMapTest, GetChanges) {
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DomainMap map;
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map[POLICY_DOMAIN_CHROME][""] = Schema();
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> older = new SchemaMap(map);
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map[POLICY_DOMAIN_CHROME][""] = Schema();
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<SchemaMap> newer = new SchemaMap(map);
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespaceList removed;
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PolicyNamespaceList added;
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  newer->GetChanges(older, &removed, &added);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(removed.empty());
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(added.empty());
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map[POLICY_DOMAIN_CHROME][""] = Schema();
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map[POLICY_DOMAIN_EXTENSIONS]["xyz"] = Schema();
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  newer = new SchemaMap(map);
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  newer->GetChanges(older, &removed, &added);
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(removed.empty());
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, added.size());
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), added[0]);
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  older = newer;
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  map[POLICY_DOMAIN_EXTENSIONS]["abc"] = Schema();
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  newer = new SchemaMap(map);
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  newer->GetChanges(older, &removed, &added);
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(2u, removed.size());
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), removed[0]);
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), removed[1]);
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_EQ(1u, added.size());
339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), added[0]);
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace policy
343