Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / components / sync_preferences / pref_service_syncable_unittest.cc
1 // Copyright 2014 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_service_syncable.h"
6
7 #include <stdint.h>
8
9 #include <memory>
10
11 #include "base/json/json_reader.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/json/json_writer.h"
14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/test/metrics/histogram_tester.h"
18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "components/prefs/pref_notifier_impl.h"
20 #include "components/prefs/scoped_user_pref_update.h"
21 #include "components/prefs/testing_pref_store.h"
22 #include "components/sync/model/sync_change.h"
23 #include "components/sync/model/sync_change_processor.h"
24 #include "components/sync/model/sync_data.h"
25 #include "components/sync/model/sync_error_factory_mock.h"
26 #include "components/sync/model/syncable_service.h"
27 #include "components/sync/protocol/preference_specifics.pb.h"
28 #include "components/sync/protocol/sync.pb.h"
29 #include "components/sync_preferences/pref_model_associator.h"
30 #include "components/sync_preferences/pref_model_associator_client.h"
31 #include "components/sync_preferences/synced_pref_observer.h"
32 #include "components/sync_preferences/testing_pref_service_syncable.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34
35 using syncer::SyncChange;
36 using syncer::SyncData;
37 using testing::Eq;
38 using testing::IsEmpty;
39 using testing::Not;
40 using testing::NotNull;
41 using testing::SizeIs;
42
43 namespace sync_preferences {
44
45 namespace {
46
47 const char kExampleUrl0[] = "http://example.com/0";
48 const char kExampleUrl1[] = "http://example.com/1";
49 const char kExampleUrl2[] = "http://example.com/2";
50 const char kStringPrefName[] = "string_pref_name";
51 const char kListPrefName[] = "list_pref_name";
52 const char kDictPrefName[] = "dict_pref_name";
53 const char kUnsyncedPreferenceName[] = "nonsense_pref_name";
54 const char kUnsyncedPreferenceDefaultValue[] = "default";
55 const char kDefaultCharsetPrefName[] = "default_charset";
56 const char kNonDefaultCharsetValue[] = "foo";
57 const char kDefaultCharsetValue[] = "utf-8";
58
59 void Increment(int* num) {
60   (*num)++;
61 }
62
63 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
64  public:
65   explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
66       : output_(output), fail_next_(false) {}
67
68   syncer::SyncError ProcessSyncChanges(
69       const base::Location& from_here,
70       const syncer::SyncChangeList& change_list) override {
71     if (output_)
72       output_->insert(output_->end(), change_list.begin(), change_list.end());
73     if (fail_next_) {
74       fail_next_ = false;
75       return syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR,
76                                "Error", syncer::PREFERENCES);
77     }
78     return syncer::SyncError();
79   }
80
81   void FailNextProcessSyncChanges() { fail_next_ = true; }
82
83   syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
84     return syncer::SyncDataList();
85   }
86
87  private:
88   syncer::SyncChangeList* output_;
89   bool fail_next_;
90 };
91
92 class PrefServiceSyncableTest : public testing::Test {
93  public:
94   PrefServiceSyncableTest()
95       : pref_sync_service_(nullptr),
96         next_pref_remote_sync_node_id_(0) {}
97
98   void SetUp() override {
99     prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName,
100                                           kUnsyncedPreferenceDefaultValue);
101     prefs_.registry()->RegisterStringPref(
102         kStringPrefName, std::string(),
103         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
104     prefs_.registry()->RegisterListPref(
105         kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
106     prefs_.registry()->RegisterStringPref(
107         kDefaultCharsetPrefName, kDefaultCharsetValue,
108         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
109
110     pref_sync_service_ = static_cast<PrefModelAssociator*>(
111         prefs_.GetSyncableService(syncer::PREFERENCES));
112     ASSERT_TRUE(pref_sync_service_);
113   }
114
115   syncer::SyncChange MakeRemoteChange(int64_t id,
116                                       const std::string& name,
117                                       const base::Value& value,
118                                       SyncChange::SyncChangeType type) {
119     std::string serialized;
120     JSONStringValueSerializer json(&serialized);
121     if (!json.Serialize(value))
122       return syncer::SyncChange();
123     sync_pb::EntitySpecifics entity;
124     sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference();
125     pref_one->set_name(name);
126     pref_one->set_value(serialized);
127     return syncer::SyncChange(FROM_HERE, type,
128                               syncer::SyncData::CreateRemoteData(id, entity));
129   }
130
131   void AddToRemoteDataList(const std::string& name,
132                            const base::Value& value,
133                            syncer::SyncDataList* out) {
134     std::string serialized;
135     JSONStringValueSerializer json(&serialized);
136     ASSERT_TRUE(json.Serialize(value));
137     sync_pb::EntitySpecifics one;
138     sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
139     pref_one->set_name(name);
140     pref_one->set_value(serialized);
141     out->push_back(
142         SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, one));
143   }
144
145   void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
146                                   syncer::SyncChangeList* output) {
147     syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing(
148         syncer::PREFERENCES, initial_data,
149         std::make_unique<TestSyncProcessorStub>(output),
150         std::make_unique<syncer::SyncErrorFactoryMock>());
151     EXPECT_FALSE(r.error().IsSet());
152   }
153
154   void InitWithNoSyncData() {
155     InitWithSyncDataTakeOutput(syncer::SyncDataList(), nullptr);
156   }
157
158   const base::Value& GetPreferenceValue(const std::string& name) {
159     const PrefService::Preference* preference =
160         prefs_.FindPreference(name.c_str());
161     return *preference->GetValue();
162   }
163
164   std::unique_ptr<base::Value> FindValue(const std::string& name,
165                                          const syncer::SyncChangeList& list) {
166     auto it = list.begin();
167     for (; it != list.end(); ++it) {
168       if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) {
169         return base::JSONReader::Read(
170             it->sync_data().GetSpecifics().preference().value());
171       }
172     }
173     return nullptr;
174   }
175
176   bool IsSynced(const std::string& pref_name) {
177     return pref_sync_service_->IsPrefSynced(pref_name);
178   }
179
180   bool IsRegistered(const std::string& pref_name) {
181     return pref_sync_service_->IsPrefRegistered(pref_name.c_str());
182   }
183
184   PrefService* GetPrefs() { return &prefs_; }
185   TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; }
186
187  protected:
188   TestingPrefServiceSyncable prefs_;
189
190   PrefModelAssociator* pref_sync_service_;
191
192   int next_pref_remote_sync_node_id_;
193 };
194
195 TEST_F(PrefServiceSyncableTest, CreatePrefSyncData) {
196   prefs_.SetString(kStringPrefName, kExampleUrl0);
197
198   const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
199   syncer::SyncData sync_data;
200   EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(
201       pref->name(), *pref->GetValue(), &sync_data));
202   EXPECT_EQ(std::string(kStringPrefName),
203             syncer::SyncDataLocal(sync_data).GetTag());
204   const sync_pb::PreferenceSpecifics& specifics(
205       sync_data.GetSpecifics().preference());
206   EXPECT_EQ(std::string(kStringPrefName), specifics.name());
207
208   std::unique_ptr<base::Value> value =
209       base::JSONReader::Read(specifics.value());
210   EXPECT_TRUE(pref->GetValue()->Equals(value.get()));
211 }
212
213 TEST_F(PrefServiceSyncableTest, ModelAssociationDoNotSyncDefaults) {
214   const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
215   EXPECT_TRUE(pref->IsDefaultValue());
216   syncer::SyncChangeList out;
217   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
218
219   EXPECT_TRUE(IsRegistered(kStringPrefName));
220   EXPECT_TRUE(pref->IsDefaultValue());
221   EXPECT_FALSE(FindValue(kStringPrefName, out).get());
222 }
223
224 TEST_F(PrefServiceSyncableTest, ModelAssociationEmptyCloud) {
225   prefs_.SetString(kStringPrefName, kExampleUrl0);
226   {
227     ListPrefUpdate update(GetPrefs(), kListPrefName);
228     base::ListValue* url_list = update.Get();
229     url_list->AppendString(kExampleUrl0);
230     url_list->AppendString(kExampleUrl1);
231   }
232   syncer::SyncChangeList out;
233   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
234
235   std::unique_ptr<base::Value> value(FindValue(kStringPrefName, out));
236   ASSERT_TRUE(value.get());
237   EXPECT_TRUE(GetPreferenceValue(kStringPrefName).Equals(value.get()));
238   value = FindValue(kListPrefName, out);
239   ASSERT_TRUE(value.get());
240   EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(value.get()));
241 }
242
243 TEST_F(PrefServiceSyncableTest, ModelAssociationCloudHasData) {
244   prefs_.SetString(kStringPrefName, kExampleUrl0);
245   {
246     ListPrefUpdate update(GetPrefs(), kListPrefName);
247     base::ListValue* url_list = update.Get();
248     url_list->AppendString(kExampleUrl0);
249   }
250
251   syncer::SyncDataList in;
252   syncer::SyncChangeList out;
253   AddToRemoteDataList(kStringPrefName, base::Value(kExampleUrl1), &in);
254   base::ListValue urls_to_restore;
255   urls_to_restore.AppendString(kExampleUrl1);
256   AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
257   AddToRemoteDataList(kDefaultCharsetPrefName,
258                       base::Value(kNonDefaultCharsetValue), &in);
259   InitWithSyncDataTakeOutput(in, &out);
260
261   ASSERT_FALSE(FindValue(kStringPrefName, out).get());
262   ASSERT_FALSE(FindValue(kDefaultCharsetPrefName, out).get());
263
264   EXPECT_EQ(kExampleUrl1, prefs_.GetString(kStringPrefName));
265
266   // No associator client is registered, so lists and dictionaries should not
267   // get merged (remote write wins).
268   auto expected_urls = std::make_unique<base::ListValue>();
269   expected_urls->AppendString(kExampleUrl1);
270   EXPECT_FALSE(FindValue(kListPrefName, out));
271   EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get()));
272   EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName));
273 }
274
275 // Verifies that the implementation gracefully handles an initial remote sync
276 // data of wrong type. The local version should not get modified in these cases.
277 TEST_F(PrefServiceSyncableTest, ModelAssociationWithDataTypeMismatch) {
278   base::HistogramTester histogram_tester;
279   prefs_.SetString(kStringPrefName, kExampleUrl0);
280
281   syncer::SyncDataList in;
282   base::Value remote_int_value(123);
283   AddToRemoteDataList(kStringPrefName, remote_int_value, &in);
284   syncer::SyncChangeList out;
285   InitWithSyncDataTakeOutput(in, &out);
286   EXPECT_THAT(out, IsEmpty());
287   histogram_tester.ExpectBucketCount("Sync.Preferences.RemotePrefTypeMismatch",
288                                      true, 1);
289   EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
290 }
291
292 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
293  public:
294   TestPrefModelAssociatorClient() {}
295   ~TestPrefModelAssociatorClient() override {}
296
297   // PrefModelAssociatorClient implementation.
298   bool IsMergeableListPreference(const std::string& pref_name) const override {
299     return pref_name == kListPrefName;
300   }
301
302   bool IsMergeableDictionaryPreference(
303       const std::string& pref_name) const override {
304     return true;
305   }
306
307   std::unique_ptr<base::Value> MaybeMergePreferenceValues(
308       const std::string& pref_name,
309       const base::Value& local_value,
310       const base::Value& server_value) const override {
311     return nullptr;
312   }
313
314  private:
315   DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient);
316 };
317
318 class PrefServiceSyncableMergeTest : public testing::Test {
319  public:
320   PrefServiceSyncableMergeTest()
321       : pref_registry_(
322             base::MakeRefCounted<user_prefs::PrefRegistrySyncable>()),
323         pref_notifier_(new PrefNotifierImpl),
324         managed_prefs_(base::MakeRefCounted<TestingPrefStore>()),
325         user_prefs_(base::MakeRefCounted<TestingPrefStore>()),
326         prefs_(
327             std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
328             std::make_unique<PrefValueStore>(managed_prefs_.get(),
329                                              new TestingPrefStore,
330                                              new TestingPrefStore,
331                                              new TestingPrefStore,
332                                              user_prefs_.get(),
333                                              new TestingPrefStore,
334                                              pref_registry_->defaults().get(),
335                                              pref_notifier_),
336             user_prefs_,
337             pref_registry_,
338             &client_,
339             base::BindRepeating(&PrefServiceSyncableMergeTest::HandleReadError),
340             /*async=*/false),
341         pref_sync_service_(nullptr),
342         next_pref_remote_sync_node_id_(0) {}
343
344   void SetUp() override {
345     pref_registry_->RegisterStringPref(kUnsyncedPreferenceName,
346                                        kUnsyncedPreferenceDefaultValue);
347     pref_registry_->RegisterStringPref(
348         kStringPrefName, std::string(),
349         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
350     pref_registry_->RegisterListPref(
351         kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
352     pref_registry_->RegisterDictionaryPref(
353         kDictPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
354     pref_registry_->RegisterStringPref(
355         kDefaultCharsetPrefName, kDefaultCharsetValue,
356         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
357
358     // Downcast to PrefModelAssociator so that tests can access its' specific
359     // behavior. This is a smell. The roles between PrefServiceSyncable and
360     // PrefModelAssociator are not clearly separated (and this test should only
361     // test against the SyncableService interface).
362     pref_sync_service_ =  // static_cast<PrefModelAssociator*>(
363         prefs_.GetSyncableService(syncer::PREFERENCES);  //);
364     ASSERT_THAT(pref_sync_service_, NotNull());
365   }
366
367   /// Empty stub for prefs_ error handling.
368   static void HandleReadError(PersistentPrefStore::PrefReadError error) {}
369
370   syncer::SyncChange MakeRemoteChange(int64_t id,
371                                       const std::string& name,
372                                       const base::Value& value,
373                                       SyncChange::SyncChangeType type) {
374     std::string serialized;
375     JSONStringValueSerializer json(&serialized);
376     CHECK(json.Serialize(value));
377     sync_pb::EntitySpecifics entity;
378     sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference();
379     pref_one->set_name(name);
380     pref_one->set_value(serialized);
381     return syncer::SyncChange(FROM_HERE, type,
382                               syncer::SyncData::CreateRemoteData(id, entity));
383   }
384
385   void AddToRemoteDataList(const std::string& name,
386                            const base::Value& value,
387                            syncer::SyncDataList* out) {
388     std::string serialized;
389     JSONStringValueSerializer json(&serialized);
390     ASSERT_TRUE(json.Serialize(value));
391     sync_pb::EntitySpecifics one;
392     sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
393     pref_one->set_name(name);
394     pref_one->set_value(serialized);
395     out->push_back(
396         SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, one));
397   }
398
399   void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
400                                   syncer::SyncChangeList* output) {
401     syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing(
402         syncer::PREFERENCES, initial_data,
403         std::make_unique<TestSyncProcessorStub>(output),
404         std::make_unique<syncer::SyncErrorFactoryMock>());
405     EXPECT_FALSE(r.error().IsSet());
406   }
407
408   const base::Value& GetPreferenceValue(const std::string& name) {
409     const PrefService::Preference* preference =
410         prefs_.FindPreference(name.c_str());
411     return *preference->GetValue();
412   }
413
414   std::unique_ptr<base::Value> FindValue(const std::string& name,
415                                          const syncer::SyncChangeList& list) {
416     auto it = list.begin();
417     for (; it != list.end(); ++it) {
418       if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) {
419         return base::JSONReader::Read(
420             it->sync_data().GetSpecifics().preference().value());
421       }
422     }
423     return nullptr;
424   }
425
426  protected:
427   scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_;
428   // Owned by prefs_;
429   PrefNotifierImpl* pref_notifier_;
430   scoped_refptr<TestingPrefStore> managed_prefs_;
431   scoped_refptr<TestingPrefStore> user_prefs_;
432   TestPrefModelAssociatorClient client_;
433   PrefServiceSyncable prefs_;
434   syncer::SyncableService* pref_sync_service_;
435   int next_pref_remote_sync_node_id_;
436 };
437
438 TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedListValues) {
439   {
440     ListPrefUpdate update(&prefs_, kListPrefName);
441     base::ListValue* url_list = update.Get();
442     url_list->AppendString(kExampleUrl0);
443     url_list->AppendString(kExampleUrl1);
444   }
445
446   base::ListValue urls_to_restore;
447   urls_to_restore.AppendString(kExampleUrl1);
448   urls_to_restore.AppendString(kExampleUrl2);
449   syncer::SyncDataList in;
450   AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
451
452   syncer::SyncChangeList out;
453   InitWithSyncDataTakeOutput(in, &out);
454
455   std::unique_ptr<base::ListValue> expected_urls(new base::ListValue);
456   expected_urls->AppendString(kExampleUrl1);
457   expected_urls->AppendString(kExampleUrl2);
458   expected_urls->AppendString(kExampleUrl0);
459   std::unique_ptr<base::Value> value(FindValue(kListPrefName, out));
460   ASSERT_TRUE(value.get());
461   EXPECT_TRUE(value->Equals(expected_urls.get())) << *value;
462   EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get()));
463 }
464
465 // List preferences have special handling at association time due to our ability
466 // to merge the local and sync value. Make sure the merge logic doesn't merge
467 // managed preferences.
468 TEST_F(PrefServiceSyncableMergeTest, ManagedListPreferences) {
469   // Make the list of urls to restore on startup managed.
470   base::ListValue managed_value;
471   managed_value.AppendString(kExampleUrl0);
472   managed_value.AppendString(kExampleUrl1);
473   managed_prefs_->SetValue(kListPrefName, managed_value.CreateDeepCopy(),
474                            WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
475
476   // Set a cloud version.
477   syncer::SyncDataList in;
478   base::ListValue urls_to_restore;
479   urls_to_restore.AppendString(kExampleUrl1);
480   urls_to_restore.AppendString(kExampleUrl2);
481   AddToRemoteDataList(kListPrefName, urls_to_restore, &in);
482
483   // Start sync and verify the synced value didn't get merged.
484   {
485     syncer::SyncChangeList out;
486     InitWithSyncDataTakeOutput(in, &out);
487     EXPECT_FALSE(FindValue(kListPrefName, out).get());
488   }
489
490   // Changing the user's urls to restore on startup pref should not sync
491   // anything.
492   {
493     syncer::SyncChangeList out;
494     base::ListValue user_value;
495     user_value.AppendString("http://chromium.org");
496     prefs_.Set(kListPrefName, user_value);
497     EXPECT_FALSE(FindValue(kListPrefName, out).get());
498   }
499
500   // An incoming sync transaction should change the user value, not the managed
501   // value.
502   base::ListValue sync_value;
503   sync_value.AppendString("http://crbug.com");
504   syncer::SyncChangeList list;
505   list.push_back(MakeRemoteChange(1, kListPrefName, sync_value,
506                                   SyncChange::ACTION_UPDATE));
507   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
508
509   const base::Value* managed_prefs_result;
510   ASSERT_TRUE(managed_prefs_->GetValue(kListPrefName, &managed_prefs_result));
511   EXPECT_TRUE(managed_value.Equals(managed_prefs_result));
512   // Get should return the managed value, too.
513   EXPECT_TRUE(managed_value.Equals(prefs_.Get(kListPrefName)));
514   // Verify the user pref value has the change.
515   EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPrefValue(kListPrefName)));
516 }
517
518 TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedDictionaryValues) {
519   {
520     DictionaryPrefUpdate update(&prefs_, kDictPrefName);
521     base::DictionaryValue* dict_value = update.Get();
522     dict_value->Set("my_key1", std::make_unique<base::Value>("my_value1"));
523     dict_value->Set("my_key3", std::make_unique<base::Value>("my_value3"));
524   }
525
526   base::DictionaryValue remote_update;
527   remote_update.Set("my_key2", std::make_unique<base::Value>("my_value2"));
528   syncer::SyncDataList in;
529   AddToRemoteDataList(kDictPrefName, remote_update, &in);
530
531   syncer::SyncChangeList out;
532   InitWithSyncDataTakeOutput(in, &out);
533
534   base::DictionaryValue expected_dict;
535   expected_dict.Set("my_key1", std::make_unique<base::Value>("my_value1"));
536   expected_dict.Set("my_key2", std::make_unique<base::Value>("my_value2"));
537   expected_dict.Set("my_key3", std::make_unique<base::Value>("my_value3"));
538   std::unique_ptr<base::Value> value(FindValue(kDictPrefName, out));
539   ASSERT_TRUE(value.get());
540   EXPECT_TRUE(value->Equals(&expected_dict));
541   EXPECT_TRUE(GetPreferenceValue(kDictPrefName).Equals(&expected_dict));
542 }
543
544 TEST_F(PrefServiceSyncableMergeTest, InitWithUnknownPrefsValue) {
545   base::HistogramTester histogram_tester;
546   const std::string pref_name1 = "testing.whitelisted_pref1";
547   const std::string pref_name2 = "testing.whitelisted_pref2";
548   pref_registry_->WhitelistLateRegistrationPrefForSync(pref_name1);
549   pref_registry_->WhitelistLateRegistrationPrefForSync(pref_name2);
550
551   syncer::SyncDataList in;
552   AddToRemoteDataList(pref_name1, base::Value("remote_value1"), &in);
553   AddToRemoteDataList(pref_name2, base::Value("remote_value2"), &in);
554   syncer::SyncChangeList out;
555   InitWithSyncDataTakeOutput(in, &out);
556   pref_registry_->RegisterStringPref(
557       pref_name1, "default_value",
558       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
559   EXPECT_THAT(GetPreferenceValue(pref_name1).GetString(), Eq("remote_value1"));
560
561   histogram_tester.ExpectBucketCount("Sync.Preferences.SyncingUnknownPrefs", 2,
562                                      1);
563 }
564
565 TEST_F(PrefServiceSyncableMergeTest, ReceiveUnknownPrefsValue) {
566   base::HistogramTester histogram_tester;
567   const std::string pref_name = "testing.whitelisted_pref";
568   pref_registry_->WhitelistLateRegistrationPrefForSync(pref_name);
569
570   syncer::SyncChangeList out;
571   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
572
573   syncer::SyncChangeList remote_changes;
574   remote_changes.push_back(MakeRemoteChange(
575       1, pref_name, base::Value("remote_value"), SyncChange::ACTION_UPDATE));
576   pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
577   EXPECT_THAT(prefs_.IsPrefSynced(pref_name), Eq(true));
578
579   pref_registry_->RegisterStringPref(
580       pref_name, "default_value",
581       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
582   EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("remote_value"));
583 }
584
585 TEST_F(PrefServiceSyncableMergeTest, KeepPriorityPreferencesSeparately) {
586   base::HistogramTester histogram_tester;
587   const std::string pref_name = "testing.priority_pref";
588   pref_registry_->RegisterStringPref(
589       pref_name, "priority-default",
590       user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
591
592   syncer::SyncDataList in;
593   // AddToRemoteDataList() produces sync data for non-priority prefs.
594   AddToRemoteDataList(pref_name, base::Value("non-priority-value"), &in);
595   syncer::SyncChangeList out;
596   InitWithSyncDataTakeOutput(in, &out);
597   EXPECT_THAT(GetPreferenceValue(pref_name).GetString(),
598               Eq("priority-default"));
599 }
600
601 class ShouldNotBeNotifedObserver : public SyncedPrefObserver {
602  public:
603   ShouldNotBeNotifedObserver() {}
604   ~ShouldNotBeNotifedObserver() {}
605
606   void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
607     ADD_FAILURE() << "Unexpected notification about a pref change with path: '"
608                   << path << "' and from_sync: " << from_sync;
609   }
610 };
611
612 TEST_F(PrefServiceSyncableMergeTest, RegisterShouldClearTypeMismatchingData) {
613   base::HistogramTester histogram_tester;
614   const std::string pref_name = "testing.whitelisted_pref";
615   pref_registry_->WhitelistLateRegistrationPrefForSync(pref_name);
616   // Make sure no changes will be communicated to any synced pref listeners
617   // (those listeners are typically only used for metrics but we still don't
618   // want to inform them).
619   ShouldNotBeNotifedObserver observer;
620   prefs_.AddSyncedPrefObserver(pref_name, &observer);
621   syncer::SyncDataList in;
622   AddToRemoteDataList(pref_name, base::Value("remote_value"), &in);
623   syncer::SyncChangeList out;
624   InitWithSyncDataTakeOutput(in, &out);
625   ASSERT_THAT(out, IsEmpty());
626
627   EXPECT_TRUE(user_prefs_->GetValue(pref_name, nullptr));
628
629   pref_registry_->RegisterListPref(
630       pref_name, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
631   EXPECT_TRUE(GetPreferenceValue(pref_name).GetList().empty());
632   EXPECT_FALSE(user_prefs_->GetValue(pref_name, nullptr));
633   // Make sure the removal of the value was not communicated to sync via the
634   // SyncProcessor.
635   EXPECT_THAT(out, IsEmpty());
636
637   histogram_tester.ExpectBucketCount(
638       "Sync.Preferences.ClearedLocalPrefOnTypeMismatch", true, 1);
639   prefs_.RemoveSyncedPrefObserver(pref_name, &observer);
640 }
641
642 TEST_F(PrefServiceSyncableMergeTest, ShouldIgnoreUpdatesToNotSyncablePrefs) {
643   const std::string pref_name = "testing.not_syncable_pref";
644   pref_registry_->RegisterStringPref(pref_name, "default_value",
645                                      PrefRegistry::NO_REGISTRATION_FLAGS);
646   syncer::SyncDataList in;
647   AddToRemoteDataList(pref_name, base::Value("remote_value"), &in);
648   syncer::SyncChangeList out;
649   InitWithSyncDataTakeOutput(in, &out);
650   EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
651
652   syncer::SyncChangeList remote_changes;
653   remote_changes.push_back(MakeRemoteChange(
654       1, pref_name, base::Value("remote_value2"), SyncChange::ACTION_UPDATE));
655   pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
656   EXPECT_THAT(prefs_.IsPrefSynced(pref_name), Eq(false));
657
658   EXPECT_THAT(GetPreferenceValue(pref_name).GetString(), Eq("default_value"));
659 }
660
661 TEST_F(PrefServiceSyncableMergeTest, GetAllSyncDataForLateRegisteredPrefs) {
662   const std::string pref_name = "testing.whitelisted_pref";
663   pref_registry_->WhitelistLateRegistrationPrefForSync(pref_name);
664
665   syncer::SyncDataList in;
666   AddToRemoteDataList(pref_name, base::Value("remote_value"), &in);
667   syncer::SyncChangeList out;
668   InitWithSyncDataTakeOutput(in, &out);
669
670   syncer::SyncDataList all_data =
671       prefs_.GetSyncableService(syncer::PREFERENCES)
672           ->GetAllSyncData(syncer::PREFERENCES);
673   EXPECT_THAT(all_data, IsEmpty());
674
675   // Make sure the preference appears in the result once it's registered.
676   pref_registry_->RegisterStringPref(
677       pref_name, "default_value",
678       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
679
680   all_data = prefs_.GetSyncableService(syncer::PREFERENCES)
681                  ->GetAllSyncData(syncer::PREFERENCES);
682   ASSERT_THAT(all_data, SizeIs(1));
683   EXPECT_THAT(all_data[0].GetSpecifics().preference().name(), Eq(pref_name));
684   EXPECT_THAT(all_data[0].GetSpecifics().preference().value(),
685               Eq("\"remote_value\""));
686 }
687
688 TEST_F(PrefServiceSyncableTest, FailModelAssociation) {
689   syncer::SyncChangeList output;
690   TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output);
691   stub->FailNextProcessSyncChanges();
692   syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing(
693       syncer::PREFERENCES, syncer::SyncDataList(), base::WrapUnique(stub),
694       std::make_unique<syncer::SyncErrorFactoryMock>());
695   EXPECT_TRUE(r.error().IsSet());
696 }
697
698 TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithDefaultValue) {
699   const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
700   EXPECT_TRUE(pref->IsDefaultValue());
701
702   syncer::SyncChangeList out;
703   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
704   out.clear();
705
706   base::Value expected(kExampleUrl0);
707   GetPrefs()->Set(kStringPrefName, expected);
708
709   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
710   ASSERT_TRUE(actual.get());
711   EXPECT_TRUE(expected.Equals(actual.get()));
712 }
713
714 TEST_F(PrefServiceSyncableTest, UpdatedPreferenceWithValue) {
715   GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
716   syncer::SyncChangeList out;
717   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
718   out.clear();
719
720   base::Value expected(kExampleUrl1);
721   GetPrefs()->Set(kStringPrefName, expected);
722
723   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
724   ASSERT_TRUE(actual.get());
725   EXPECT_TRUE(expected.Equals(actual.get()));
726 }
727
728 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdate) {
729   GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
730   InitWithNoSyncData();
731
732   base::Value expected(kExampleUrl1);
733   syncer::SyncChangeList list;
734   list.push_back(MakeRemoteChange(1, kStringPrefName, expected,
735                                   SyncChange::ACTION_UPDATE));
736   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
737
738   const base::Value& actual = GetPreferenceValue(kStringPrefName);
739   EXPECT_TRUE(expected.Equals(&actual));
740 }
741
742 // Verifies that the implementation gracefully handles a remote update with the
743 // wrong type. The local version should not get modified in these cases.
744 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionUpdateTypeMismatch) {
745   base::HistogramTester histogram_tester;
746   GetPrefs()->SetString(kStringPrefName, kExampleUrl0);
747   InitWithNoSyncData();
748
749   base::Value remote_int_value(123);
750   syncer::SyncChangeList remote_changes;
751   remote_changes.push_back(MakeRemoteChange(
752       1, kStringPrefName, remote_int_value, SyncChange::ACTION_UPDATE));
753   pref_sync_service_->ProcessSyncChanges(FROM_HERE, remote_changes);
754
755   EXPECT_THAT(prefs_.GetString(kStringPrefName), Eq(kExampleUrl0));
756   histogram_tester.ExpectBucketCount("Sync.Preferences.RemotePrefTypeMismatch",
757                                      true, 1);
758 }
759
760 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeActionAdd) {
761   InitWithNoSyncData();
762
763   base::Value expected(kExampleUrl0);
764   syncer::SyncChangeList list;
765   list.push_back(
766       MakeRemoteChange(1, kStringPrefName, expected, SyncChange::ACTION_ADD));
767   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
768
769   const base::Value& actual = GetPreferenceValue(kStringPrefName);
770   EXPECT_TRUE(expected.Equals(&actual));
771   EXPECT_TRUE(pref_sync_service_->IsPrefSynced(kStringPrefName));
772 }
773
774 TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeUnknownPreference) {
775   InitWithNoSyncData();
776   syncer::SyncChangeList list;
777   base::Value expected(kExampleUrl0);
778   list.push_back(MakeRemoteChange(1, "unknown preference", expected,
779                                   SyncChange::ACTION_UPDATE));
780   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
781   // Nothing interesting happens on the client when it gets an update
782   // of an unknown preference.  We just should not crash.
783 }
784
785 TEST_F(PrefServiceSyncableTest, ManagedPreferences) {
786   // Make the homepage preference managed.
787   base::Value managed_value("http://example.com");
788   prefs_.SetManagedPref(kStringPrefName, managed_value.CreateDeepCopy());
789
790   syncer::SyncChangeList out;
791   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
792   out.clear();
793
794   // Changing the homepage preference should not sync anything.
795   base::Value user_value("http://chromium..com");
796   prefs_.SetUserPref(kStringPrefName, user_value.CreateDeepCopy());
797   EXPECT_TRUE(out.empty());
798
799   // An incoming sync transaction should change the user value, not the managed
800   // value.
801   base::Value sync_value("http://crbug.com");
802   syncer::SyncChangeList list;
803   list.push_back(MakeRemoteChange(1, kStringPrefName, sync_value,
804                                   SyncChange::ACTION_UPDATE));
805   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
806
807   EXPECT_TRUE(managed_value.Equals(prefs_.GetManagedPref(kStringPrefName)));
808   EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(kStringPrefName)));
809 }
810
811 TEST_F(PrefServiceSyncableTest, DynamicManagedPreferences) {
812   syncer::SyncChangeList out;
813   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
814   out.clear();
815   base::Value initial_value("http://example.com/initial");
816   GetPrefs()->Set(kStringPrefName, initial_value);
817   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
818   ASSERT_TRUE(actual.get());
819   EXPECT_TRUE(initial_value.Equals(actual.get()));
820
821   // Switch kHomePage to managed and set a different value.
822   base::Value managed_value("http://example.com/managed");
823   GetTestingPrefService()->SetManagedPref(kStringPrefName,
824                                           managed_value.CreateDeepCopy());
825
826   // The pref value should be the one dictated by policy.
827   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(kStringPrefName)));
828
829   // Switch kHomePage back to unmanaged.
830   GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
831
832   // The original value should be picked up.
833   EXPECT_TRUE(initial_value.Equals(&GetPreferenceValue(kStringPrefName)));
834 }
835
836 TEST_F(PrefServiceSyncableTest, DynamicManagedPreferencesWithSyncChange) {
837   syncer::SyncChangeList out;
838   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
839   out.clear();
840
841   base::Value initial_value("http://example.com/initial");
842   GetPrefs()->Set(kStringPrefName, initial_value);
843   std::unique_ptr<base::Value> actual(FindValue(kStringPrefName, out));
844   EXPECT_TRUE(initial_value.Equals(actual.get()));
845
846   // Switch kHomePage to managed and set a different value.
847   base::Value managed_value("http://example.com/managed");
848   GetTestingPrefService()->SetManagedPref(kStringPrefName,
849                                           managed_value.CreateDeepCopy());
850
851   // Change the sync value.
852   base::Value sync_value("http://example.com/sync");
853   syncer::SyncChangeList list;
854   list.push_back(MakeRemoteChange(1, kStringPrefName, sync_value,
855                                   SyncChange::ACTION_UPDATE));
856   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
857
858   // The pref value should still be the one dictated by policy.
859   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(kStringPrefName)));
860
861   // Switch kHomePage back to unmanaged.
862   GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
863
864   // Sync value should be picked up.
865   EXPECT_TRUE(sync_value.Equals(&GetPreferenceValue(kStringPrefName)));
866 }
867
868 TEST_F(PrefServiceSyncableTest, DynamicManagedDefaultPreferences) {
869   const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
870   EXPECT_TRUE(pref->IsDefaultValue());
871   syncer::SyncChangeList out;
872   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
873
874   EXPECT_TRUE(IsRegistered(kStringPrefName));
875   EXPECT_TRUE(pref->IsDefaultValue());
876   EXPECT_FALSE(FindValue(kStringPrefName, out).get());
877   out.clear();
878
879   // Switch kHomePage to managed and set a different value.
880   base::Value managed_value("http://example.com/managed");
881   GetTestingPrefService()->SetManagedPref(kStringPrefName,
882                                           managed_value.CreateDeepCopy());
883   // The pref value should be the one dictated by policy.
884   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(kStringPrefName)));
885   EXPECT_FALSE(pref->IsDefaultValue());
886   // There should be no synced value.
887   EXPECT_FALSE(FindValue(kStringPrefName, out).get());
888   // Switch kHomePage back to unmanaged.
889   GetTestingPrefService()->RemoveManagedPref(kStringPrefName);
890   // The original value should be picked up.
891   EXPECT_TRUE(pref->IsDefaultValue());
892   // There should still be no synced value.
893   EXPECT_FALSE(FindValue(kStringPrefName, out).get());
894 }
895
896 TEST_F(PrefServiceSyncableTest, DeletePreference) {
897   prefs_.SetString(kStringPrefName, kExampleUrl0);
898   const PrefService::Preference* pref = prefs_.FindPreference(kStringPrefName);
899   EXPECT_FALSE(pref->IsDefaultValue());
900
901   InitWithNoSyncData();
902
903   auto null_value = std::make_unique<base::Value>();
904   syncer::SyncChangeList list;
905   list.push_back(MakeRemoteChange(1, kStringPrefName, *null_value,
906                                   SyncChange::ACTION_DELETE));
907   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
908   EXPECT_TRUE(pref->IsDefaultValue());
909 }
910
911 TEST_F(PrefServiceSyncableTest, RegisterMergeDataFinishedCallback) {
912   int num_callbacks = 0;
913
914   prefs_.RegisterMergeDataFinishedCallback(
915       base::Bind(&Increment, &num_callbacks));
916   EXPECT_EQ(0, num_callbacks);
917
918   InitWithNoSyncData();
919   EXPECT_EQ(1, num_callbacks);
920 }
921
922 }  // namespace
923
924 }  // namespace sync_preferences