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