• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/registry_dict.h"
6 
7 #include <string>
8 #include <utility>
9 
10 #include "base/values.h"
11 #include "components/policy/core/common/schema.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace policy {
15 namespace {
16 
TEST(RegistryDictTest,SetAndGetValue)17 TEST(RegistryDictTest, SetAndGetValue) {
18   RegistryDict test_dict;
19 
20   base::Value int_value(42);
21   base::Value string_value("fortytwo");
22 
23   test_dict.SetValue("one", int_value.CreateDeepCopy());
24   EXPECT_EQ(1u, test_dict.values().size());
25   EXPECT_EQ(int_value, *test_dict.GetValue("one"));
26   EXPECT_FALSE(test_dict.GetValue("two"));
27 
28   test_dict.SetValue("two", string_value.CreateDeepCopy());
29   EXPECT_EQ(2u, test_dict.values().size());
30   EXPECT_EQ(int_value, *test_dict.GetValue("one"));
31   EXPECT_EQ(string_value, *test_dict.GetValue("two"));
32 
33   std::unique_ptr<base::Value> one(test_dict.RemoveValue("one"));
34   EXPECT_EQ(1u, test_dict.values().size());
35   EXPECT_EQ(int_value, *one);
36   EXPECT_FALSE(test_dict.GetValue("one"));
37   EXPECT_EQ(string_value, *test_dict.GetValue("two"));
38 
39   test_dict.ClearValues();
40   EXPECT_FALSE(test_dict.GetValue("one"));
41   EXPECT_FALSE(test_dict.GetValue("two"));
42   EXPECT_TRUE(test_dict.values().empty());
43 }
44 
TEST(RegistryDictTest,CaseInsensitiveButPreservingValueNames)45 TEST(RegistryDictTest, CaseInsensitiveButPreservingValueNames) {
46   RegistryDict test_dict;
47 
48   base::Value int_value(42);
49   base::Value string_value("fortytwo");
50 
51   test_dict.SetValue("One", int_value.CreateDeepCopy());
52   EXPECT_EQ(1u, test_dict.values().size());
53   EXPECT_EQ(int_value, *test_dict.GetValue("oNe"));
54 
55   RegistryDict::ValueMap::const_iterator entry = test_dict.values().begin();
56   ASSERT_NE(entry, test_dict.values().end());
57   EXPECT_EQ("One", entry->first);
58 
59   test_dict.SetValue("ONE", string_value.CreateDeepCopy());
60   EXPECT_EQ(1u, test_dict.values().size());
61   EXPECT_EQ(string_value, *test_dict.GetValue("one"));
62 
63   std::unique_ptr<base::Value> removed_value(test_dict.RemoveValue("onE"));
64   EXPECT_EQ(string_value, *removed_value);
65   EXPECT_TRUE(test_dict.values().empty());
66 }
67 
TEST(RegistryDictTest,SetAndGetKeys)68 TEST(RegistryDictTest, SetAndGetKeys) {
69   RegistryDict test_dict;
70 
71   base::Value int_value(42);
72   base::Value string_value("fortytwo");
73 
74   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
75   subdict->SetValue("one", int_value.CreateDeepCopy());
76   test_dict.SetKey("two", std::move(subdict));
77   EXPECT_EQ(1u, test_dict.keys().size());
78   RegistryDict* actual_subdict = test_dict.GetKey("two");
79   ASSERT_TRUE(actual_subdict);
80   EXPECT_EQ(int_value, *actual_subdict->GetValue("one"));
81 
82   subdict.reset(new RegistryDict());
83   subdict->SetValue("three", string_value.CreateDeepCopy());
84   test_dict.SetKey("four", std::move(subdict));
85   EXPECT_EQ(2u, test_dict.keys().size());
86   actual_subdict = test_dict.GetKey("two");
87   ASSERT_TRUE(actual_subdict);
88   EXPECT_EQ(int_value, *actual_subdict->GetValue("one"));
89   actual_subdict = test_dict.GetKey("four");
90   ASSERT_TRUE(actual_subdict);
91   EXPECT_EQ(string_value, *actual_subdict->GetValue("three"));
92 
93   test_dict.ClearKeys();
94   EXPECT_FALSE(test_dict.GetKey("one"));
95   EXPECT_FALSE(test_dict.GetKey("three"));
96   EXPECT_TRUE(test_dict.keys().empty());
97 }
98 
TEST(RegistryDictTest,CaseInsensitiveButPreservingKeyNames)99 TEST(RegistryDictTest, CaseInsensitiveButPreservingKeyNames) {
100   RegistryDict test_dict;
101 
102   base::Value int_value(42);
103 
104   test_dict.SetKey("One", std::make_unique<RegistryDict>());
105   EXPECT_EQ(1u, test_dict.keys().size());
106   RegistryDict* actual_subdict = test_dict.GetKey("One");
107   ASSERT_TRUE(actual_subdict);
108   EXPECT_TRUE(actual_subdict->values().empty());
109 
110   RegistryDict::KeyMap::const_iterator entry = test_dict.keys().begin();
111   ASSERT_NE(entry, test_dict.keys().end());
112   EXPECT_EQ("One", entry->first);
113 
114   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
115   subdict->SetValue("two", int_value.CreateDeepCopy());
116   test_dict.SetKey("ONE", std::move(subdict));
117   EXPECT_EQ(1u, test_dict.keys().size());
118   actual_subdict = test_dict.GetKey("One");
119   ASSERT_TRUE(actual_subdict);
120   EXPECT_EQ(int_value, *actual_subdict->GetValue("two"));
121 
122   std::unique_ptr<RegistryDict> removed_key(test_dict.RemoveKey("one"));
123   ASSERT_TRUE(removed_key);
124   EXPECT_EQ(int_value, *removed_key->GetValue("two"));
125   EXPECT_TRUE(test_dict.keys().empty());
126 }
127 
TEST(RegistryDictTest,Merge)128 TEST(RegistryDictTest, Merge) {
129   RegistryDict dict_a;
130   RegistryDict dict_b;
131 
132   base::Value int_value(42);
133   base::Value string_value("fortytwo");
134 
135   dict_a.SetValue("one", int_value.CreateDeepCopy());
136   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
137   subdict->SetValue("two", string_value.CreateDeepCopy());
138   dict_a.SetKey("three", std::move(subdict));
139 
140   dict_b.SetValue("four", string_value.CreateDeepCopy());
141   subdict.reset(new RegistryDict());
142   subdict->SetValue("two", int_value.CreateDeepCopy());
143   dict_b.SetKey("three", std::move(subdict));
144   subdict.reset(new RegistryDict());
145   subdict->SetValue("five", int_value.CreateDeepCopy());
146   dict_b.SetKey("six", std::move(subdict));
147 
148   dict_a.Merge(dict_b);
149 
150   EXPECT_EQ(int_value, *dict_a.GetValue("one"));
151   EXPECT_EQ(string_value, *dict_b.GetValue("four"));
152   RegistryDict* actual_subdict = dict_a.GetKey("three");
153   ASSERT_TRUE(actual_subdict);
154   EXPECT_EQ(int_value, *actual_subdict->GetValue("two"));
155   actual_subdict = dict_a.GetKey("six");
156   ASSERT_TRUE(actual_subdict);
157   EXPECT_EQ(int_value, *actual_subdict->GetValue("five"));
158 }
159 
TEST(RegistryDictTest,Swap)160 TEST(RegistryDictTest, Swap) {
161   RegistryDict dict_a;
162   RegistryDict dict_b;
163 
164   base::Value int_value(42);
165   base::Value string_value("fortytwo");
166 
167   dict_a.SetValue("one", int_value.CreateDeepCopy());
168   dict_a.SetKey("two", std::make_unique<RegistryDict>());
169   dict_b.SetValue("three", string_value.CreateDeepCopy());
170 
171   dict_a.Swap(&dict_b);
172 
173   EXPECT_EQ(int_value, *dict_b.GetValue("one"));
174   EXPECT_TRUE(dict_b.GetKey("two"));
175   EXPECT_FALSE(dict_b.GetValue("two"));
176 
177   EXPECT_EQ(string_value, *dict_a.GetValue("three"));
178   EXPECT_FALSE(dict_a.GetValue("one"));
179   EXPECT_FALSE(dict_a.GetKey("two"));
180 }
181 
182 #if defined(OS_WIN)
TEST(RegistryDictTest,ConvertToJSON)183 TEST(RegistryDictTest, ConvertToJSON) {
184   RegistryDict test_dict;
185 
186   base::Value int_value(42);
187   base::Value string_value("fortytwo");
188   base::Value string_zero("0");
189   base::Value string_dict("{ \"key\": [ \"value\" ] }");
190 
191   test_dict.SetValue("one", int_value.CreateDeepCopy());
192   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
193   subdict->SetValue("two", string_value.CreateDeepCopy());
194   test_dict.SetKey("three", std::move(subdict));
195   std::unique_ptr<RegistryDict> list(new RegistryDict());
196   list->SetValue("1", string_value.CreateDeepCopy());
197   test_dict.SetKey("dict-to-list", std::move(list));
198   test_dict.SetValue("int-to-bool", int_value.CreateDeepCopy());
199   test_dict.SetValue("int-to-double", int_value.CreateDeepCopy());
200   test_dict.SetValue("string-to-bool", string_zero.CreateDeepCopy());
201   test_dict.SetValue("string-to-double", string_zero.CreateDeepCopy());
202   test_dict.SetValue("string-to-int", string_zero.CreateDeepCopy());
203   test_dict.SetValue("string-to-dict", string_dict.CreateDeepCopy());
204 
205   std::string error;
206   Schema schema = Schema::Parse(
207       "{"
208       "  \"type\": \"object\","
209       "  \"properties\": {"
210       "    \"dict-to-list\": {"
211       "      \"type\": \"array\","
212       "      \"items\": { \"type\": \"string\" }"
213       "    },"
214       "    \"int-to-bool\": { \"type\": \"boolean\" },"
215       "    \"int-to-double\": { \"type\": \"number\" },"
216       "    \"string-to-bool\": { \"type\": \"boolean\" },"
217       "    \"string-to-double\": { \"type\": \"number\" },"
218       "    \"string-to-int\": { \"type\": \"integer\" },"
219       "    \"string-to-dict\": { \"type\": \"object\" }"
220       "  }"
221       "}",
222       &error);
223   ASSERT_TRUE(schema.valid()) << error;
224 
225   std::unique_ptr<base::Value> actual(test_dict.ConvertToJSON(schema));
226 
227   base::DictionaryValue expected;
228   expected.SetKey("one", int_value.Clone());
229   auto expected_subdict = std::make_unique<base::DictionaryValue>();
230   expected_subdict->SetKey("two", string_value.Clone());
231   expected.Set("three", std::move(expected_subdict));
232   auto expected_list = std::make_unique<base::ListValue>();
233   expected_list->Append(std::make_unique<base::Value>(string_value.Clone()));
234   expected.Set("dict-to-list", std::move(expected_list));
235   expected.SetBoolean("int-to-bool", true);
236   expected.SetDouble("int-to-double", 42.0);
237   expected.SetBoolean("string-to-bool", false);
238   expected.SetDouble("string-to-double", 0.0);
239   expected.SetInteger("string-to-int", static_cast<int>(0));
240   expected_list = std::make_unique<base::ListValue>();
241   expected_list->Append(std::make_unique<base::Value>("value"));
242   expected_subdict = std::make_unique<base::DictionaryValue>();
243   expected_subdict->Set("key", std::move(expected_list));
244   expected.Set("string-to-dict", std::move(expected_subdict));
245 
246   EXPECT_EQ(expected, *actual);
247 }
248 
TEST(RegistryDictTest,NonSequentialConvertToJSON)249 TEST(RegistryDictTest, NonSequentialConvertToJSON) {
250   RegistryDict test_dict;
251 
252   std::unique_ptr<RegistryDict> list(new RegistryDict());
253   list->SetValue("1", base::Value("1").CreateDeepCopy());
254   list->SetValue("2", base::Value("2").CreateDeepCopy());
255   list->SetValue("THREE", base::Value("3").CreateDeepCopy());
256   list->SetValue("4", base::Value("4").CreateDeepCopy());
257   test_dict.SetKey("dict-to-list", std::move(list));
258 
259   std::string error;
260   Schema schema = Schema::Parse(
261       "{"
262       "  \"type\": \"object\","
263       "  \"properties\": {"
264       "    \"dict-to-list\": {"
265       "      \"type\": \"array\","
266       "      \"items\": { \"type\": \"string\" }"
267       "    }"
268       "  }"
269       "}",
270       &error);
271   ASSERT_TRUE(schema.valid()) << error;
272 
273   std::unique_ptr<base::Value> actual(test_dict.ConvertToJSON(schema));
274 
275   base::DictionaryValue expected;
276   std::unique_ptr<base::ListValue> expected_list(new base::ListValue());
277   expected_list->Append(base::Value("1").CreateDeepCopy());
278   expected_list->Append(base::Value("2").CreateDeepCopy());
279   expected_list->Append(base::Value("4").CreateDeepCopy());
280   expected.Set("dict-to-list", std::move(expected_list));
281 
282   EXPECT_EQ(expected, *actual);
283 }
284 #endif
285 
TEST(RegistryDictTest,KeyValueNameClashes)286 TEST(RegistryDictTest, KeyValueNameClashes) {
287   RegistryDict test_dict;
288 
289   base::Value int_value(42);
290   base::Value string_value("fortytwo");
291 
292   test_dict.SetValue("one", int_value.CreateDeepCopy());
293   std::unique_ptr<RegistryDict> subdict(new RegistryDict());
294   subdict->SetValue("two", string_value.CreateDeepCopy());
295   test_dict.SetKey("one", std::move(subdict));
296 
297   EXPECT_EQ(int_value, *test_dict.GetValue("one"));
298   RegistryDict* actual_subdict = test_dict.GetKey("one");
299   ASSERT_TRUE(actual_subdict);
300   EXPECT_EQ(string_value, *actual_subdict->GetValue("two"));
301 }
302 
303 }  // namespace
304 }  // namespace policy
305