Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / policy / core / common / configuration_policy_provider_test.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/configuration_policy_provider_test.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/values.h"
11 #include "components/policy/core/common/configuration_policy_provider.h"
12 #include "components/policy/core/common/external_data_fetcher.h"
13 #include "components/policy/core/common/mock_configuration_policy_provider.h"
14 #include "components/policy/core/common/policy_bundle.h"
15 #include "components/policy/core/common/policy_map.h"
16 #include "components/policy/core/common/policy_namespace.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18
19 using ::testing::Mock;
20 using ::testing::_;
21
22 namespace policy {
23
24 const char kTestChromeSchema[] =
25     "{"
26     "  \"type\": \"object\","
27     "  \"properties\": {"
28     "    \"StringPolicy\": { \"type\": \"string\" },"
29     "    \"BooleanPolicy\": { \"type\": \"boolean\" },"
30     "    \"IntegerPolicy\": { \"type\": \"integer\" },"
31     "    \"StringListPolicy\": {"
32     "      \"type\": \"array\","
33     "      \"items\": { \"type\": \"string\" }"
34     "    },"
35     "    \"DictionaryPolicy\": {"
36     "      \"type\": \"object\","
37     "      \"properties\": {"
38     "        \"bool\": { \"type\": \"boolean\" },"
39     "        \"double\": { \"type\": \"number\" },"
40     "        \"int\": { \"type\": \"integer\" },"
41     "        \"string\": { \"type\": \"string\" },"
42     "        \"array\": {"
43     "          \"type\": \"array\","
44     "          \"items\": { \"type\": \"string\" }"
45     "        },"
46     "        \"dictionary\": {"
47     "          \"type\": \"object\","
48     "          \"properties\": {"
49     "            \"sub\": { \"type\": \"string\" },"
50     "            \"sublist\": {"
51     "              \"type\": \"array\","
52     "              \"items\": {"
53     "                \"type\": \"object\","
54     "                \"properties\": {"
55     "                  \"aaa\": { \"type\": \"integer\" },"
56     "                  \"bbb\": { \"type\": \"integer\" },"
57     "                  \"ccc\": { \"type\": \"string\" },"
58     "                  \"ddd\": { \"type\": \"string\" }"
59     "                }"
60     "              }"
61     "            }"
62     "          }"
63     "        },"
64     "        \"list\": {"
65     "          \"type\": \"array\","
66     "          \"items\": {"
67     "            \"type\": \"object\","
68     "            \"properties\": {"
69     "              \"subdictindex\": { \"type\": \"integer\" },"
70     "              \"subdict\": {"
71     "                \"type\": \"object\","
72     "                \"properties\": {"
73     "                  \"bool\": { \"type\": \"boolean\" },"
74     "                  \"double\": { \"type\": \"number\" },"
75     "                  \"int\": { \"type\": \"integer\" },"
76     "                  \"string\": { \"type\": \"string\" }"
77     "                }"
78     "              }"
79     "            }"
80     "          }"
81     "        },"
82     "        \"dict\": {"
83     "          \"type\": \"object\","
84     "          \"properties\": {"
85     "            \"bool\": { \"type\": \"boolean\" },"
86     "            \"double\": { \"type\": \"number\" },"
87     "            \"int\": { \"type\": \"integer\" },"
88     "            \"string\": { \"type\": \"string\" },"
89     "            \"list\": {"
90     "              \"type\": \"array\","
91     "              \"items\": {"
92     "                \"type\": \"object\","
93     "                \"properties\": {"
94     "                  \"subdictindex\": { \"type\": \"integer\" },"
95     "                  \"subdict\": {"
96     "                    \"type\": \"object\","
97     "                    \"properties\": {"
98     "                      \"bool\": { \"type\": \"boolean\" },"
99     "                      \"double\": { \"type\": \"number\" },"
100     "                      \"int\": { \"type\": \"integer\" },"
101     "                      \"string\": { \"type\": \"string\" }"
102     "                    }"
103     "                  }"
104     "                }"
105     "              }"
106     "            }"
107     "          }"
108     "        }"
109     "      }"
110     "    }"
111     "  }"
112     "}";
113
114 namespace test_keys {
115
116 const char kKeyString[] = "StringPolicy";
117 const char kKeyBoolean[] = "BooleanPolicy";
118 const char kKeyInteger[] = "IntegerPolicy";
119 const char kKeyStringList[] = "StringListPolicy";
120 const char kKeyDictionary[] = "DictionaryPolicy";
121
122 }  // namespace test_keys
123
124 PolicyTestBase::PolicyTestBase() {}
125
126 PolicyTestBase::~PolicyTestBase() {}
127
128 void PolicyTestBase::SetUp() {
129   const PolicyNamespace ns(POLICY_DOMAIN_CHROME, "");
130   ASSERT_TRUE(RegisterSchema(ns, kTestChromeSchema));
131 }
132
133 void PolicyTestBase::TearDown() {
134   loop_.RunUntilIdle();
135 }
136
137 bool PolicyTestBase::RegisterSchema(const PolicyNamespace& ns,
138                                     const std::string& schema_string) {
139   std::string error;
140   Schema schema = Schema::Parse(schema_string, &error);
141   if (schema.valid()) {
142     schema_registry_.RegisterComponent(ns, schema);
143     return true;
144   }
145   ADD_FAILURE() << error;
146   return false;
147 }
148
149 PolicyProviderTestHarness::PolicyProviderTestHarness(PolicyLevel level,
150                                                      PolicyScope scope)
151     : level_(level), scope_(scope) {}
152
153 PolicyProviderTestHarness::~PolicyProviderTestHarness() {}
154
155 PolicyLevel PolicyProviderTestHarness::policy_level() const {
156   return level_;
157 }
158
159 PolicyScope PolicyProviderTestHarness::policy_scope() const {
160   return scope_;
161 }
162
163 void PolicyProviderTestHarness::Install3rdPartyPolicy(
164     const base::DictionaryValue* policies) {
165   FAIL();
166 }
167
168 ConfigurationPolicyProviderTest::ConfigurationPolicyProviderTest() {}
169
170 ConfigurationPolicyProviderTest::~ConfigurationPolicyProviderTest() {}
171
172 void ConfigurationPolicyProviderTest::SetUp() {
173   PolicyTestBase::SetUp();
174
175   test_harness_.reset((*GetParam())());
176   test_harness_->SetUp();
177
178   const PolicyNamespace chrome_ns(POLICY_DOMAIN_CHROME, "");
179   Schema chrome_schema = *schema_registry_.schema_map()->GetSchema(chrome_ns);
180   Schema extension_schema =
181       chrome_schema.GetKnownProperty(test_keys::kKeyDictionary);
182   ASSERT_TRUE(extension_schema.valid());
183   schema_registry_.RegisterComponent(
184       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
185                       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
186       extension_schema);
187   schema_registry_.RegisterComponent(
188       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
189                       "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
190       extension_schema);
191   schema_registry_.RegisterComponent(
192       PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
193                       "cccccccccccccccccccccccccccccccc"),
194       extension_schema);
195
196   provider_.reset(test_harness_->CreateProvider(&schema_registry_,
197                                                 loop_.message_loop_proxy()));
198   provider_->Init(&schema_registry_);
199   // Some providers do a reload on init. Make sure any notifications generated
200   // are fired now.
201   loop_.RunUntilIdle();
202
203   const PolicyBundle kEmptyBundle;
204   EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
205 }
206
207 void ConfigurationPolicyProviderTest::TearDown() {
208   // Give providers the chance to clean up after themselves on the file thread.
209   provider_->Shutdown();
210   provider_.reset();
211
212   PolicyTestBase::TearDown();
213 }
214
215 void ConfigurationPolicyProviderTest::CheckValue(
216     const char* policy_name,
217     const base::Value& expected_value,
218     base::Closure install_value) {
219   // Install the value, reload policy and check the provider for the value.
220   install_value.Run();
221   provider_->RefreshPolicies();
222   loop_.RunUntilIdle();
223   PolicyBundle expected_bundle;
224   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
225       .Set(policy_name,
226            test_harness_->policy_level(),
227            test_harness_->policy_scope(),
228            expected_value.DeepCopy(),
229            NULL);
230   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
231   // TODO(joaodasilva): set the policy in the POLICY_DOMAIN_EXTENSIONS too,
232   // and extend the |expected_bundle|, once all providers are ready.
233 }
234
235 TEST_P(ConfigurationPolicyProviderTest, Empty) {
236   provider_->RefreshPolicies();
237   loop_.RunUntilIdle();
238   const PolicyBundle kEmptyBundle;
239   EXPECT_TRUE(provider_->policies().Equals(kEmptyBundle));
240 }
241
242 TEST_P(ConfigurationPolicyProviderTest, StringValue) {
243   const char kTestString[] = "string_value";
244   base::StringValue expected_value(kTestString);
245   CheckValue(test_keys::kKeyString,
246              expected_value,
247              base::Bind(&PolicyProviderTestHarness::InstallStringPolicy,
248                         base::Unretained(test_harness_.get()),
249                         test_keys::kKeyString,
250                         kTestString));
251 }
252
253 TEST_P(ConfigurationPolicyProviderTest, BooleanValue) {
254   base::FundamentalValue expected_value(true);
255   CheckValue(test_keys::kKeyBoolean,
256              expected_value,
257              base::Bind(&PolicyProviderTestHarness::InstallBooleanPolicy,
258                         base::Unretained(test_harness_.get()),
259                         test_keys::kKeyBoolean,
260                         true));
261 }
262
263 TEST_P(ConfigurationPolicyProviderTest, IntegerValue) {
264   base::FundamentalValue expected_value(42);
265   CheckValue(test_keys::kKeyInteger,
266              expected_value,
267              base::Bind(&PolicyProviderTestHarness::InstallIntegerPolicy,
268                         base::Unretained(test_harness_.get()),
269                         test_keys::kKeyInteger,
270                         42));
271 }
272
273 TEST_P(ConfigurationPolicyProviderTest, StringListValue) {
274   base::ListValue expected_value;
275   expected_value.Set(0U, new base::StringValue("first"));
276   expected_value.Set(1U, new base::StringValue("second"));
277   CheckValue(test_keys::kKeyStringList,
278              expected_value,
279              base::Bind(&PolicyProviderTestHarness::InstallStringListPolicy,
280                         base::Unretained(test_harness_.get()),
281                         test_keys::kKeyStringList,
282                         &expected_value));
283 }
284
285 TEST_P(ConfigurationPolicyProviderTest, DictionaryValue) {
286   base::DictionaryValue expected_value;
287   expected_value.SetBoolean("bool", true);
288   expected_value.SetDouble("double", 123.456);
289   expected_value.SetInteger("int", 123);
290   expected_value.SetString("string", "omg");
291
292   base::ListValue* list = new base::ListValue();
293   list->Set(0U, new base::StringValue("first"));
294   list->Set(1U, new base::StringValue("second"));
295   expected_value.Set("array", list);
296
297   base::DictionaryValue* dict = new base::DictionaryValue();
298   dict->SetString("sub", "value");
299   list = new base::ListValue();
300   base::DictionaryValue* sub = new base::DictionaryValue();
301   sub->SetInteger("aaa", 111);
302   sub->SetInteger("bbb", 222);
303   list->Append(sub);
304   sub = new base::DictionaryValue();
305   sub->SetString("ccc", "333");
306   sub->SetString("ddd", "444");
307   list->Append(sub);
308   dict->Set("sublist", list);
309   expected_value.Set("dictionary", dict);
310
311   CheckValue(test_keys::kKeyDictionary,
312              expected_value,
313              base::Bind(&PolicyProviderTestHarness::InstallDictionaryPolicy,
314                         base::Unretained(test_harness_.get()),
315                         test_keys::kKeyDictionary,
316                         &expected_value));
317 }
318
319 TEST_P(ConfigurationPolicyProviderTest, RefreshPolicies) {
320   PolicyBundle bundle;
321   EXPECT_TRUE(provider_->policies().Equals(bundle));
322
323   // OnUpdatePolicy is called even when there are no changes.
324   MockConfigurationPolicyObserver observer;
325   provider_->AddObserver(&observer);
326   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
327   provider_->RefreshPolicies();
328   loop_.RunUntilIdle();
329   Mock::VerifyAndClearExpectations(&observer);
330
331   EXPECT_TRUE(provider_->policies().Equals(bundle));
332
333   // OnUpdatePolicy is called when there are changes.
334   test_harness_->InstallStringPolicy(test_keys::kKeyString, "value");
335   EXPECT_CALL(observer, OnUpdatePolicy(provider_.get())).Times(1);
336   provider_->RefreshPolicies();
337   loop_.RunUntilIdle();
338   Mock::VerifyAndClearExpectations(&observer);
339
340   bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
341       .Set(test_keys::kKeyString,
342            test_harness_->policy_level(),
343            test_harness_->policy_scope(),
344            new base::StringValue("value"),
345            NULL);
346   EXPECT_TRUE(provider_->policies().Equals(bundle));
347   provider_->RemoveObserver(&observer);
348 }
349
350 Configuration3rdPartyPolicyProviderTest::
351     Configuration3rdPartyPolicyProviderTest() {}
352
353 Configuration3rdPartyPolicyProviderTest::
354     ~Configuration3rdPartyPolicyProviderTest() {}
355
356 TEST_P(Configuration3rdPartyPolicyProviderTest, Load3rdParty) {
357   base::DictionaryValue policy_dict;
358   policy_dict.SetBoolean("bool", true);
359   policy_dict.SetDouble("double", 123.456);
360   policy_dict.SetInteger("int", 789);
361   policy_dict.SetString("string", "string value");
362
363   base::ListValue* list = new base::ListValue();
364   for (int i = 0; i < 2; ++i) {
365     base::DictionaryValue* dict = new base::DictionaryValue();
366     dict->SetInteger("subdictindex", i);
367     dict->Set("subdict", policy_dict.DeepCopy());
368     list->Append(dict);
369   }
370   policy_dict.Set("list", list);
371   policy_dict.Set("dict", policy_dict.DeepCopy());
372
373   // Install these policies as a Chrome policy.
374   test_harness_->InstallDictionaryPolicy(test_keys::kKeyDictionary,
375                                          &policy_dict);
376   // Install them as 3rd party policies too.
377   base::DictionaryValue policy_3rdparty;
378   policy_3rdparty.Set("extensions.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
379                       policy_dict.DeepCopy());
380   policy_3rdparty.Set("extensions.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
381                       policy_dict.DeepCopy());
382   // Install invalid 3rd party policies that shouldn't be loaded. These also
383   // help detecting memory leaks in the code paths that detect invalid input.
384   policy_3rdparty.Set("invalid-domain.component", policy_dict.DeepCopy());
385   policy_3rdparty.Set("extensions.cccccccccccccccccccccccccccccccc",
386                       new base::StringValue("invalid-value"));
387   test_harness_->Install3rdPartyPolicy(&policy_3rdparty);
388
389   provider_->RefreshPolicies();
390   loop_.RunUntilIdle();
391
392   PolicyMap expected_policy;
393   expected_policy.Set(test_keys::kKeyDictionary,
394                       test_harness_->policy_level(),
395                       test_harness_->policy_scope(),
396                       policy_dict.DeepCopy(),
397                       NULL);
398   PolicyBundle expected_bundle;
399   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
400       .CopyFrom(expected_policy);
401   expected_policy.Clear();
402   expected_policy.LoadFrom(&policy_dict,
403                            test_harness_->policy_level(),
404                            test_harness_->policy_scope());
405   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
406                                       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
407       .CopyFrom(expected_policy);
408   expected_bundle.Get(PolicyNamespace(POLICY_DOMAIN_EXTENSIONS,
409                                       "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
410       .CopyFrom(expected_policy);
411   EXPECT_TRUE(provider_->policies().Equals(expected_bundle));
412 }
413
414 }  // namespace policy