e0eb089ab7454c1cb907fb54be3b840d532e0848
[platform/framework/web/crosswalk.git] / src / components / policy / core / common / schema_map_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/policy/core/common/schema_map.h"
6
7 #include "base/memory/weak_ptr.h"
8 #include "base/values.h"
9 #include "components/policy/core/common/external_data_fetcher.h"
10 #include "components/policy/core/common/external_data_manager.h"
11 #include "components/policy/core/common/policy_bundle.h"
12 #include "components/policy/core/common/policy_map.h"
13 #include "components/policy/core/common/schema.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace policy {
17
18 namespace {
19
20 const char kTestSchema[] =
21     "{"
22     "  \"type\": \"object\","
23     "  \"properties\": {"
24     "    \"string\": { \"type\": \"string\" },"
25     "    \"integer\": { \"type\": \"integer\" },"
26     "    \"boolean\": { \"type\": \"boolean\" },"
27     "    \"null\": { \"type\": \"null\" },"
28     "    \"double\": { \"type\": \"number\" },"
29     "    \"list\": {"
30     "      \"type\": \"array\","
31     "      \"items\": { \"type\": \"string\" }"
32     "    },"
33     "    \"object\": {"
34     "      \"type\": \"object\","
35     "      \"properties\": {"
36     "        \"a\": { \"type\": \"string\" },"
37     "        \"b\": { \"type\": \"integer\" }"
38     "      }"
39     "    }"
40     "  }"
41     "}";
42
43 }  // namespace
44
45 class SchemaMapTest : public testing::Test {
46  protected:
47   Schema CreateTestSchema() {
48     std::string error;
49     Schema schema = Schema::Parse(kTestSchema, &error);
50     if (!schema.valid())
51       ADD_FAILURE() << error;
52     return schema;
53   }
54
55   scoped_refptr<SchemaMap> CreateTestMap() {
56     Schema schema = CreateTestSchema();
57     ComponentMap component_map;
58     component_map["extension-1"] = schema;
59     component_map["extension-2"] = schema;
60     component_map["legacy-extension"] = Schema();
61
62     DomainMap domain_map;
63     domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
64
65     return new SchemaMap(domain_map);
66   }
67 };
68
69 TEST_F(SchemaMapTest, Empty) {
70   scoped_refptr<SchemaMap> map = new SchemaMap();
71   EXPECT_TRUE(map->GetDomains().empty());
72   EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_CHROME));
73   EXPECT_FALSE(map->GetComponents(POLICY_DOMAIN_EXTENSIONS));
74   EXPECT_FALSE(map->GetSchema(PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
75   EXPECT_FALSE(map->HasComponents());
76 }
77
78 TEST_F(SchemaMapTest, HasComponents) {
79   scoped_refptr<SchemaMap> map = new SchemaMap();
80   EXPECT_FALSE(map->HasComponents());
81
82   // The Chrome schema does not count as a component.
83   Schema schema = CreateTestSchema();
84   ComponentMap component_map;
85   component_map[""] = schema;
86   DomainMap domain_map;
87   domain_map[POLICY_DOMAIN_CHROME] = component_map;
88   map = new SchemaMap(domain_map);
89   EXPECT_FALSE(map->HasComponents());
90
91   // An extension schema does.
92   domain_map[POLICY_DOMAIN_EXTENSIONS] = component_map;
93   map = new SchemaMap(domain_map);
94   EXPECT_TRUE(map->HasComponents());
95 }
96
97 TEST_F(SchemaMapTest, Lookups) {
98   scoped_refptr<SchemaMap> map = CreateTestMap();
99   ASSERT_TRUE(map);
100   EXPECT_TRUE(map->HasComponents());
101
102   EXPECT_FALSE(map->GetSchema(
103       PolicyNamespace(POLICY_DOMAIN_CHROME, "")));
104   EXPECT_FALSE(map->GetSchema(
105       PolicyNamespace(POLICY_DOMAIN_CHROME, "extension-1")));
106   EXPECT_FALSE(map->GetSchema(
107       PolicyNamespace(POLICY_DOMAIN_CHROME, "legacy-extension")));
108   EXPECT_FALSE(map->GetSchema(
109       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "")));
110   EXPECT_FALSE(map->GetSchema(
111       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-3")));
112
113   const Schema* schema =
114       map->GetSchema(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "extension-1"));
115   ASSERT_TRUE(schema);
116   EXPECT_TRUE(schema->valid());
117
118   schema = map->GetSchema(
119       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "legacy-extension"));
120   ASSERT_TRUE(schema);
121   EXPECT_FALSE(schema->valid());
122 }
123
124 TEST_F(SchemaMapTest, FilterBundle) {
125   std::string error;
126   Schema schema = Schema::Parse(kTestSchema, &error);
127   ASSERT_TRUE(schema.valid()) << error;
128
129   DomainMap domain_map;
130   domain_map[POLICY_DOMAIN_EXTENSIONS]["abc"] = schema;
131   scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
132
133   PolicyBundle bundle;
134   schema_map->FilterBundle(&bundle);
135   const PolicyBundle empty_bundle;
136   EXPECT_TRUE(bundle.Equals(empty_bundle));
137
138   // The Chrome namespace isn't filtered.
139   PolicyBundle expected_bundle;
140   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
141   expected_bundle.Get(chrome_ns).Set("ChromePolicy",
142                                      POLICY_LEVEL_MANDATORY,
143                                      POLICY_SCOPE_USER,
144                                      base::Value::CreateStringValue("value"),
145                                      NULL);
146   bundle.CopyFrom(expected_bundle);
147
148   // Unknown components are filtered out.
149   PolicyNamespace another_extension_ns(POLICY_DOMAIN_EXTENSIONS, "xyz");
150   bundle.Get(another_extension_ns).Set(
151       "AnotherExtensionPolicy",
152       POLICY_LEVEL_MANDATORY,
153       POLICY_SCOPE_USER,
154       base::Value::CreateStringValue("value"),
155       NULL);
156   schema_map->FilterBundle(&bundle);
157   EXPECT_TRUE(bundle.Equals(expected_bundle));
158
159   PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "abc");
160   PolicyMap& map = expected_bundle.Get(extension_ns);
161   base::ListValue list;
162   list.AppendString("a");
163   list.AppendString("b");
164   map.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
165           list.DeepCopy(), NULL);
166   map.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
167           base::Value::CreateBooleanValue(true), NULL);
168   map.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
169           base::Value::CreateIntegerValue(1), NULL);
170   map.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
171           base::Value::CreateNullValue(), NULL);
172   map.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
173           base::Value::CreateDoubleValue(1.2), NULL);
174   base::DictionaryValue dict;
175   dict.SetString("a", "b");
176   dict.SetInteger("b", 2);
177   map.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
178           dict.DeepCopy(), NULL);
179   map.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
180           base::Value::CreateStringValue("value"), NULL);
181
182   bundle.MergeFrom(expected_bundle);
183   bundle.Get(extension_ns).Set("Unexpected",
184                                POLICY_LEVEL_MANDATORY,
185                                POLICY_SCOPE_USER,
186                                base::Value::CreateStringValue("to-be-removed"),
187                                NULL);
188
189   schema_map->FilterBundle(&bundle);
190   EXPECT_TRUE(bundle.Equals(expected_bundle));
191
192   // Mismatched types are also removed.
193   bundle.Clear();
194   PolicyMap& badmap = bundle.Get(extension_ns);
195   badmap.Set("list", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
196              base::Value::CreateBooleanValue(false), NULL);
197   badmap.Set("boolean", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
198              base::Value::CreateIntegerValue(0), NULL);
199   badmap.Set("integer", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
200              base::Value::CreateBooleanValue(false), NULL);
201   badmap.Set("null", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
202              base::Value::CreateBooleanValue(false), NULL);
203   badmap.Set("double", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
204              base::Value::CreateBooleanValue(false), NULL);
205   badmap.Set("object", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
206              base::Value::CreateBooleanValue(false), NULL);
207   badmap.Set("string", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
208              NULL,
209              new ExternalDataFetcher(base::WeakPtr<ExternalDataManager>(),
210                                      std::string()));
211
212   schema_map->FilterBundle(&bundle);
213   EXPECT_TRUE(bundle.Equals(empty_bundle));
214 }
215
216 TEST_F(SchemaMapTest, LegacyComponents) {
217   std::string error;
218   Schema schema = Schema::Parse(
219       "{"
220       "  \"type\":\"object\","
221       "  \"properties\": {"
222       "    \"String\": { \"type\": \"string\" }"
223       "  }"
224       "}", &error);
225   ASSERT_TRUE(schema.valid()) << error;
226
227   DomainMap domain_map;
228   domain_map[POLICY_DOMAIN_EXTENSIONS]["with-schema"] = schema;
229   domain_map[POLICY_DOMAIN_EXTENSIONS]["without-schema"] = Schema();
230   scoped_refptr<SchemaMap> schema_map = new SchemaMap(domain_map);
231
232   // |bundle| contains policies loaded by a policy provider.
233   PolicyBundle bundle;
234
235   // Known components with schemas are filtered.
236   PolicyNamespace extension_ns(POLICY_DOMAIN_EXTENSIONS, "with-schema");
237   bundle.Get(extension_ns).Set("String",
238                                POLICY_LEVEL_MANDATORY,
239                                POLICY_SCOPE_USER,
240                                base::Value::CreateStringValue("value 1"),
241                                NULL);
242
243   // The Chrome namespace isn't filtered.
244   PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
245   bundle.Get(chrome_ns).Set("ChromePolicy",
246                             POLICY_LEVEL_MANDATORY,
247                             POLICY_SCOPE_USER,
248                             base::Value::CreateStringValue("value 3"),
249                             NULL);
250
251   PolicyBundle expected_bundle;
252   expected_bundle.MergeFrom(bundle);
253
254   // Known components without a schema are filtered out completely.
255   PolicyNamespace without_schema_ns(POLICY_DOMAIN_EXTENSIONS, "without-schema");
256   bundle.Get(without_schema_ns).Set("Schemaless",
257                                     POLICY_LEVEL_MANDATORY,
258                                     POLICY_SCOPE_USER,
259                                     base::Value::CreateStringValue("value 2"),
260                                     NULL);
261
262   // Unknown policies of known components with a schema are removed.
263   bundle.Get(extension_ns).Set("Surprise",
264                                POLICY_LEVEL_MANDATORY,
265                                POLICY_SCOPE_USER,
266                                base::Value::CreateStringValue("value 4"),
267                                NULL);
268
269   // Unknown components are removed.
270   PolicyNamespace unknown_ns(POLICY_DOMAIN_EXTENSIONS, "unknown");
271   bundle.Get(unknown_ns).Set("Surprise",
272                              POLICY_LEVEL_MANDATORY,
273                              POLICY_SCOPE_USER,
274                              base::Value::CreateStringValue("value 5"),
275                              NULL);
276
277   schema_map->FilterBundle(&bundle);
278   EXPECT_TRUE(bundle.Equals(expected_bundle));
279 }
280
281 TEST_F(SchemaMapTest, GetChanges) {
282   DomainMap map;
283   map[POLICY_DOMAIN_CHROME][""] = Schema();
284   scoped_refptr<SchemaMap> older = new SchemaMap(map);
285   map[POLICY_DOMAIN_CHROME][""] = Schema();
286   scoped_refptr<SchemaMap> newer = new SchemaMap(map);
287
288   PolicyNamespaceList removed;
289   PolicyNamespaceList added;
290   newer->GetChanges(older, &removed, &added);
291   EXPECT_TRUE(removed.empty());
292   EXPECT_TRUE(added.empty());
293
294   map[POLICY_DOMAIN_CHROME][""] = Schema();
295   map[POLICY_DOMAIN_EXTENSIONS]["xyz"] = Schema();
296   newer = new SchemaMap(map);
297   newer->GetChanges(older, &removed, &added);
298   EXPECT_TRUE(removed.empty());
299   ASSERT_EQ(1u, added.size());
300   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), added[0]);
301
302   older = newer;
303   map[POLICY_DOMAIN_EXTENSIONS]["abc"] = Schema();
304   newer = new SchemaMap(map);
305   newer->GetChanges(older, &removed, &added);
306   ASSERT_EQ(2u, removed.size());
307   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_CHROME, ""), removed[0]);
308   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "xyz"), removed[1]);
309   ASSERT_EQ(1u, added.size());
310   EXPECT_EQ(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS, "abc"), added[0]);
311 }
312
313 }  // namespace policy