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