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