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.
5 #include "chrome/browser/prefs/pref_service_syncable.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_string_value_serializer.h"
9 #include "base/json/json_writer.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/prefs/pref_model_associator.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/grit/locale_settings.h"
16 #include "chrome/test/base/testing_pref_service_syncable.h"
17 #include "components/content_settings/core/browser/content_settings_registry.h"
18 #include "components/pref_registry/pref_registry_syncable.h"
19 #include "sync/api/attachments/attachment_id.h"
20 #include "sync/api/sync_change.h"
21 #include "sync/api/sync_data.h"
22 #include "sync/api/sync_error_factory_mock.h"
23 #include "sync/api/syncable_service.h"
24 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
25 #include "sync/protocol/preference_specifics.pb.h"
26 #include "sync/protocol/sync.pb.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "ui/base/l10n/l10n_util.h"
30 using syncer::SyncChange
;
31 using syncer::SyncData
;
34 const char kExampleUrl0
[] = "http://example.com/0";
35 const char kExampleUrl1
[] = "http://example.com/1";
36 const char kExampleUrl2
[] = "http://example.com/2";
37 const char kUnsyncedPreferenceName
[] = "nonsense_pref_name";
38 const char kUnsyncedPreferenceDefaultValue
[] = "default";
39 const char kNonDefaultCharsetValue
[] = "foo";
42 class TestSyncProcessorStub
: public syncer::SyncChangeProcessor
{
44 explicit TestSyncProcessorStub(syncer::SyncChangeList
* output
)
45 : output_(output
), fail_next_(false) {}
46 syncer::SyncError
ProcessSyncChanges(
47 const tracked_objects::Location
& from_here
,
48 const syncer::SyncChangeList
& change_list
) override
{
50 output_
->insert(output_
->end(), change_list
.begin(), change_list
.end());
53 return syncer::SyncError(
54 FROM_HERE
, syncer::SyncError::DATATYPE_ERROR
, "Error",
57 return syncer::SyncError();
60 void FailNextProcessSyncChanges() {
64 syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const override
{
65 return syncer::SyncDataList();
68 syncer::SyncChangeList
* output_
;
72 class PrefServiceSyncableTest
: public testing::Test
{
74 PrefServiceSyncableTest()
75 : pref_sync_service_(NULL
),
76 test_processor_(NULL
),
77 next_pref_remote_sync_node_id_(0) {}
79 void SetUp() override
{
80 // Ensure all content settings are initialized. TODO(raymes): remove this
81 // once WebsiteSettingsRegistry is properly iterable.
82 content_settings::ContentSettingsRegistry::GetInstance();
84 prefs_
.registry()->RegisterStringPref(kUnsyncedPreferenceName
,
85 kUnsyncedPreferenceDefaultValue
);
86 prefs_
.registry()->RegisterStringPref(
89 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
90 prefs_
.registry()->RegisterListPref(
91 prefs::kURLsToRestoreOnStartup
,
92 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
93 prefs_
.registry()->RegisterListPref(prefs::kURLsToRestoreOnStartupOld
);
94 prefs_
.registry()->RegisterStringPref(
95 prefs::kDefaultCharset
,
96 l10n_util::GetStringUTF8(IDS_DEFAULT_ENCODING
),
97 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
99 pref_sync_service_
= reinterpret_cast<PrefModelAssociator
*>(
100 prefs_
.GetSyncableService(syncer::PREFERENCES
));
101 ASSERT_TRUE(pref_sync_service_
);
102 next_pref_remote_sync_node_id_
= 0;
105 syncer::SyncChange
MakeRemoteChange(
107 const std::string
& name
,
108 const base::Value
& value
,
109 SyncChange::SyncChangeType type
) {
110 std::string serialized
;
111 JSONStringValueSerializer
json(&serialized
);
112 if (!json
.Serialize(value
))
113 return syncer::SyncChange();
114 sync_pb::EntitySpecifics entity
;
115 sync_pb::PreferenceSpecifics
* pref_one
= entity
.mutable_preference();
116 pref_one
->set_name(name
);
117 pref_one
->set_value(serialized
);
118 return syncer::SyncChange(
121 syncer::SyncData::CreateRemoteData(
125 syncer::AttachmentIdList(),
126 syncer::AttachmentServiceProxyForTest::Create()));
129 void AddToRemoteDataList(const std::string
& name
,
130 const base::Value
& value
,
131 syncer::SyncDataList
* out
) {
132 std::string serialized
;
133 JSONStringValueSerializer
json(&serialized
);
134 ASSERT_TRUE(json
.Serialize(value
));
135 sync_pb::EntitySpecifics one
;
136 sync_pb::PreferenceSpecifics
* pref_one
= one
.mutable_preference();
137 pref_one
->set_name(name
);
138 pref_one
->set_value(serialized
);
139 out
->push_back(SyncData::CreateRemoteData(
140 ++next_pref_remote_sync_node_id_
,
143 syncer::AttachmentIdList(),
144 syncer::AttachmentServiceProxyForTest::Create()));
147 void InitWithSyncDataTakeOutput(const syncer::SyncDataList
& initial_data
,
148 syncer::SyncChangeList
* output
) {
149 test_processor_
= new TestSyncProcessorStub(output
);
150 syncer::SyncMergeResult r
= pref_sync_service_
->MergeDataAndStartSyncing(
151 syncer::PREFERENCES
, initial_data
,
152 scoped_ptr
<syncer::SyncChangeProcessor
>(test_processor_
),
153 scoped_ptr
<syncer::SyncErrorFactory
>(
154 new syncer::SyncErrorFactoryMock()));
155 EXPECT_FALSE(r
.error().IsSet());
158 void InitWithNoSyncData() {
159 InitWithSyncDataTakeOutput(syncer::SyncDataList(), NULL
);
162 const base::Value
& GetPreferenceValue(const std::string
& name
) {
163 const PrefService::Preference
* preference
=
164 prefs_
.FindPreference(name
.c_str());
165 return *preference
->GetValue();
168 scoped_ptr
<base::Value
> FindValue(const std::string
& name
,
169 const syncer::SyncChangeList
& list
) {
170 syncer::SyncChangeList::const_iterator it
= list
.begin();
171 for (; it
!= list
.end(); ++it
) {
172 if (syncer::SyncDataLocal(it
->sync_data()).GetTag() == name
) {
173 return make_scoped_ptr(base::JSONReader::DeprecatedRead(
174 it
->sync_data().GetSpecifics().preference().value()));
177 return scoped_ptr
<base::Value
>();
180 bool IsSynced(const std::string
& pref_name
) {
181 return pref_sync_service_
->registered_preferences().count(pref_name
) > 0;
184 bool HasSyncData(const std::string
& pref_name
) {
185 return pref_sync_service_
->IsPrefSynced(pref_name
);
188 // Returns whether a given preference name is a new name of a migrated
189 // preference. Exposed here for testing.
190 static bool IsMigratedPreference(const char* preference_name
) {
191 return PrefModelAssociator::IsMigratedPreference(preference_name
);
193 static bool IsOldMigratedPreference(const char* old_preference_name
) {
194 return PrefModelAssociator::IsOldMigratedPreference(old_preference_name
);
197 PrefService
* GetPrefs() { return &prefs_
; }
198 TestingPrefServiceSyncable
* GetTestingPrefService() { return &prefs_
; }
201 TestingPrefServiceSyncable prefs_
;
203 PrefModelAssociator
* pref_sync_service_
;
204 TestSyncProcessorStub
* test_processor_
;
206 // TODO(tim): Remove this by fixing AttachmentServiceProxyForTest.
207 base::MessageLoop loop_
;
209 int next_pref_remote_sync_node_id_
;
212 TEST_F(PrefServiceSyncableTest
, CreatePrefSyncData
) {
213 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
215 const PrefService::Preference
* pref
=
216 prefs_
.FindPreference(prefs::kHomePage
);
217 syncer::SyncData sync_data
;
218 EXPECT_TRUE(pref_sync_service_
->CreatePrefSyncData(pref
->name(),
219 *pref
->GetValue(), &sync_data
));
220 EXPECT_EQ(std::string(prefs::kHomePage
),
221 syncer::SyncDataLocal(sync_data
).GetTag());
222 const sync_pb::PreferenceSpecifics
& specifics(sync_data
.GetSpecifics().
224 EXPECT_EQ(std::string(prefs::kHomePage
), specifics
.name());
226 scoped_ptr
<base::Value
> value
= base::JSONReader::Read(specifics
.value());
227 EXPECT_TRUE(pref
->GetValue()->Equals(value
.get()));
230 TEST_F(PrefServiceSyncableTest
, ModelAssociationDoNotSyncDefaults
) {
231 const PrefService::Preference
* pref
=
232 prefs_
.FindPreference(prefs::kHomePage
);
233 EXPECT_TRUE(pref
->IsDefaultValue());
234 syncer::SyncChangeList out
;
235 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
237 EXPECT_TRUE(IsSynced(prefs::kHomePage
));
238 EXPECT_TRUE(pref
->IsDefaultValue());
239 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
242 TEST_F(PrefServiceSyncableTest
, ModelAssociationEmptyCloud
) {
243 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
245 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
246 base::ListValue
* url_list
= update
.Get();
247 url_list
->Append(new base::StringValue(kExampleUrl0
));
248 url_list
->Append(new base::StringValue(kExampleUrl1
));
250 syncer::SyncChangeList out
;
251 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
253 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
254 ASSERT_TRUE(value
.get());
255 EXPECT_TRUE(GetPreferenceValue(prefs::kHomePage
).Equals(value
.get()));
256 value
= FindValue(prefs::kURLsToRestoreOnStartup
, out
).Pass();
257 ASSERT_TRUE(value
.get());
259 GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).Equals(value
.get()));
262 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasData
) {
263 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
265 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
266 base::ListValue
* url_list
= update
.Get();
267 url_list
->Append(new base::StringValue(kExampleUrl0
));
268 url_list
->Append(new base::StringValue(kExampleUrl1
));
271 syncer::SyncDataList in
;
272 syncer::SyncChangeList out
;
273 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
274 base::ListValue urls_to_restore
;
275 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
276 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
277 AddToRemoteDataList(prefs::kURLsToRestoreOnStartup
, urls_to_restore
, &in
);
278 AddToRemoteDataList(prefs::kDefaultCharset
,
279 base::StringValue(kNonDefaultCharsetValue
),
281 InitWithSyncDataTakeOutput(in
, &out
);
283 ASSERT_FALSE(FindValue(prefs::kHomePage
, out
).get());
284 ASSERT_FALSE(FindValue(prefs::kDefaultCharset
, out
).get());
286 EXPECT_EQ(kExampleUrl1
, prefs_
.GetString(prefs::kHomePage
));
288 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
289 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
290 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
291 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
292 scoped_ptr
<base::Value
> value(
293 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
294 ASSERT_TRUE(value
.get());
295 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
296 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
297 Equals(expected_urls
.get()));
298 EXPECT_EQ(kNonDefaultCharsetValue
,
299 prefs_
.GetString(prefs::kDefaultCharset
));
302 TEST_F(PrefServiceSyncableTest
, ModelAssociationMigrateOldData
) {
303 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
304 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
306 syncer::SyncDataList in
;
307 syncer::SyncChangeList out
;
308 base::ListValue urls_to_restore
;
309 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
310 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
311 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld
, urls_to_restore
,
313 InitWithSyncDataTakeOutput(in
, &out
);
315 // Expect that the new preference data contains the old pref's values.
316 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
317 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
318 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
320 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
321 scoped_ptr
<base::Value
> value(
322 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
323 ASSERT_TRUE(value
.get());
324 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
325 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
326 Equals(expected_urls
.get()));
328 // The old preference value should be the same.
329 expected_urls
.reset(new base::ListValue
);
330 ASSERT_FALSE(FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).get());
331 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
332 Equals(expected_urls
.get()));
335 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasOldMigratedData
) {
336 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
337 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
338 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
340 ListPrefUpdate
update(GetPrefs(), prefs::kURLsToRestoreOnStartup
);
341 base::ListValue
* url_list
= update
.Get();
342 url_list
->Append(new base::StringValue(kExampleUrl0
));
343 url_list
->Append(new base::StringValue(kExampleUrl1
));
346 syncer::SyncDataList in
;
347 syncer::SyncChangeList out
;
348 base::ListValue urls_to_restore
;
349 urls_to_restore
.Append(new base::StringValue(kExampleUrl1
));
350 urls_to_restore
.Append(new base::StringValue(kExampleUrl2
));
351 AddToRemoteDataList(prefs::kURLsToRestoreOnStartupOld
, urls_to_restore
, &in
);
352 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
353 InitWithSyncDataTakeOutput(in
, &out
);
355 ASSERT_FALSE(FindValue(prefs::kHomePage
, out
).get());
357 // Expect that the new preference data contains the merged old prefs values.
358 scoped_ptr
<base::ListValue
> expected_urls(new base::ListValue
);
359 expected_urls
->Append(new base::StringValue(kExampleUrl1
));
360 expected_urls
->Append(new base::StringValue(kExampleUrl2
));
361 expected_urls
->Append(new base::StringValue(kExampleUrl0
));
363 ASSERT_TRUE(HasSyncData(prefs::kURLsToRestoreOnStartup
));
364 scoped_ptr
<base::Value
> value(
365 FindValue(prefs::kURLsToRestoreOnStartup
, out
));
366 ASSERT_TRUE(value
.get());
367 EXPECT_TRUE(value
->Equals(expected_urls
.get()));
368 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartup
).
369 Equals(expected_urls
.get()));
371 expected_urls
.reset(new base::ListValue
);
372 value
= FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).Pass();
373 ASSERT_TRUE(value
.get());
374 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
375 Equals(expected_urls
.get()));
378 TEST_F(PrefServiceSyncableTest
, ModelAssociationCloudHasNewMigratedData
) {
379 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
380 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
381 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
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
));
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
);
398 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
399 ASSERT_FALSE(value
.get());
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
));
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()));
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
));
418 value
= FindValue(prefs::kURLsToRestoreOnStartupOld
, out
).Pass();
419 ASSERT_FALSE(value
.get());
420 EXPECT_TRUE(GetPreferenceValue(prefs::kURLsToRestoreOnStartupOld
).
421 Equals(expected_urls
.get()));
424 TEST_F(PrefServiceSyncableTest
,
425 ModelAssociationCloudAddsOldAndNewMigratedData
) {
426 ASSERT_TRUE(IsMigratedPreference(prefs::kURLsToRestoreOnStartup
));
427 ASSERT_TRUE(IsOldMigratedPreference(prefs::kURLsToRestoreOnStartupOld
));
428 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
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
));
440 syncer::SyncDataList in
;
441 syncer::SyncChangeList out
;
442 AddToRemoteDataList(prefs::kHomePage
, base::StringValue(kExampleUrl1
), &in
);
443 InitWithSyncDataTakeOutput(in
, &out
);
445 scoped_ptr
<base::Value
> value(FindValue(prefs::kHomePage
, out
));
446 ASSERT_FALSE(value
.get());
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
));
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()));
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()));
467 TEST_F(PrefServiceSyncableTest
, 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());
479 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithDefaultValue
) {
480 const PrefService::Preference
* pref
=
481 prefs_
.FindPreference(prefs::kHomePage
);
482 EXPECT_TRUE(pref
->IsDefaultValue());
484 syncer::SyncChangeList out
;
485 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
488 base::StringValue
expected(kExampleUrl0
);
489 GetPrefs()->Set(prefs::kHomePage
, expected
);
491 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
492 ASSERT_TRUE(actual
.get());
493 EXPECT_TRUE(expected
.Equals(actual
.get()));
496 TEST_F(PrefServiceSyncableTest
, UpdatedPreferenceWithValue
) {
497 GetPrefs()->SetString(prefs::kHomePage
, kExampleUrl0
);
498 syncer::SyncChangeList out
;
499 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
502 base::StringValue
expected(kExampleUrl1
);
503 GetPrefs()->Set(prefs::kHomePage
, expected
);
505 scoped_ptr
<base::Value
> actual(FindValue(prefs::kHomePage
, out
));
506 ASSERT_TRUE(actual
.get());
507 EXPECT_TRUE(expected
.Equals(actual
.get()));
510 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionUpdate
) {
511 GetPrefs()->SetString(prefs::kHomePage
, kExampleUrl0
);
512 InitWithNoSyncData();
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
);
520 const base::Value
& actual
= GetPreferenceValue(prefs::kHomePage
);
521 EXPECT_TRUE(expected
.Equals(&actual
));
524 TEST_F(PrefServiceSyncableTest
, UpdatedSyncNodeActionAdd
) {
525 InitWithNoSyncData();
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
);
533 const base::Value
& actual
= GetPreferenceValue(prefs::kHomePage
);
534 EXPECT_TRUE(expected
.Equals(&actual
));
536 pref_sync_service_
->registered_preferences().count(prefs::kHomePage
));
539 TEST_F(PrefServiceSyncableTest
, 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.
550 TEST_F(PrefServiceSyncableTest
, ManagedPreferences
) {
551 // Make the homepage preference managed.
552 base::StringValue
managed_value("http://example.com");
553 prefs_
.SetManagedPref(prefs::kHomePage
, managed_value
.DeepCopy());
555 syncer::SyncChangeList out
;
556 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
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());
564 // An incoming sync transaction should change the user value, not the managed
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
);
572 EXPECT_TRUE(managed_value
.Equals(prefs_
.GetManagedPref(prefs::kHomePage
)));
573 EXPECT_TRUE(sync_value
.Equals(prefs_
.GetUserPref(prefs::kHomePage
)));
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(PrefServiceSyncableTest
, 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());
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
);
595 // Start sync and verify the synced value didn't get merged.
596 InitWithSyncDataTakeOutput(in
, &out
);
597 EXPECT_FALSE(FindValue(prefs::kURLsToRestoreOnStartup
, out
).get());
600 // Changing the user's urls to restore on startup pref should not sync
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());
607 // An incoming sync transaction should change the user value, not the managed
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
);
617 EXPECT_TRUE(managed_value
.Equals(
618 prefs_
.GetManagedPref(prefs::kURLsToRestoreOnStartup
)));
619 EXPECT_TRUE(sync_value
.Equals(
620 prefs_
.GetUserPref(prefs::kURLsToRestoreOnStartup
)));
623 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferences
) {
624 syncer::SyncChangeList out
;
625 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
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()));
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());
638 // The pref value should be the one dictated by policy.
639 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
641 // Switch kHomePage back to unmanaged.
642 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage
);
644 // The original value should be picked up.
645 EXPECT_TRUE(initial_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
648 TEST_F(PrefServiceSyncableTest
, DynamicManagedPreferencesWithSyncChange
) {
649 syncer::SyncChangeList out
;
650 InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out
);
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()));
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());
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
);
670 // The pref value should still be the one dictated by policy.
671 EXPECT_TRUE(managed_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
673 // Switch kHomePage back to unmanaged.
674 GetTestingPrefService()->RemoveManagedPref(prefs::kHomePage
);
676 // Sync value should be picked up.
677 EXPECT_TRUE(sync_value
.Equals(&GetPreferenceValue(prefs::kHomePage
)));
680 TEST_F(PrefServiceSyncableTest
, 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
);
687 EXPECT_TRUE(IsSynced(prefs::kHomePage
));
688 EXPECT_TRUE(pref
->IsDefaultValue());
689 EXPECT_FALSE(FindValue(prefs::kHomePage
, out
).get());
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());
709 TEST_F(PrefServiceSyncableTest
, DeletePreference
) {
710 prefs_
.SetString(prefs::kHomePage
, kExampleUrl0
);
711 const PrefService::Preference
* pref
=
712 prefs_
.FindPreference(prefs::kHomePage
);
713 EXPECT_FALSE(pref
->IsDefaultValue());
715 InitWithNoSyncData();
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());