Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / syncable_prefs / pref_model_associator_unittest.cc
blob84523dbbaf54788176d8dc843d6bcbe14b4751e5
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.
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 "components/syncable_prefs/pref_model_associator.h"
11 #include "components/syncable_prefs/pref_model_associator_client.h"
12 #include "components/syncable_prefs/pref_service_mock_factory.h"
13 #include "components/syncable_prefs/pref_service_syncable.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace syncable_prefs {
18 namespace {
20 const char kStringPrefName[] = "pref.string";
21 const char kListPrefName[] = "pref.list";
22 const char kDictionaryPrefName[] = "pref.dictionary";
24 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
25 public:
26 TestPrefModelAssociatorClient() {}
27 ~TestPrefModelAssociatorClient() override {}
29 // PrefModelAssociatorClient implementation.
30 bool IsMergeableListPreference(const std::string& pref_name) const override {
31 return pref_name == kListPrefName;
34 bool IsMergeableDictionaryPreference(
35 const std::string& pref_name) const override {
36 return pref_name == kDictionaryPrefName;
39 bool IsMigratedPreference(const std::string& new_pref_name,
40 std::string* old_pref_name) const override {
41 return false;
44 bool IsOldMigratedPreference(const std::string& old_pref_name,
45 std::string* new_pref_name) const override {
46 return false;
49 private:
50 DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient);
53 class AbstractPreferenceMergeTest : public testing::Test {
54 protected:
55 AbstractPreferenceMergeTest() {
56 PrefServiceMockFactory factory;
57 factory.SetPrefModelAssociatorClient(&client_);
58 scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry(
59 new user_prefs::PrefRegistrySyncable);
60 pref_registry->RegisterStringPref(
61 kStringPrefName,
62 std::string(),
63 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
64 pref_registry->RegisterListPref(
65 kListPrefName,
66 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
67 pref_registry->RegisterDictionaryPref(
68 kDictionaryPrefName,
69 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
70 pref_service_ = factory.CreateSyncable(pref_registry.get());
71 pref_sync_service_ = static_cast<PrefModelAssociator*>(
72 pref_service_->GetSyncableService(syncer::PREFERENCES));
75 void SetContentPattern(base::DictionaryValue* patterns_dict,
76 const std::string& expression,
77 int setting) {
78 base::DictionaryValue* expression_dict;
79 bool found =
80 patterns_dict->GetDictionaryWithoutPathExpansion(expression,
81 &expression_dict);
82 if (!found) {
83 expression_dict = new base::DictionaryValue;
84 patterns_dict->SetWithoutPathExpansion(expression, expression_dict);
86 expression_dict->SetWithoutPathExpansion(
87 "setting", new base::FundamentalValue(setting));
90 void SetPrefToEmpty(const std::string& pref_name) {
91 scoped_ptr<base::Value> empty_value;
92 const PrefService::Preference* pref =
93 pref_service_->FindPreference(pref_name.c_str());
94 ASSERT_TRUE(pref);
95 base::Value::Type type = pref->GetType();
96 if (type == base::Value::TYPE_DICTIONARY)
97 empty_value.reset(new base::DictionaryValue);
98 else if (type == base::Value::TYPE_LIST)
99 empty_value.reset(new base::ListValue);
100 else
101 FAIL();
102 pref_service_->Set(pref_name.c_str(), *empty_value);
105 TestPrefModelAssociatorClient client_;
106 scoped_ptr<PrefServiceSyncable> pref_service_;
107 PrefModelAssociator* pref_sync_service_;
110 class ListPreferenceMergeTest : public AbstractPreferenceMergeTest {
111 protected:
112 ListPreferenceMergeTest()
113 : server_url0_("http://example.com/server0"),
114 server_url1_("http://example.com/server1"),
115 local_url0_("http://example.com/local0"),
116 local_url1_("http://example.com/local1") {
117 server_url_list_.Append(new base::StringValue(server_url0_));
118 server_url_list_.Append(new base::StringValue(server_url1_));
121 std::string server_url0_;
122 std::string server_url1_;
123 std::string local_url0_;
124 std::string local_url1_;
125 base::ListValue server_url_list_;
128 TEST_F(ListPreferenceMergeTest, NotListOrDictionary) {
129 pref_service_->SetString(kStringPrefName, local_url0_);
130 const PrefService::Preference* pref =
131 pref_service_->FindPreference(kStringPrefName);
132 scoped_ptr<base::Value> server_value(new base::StringValue(server_url0_));
133 scoped_ptr<base::Value> merged_value(
134 pref_sync_service_->MergePreference(pref->name(),
135 *pref->GetValue(),
136 *server_value));
137 EXPECT_TRUE(merged_value->Equals(server_value.get()));
140 TEST_F(ListPreferenceMergeTest, LocalEmpty) {
141 SetPrefToEmpty(kListPrefName);
142 const PrefService::Preference* pref =
143 pref_service_->FindPreference(kListPrefName);
144 scoped_ptr<base::Value> merged_value(
145 pref_sync_service_->MergePreference(pref->name(),
146 *pref->GetValue(),
147 server_url_list_));
148 EXPECT_TRUE(merged_value->Equals(&server_url_list_));
151 TEST_F(ListPreferenceMergeTest, ServerNull) {
152 scoped_ptr<base::Value> null_value = base::Value::CreateNullValue();
154 ListPrefUpdate update(pref_service_.get(), kListPrefName);
155 base::ListValue* local_list_value = update.Get();
156 local_list_value->Append(new base::StringValue(local_url0_));
159 const PrefService::Preference* pref =
160 pref_service_->FindPreference(kListPrefName);
161 scoped_ptr<base::Value> merged_value(
162 pref_sync_service_->MergePreference(pref->name(),
163 *pref->GetValue(),
164 *null_value));
165 const base::ListValue* local_list_value =
166 pref_service_->GetList(kListPrefName);
167 EXPECT_TRUE(merged_value->Equals(local_list_value));
170 TEST_F(ListPreferenceMergeTest, ServerEmpty) {
171 scoped_ptr<base::Value> empty_value(new base::ListValue);
173 ListPrefUpdate update(pref_service_.get(), kListPrefName);
174 base::ListValue* local_list_value = update.Get();
175 local_list_value->Append(new base::StringValue(local_url0_));
178 const PrefService::Preference* pref =
179 pref_service_->FindPreference(kListPrefName);
180 scoped_ptr<base::Value> merged_value(
181 pref_sync_service_->MergePreference(pref->name(),
182 *pref->GetValue(),
183 *empty_value));
184 const base::ListValue* local_list_value =
185 pref_service_->GetList(kListPrefName);
186 EXPECT_TRUE(merged_value->Equals(local_list_value));
189 TEST_F(ListPreferenceMergeTest, Merge) {
191 ListPrefUpdate update(pref_service_.get(), kListPrefName);
192 base::ListValue* local_list_value = update.Get();
193 local_list_value->Append(new base::StringValue(local_url0_));
194 local_list_value->Append(new base::StringValue(local_url1_));
197 const PrefService::Preference* pref =
198 pref_service_->FindPreference(kListPrefName);
199 scoped_ptr<base::Value> merged_value(
200 pref_sync_service_->MergePreference(pref->name(),
201 *pref->GetValue(),
202 server_url_list_));
204 base::ListValue expected;
205 expected.Append(new base::StringValue(server_url0_));
206 expected.Append(new base::StringValue(server_url1_));
207 expected.Append(new base::StringValue(local_url0_));
208 expected.Append(new base::StringValue(local_url1_));
209 EXPECT_TRUE(merged_value->Equals(&expected));
212 TEST_F(ListPreferenceMergeTest, Duplicates) {
214 ListPrefUpdate update(pref_service_.get(), kListPrefName);
215 base::ListValue* local_list_value = update.Get();
216 local_list_value->Append(new base::StringValue(local_url0_));
217 local_list_value->Append(new base::StringValue(server_url0_));
218 local_list_value->Append(new base::StringValue(server_url1_));
221 const PrefService::Preference* pref =
222 pref_service_->FindPreference(kListPrefName);
223 scoped_ptr<base::Value> merged_value(
224 pref_sync_service_->MergePreference(pref->name(),
225 *pref->GetValue(),
226 server_url_list_));
228 base::ListValue expected;
229 expected.Append(new base::StringValue(server_url0_));
230 expected.Append(new base::StringValue(server_url1_));
231 expected.Append(new base::StringValue(local_url0_));
232 EXPECT_TRUE(merged_value->Equals(&expected));
235 TEST_F(ListPreferenceMergeTest, Equals) {
237 ListPrefUpdate update(pref_service_.get(), kListPrefName);
238 base::ListValue* local_list_value = update.Get();
239 local_list_value->Append(new base::StringValue(server_url0_));
240 local_list_value->Append(new base::StringValue(server_url1_));
243 scoped_ptr<base::Value> original(server_url_list_.DeepCopy());
244 const PrefService::Preference* pref =
245 pref_service_->FindPreference(kListPrefName);
246 scoped_ptr<base::Value> merged_value(
247 pref_sync_service_->MergePreference(pref->name(),
248 *pref->GetValue(),
249 server_url_list_));
250 EXPECT_TRUE(merged_value->Equals(original.get()));
253 class DictionaryPreferenceMergeTest : public AbstractPreferenceMergeTest {
254 protected:
255 DictionaryPreferenceMergeTest()
256 : expression0_("expression0"),
257 expression1_("expression1"),
258 expression2_("expression2"),
259 expression3_("expression3"),
260 expression4_("expression4") {
261 SetContentPattern(&server_patterns_, expression0_, 1);
262 SetContentPattern(&server_patterns_, expression1_, 2);
263 SetContentPattern(&server_patterns_, expression2_, 1);
266 std::string expression0_;
267 std::string expression1_;
268 std::string expression2_;
269 std::string expression3_;
270 std::string expression4_;
271 base::DictionaryValue server_patterns_;
274 TEST_F(DictionaryPreferenceMergeTest, LocalEmpty) {
275 SetPrefToEmpty(kDictionaryPrefName);
276 const PrefService::Preference* pref =
277 pref_service_->FindPreference(kDictionaryPrefName);
278 scoped_ptr<base::Value> merged_value(
279 pref_sync_service_->MergePreference(pref->name(),
280 *pref->GetValue(),
281 server_patterns_));
282 EXPECT_TRUE(merged_value->Equals(&server_patterns_));
285 TEST_F(DictionaryPreferenceMergeTest, ServerNull) {
286 scoped_ptr<base::Value> null_value = base::Value::CreateNullValue();
288 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
289 base::DictionaryValue* local_dict_value = update.Get();
290 SetContentPattern(local_dict_value, expression3_, 1);
293 const PrefService::Preference* pref =
294 pref_service_->FindPreference(kDictionaryPrefName);
295 scoped_ptr<base::Value> merged_value(
296 pref_sync_service_->MergePreference(pref->name(),
297 *pref->GetValue(),
298 *null_value));
299 const base::DictionaryValue* local_dict_value =
300 pref_service_->GetDictionary(kDictionaryPrefName);
301 EXPECT_TRUE(merged_value->Equals(local_dict_value));
304 TEST_F(DictionaryPreferenceMergeTest, ServerEmpty) {
305 scoped_ptr<base::Value> empty_value(new base::DictionaryValue);
307 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
308 base::DictionaryValue* local_dict_value = update.Get();
309 SetContentPattern(local_dict_value, expression3_, 1);
312 const PrefService::Preference* pref =
313 pref_service_->FindPreference(kDictionaryPrefName);
314 scoped_ptr<base::Value> merged_value(
315 pref_sync_service_->MergePreference(pref->name(),
316 *pref->GetValue(),
317 *empty_value));
318 const base::DictionaryValue* local_dict_value =
319 pref_service_->GetDictionary(kDictionaryPrefName);
320 EXPECT_TRUE(merged_value->Equals(local_dict_value));
323 TEST_F(DictionaryPreferenceMergeTest, MergeNoConflicts) {
325 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
326 base::DictionaryValue* local_dict_value = update.Get();
327 SetContentPattern(local_dict_value, expression3_, 1);
330 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
331 kDictionaryPrefName,
332 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(),
333 server_patterns_));
335 base::DictionaryValue expected;
336 SetContentPattern(&expected, expression0_, 1);
337 SetContentPattern(&expected, expression1_, 2);
338 SetContentPattern(&expected, expression2_, 1);
339 SetContentPattern(&expected, expression3_, 1);
340 EXPECT_TRUE(merged_value->Equals(&expected));
343 TEST_F(DictionaryPreferenceMergeTest, MergeConflicts) {
345 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
346 base::DictionaryValue* local_dict_value = update.Get();
347 SetContentPattern(local_dict_value, expression0_, 2);
348 SetContentPattern(local_dict_value, expression2_, 1);
349 SetContentPattern(local_dict_value, expression3_, 1);
350 SetContentPattern(local_dict_value, expression4_, 2);
353 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
354 kDictionaryPrefName,
355 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(),
356 server_patterns_));
358 base::DictionaryValue expected;
359 SetContentPattern(&expected, expression0_, 1);
360 SetContentPattern(&expected, expression1_, 2);
361 SetContentPattern(&expected, expression2_, 1);
362 SetContentPattern(&expected, expression3_, 1);
363 SetContentPattern(&expected, expression4_, 2);
364 EXPECT_TRUE(merged_value->Equals(&expected));
367 TEST_F(DictionaryPreferenceMergeTest, MergeValueToDictionary) {
368 base::DictionaryValue local_dict_value;
369 local_dict_value.SetInteger("key", 0);
371 base::DictionaryValue server_dict_value;
372 server_dict_value.SetInteger("key.subkey", 0);
374 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
375 kDictionaryPrefName,
376 local_dict_value,
377 server_dict_value));
379 EXPECT_TRUE(merged_value->Equals(&server_dict_value));
382 TEST_F(DictionaryPreferenceMergeTest, Equal) {
384 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
385 base::DictionaryValue* local_dict_value = update.Get();
386 SetContentPattern(local_dict_value, expression0_, 1);
387 SetContentPattern(local_dict_value, expression1_, 2);
388 SetContentPattern(local_dict_value, expression2_, 1);
391 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
392 kDictionaryPrefName,
393 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(),
394 server_patterns_));
395 EXPECT_TRUE(merged_value->Equals(&server_patterns_));
398 TEST_F(DictionaryPreferenceMergeTest, ConflictButServerWins) {
400 DictionaryPrefUpdate update(pref_service_.get(), kDictionaryPrefName);
401 base::DictionaryValue* local_dict_value = update.Get();
402 SetContentPattern(local_dict_value, expression0_, 2);
403 SetContentPattern(local_dict_value, expression1_, 2);
404 SetContentPattern(local_dict_value, expression2_, 1);
407 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
408 kDictionaryPrefName,
409 *pref_service_->FindPreference(kDictionaryPrefName)->GetValue(),
410 server_patterns_));
411 EXPECT_TRUE(merged_value->Equals(&server_patterns_));
414 class IndividualPreferenceMergeTest : public AbstractPreferenceMergeTest {
415 protected:
416 IndividualPreferenceMergeTest()
417 : url0_("http://example.com/server0"),
418 url1_("http://example.com/server1"),
419 expression0_("expression0"),
420 expression1_("expression1") {
421 server_url_list_.Append(new base::StringValue(url0_));
422 SetContentPattern(&server_patterns_, expression0_, 1);
425 bool MergeListPreference(const char* pref) {
427 ListPrefUpdate update(pref_service_.get(), pref);
428 base::ListValue* local_list_value = update.Get();
429 local_list_value->Append(new base::StringValue(url1_));
432 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
433 pref,
434 *pref_service_->GetUserPrefValue(pref),
435 server_url_list_));
437 base::ListValue expected;
438 expected.Append(new base::StringValue(url0_));
439 expected.Append(new base::StringValue(url1_));
440 return merged_value->Equals(&expected);
443 bool MergeDictionaryPreference(const char* pref) {
445 DictionaryPrefUpdate update(pref_service_.get(), pref);
446 base::DictionaryValue* local_dict_value = update.Get();
447 SetContentPattern(local_dict_value, expression1_, 1);
450 scoped_ptr<base::Value> merged_value(pref_sync_service_->MergePreference(
451 pref,
452 *pref_service_->GetUserPrefValue(pref),
453 server_patterns_));
455 base::DictionaryValue expected;
456 SetContentPattern(&expected, expression0_, 1);
457 SetContentPattern(&expected, expression1_, 1);
458 return merged_value->Equals(&expected);
461 std::string url0_;
462 std::string url1_;
463 std::string expression0_;
464 std::string expression1_;
465 std::string content_type0_;
466 base::ListValue server_url_list_;
467 base::DictionaryValue server_patterns_;
470 TEST_F(IndividualPreferenceMergeTest, ListPreference) {
471 EXPECT_TRUE(MergeListPreference(kListPrefName));
474 } // namespace
476 } // namespace syncable_prefs