OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/syncable_prefs/pref_model_associator.h" | |
6 | |
7 #include <memory> | |
8 | |
9 #include "base/macros.h" | |
10 #include "base/memory/ref_counted.h" | |
11 #include "base/values.h" | |
12 #include "components/prefs/scoped_user_pref_update.h" | |
13 #include "components/syncable_prefs/pref_model_associator_client.h" | |
14 #include "components/syncable_prefs/pref_service_mock_factory.h" | |
15 #include "components/syncable_prefs/pref_service_syncable.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace syncable_prefs { | |
19 | |
20 namespace { | |
21 | |
22 const char kStringPrefName[] = "pref.string"; | |
23 const char kListPrefName[] = "pref.list"; | |
24 const char kDictionaryPrefName[] = "pref.dictionary"; | |
25 | |
26 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient { | |
27 public: | |
28 TestPrefModelAssociatorClient() {} | |
29 ~TestPrefModelAssociatorClient() override {} | |
30 | |
31 // PrefModelAssociatorClient implementation. | |
32 bool IsMergeableListPreference(const std::string& pref_name) const override { | |
33 return pref_name == kListPrefName; | |
34 } | |
35 | |
36 bool IsMergeableDictionaryPreference( | |
37 const std::string& pref_name) const override { | |
38 return pref_name == kDictionaryPrefName; | |
39 } | |
40 | |
41 private: | |
42 DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient); | |
43 }; | |
44 | |
45 class AbstractPreferenceMergeTest : public testing::Test { | |
46 protected: | |
47 AbstractPreferenceMergeTest() { | |
48 PrefServiceMockFactory factory; | |
49 factory.SetPrefModelAssociatorClient(&client_); | |
50 scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry( | |
51 new user_prefs::PrefRegistrySyncable); | |
52 pref_registry->RegisterStringPref( | |
53 kStringPrefName, | |
54 std::string(), | |
55 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
56 pref_registry->RegisterListPref( | |
57 kListPrefName, | |
58 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
59 pref_registry->RegisterDictionaryPref( | |
60 kDictionaryPrefName, | |
61 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); | |
62 pref_service_ = factory.CreateSyncable(pref_registry.get()); | |
63 pref_sync_service_ = static_cast<PrefModelAssociator*>( | |
64 pref_service_->GetSyncableService(syncer::PREFERENCES)); | |
65 } | |
66 | |
67 void SetContentPattern(base::DictionaryValue* patterns_dict, | |
68 const std::string& expression, | |
69 int setting) { | |
70 base::DictionaryValue* expression_dict; | |
71 bool found = | |
72 patterns_dict->GetDictionaryWithoutPathExpansion(expression, | |
73 &expression_dict); | |
74 if (!found) { | |
75 expression_dict = new base::DictionaryValue; | |
76 patterns_dict->SetWithoutPathExpansion(expression, expression_dict); | |
77 } | |
78 expression_dict->SetWithoutPathExpansion( | |
79 "setting", new base::FundamentalValue(setting)); | |
80 } | |
81 | |
82 void SetPrefToEmpty(const std::string& pref_name) { | |
83 std::unique_ptr<base::Value> empty_value; | |
84 const PrefService::Preference* pref = | |
85 pref_service_->FindPreference(pref_name.c_str()); | |
86 ASSERT_TRUE(pref); | |
87 base::Value::Type type = pref->GetType(); | |
88 if (type == base::Value::TYPE_DICTIONARY) | |
89 empty_value.reset(new base::DictionaryValue); | |
90 else if (type == base::Value::TYPE_LIST) | |
91 empty_value.reset(new base::ListValue); | |
92 else | |
93 FAIL(); | |
94 pref_service_->Set(pref_name.c_str(), *empty_value); | |
95 } | |
96 | |
97 TestPrefModelAssociatorClient client_; | |
98 std::unique_ptr<PrefServiceSyncable> pref_service_; | |
99 PrefModelAssociator* pref_sync_service_; | |
100 }; | |
101 | |
102 class ListPreferenceMergeTest : public AbstractPreferenceMergeTest { | |
103 protected: | |
104 ListPreferenceMergeTest() | |
105 : server_url0_("http://example.com/server0"), | |
106 server_url1_("http://example.com/server1"), | |
107 local_url0_("http://example.com/local0"), | |
108 local_url1_("http://example.com/local1") { | |
109 server_url_list_.AppendString(server_url0_); | |
110 server_url_list_.AppendString(server_url1_); | |
111 } | |
112 | |
113 std::string server_url0_; | |
114 std::string server_url1_; | |
115 std::string local_url0_; | |
116 std::string local_url1_; | |
117 base::ListValue server_url_list_; | |
118 }; | |
119 | |
120 TEST_F(ListPreferenceMergeTest, NotListOrDictionary) { | |
121 pref_service_->SetString(kStringPrefName, local_url0_); | |
122 const PrefService::Preference* pref = | |
123 pref_service_->FindPreference(kStringPrefName); | |
124 std::unique_ptr<base::Value> server_value( | |
125 new base::StringValue(server_url0_)); | |
126 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
127 pref->name(), *pref->GetValue(), *server_value)); | |
128 EXPECT_TRUE(merged_value->Equals(server_value.get())); | |
129 } | |
130 | |
131 TEST_F(ListPreferenceMergeTest, LocalEmpty) { | |
132 SetPrefToEmpty(kListPrefName); | |
133 const PrefService::Preference* pref = | |
134 pref_service_->FindPreference(kListPrefName); | |
135 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
136 pref->name(), *pref->GetValue(), server_url_list_)); | |
137 EXPECT_TRUE(merged_value->Equals(&server_url_list_)); | |
138 } | |
139 | |
140 TEST_F(ListPreferenceMergeTest, ServerNull) { | |
141 std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue(); | |
142 { | |
143 ListPrefUpdate update(pref_service_.get(), kListPrefName); | |
144 base::ListValue* local_list_value = update.Get(); | |
145 local_list_value->AppendString(local_url0_); | |
146 } | |
147 | |
148 const PrefService::Preference* pref = | |
149 pref_service_->FindPreference(kListPrefName); | |
150 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
151 pref->name(), *pref->GetValue(), *null_value)); | |
152 const base::ListValue* local_list_value = | |
153 pref_service_->GetList(kListPrefName); | |
154 EXPECT_TRUE(merged_value->Equals(local_list_value)); | |
155 } | |
156 | |
157 TEST_F(ListPreferenceMergeTest, ServerEmpty) { | |
158 std::unique_ptr<base::Value> empty_value(new base::ListValue); | |
159 { | |
160 ListPrefUpdate update(pref_service_.get(), kListPrefName); | |
161 base::ListValue* local_list_value = update.Get(); | |
162 local_list_value->AppendString(local_url0_); | |
163 } | |
164 | |
165 const PrefService::Preference* pref = | |
166 pref_service_->FindPreference(kListPrefName); | |
167 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
168 pref->name(), *pref->GetValue(), *empty_value)); | |
169 const base::ListValue* local_list_value = | |
170 pref_service_->GetList(kListPrefName); | |
171 EXPECT_TRUE(merged_value->Equals(local_list_value)); | |
172 } | |
173 | |
174 TEST_F(ListPreferenceMergeTest, Merge) { | |
175 { | |
176 ListPrefUpdate update(pref_service_.get(), kListPrefName); | |
177 base::ListValue* local_list_value = update.Get(); | |
178 local_list_value->AppendString(local_url0_); | |
179 local_list_value->AppendString(local_url1_); | |
180 } | |
181 | |
182 const PrefService::Preference* pref = | |
183 pref_service_->FindPreference(kListPrefName); | |
184 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
185 pref->name(), *pref->GetValue(), server_url_list_)); | |
186 | |
187 base::ListValue expected; | |
188 expected.AppendString(server_url0_); | |
189 expected.AppendString(server_url1_); | |
190 expected.AppendString(local_url0_); | |
191 expected.AppendString(local_url1_); | |
192 EXPECT_TRUE(merged_value->Equals(&expected)); | |
193 } | |
194 | |
195 TEST_F(ListPreferenceMergeTest, Duplicates) { | |
196 { | |
197 ListPrefUpdate update(pref_service_.get(), kListPrefName); | |
198 base::ListValue* local_list_value = update.Get(); | |
199 local_list_value->AppendString(local_url0_); | |
200 local_list_value->AppendString(server_url0_); | |
201 local_list_value->AppendString(server_url1_); | |
202 } | |
203 | |
204 const PrefService::Preference* pref = | |
205 pref_service_->FindPreference(kListPrefName); | |
206 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
207 pref->name(), *pref->GetValue(), server_url_list_)); | |
208 | |
209 base::ListValue expected; | |
210 expected.AppendString(server_url0_); | |
211 expected.AppendString(server_url1_); | |
212 expected.AppendString(local_url0_); | |
213 EXPECT_TRUE(merged_value->Equals(&expected)); | |
214 } | |
215 | |
216 TEST_F(ListPreferenceMergeTest, Equals) { | |
217 { | |
218 ListPrefUpdate update(pref_service_.get(), kListPrefName); | |
219 base::ListValue* local_list_value = update.Get(); | |
220 local_list_value->AppendString(server_url0_); | |
221 local_list_value->AppendString(server_url1_); | |
222 } | |
223 | |
224 std::unique_ptr<base::Value> original(server_url_list_.DeepCopy()); | |
225 const PrefService::Preference* pref = | |
226 pref_service_->FindPreference(kListPrefName); | |
227 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
228 pref->name(), *pref->GetValue(), server_url_list_)); | |
229 EXPECT_TRUE(merged_value->Equals(original.get())); | |
230 } | |
231 | |
232 class DictionaryPreferenceMergeTest : public AbstractPreferenceMergeTest { | |
233 protected: | |
234 DictionaryPreferenceMergeTest() | |
235 : expression0_("expression0"), | |
236 expression1_("expression1"), | |
237 expression2_("expression2"), | |
238 expression3_("expression3"), | |
239 expression4_("expression4") { | |
240 SetContentPattern(&server_patterns_, expression0_, 1); | |
241 SetContentPattern(&server_patterns_, expression1_, 2); | |
242 SetContentPattern(&server_patterns_, expression2_, 1); | |
243 } | |
244 | |
245 std::string expression0_; | |
246 std::string expression1_; | |
247 std::string expression2_; | |
248 std::string expression3_; | |
249 std::string expression4_; | |
250 base::DictionaryValue server_patterns_; | |
251 }; | |
252 | |
253 TEST_F(DictionaryPreferenceMergeTest, LocalEmpty) { | |
254 SetPrefToEmpty(kDictionaryPrefName); | |
255 const PrefService::Preference* pref = | |
256 pref_service_->FindPreference(kDictionaryPrefName); | |
257 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
258 pref->name(), *pref->GetValue(), server_patterns_)); | |
259 EXPECT_TRUE(merged_value->Equals(&server_patterns_)); | |
260 } | |
261 | |
262 TEST_F(DictionaryPreferenceMergeTest, ServerNull) { | |
263 std::unique_ptr<base::Value> null_value = base::Value::CreateNullValue(); | |
264 { | |
265 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
266 base::DictionaryValue* local_dict_value = update.Get(); | |
267 SetContentPattern(local_dict_value, expression3_, 1); | |
268 } | |
269 | |
270 const PrefService::Preference* pref = | |
271 pref_service_->FindPreference(kDictionaryPrefName); | |
272 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
273 pref->name(), *pref->GetValue(), *null_value)); | |
274 const base::DictionaryValue* local_dict_value = | |
275 pref_service_->GetDictionary(kDictionaryPrefName); | |
276 EXPECT_TRUE(merged_value->Equals(local_dict_value)); | |
277 } | |
278 | |
279 TEST_F(DictionaryPreferenceMergeTest, ServerEmpty) { | |
280 std::unique_ptr<base::Value> empty_value(new base::DictionaryValue); | |
281 { | |
282 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
283 base::DictionaryValue* local_dict_value = update.Get(); | |
284 SetContentPattern(local_dict_value, expression3_, 1); | |
285 } | |
286 | |
287 const PrefService::Preference* pref = | |
288 pref_service_->FindPreference(kDictionaryPrefName); | |
289 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
290 pref->name(), *pref->GetValue(), *empty_value)); | |
291 const base::DictionaryValue* local_dict_value = | |
292 pref_service_->GetDictionary(kDictionaryPrefName); | |
293 EXPECT_TRUE(merged_value->Equals(local_dict_value)); | |
294 } | |
295 | |
296 TEST_F(DictionaryPreferenceMergeTest, MergeNoConflicts) { | |
297 { | |
298 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
299 base::DictionaryValue* local_dict_value = update.Get(); | |
300 SetContentPattern(local_dict_value, expression3_, 1); | |
301 } | |
302 | |
303 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
304 kDictionaryPrefName, | |
305 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(), | |
306 server_patterns_)); | |
307 | |
308 base::DictionaryValue expected; | |
309 SetContentPattern(&expected, expression0_, 1); | |
310 SetContentPattern(&expected, expression1_, 2); | |
311 SetContentPattern(&expected, expression2_, 1); | |
312 SetContentPattern(&expected, expression3_, 1); | |
313 EXPECT_TRUE(merged_value->Equals(&expected)); | |
314 } | |
315 | |
316 TEST_F(DictionaryPreferenceMergeTest, MergeConflicts) { | |
317 { | |
318 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
319 base::DictionaryValue* local_dict_value = update.Get(); | |
320 SetContentPattern(local_dict_value, expression0_, 2); | |
321 SetContentPattern(local_dict_value, expression2_, 1); | |
322 SetContentPattern(local_dict_value, expression3_, 1); | |
323 SetContentPattern(local_dict_value, expression4_, 2); | |
324 } | |
325 | |
326 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
327 kDictionaryPrefName, | |
328 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(), | |
329 server_patterns_)); | |
330 | |
331 base::DictionaryValue expected; | |
332 SetContentPattern(&expected, expression0_, 1); | |
333 SetContentPattern(&expected, expression1_, 2); | |
334 SetContentPattern(&expected, expression2_, 1); | |
335 SetContentPattern(&expected, expression3_, 1); | |
336 SetContentPattern(&expected, expression4_, 2); | |
337 EXPECT_TRUE(merged_value->Equals(&expected)); | |
338 } | |
339 | |
340 TEST_F(DictionaryPreferenceMergeTest, MergeValueToDictionary) { | |
341 base::DictionaryValue local_dict_value; | |
342 local_dict_value.SetInteger("key", 0); | |
343 | |
344 base::DictionaryValue server_dict_value; | |
345 server_dict_value.SetInteger("key.subkey", 0); | |
346 | |
347 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
348 kDictionaryPrefName, local_dict_value, server_dict_value)); | |
349 | |
350 EXPECT_TRUE(merged_value->Equals(&server_dict_value)); | |
351 } | |
352 | |
353 TEST_F(DictionaryPreferenceMergeTest, Equal) { | |
354 { | |
355 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
356 base::DictionaryValue* local_dict_value = update.Get(); | |
357 SetContentPattern(local_dict_value, expression0_, 1); | |
358 SetContentPattern(local_dict_value, expression1_, 2); | |
359 SetContentPattern(local_dict_value, expression2_, 1); | |
360 } | |
361 | |
362 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
363 kDictionaryPrefName, | |
364 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(), | |
365 server_patterns_)); | |
366 EXPECT_TRUE(merged_value->Equals(&server_patterns_)); | |
367 } | |
368 | |
369 TEST_F(DictionaryPreferenceMergeTest, ConflictButServerWins) { | |
370 { | |
371 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName); | |
372 base::DictionaryValue* local_dict_value = update.Get(); | |
373 SetContentPattern(local_dict_value, expression0_, 2); | |
374 SetContentPattern(local_dict_value, expression1_, 2); | |
375 SetContentPattern(local_dict_value, expression2_, 1); | |
376 } | |
377 | |
378 std::unique_ptr<base::Value> merged_value(pref_sync_service_->MergePreference( | |
379 kDictionaryPrefName, | |
380 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(), | |
381 server_patterns_)); | |
382 EXPECT_TRUE(merged_value->Equals(&server_patterns_)); | |
383 } | |
384 | |
385 class IndividualPreferenceMergeTest : public AbstractPreferenceMergeTest { | |
386 protected: | |
387 IndividualPreferenceMergeTest() | |
388 : url0_("http://example.com/server0"), | |
389 url1_("http://example.com/server1"), | |
390 expression0_("expression0"), | |
391 expression1_("expression1") { | |
392 server_url_list_.AppendString(url0_); | |
393 SetContentPattern(&server_patterns_, expression0_, 1); | |
394 } | |
395 | |
396 bool MergeListPreference(const char* pref) { | |
397 { | |
398 ListPrefUpdate update(pref_service_.get(), pref); | |
399 base::ListValue* local_list_value = update.Get(); | |
400 local_list_value->AppendString(url1_); | |
401 } | |
402 | |
403 std::unique_ptr<base::Value> merged_value( | |
404 pref_sync_service_->MergePreference( | |
405 pref, *pref_service_->GetUserPrefValue(pref), server_url_list_)); | |
406 | |
407 base::ListValue expected; | |
408 expected.AppendString(url0_); | |
409 expected.AppendString(url1_); | |
410 return merged_value->Equals(&expected); | |
411 } | |
412 | |
413 bool MergeDictionaryPreference(const char* pref) { | |
414 { | |
415 DictionaryPrefUpdate update(pref_service_.get(), pref); | |
416 base::DictionaryValue* local_dict_value = update.Get(); | |
417 SetContentPattern(local_dict_value, expression1_, 1); | |
418 } | |
419 | |
420 std::unique_ptr<base::Value> merged_value( | |
421 pref_sync_service_->MergePreference( | |
422 pref, *pref_service_->GetUserPrefValue(pref), server_patterns_)); | |
423 | |
424 base::DictionaryValue expected; | |
425 SetContentPattern(&expected, expression0_, 1); | |
426 SetContentPattern(&expected, expression1_, 1); | |
427 return merged_value->Equals(&expected); | |
428 } | |
429 | |
430 std::string url0_; | |
431 std::string url1_; | |
432 std::string expression0_; | |
433 std::string expression1_; | |
434 std::string content_type0_; | |
435 base::ListValue server_url_list_; | |
436 base::DictionaryValue server_patterns_; | |
437 }; | |
438 | |
439 TEST_F(IndividualPreferenceMergeTest, ListPreference) { | |
440 EXPECT_TRUE(MergeListPreference(kListPrefName)); | |
441 } | |
442 | |
443 } // namespace | |
444 | |
445 } // namespace syncable_prefs | |
OLD | NEW |