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