Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / prefs / prefs_syncable_service_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 "base/json/json_reader.h"
6 #include "base/json/json_string_value_serializer.h"
7 #include "base/json/json_writer.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/prefs/pref_model_associator.h"
12 #include "chrome/browser/prefs/pref_service_syncable.h"
13 #include "chrome/common/pref_names.h"
14 #include "chrome/grit/locale_settings.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "components/pref_registry/pref_registry_syncable.h"
17 #include "sync/api/attachments/attachment_id.h"
18 #include "sync/api/sync_change.h"
19 #include "sync/api/sync_data.h"
20 #include "sync/api/sync_error_factory_mock.h"
21 #include "sync/api/syncable_service.h"
22 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
23 #include "sync/protocol/preference_specifics.pb.h"
24 #include "sync/protocol/sync.pb.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using syncer::SyncChange;
28 using syncer::SyncData;
29
30 namespace {
31 const char kExampleUrl0[] = "http://example.com/0";
32 const char kExampleUrl1[] = "http://example.com/1";
33 const char kExampleUrl2[] = "http://example.com/2";
34 const char kUnsyncedPreferenceName[] = "nonsense_pref_name";
35 const char kUnsyncedPreferenceDefaultValue[] = "default";
36 const char kNonDefaultCharsetValue[] = "foo";
37 }  // namespace
38
39 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
40  public:
41   explicit TestSyncProcessorStub(syncer::SyncChangeList* output)
42       : output_(output), fail_next_(false) {}
43   syncer::SyncError ProcessSyncChanges(
44       const tracked_objects::Location& from_here,
45       const syncer::SyncChangeList& change_list) override {
46     if (output_)
47       output_->insert(output_->end(), change_list.begin(), change_list.end());
48     if (fail_next_) {
49       fail_next_ = false;
50       return syncer::SyncError(
51           FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error",
52           syncer::PREFERENCES);
53     }
54     return syncer::SyncError();
55   }
56
57   void FailNextProcessSyncChanges() {
58     fail_next_ = true;
59   }
60
61   syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override {
62     return syncer::SyncDataList();
63   }
64  private:
65   syncer::SyncChangeList* output_;
66   bool fail_next_;
67 };
68
69 class PrefsSyncableServiceTest : public testing::Test {
70  public:
71   PrefsSyncableServiceTest() :
72       pref_sync_service_(NULL),
73       test_processor_(NULL),
74       next_pref_remote_sync_node_id_(0) {}
75
76   void SetUp() override {
77     prefs_.registry()->RegisterStringPref(
78         kUnsyncedPreferenceName,
79         kUnsyncedPreferenceDefaultValue,
80         user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
81     prefs_.registry()->RegisterStringPref(
82         prefs::kHomePage,
83         std::string(),
84         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
85     prefs_.registry()->RegisterListPref(
86         prefs::kURLsToRestoreOnStartup,
87         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
88     prefs_.registry()->RegisterListPref(
89         prefs::kURLsToRestoreOnStartupOld,
90         user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
91     prefs_.registry()->RegisterLocalizedStringPref(
92         prefs::kDefaultCharset,
93         IDS_DEFAULT_ENCODING,
94         user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
95
96     pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>(
97         prefs_.GetSyncableService(syncer::PREFERENCES));
98     ASSERT_TRUE(pref_sync_service_);
99     next_pref_remote_sync_node_id_ = 0;
100   }
101
102   syncer::SyncChange MakeRemoteChange(
103       int64 id,
104       const std::string& name,
105       const base::Value& value,
106       SyncChange::SyncChangeType type) {
107     std::string serialized;
108     JSONStringValueSerializer json(&serialized);
109     if (!json.Serialize(value))
110       return syncer::SyncChange();
111     sync_pb::EntitySpecifics entity;
112     sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference();
113     pref_one->set_name(name);
114     pref_one->set_value(serialized);
115     return syncer::SyncChange(
116         FROM_HERE,
117         type,
118         syncer::SyncData::CreateRemoteData(
119             id,
120             entity,
121             base::Time(),
122             syncer::AttachmentIdList(),
123             syncer::AttachmentServiceProxyForTest::Create()));
124   }
125
126   void AddToRemoteDataList(const std::string& name,
127                            const base::Value& value,
128                            syncer::SyncDataList* out) {
129     std::string serialized;
130     JSONStringValueSerializer json(&serialized);
131     ASSERT_TRUE(json.Serialize(value));
132     sync_pb::EntitySpecifics one;
133     sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference();
134     pref_one->set_name(name);
135     pref_one->set_value(serialized);
136     out->push_back(SyncData::CreateRemoteData(
137         ++next_pref_remote_sync_node_id_,
138         one,
139         base::Time(),
140         syncer::AttachmentIdList(),
141         syncer::AttachmentServiceProxyForTest::Create()));
142   }
143
144   void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data,
145                                   syncer::SyncChangeList* output) {
146     test_processor_ = new TestSyncProcessorStub(output);
147     syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing(
148         syncer::PREFERENCES, initial_data,
149         scoped_ptr<syncer::SyncChangeProcessor>(test_processor_),
150         scoped_ptr<syncer::SyncErrorFactory>(
151             new syncer::SyncErrorFactoryMock()));
152     EXPECT_FALSE(r.error().IsSet());
153   }
154
155   void InitWithNoSyncData() {
156     InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL);
157   }
158
159   const base::Value& GetPreferenceValue(const std::string& name) {
160     const PrefService::Preference* preference =
161         prefs_.FindPreference(name.c_str());
162     return *preference->GetValue();
163   }
164
165   scoped_ptr<base::Value> FindValue(const std::string& name,
166       const syncer::SyncChangeList& list) {
167     syncer::SyncChangeList::const_iterator it = list.begin();
168     for (; it != list.end(); ++it) {
169       if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) {
170         return make_scoped_ptr(base::JSONReader::Read(
171             it->sync_data().GetSpecifics().preference().value()));
172       }
173     }
174     return scoped_ptr<base::Value>();
175   }
176
177   bool IsSynced(const std::string& pref_name) {
178     return pref_sync_service_->registered_preferences().count(pref_name) > 0;
179   }
180
181   bool HasSyncData(const std::string& pref_name) {
182     return pref_sync_service_->IsPrefSynced(pref_name);
183   }
184
185   // Returns whether a given preference name is a new name of a migrated
186   // preference. Exposed here for testing.
187   static bool IsMigratedPreference(const char* preference_name) {
188     return PrefModelAssociator::IsMigratedPreference(preference_name);
189   }
190   static bool IsOldMigratedPreference(const char* old_preference_name) {
191     return PrefModelAssociator::IsOldMigratedPreference(old_preference_name);
192   }
193
194   PrefService* GetPrefs() { return &prefs_; }
195   TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; }
196
197  protected:
198   TestingPrefServiceSyncable prefs_;
199
200   PrefModelAssociator* pref_sync_service_;
201   TestSyncProcessorStub* test_processor_;
202
203   // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest.
204   base::MessageLoop loop_;
205
206   int next_pref_remote_sync_node_id_;
207 };
208
209 TEST_F(PrefsSyncableServiceTest, CreatePrefSyncData) {
210   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
211
212   const PrefService::Preference* pref =
213       prefs_.FindPreference(prefs::kHomePage);
214   syncer::SyncData sync_data;
215   EXPECT_TRUE(pref_sync_service_->CreatePrefSyncData(pref->name(),
216       *pref->GetValue(), &sync_data));
217   EXPECT_EQ(std::string(prefs::kHomePage),
218             syncer::SyncDataLocal(sync_data).GetTag());
219   const sync_pb::PreferenceSpecifics& specifics(sync_data.GetSpecifics().
220       preference());
221   EXPECT_EQ(std::string(prefs::kHomePage), specifics.name());
222
223   scoped_ptr<base::Value> value(base::JSONReader::Read(specifics.value()));
224   EXPECT_TRUE(pref->GetValue()->Equals(value.get()));
225 }
226
227 TEST_F(PrefsSyncableServiceTest, ModelAssociationDoNotSyncDefaults) {
228   const PrefService::Preference* pref =
229       prefs_.FindPreference(prefs::kHomePage);
230   EXPECT_TRUE(pref->IsDefaultValue());
231   syncer::SyncChangeList out;
232   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
233
234   EXPECT_TRUE(IsSynced(prefs::kHomePage));
235   EXPECT_TRUE(pref->IsDefaultValue());
236   EXPECT_FALSE(FindValue(prefs::kHomePage, out).get());
237 }
238
239 TEST_F(PrefsSyncableServiceTest, ModelAssociationEmptyCloud) {
240   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
241   {
242     ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup);
243     base::ListValue* url_list = update.Get();
244     url_list->Append(new base::StringValue(kExampleUrl0));
245     url_list->Append(new base::StringValue(kExampleUrl1));
246   }
247   syncer::SyncChangeList out;
248   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
249
250   scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out));
251   ASSERT_TRUE(value.get());
252   EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage).Equals(value.get()));
253   value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass();
254   ASSERT_TRUE(value.get());
255   EXPECT_TRUE(
256       GetPreferenceValue(prefs::kURLsToRestoreOnStartup).Equals(value.get()));
257 }
258
259 TEST_F(PrefsSyncableServiceTest, ModelAssociationCloudHasData) {
260   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
261   {
262     ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup);
263     base::ListValue* url_list = update.Get();
264     url_list->Append(new base::StringValue(kExampleUrl0));
265     url_list->Append(new base::StringValue(kExampleUrl1));
266   }
267
268   syncer::SyncDataList in;
269   syncer::SyncChangeList out;
270   AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in);
271   base::ListValue urls_to_restore;
272   urls_to_restore.Append(new base::StringValue(kExampleUrl1));
273   urls_to_restore.Append(new base::StringValue(kExampleUrl2));
274   AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in);
275   AddToRemoteDataList(prefs::kDefaultCharset,
276                       base::StringValue(kNonDefaultCharsetValue),
277                       &in);
278   InitWithSyncDataTakeOutput(in, &out);
279
280   ASSERT_FALSE(FindValue(prefs::kHomePage, out).get());
281   ASSERT_FALSE(FindValue(prefs::kDefaultCharset, out).get());
282
283   EXPECT_EQ(kExampleUrl1, prefs_.GetString(prefs::kHomePage));
284
285   scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
286   expected_urls->Append(new base::StringValue(kExampleUrl1));
287   expected_urls->Append(new base::StringValue(kExampleUrl2));
288   expected_urls->Append(new base::StringValue(kExampleUrl0));
289   scoped_ptr<base::Value> value(
290       FindValue(prefs::kURLsToRestoreOnStartup, out));
291   ASSERT_TRUE(value.get());
292   EXPECT_TRUE(value->Equals(expected_urls.get()));
293   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
294               Equals(expected_urls.get()));
295   EXPECT_EQ(kNonDefaultCharsetValue,
296             prefs_.GetString(prefs::kDefaultCharset));
297 }
298
299 TEST_F(PrefsSyncableServiceTest, ModelAssociationMigrateOldData) {
300   ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
301   ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
302
303   syncer::SyncDataList in;
304   syncer::SyncChangeList out;
305   base::ListValue urls_to_restore;
306   urls_to_restore.Append(new base::StringValue(kExampleUrl1));
307   urls_to_restore.Append(new base::StringValue(kExampleUrl2));
308   AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore,
309                       &in);
310   InitWithSyncDataTakeOutput(in, &out);
311
312   // Expect that the new preference data contains the old pref's values.
313   scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
314   expected_urls->Append(new base::StringValue(kExampleUrl1));
315   expected_urls->Append(new base::StringValue(kExampleUrl2));
316
317   ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
318   scoped_ptr<base::Value> value(
319       FindValue(prefs::kURLsToRestoreOnStartup, out));
320   ASSERT_TRUE(value.get());
321   EXPECT_TRUE(value->Equals(expected_urls.get()));
322   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
323               Equals(expected_urls.get()));
324
325   // The old preference value should be the same.
326   expected_urls.reset(new base::ListValue);
327   ASSERT_FALSE(FindValue(prefs::kURLsToRestoreOnStartupOld, out).get());
328   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
329               Equals(expected_urls.get()));
330 }
331
332 TEST_F(PrefsSyncableServiceTest,
333        ModelAssociationCloudHasOldMigratedData) {
334   ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
335   ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
336   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
337   {
338     ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup);
339     base::ListValue* url_list = update.Get();
340     url_list->Append(new base::StringValue(kExampleUrl0));
341     url_list->Append(new base::StringValue(kExampleUrl1));
342   }
343
344   syncer::SyncDataList in;
345   syncer::SyncChangeList out;
346   base::ListValue urls_to_restore;
347   urls_to_restore.Append(new base::StringValue(kExampleUrl1));
348   urls_to_restore.Append(new base::StringValue(kExampleUrl2));
349   AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in);
350   AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in);
351   InitWithSyncDataTakeOutput(in, &out);
352
353   ASSERT_FALSE(FindValue(prefs::kHomePage, out).get());
354
355   // Expect that the new preference data contains the merged old prefs values.
356   scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
357   expected_urls->Append(new base::StringValue(kExampleUrl1));
358   expected_urls->Append(new base::StringValue(kExampleUrl2));
359   expected_urls->Append(new base::StringValue(kExampleUrl0));
360
361   ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
362   scoped_ptr<base::Value> value(
363       FindValue(prefs::kURLsToRestoreOnStartup, out));
364   ASSERT_TRUE(value.get());
365   EXPECT_TRUE(value->Equals(expected_urls.get()));
366   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
367               Equals(expected_urls.get()));
368
369   expected_urls.reset(new base::ListValue);
370   value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass();
371   ASSERT_TRUE(value.get());
372   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
373               Equals(expected_urls.get()));
374 }
375
376 TEST_F(PrefsSyncableServiceTest,
377        ModelAssociationCloudHasNewMigratedData) {
378   ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
379   ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
380   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
381   {
382     ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartupOld);
383     base::ListValue* url_list = update.Get();
384     url_list->Append(new base::StringValue(kExampleUrl0));
385     url_list->Append(new base::StringValue(kExampleUrl1));
386   }
387
388   syncer::SyncDataList in;
389   syncer::SyncChangeList out;
390   base::ListValue urls_to_restore;
391   urls_to_restore.Append(new base::StringValue(kExampleUrl1));
392   urls_to_restore.Append(new base::StringValue(kExampleUrl2));
393   AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld, urls_to_restore, &in);
394   AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in);
395   InitWithSyncDataTakeOutput(in, &out);
396
397   scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out));
398   ASSERT_FALSE(value.get());
399
400   // Expect that the cloud data under the new migrated preference name sticks.
401   scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
402   expected_urls->Append(new base::StringValue(kExampleUrl1));
403   expected_urls->Append(new base::StringValue(kExampleUrl2));
404
405   ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
406   value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass();
407   ASSERT_TRUE(value.get());
408   EXPECT_TRUE(value->Equals(expected_urls.get()));
409   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
410               Equals(expected_urls.get()));
411
412   // The old preference data should still be here, though not synced.
413   expected_urls.reset(new base::ListValue);
414   expected_urls->Append(new base::StringValue(kExampleUrl0));
415   expected_urls->Append(new base::StringValue(kExampleUrl1));
416
417   value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass();
418   ASSERT_FALSE(value.get());
419   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
420               Equals(expected_urls.get()));
421 }
422
423 TEST_F(PrefsSyncableServiceTest,
424        ModelAssociationCloudAddsOldAndNewMigratedData) {
425   ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup));
426   ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld));
427   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
428   {
429     ListPrefUpdate update_old(GetPrefs(), prefs::kURLsToRestoreOnStartupOld);
430     base::ListValue* url_list_old = update_old.Get();
431     url_list_old->Append(new base::StringValue(kExampleUrl0));
432     url_list_old->Append(new base::StringValue(kExampleUrl1));
433     ListPrefUpdate update(GetPrefs(), prefs::kURLsToRestoreOnStartup);
434     base::ListValue* url_list = update.Get();
435     url_list->Append(new base::StringValue(kExampleUrl1));
436     url_list->Append(new base::StringValue(kExampleUrl2));
437   }
438
439   syncer::SyncDataList in;
440   syncer::SyncChangeList out;
441   AddToRemoteDataList(prefs::kHomePage, base::StringValue(kExampleUrl1), &in);
442   InitWithSyncDataTakeOutput(in, &out);
443
444   scoped_ptr<base::Value> value(FindValue(prefs::kHomePage, out));
445   ASSERT_FALSE(value.get());
446
447   // Expect that the cloud data under the new migrated preference name sticks.
448   scoped_ptr<base::ListValue> expected_urls(new base::ListValue);
449   expected_urls->Append(new base::StringValue(kExampleUrl1));
450   expected_urls->Append(new base::StringValue(kExampleUrl2));
451
452   ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup));
453   value = FindValue(prefs::kURLsToRestoreOnStartup, out).Pass();
454   ASSERT_TRUE(value.get());
455   EXPECT_TRUE(value->Equals(expected_urls.get()));
456   EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup).
457               Equals(expected_urls.get()));
458
459   // Should not have synced in the old startup url values.
460   value = FindValue(prefs::kURLsToRestoreOnStartupOld, out).Pass();
461   ASSERT_FALSE(value.get());
462   EXPECT_FALSE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld).
463                Equals(expected_urls.get()));
464 }
465
466 TEST_F(PrefsSyncableServiceTest, FailModelAssociation) {
467   syncer::SyncChangeList output;
468   TestSyncProcessorStub* stub = new TestSyncProcessorStub(&output);
469   stub->FailNextProcessSyncChanges();
470   syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing(
471       syncer::PREFERENCES, syncer::SyncDataList(),
472       scoped_ptr<syncer::SyncChangeProcessor>(stub),
473       scoped_ptr<syncer::SyncErrorFactory>(
474           new syncer::SyncErrorFactoryMock()));
475   EXPECT_TRUE(r.error().IsSet());
476 }
477
478 TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithDefaultValue) {
479   const PrefService::Preference* pref =
480       prefs_.FindPreference(prefs::kHomePage);
481   EXPECT_TRUE(pref->IsDefaultValue());
482
483   syncer::SyncChangeList out;
484   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
485   out.clear();
486
487   base::StringValue expected(kExampleUrl0);
488   GetPrefs()->Set(prefs::kHomePage, expected);
489
490   scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out));
491   ASSERT_TRUE(actual.get());
492   EXPECT_TRUE(expected.Equals(actual.get()));
493 }
494
495 TEST_F(PrefsSyncableServiceTest, UpdatedPreferenceWithValue) {
496   GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0);
497   syncer::SyncChangeList out;
498   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
499   out.clear();
500
501   base::StringValue expected(kExampleUrl1);
502   GetPrefs()->Set(prefs::kHomePage, expected);
503
504   scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out));
505   ASSERT_TRUE(actual.get());
506   EXPECT_TRUE(expected.Equals(actual.get()));
507 }
508
509 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionUpdate) {
510   GetPrefs()->SetString(prefs::kHomePage, kExampleUrl0);
511   InitWithNoSyncData();
512
513   base::StringValue expected(kExampleUrl1);
514   syncer::SyncChangeList list;
515   list.push_back(MakeRemoteChange(
516       1, prefs::kHomePage, expected, SyncChange::ACTION_UPDATE));
517   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
518
519   const base::Value& actual = GetPreferenceValue(prefs::kHomePage);
520   EXPECT_TRUE(expected.Equals(&actual));
521 }
522
523 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeActionAdd) {
524   InitWithNoSyncData();
525
526   base::StringValue expected(kExampleUrl0);
527   syncer::SyncChangeList list;
528   list.push_back(MakeRemoteChange(
529       1, prefs::kHomePage, expected, SyncChange::ACTION_ADD));
530   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
531
532   const base::Value& actual = GetPreferenceValue(prefs::kHomePage);
533   EXPECT_TRUE(expected.Equals(&actual));
534   EXPECT_EQ(1U,
535       pref_sync_service_->registered_preferences().count(prefs::kHomePage));
536 }
537
538 TEST_F(PrefsSyncableServiceTest, UpdatedSyncNodeUnknownPreference) {
539   InitWithNoSyncData();
540   syncer::SyncChangeList list;
541   base::StringValue expected(kExampleUrl0);
542   list.push_back(MakeRemoteChange(
543       1, "unknown preference", expected, SyncChange::ACTION_UPDATE));
544   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
545   // Nothing interesting happens on the client when it gets an update
546   // of an unknown preference.  We just should not crash.
547 }
548
549 TEST_F(PrefsSyncableServiceTest, ManagedPreferences) {
550   // Make the homepage preference managed.
551   base::StringValue managed_value("http://example.com");
552   prefs_.SetManagedPref(prefs::kHomePage, managed_value.DeepCopy());
553
554   syncer::SyncChangeList out;
555   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
556   out.clear();
557
558   // Changing the homepage preference should not sync anything.
559   base::StringValue user_value("http://chromium..com");
560   prefs_.SetUserPref(prefs::kHomePage, user_value.DeepCopy());
561   EXPECT_TRUE(out.empty());
562
563   // An incoming sync transaction should change the user value, not the managed
564   // value.
565   base::StringValue sync_value("http://crbug.com");
566   syncer::SyncChangeList list;
567   list.push_back(MakeRemoteChange(
568       1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE));
569   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
570
571   EXPECT_TRUE(managed_value.Equals(prefs_.GetManagedPref(prefs::kHomePage)));
572   EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(prefs::kHomePage)));
573 }
574
575 // List preferences have special handling at association time due to our ability
576 // to merge the local and sync value. Make sure the merge logic doesn't merge
577 // managed preferences.
578 TEST_F(PrefsSyncableServiceTest, ManagedListPreferences) {
579   // Make the list of urls to restore on startup managed.
580   base::ListValue managed_value;
581   managed_value.Append(new base::StringValue(kExampleUrl0));
582   managed_value.Append(new base::StringValue(kExampleUrl1));
583   prefs_.SetManagedPref(prefs::kURLsToRestoreOnStartup,
584                          managed_value.DeepCopy());
585
586   // Set a cloud version.
587   syncer::SyncDataList in;
588   syncer::SyncChangeList out;
589   base::ListValue urls_to_restore;
590   urls_to_restore.Append(new base::StringValue(kExampleUrl1));
591   urls_to_restore.Append(new base::StringValue(kExampleUrl2));
592   AddToRemoteDataList(prefs::kURLsToRestoreOnStartup, urls_to_restore, &in);
593
594   // Start sync and verify the synced value didn't get merged.
595   InitWithSyncDataTakeOutput(in, &out);
596   EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get());
597   out.clear();
598
599   // Changing the user's urls to restore on startup pref should not sync
600   // anything.
601   base::ListValue user_value;
602   user_value.Append(new base::StringValue("http://chromium.org"));
603   prefs_.SetUserPref(prefs::kURLsToRestoreOnStartup, user_value.DeepCopy());
604   EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup, out).get());
605
606   // An incoming sync transaction should change the user value, not the managed
607   // value.
608   base::ListValue sync_value;
609   sync_value.Append(new base::StringValue("http://crbug.com"));
610   syncer::SyncChangeList list;
611   list.push_back(MakeRemoteChange(
612       1, prefs::kURLsToRestoreOnStartup, sync_value,
613       SyncChange::ACTION_UPDATE));
614   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
615
616   EXPECT_TRUE(managed_value.Equals(
617           prefs_.GetManagedPref(prefs::kURLsToRestoreOnStartup)));
618   EXPECT_TRUE(sync_value.Equals(
619           prefs_.GetUserPref(prefs::kURLsToRestoreOnStartup)));
620 }
621
622 TEST_F(PrefsSyncableServiceTest, DynamicManagedPreferences) {
623   syncer::SyncChangeList out;
624   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
625   out.clear();
626   base::StringValue initial_value("http://example.com/initial");
627   GetPrefs()->Set(prefs::kHomePage, initial_value);
628   scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out));
629   ASSERT_TRUE(actual.get());
630   EXPECT_TRUE(initial_value.Equals(actual.get()));
631
632   // Switch kHomePage to managed and set a different value.
633   base::StringValue managed_value("http://example.com/managed");
634   GetTestingPrefService()->SetManagedPref(prefs::kHomePage,
635                                                     managed_value.DeepCopy());
636
637   // The pref value should be the one dictated by policy.
638   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage)));
639
640   // Switch kHomePage back to unmanaged.
641   GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
642
643   // The original value should be picked up.
644   EXPECT_TRUE(initial_value.Equals(&GetPreferenceValue(prefs::kHomePage)));
645 }
646
647 TEST_F(PrefsSyncableServiceTest,
648        DynamicManagedPreferencesWithSyncChange) {
649   syncer::SyncChangeList out;
650   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
651   out.clear();
652
653   base::StringValue initial_value("http://example.com/initial");
654   GetPrefs()->Set(prefs::kHomePage, initial_value);
655   scoped_ptr<base::Value> actual(FindValue(prefs::kHomePage, out));
656   EXPECT_TRUE(initial_value.Equals(actual.get()));
657
658   // Switch kHomePage to managed and set a different value.
659   base::StringValue managed_value("http://example.com/managed");
660   GetTestingPrefService()->SetManagedPref(prefs::kHomePage,
661                                                     managed_value.DeepCopy());
662
663   // Change the sync value.
664   base::StringValue sync_value("http://example.com/sync");
665   syncer::SyncChangeList list;
666   list.push_back(MakeRemoteChange(
667       1, prefs::kHomePage, sync_value, SyncChange::ACTION_UPDATE));
668   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
669
670   // The pref value should still be the one dictated by policy.
671   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage)));
672
673   // Switch kHomePage back to unmanaged.
674   GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
675
676   // Sync value should be picked up.
677   EXPECT_TRUE(sync_value.Equals(&GetPreferenceValue(prefs::kHomePage)));
678 }
679
680 TEST_F(PrefsSyncableServiceTest, DynamicManagedDefaultPreferences) {
681   const PrefService::Preference* pref =
682       prefs_.FindPreference(prefs::kHomePage);
683   EXPECT_TRUE(pref->IsDefaultValue());
684   syncer::SyncChangeList out;
685   InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out);
686
687   EXPECT_TRUE(IsSynced(prefs::kHomePage));
688   EXPECT_TRUE(pref->IsDefaultValue());
689   EXPECT_FALSE(FindValue(prefs::kHomePage, out).get());
690   out.clear();
691
692   // Switch kHomePage to managed and set a different value.
693   base::StringValue managed_value("http://example.com/managed");
694   GetTestingPrefService()->SetManagedPref(prefs::kHomePage,
695                                           managed_value.DeepCopy());
696   // The pref value should be the one dictated by policy.
697   EXPECT_TRUE(managed_value.Equals(&GetPreferenceValue(prefs::kHomePage)));
698   EXPECT_FALSE(pref->IsDefaultValue());
699   // There should be no synced value.
700   EXPECT_FALSE(FindValue(prefs::kHomePage, out).get());
701   // Switch kHomePage back to unmanaged.
702   GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage);
703   // The original value should be picked up.
704   EXPECT_TRUE(pref->IsDefaultValue());
705   // There should still be no synced value.
706   EXPECT_FALSE(FindValue(prefs::kHomePage, out).get());
707 }
708
709 TEST_F(PrefsSyncableServiceTest, DeletePreference) {
710   prefs_.SetString(prefs::kHomePage, kExampleUrl0);
711   const PrefService::Preference* pref =
712       prefs_.FindPreference(prefs::kHomePage);
713   EXPECT_FALSE(pref->IsDefaultValue());
714
715   InitWithNoSyncData();
716
717   scoped_ptr<base::Value> null_value(base::Value::CreateNullValue());
718   syncer::SyncChangeList list;
719   list.push_back(MakeRemoteChange(
720       1, prefs::kHomePage, *null_value, SyncChange::ACTION_DELETE));
721   pref_sync_service_->ProcessSyncChanges(FROM_HERE, list);
722   EXPECT_TRUE(pref->IsDefaultValue());
723 }